How to write regex expression for this type of text? - html

I'm trying to extract the price from the following HTML.
<td>$75.00/<span class='small font-weight-bold text-
danger'>Piece</span></small> *some more text here* </td>
What is the regex expression to get the number 75.00?
Is it something like:
<td>$*/<span class='small font-weight-bold text-danger'>

The dollar sign is a special character in regex, so you need to escape it with a backslash. Also, you only want to capture digits, so you should use character classes.
<td>\$(\d+[.]\d\d)<span
As the other respondent mentioned, regex changes a bit with each implementing language, so you may have to make some adjustments, but this should get you started.

I think you can go with /[0-9]+\.[0-9]+/.
[0-9] matches a single number. In this example you should get the number 7.
The + afterwards just says that it should look for more then just one number. So [0-9]+ will match with 75. It stops there because the character after 5 is a period.
Said so we will add a period to the regex and make sure it's escaped. A period usually means "every character". By escaping it will just look for a period. So we have /[0-9]+\./ so far.
Next we just to add [0-9]+ so it will find the other number(s) too.
It's important that you don't give it the global-flag like this /[0-9]+\.[0-9]+/g. Unless you want it to find more then just the first number/period-combination.
There is another regex you can use. It uses the parentheses to group the part you're looking for like this: /<td>\$(.+)<span/
It will match everything from <td>$ up to <span. From there you can filter out the group/part you're looking for. See the examples below.
// JavaScript
const text = "<td>$something<span class='small font-weight..."
const regex = /<td>\$(.+)<span/g
const match = regex.exec(text) // this will return an Array
console.log( match[1] ) // prints out "something"
// python
text = "<td>$something<span class='small font-weight..."
regex = re.compile(r"<td>\$(.+)<span")
print( regex.search(text).group(1) ) // prints out "something"

As an alternative you could use a DOMParser.
Wrap your <td> inside a table, use for example querySelector to get your element and get the first node from the childNodes.
That would give you $75.00/.
To remove the $ and the trailing forward slash you could use slice or use a regex like \$(\d+\.\d+) and get the value from capture group 1.
let html = `<table><tr><td>$75.00/<span class='small font-weight-bold text-
danger'>Piece</span></small> *some more text here* </td></tr></table>`;
let parser = new DOMParser();
let doc = parser.parseFromString(html, "text/html");
let result = doc.querySelector("td");
let textContent = result.childNodes.item(0).nodeValue;
console.log(textContent.slice(1, -1));
console.log(textContent.match(/\$(\d+\.\d+)/)[1]);

Related

Appending long snippets of html in jquery [duplicate]

I have the following code in Ruby. I want to convert this code into JavaScript. What is the equivalent code in JS?
text = <<"HERE"
This
Is
A
Multiline
String
HERE
Update:
ECMAScript 6 (ES6) introduces a new type of literal, namely template literals. They have many features, variable interpolation among others, but most importantly for this question, they can be multiline.
A template literal is delimited by backticks:
var html = `
<div>
<span>Some HTML here</span>
</div>
`;
(Note: I'm not advocating to use HTML in strings)
Browser support is OK, but you can use transpilers to be more compatible.
Original ES5 answer:
Javascript doesn't have a here-document syntax. You can escape the literal newline, however, which comes close:
"foo \
bar"
ES6 Update:
As the first answer mentions, with ES6/Babel, you can now create multi-line strings simply by using backticks:
const htmlString = `Say hello to
multi-line
strings!`;
Interpolating variables is a popular new feature that comes with back-tick delimited strings:
const htmlString = `${user.name} liked your post about strings`;
This just transpiles down to concatenation:
user.name + ' liked your post about strings'
Original ES5 answer:
Google's JavaScript style guide recommends to use string concatenation instead of escaping newlines:
Do not do this:
var myString = 'A rather long string of English text, an error message \
actually that just keeps going and going -- an error \
message to make the Energizer bunny blush (right through \
those Schwarzenegger shades)! Where was I? Oh yes, \
you\'ve got an error and all the extraneous whitespace is \
just gravy. Have a nice day.';
The whitespace at the beginning of each line can't be safely stripped at compile time; whitespace after the slash will result in tricky errors; and while most script engines support this, it is not part of ECMAScript.
Use string concatenation instead:
var myString = 'A rather long string of English text, an error message ' +
'actually that just keeps going and going -- an error ' +
'message to make the Energizer bunny blush (right through ' +
'those Schwarzenegger shades)! Where was I? Oh yes, ' +
'you\'ve got an error and all the extraneous whitespace is ' +
'just gravy. Have a nice day.';
the pattern text = <<"HERE" This Is A Multiline String HERE is not available in js (I remember using it much in my good old Perl days).
To keep oversight with complex or long multiline strings I sometimes use an array pattern:
var myString =
['<div id="someId">',
'some content<br />',
'someRefTxt',
'</div>'
].join('\n');
or the pattern anonymous already showed (escape newline), which can be an ugly block in your code:
var myString =
'<div id="someId"> \
some content<br /> \
someRefTxt \
</div>';
Here's another weird but working 'trick'1:
var myString = (function () {/*
<div id="someId">
some content<br />
someRefTxt
</div>
*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];
external edit: jsfiddle
ES20xx supports spanning strings over multiple lines using template strings:
let str = `This is a text
with multiple lines.
Escapes are interpreted,
\n is a newline.`;
let str = String.raw`This is a text
with multiple lines.
Escapes are not interpreted,
\n is not a newline.`;
1 Note: this will be lost after minifying/obfuscating your code
You can have multiline strings in pure JavaScript.
This method is based on the serialization of functions, which is defined to be implementation-dependent. It does work in the most browsers (see below), but there's no guarantee that it will still work in the future, so do not rely on it.
Using the following function:
function hereDoc(f) {
return f.toString().
replace(/^[^\/]+\/\*!?/, '').
replace(/\*\/[^\/]+$/, '');
}
You can have here-documents like this:
var tennysonQuote = hereDoc(function() {/*!
Theirs not to make reply,
Theirs not to reason why,
Theirs but to do and die
*/});
The method has successfully been tested in the following browsers (not mentioned = not tested):
IE 4 - 10
Opera 9.50 - 12 (not in 9-)
Safari 4 - 6 (not in 3-)
Chrome 1 - 45
Firefox 17 - 21 (not in 16-)
Rekonq 0.7.0 - 0.8.0
Not supported in Konqueror 4.7.4
Be careful with your minifier, though. It tends to remove comments. For the YUI compressor, a comment starting with /*! (like the one I used) will be preserved.
I think a real solution would be to use CoffeeScript.
ES6 UPDATE: You could use backtick instead of creating a function with a comment and running toString on the comment. The regex would need to be updated to only strip spaces. You could also have a string prototype method for doing this:
let foo = `
bar loves cake
baz loves beer
beer loves people
`.removeIndentation()
Someone should write this .removeIndentation string method... ;)
You can do this...
var string = 'This is\n' +
'a multiline\n' +
'string';
I came up with this very jimmy rigged method of a multi lined string. Since converting a function into a string also returns any comments inside the function you can use the comments as your string using a multilined comment /**/. You just have to trim off the ends and you have your string.
var myString = function(){/*
This is some
awesome multi-lined
string using a comment
inside a function
returned as a string.
Enjoy the jimmy rigged code.
*/}.toString().slice(14,-3)
alert(myString)
I'm surprised I didn't see this, because it works everywhere I've tested it and is very useful for e.g. templates:
<script type="bogus" id="multi">
My
multiline
string
</script>
<script>
alert($('#multi').html());
</script>
Does anybody know of an environment where there is HTML but it doesn't work?
I solved this by outputting a div, making it hidden, and calling the div id by jQuery when I needed it.
e.g.
<div id="UniqueID" style="display:none;">
Strings
On
Multiple
Lines
Here
</div>
Then when I need to get the string, I just use the following jQuery:
$('#UniqueID').html();
Which returns my text on multiple lines. If I call
alert($('#UniqueID').html());
I get:
There are multiple ways to achieve this
1. Slash concatenation
var MultiLine= '1\
2\
3\
4\
5\
6\
7\
8\
9';
2. regular concatenation
var MultiLine = '1'
+'2'
+'3'
+'4'
+'5';
3. Array Join concatenation
var MultiLine = [
'1',
'2',
'3',
'4',
'5'
].join('');
Performance wise, Slash concatenation (first one) is the fastest.
Refer this test case for more details regarding the performance
Update:
With the ES2015, we can take advantage of its Template strings feature. With it, we just need to use back-ticks for creating multi line strings
Example:
`<h1>{{title}}</h1>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div><label>name: </label>{{hero.name}}</div>
`
Using script tags:
add a <script>...</script> block containing your multiline text into head tag;
get your multiline text as is... (watch out for text encoding: UTF-8, ASCII)
<script>
// pure javascript
var text = document.getElementById("mySoapMessage").innerHTML ;
// using JQuery's document ready for safety
$(document).ready(function() {
var text = $("#mySoapMessage").html();
});
</script>
<script id="mySoapMessage" type="text/plain">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="...">
<soapenv:Header/>
<soapenv:Body>
<typ:getConvocadosElement>
...
</typ:getConvocadosElement>
</soapenv:Body>
</soapenv:Envelope>
<!-- this comment will be present on your string -->
//uh-oh, javascript comments... SOAP request will fail
</script>
I like this syntax and indendation:
string = 'my long string...\n'
+ 'continue here\n'
+ 'and here.';
(but actually can't be considered as multiline string)
Downvoters: This code is supplied for information only.
This has been tested in Fx 19 and Chrome 24 on Mac
DEMO
var new_comment; /*<<<EOF
<li class="photobooth-comment">
<span class="username">
You:
</span>
<span class="comment-text">
$text
</span>
#<span class="comment-time">
2d
</span> ago
</li>
EOF*/
// note the script tag here is hardcoded as the FIRST tag
new_comment=document.currentScript.innerHTML.split("EOF")[1];
document.querySelector("ul").innerHTML=new_comment.replace('$text','This is a dynamically created text');
<ul></ul>
A simple way to print multiline strings in JavaScript is by using template literals(template strings) denoted by backticks (` `). you can also use variables inside a template string-like (` name is ${value} `)
You can also
const value = `multiline`
const text = `This is a
${value}
string in js`;
console.log(text);
There's this library that makes it beautiful:
https://github.com/sindresorhus/multiline
Before
var str = '' +
'<!doctype html>' +
'<html>' +
' <body>' +
' <h1>❤ unicorns</h1>' +
' </body>' +
'</html>' +
'';
After
var str = multiline(function(){/*
<!doctype html>
<html>
<body>
<h1>❤ unicorns</h1>
</body>
</html>
*/});
Found a lot of over engineered answers here.
The two best answers in my opinion were:
1:
let str = `Multiline string.
foo.
bar.`
which eventually logs:
Multiline string.
foo.
bar.
2:
let str = `Multiline string.
foo.
bar.`
That logs it correctly but it's ugly in the script file if str is nested inside functions / objects etc...:
Multiline string.
foo.
bar.
My really simple answer with regex which logs the str correctly:
let str = `Multiline string.
foo.
bar.`.replace(/\n +/g, '\n');
Please note that it is not the perfect solution but it works if you are sure that after the new line (\n) at least one space will come (+ means at least one occurrence). It also will work with * (zero or more).
You can be more explicit and use {n,} which means at least n occurrences.
The equivalent in javascript is:
var text = `
This
Is
A
Multiline
String
`;
Here's the specification. See browser support at the bottom of this page. Here are some examples too.
This works in IE, Safari, Chrome and Firefox:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<div class="crazy_idea" thorn_in_my_side='<table border="0">
<tr>
<td ><span class="mlayouttablecellsdynamic">PACKAGE price $65.00</span></td>
</tr>
</table>'></div>
<script type="text/javascript">
alert($(".crazy_idea").attr("thorn_in_my_side"));
</script>
to sum up, I have tried 2 approaches listed here in user javascript programming (Opera 11.01):
this one didn't work: Creating multiline strings in JavaScript
this worked fairly well, I have also figured out how to make it look good in Notepad++ source view: Creating multiline strings in JavaScript
So I recommend the working approach for Opera user JS users. Unlike what the author was saying:
It doesn't work on firefox or opera; only on IE, chrome and safari.
It DOES work in Opera 11. At least in user JS scripts. Too bad I can't comment on individual answers or upvote the answer, I'd do it immediately. If possible, someone with higher privileges please do it for me.
Exact
Ruby produce: "This\nIs\nA\nMultiline\nString\n" - below JS produce exact same string
text = `This
Is
A
Multiline
String
`
// TEST
console.log(JSON.stringify(text));
console.log(text);
This is improvement to Lonnie Best answer because new-line characters in his answer are not exactly the same positions as in ruby output
My extension to https://stackoverflow.com/a/15558082/80404.
It expects comment in a form /*! any multiline comment */ where symbol ! is used to prevent removing by minification (at least for YUI compressor)
Function.prototype.extractComment = function() {
var startComment = "/*!";
var endComment = "*/";
var str = this.toString();
var start = str.indexOf(startComment);
var end = str.lastIndexOf(endComment);
return str.slice(start + startComment.length, -(str.length - end));
};
Example:
var tmpl = function() { /*!
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
</div>
*/}.extractComment();
Updated for 2015: it's six years later now: most people use a module loader, and the main module systems each have ways of loading templates. It's not inline, but the most common type of multiline string are templates, and templates should generally be kept out of JS anyway.
require.js: 'require text'.
Using require.js 'text' plugin, with a multiline template in template.html
var template = require('text!template.html')
NPM/browserify: the 'brfs' module
Browserify uses a 'brfs' module to load text files. This will actually build your template into your bundled HTML.
var fs = require("fs");
var template = fs.readFileSync(template.html', 'utf8');
Easy.
If you're willing to use the escaped newlines, they can be used nicely. It looks like a document with a page border.
Easiest way to make multiline strings in Javascrips is with the use of backticks ( `` ). This allows you to create multiline strings in which you can insert variables with ${variableName}.
Example:
let name = 'Willem';
let age = 26;
let multilineString = `
my name is: ${name}
my age is: ${age}
`;
console.log(multilineString);
compatibility :
It was introduces in ES6//es2015
It is now natively supported by all major browser vendors (except internet explorer)
Check exact compatibility in Mozilla docs here
The ES6 way of doing it would be by using template literals:
const str = `This
is
a
multiline text`;
console.log(str);
More reference here
You can use TypeScript (JavaScript SuperSet), it supports multiline strings, and transpiles back down to pure JavaScript without overhead:
var templates = {
myString: `this is
a multiline
string`
}
alert(templates.myString);
If you'd want to accomplish the same with plain JavaScript:
var templates =
{
myString: function(){/*
This is some
awesome multi-lined
string using a comment
inside a function
returned as a string.
Enjoy the jimmy rigged code.
*/}.toString().slice(14,-3)
}
alert(templates.myString)
Note that the iPad/Safari does not support 'functionName.toString()'
If you have a lot of legacy code, you can also use the plain JavaScript variant in TypeScript (for cleanup purposes):
interface externTemplates
{
myString:string;
}
declare var templates:externTemplates;
alert(templates.myString)
and you can use the multiline-string object from the plain JavaScript variant, where you put the templates into another file (which you can merge in the bundle).
You can try TypeScript at
http://www.typescriptlang.org/Playground
ES6 allows you to use a backtick to specify a string on multiple lines. It's called a Template Literal. Like this:
var multilineString = `One line of text
second line of text
third line of text
fourth line of text`;
Using the backtick works in NodeJS, and it's supported by Chrome, Firefox, Edge, Safari, and Opera.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
Also do note that, when extending string over multiple lines using forward backslash at end of each line, any extra characters (mostly spaces, tabs and comments added by mistake) after forward backslash will cause unexpected character error, which i took an hour to find out
var string = "line1\ // comment, space or tabs here raise error
line2";
Please for the love of the internet use string concatenation and opt not to use ES6 solutions for this. ES6 is NOT supported all across the board, much like CSS3 and certain browsers being slow to adapt to the CSS3 movement. Use plain ol' JavaScript, your end users will thank you.
Example:
var str = "This world is neither flat nor round. "+
"Once was lost will be found";
You can use tagged templates to make sure you get the desired output.
For example:
// Merging multiple whitespaces and trimming the output
const t = (strings) => { return strings.map((s) => s.replace(/\s+/g, ' ')).join("").trim() }
console.log(t`
This
Is
A
Multiline
String
`);
// Output: 'This Is A Multiline String'
// Similar but keeping whitespaces:
const tW = (strings) => { return strings.map((s) => s.replace(/\s+/g, '\n')).join("").trim() }
console.log(tW`
This
Is
A
Multiline
String
`);
// Output: 'This\nIs\nA\nMultiline\nString'
Multiline string with variables
var x = 1
string = string + `<label class="container">
<p>${x}</p>
</label>`;

How to replace numbered list elements with an identifier containing the number

I have gotten amazing help here today!
I'm trying to do something else. I have a numbered list of questions in a Google Doc, and I'd like to replace the numbers with something else.
For example, I'd like to replace the numbers in a list such as:
The Earth is closest to the Sun in which month of the year?
~July
~June
=January
~March
~September
In Australia (in the Southern Hemisphere), when are the days the shortest and the nights the longest?
~in late December
~in late March
=in late June
~in late April
~days and nights are pretty much the same length throughout the year in Australia
With:
::Q09:: The Earth is closest to the Sun in which month of the year?
~July
~June
=January
~March
~September
::Q11:: In Australia (in the Southern Hemisphere), when are the days the shortest and the nights the longest?
~in late December
~in late March
=in late June
~in late April
~days and nights are pretty much the same length throughout the year in Australia
I've tried using suggestions from previous posts but have come up only with things such as the following, which doesn't seem to work.
Thank you for being here!!!
function questionName2(){
var body = DocumentApp.getActiveDocument().getBody();
var text = body.editAsText();
var pattern = "^[1-9]";
var found = body.findText(pattern);
var matchPosition = found.getStartOffset();
while(found){
text.insertText(matchPosition,'::Q0');
found = body.findText(pattern, found);
}
}
Regular expressions
Text.findText(searchPattern) uses a string that will be parsed as a regular expression using Google's RE2 library for the searchPattern. Using a string in this way requires we add an extra backslash whenever we are removing special meaning from a character, such as matching the period after the question number, or using a character matching set like \d for digits.
^\\s*\\d+?\\. will match a set of digits, of any non-zero length, that begin a line, with any length (including zero) of leading white space. \d is for digits, + is one or more, and the combination +? makes the match lazy. The lazy part is not required here, but it's my habit to default to lazy to avoid bugs. An alternative would be \d{1,2} to specifically match 1 to 2 digits.
To extract just the digits from the matched text, we can use a JavaScript RegExp object. Unlike the Doc regular expression, this regular expression will not require extra backslashes and will allow us to use capture groups using parentheses.
^\s*(\d+?)\. is almost the same as above, except no extraneous slashes and we will now "save" the digits so we can use them in our replacement string. We mark what we want to save using parentheses. Because this will be a normal JavaScript regular expression literal, we will wrap the whole thing in slashes: /^\s*(\d+?)\./, but the starting and ending / are just to indicate this is a RegExp literal.
text elements and text strings
Text.findText can return more than just the exact match we asked for: it returns the entire element that contains the text plus indices for what the regular expression matched. In order to perform search and replace with capture groups, we have to use the indices to delete the old text and then insert the new text.
The following assignments get us all the data we need to do the search and replace: first the element, then the start & stop indices, and finally extracting the matched text string using slice (note that slice uses an exclusive end, whereas the Doc API uses an inclusive end, hence the +1).
var found = DocumentApp.getActiveDocument().getBody().findText(pattern);
var matchStart = found.getStartOffset();
var matchEnd = found.getEndOffsetInclusive();
var matchElement = found.getElement().asText();
var matchText = matchElement.getText().slice(matchStart, matchEnd + 1);
Caveats
As Tanaike pointed out in the comments, this assumes the numbering is not List Items, which automatically generates numbers, but numbers you typed in manually. If you are using an automatically generated list of numbers, the API does not allow you to edit the format of the numbering.
This answer also assumes that in the example, when you mapped "9." to "::Q09::" and "10." to "::Q11::", that the mapping of 10 to 11 was a typo. If this was intended, please update the question to clarify the rules for why the numbering might change.
Also assumed is that the numbers are supposed to be less than 100, given the example zero padding of "Q09". The example should be flexible enough to allow you to update this to a different padding scheme if needed.
Full example
Since the question did not use any V8 features, this assumes the older Rhino environment.
/**
* Replaces "1." with "::Q01::"
*/
function updateQuestionNumbering(){
var text = DocumentApp.getActiveDocument().getBody();
var pattern = "^\\s*\\d+?\\.";
var found = text.findText(pattern);
while(found){
var matchStart = found.getStartOffset();
var matchEnd = found.getEndOffsetInclusive();
var matchElement = found.getElement().asText();
var matchText = matchElement.getText().slice(matchStart, matchEnd + 1);
matchElement.deleteText(matchStart, matchEnd);
matchElement.insertText(matchStart, matchText.replace(/^\s*(\d+?)\./, replacer));
found = text.findText(pattern, found);
}
/**
* #param {string} _ - full match (ignored)
* #param {string} number - the sequence of digits matched
*/
function replacer(_, number) {
return "::Q" + padStart(number, 2, "0") + "::";
}
// use String.prototype.padStart() in V8 environment
// above usage would become `number.padStart(2, "0")`
function padStart(string, targetLength, padString) {
while (string.length < targetLength) string = padString + string;
return string;
}
}

Find the word and replace with html tag using regex

I have a text equation like: 10x^2-8y^2-7k^4=0.
How can I find the ^ and replace it with <sup>2</sup> in the whole string using regex. The result should be like:
I tried str = str.replace(/\^\s/g, "<sup>$1</sup> ") but I’m not getting the expected result.
Any ideas that can help to solve my problem?
I think you're looking for something like
\^(\d+)
It matches the ^, captures the exponent and replace with
<sup>$1</sup>
See it here at regex101.
Edit:
To meet your new demands, check this fiddle. It handles the sub as well using replace with a function.
Your current pattern matches a caret followed by a space character (space, tab, new-line, etc.), but you want to match a caret followed by a single character or multiple characters wrapped in accolades, as your string is in TeX.
/\^(?:([\w\d])|\{([\w\d]{2,})\})/g
Now, using str = str.replace(/\^(?:([\w\d])|\{([\w\d]{2,})\})/g, "<sup>$1</sup>"); should do the job.
You can make a more generic function from this expression that can wrap characters prefixed by a specific character with a specific tag.
function wrapPrefixed(string, prefix, tagName) {
return string.replace(new RegExp("\\" + prefix + "(?:([\\w\\d])|\\{([\\w\\d]{2,})\\})"), "<" + tagname + ">$1</" + tagname + ">");
}
For instance, calling wrapPrefixed("1_2 + 4_{3+2}", "_", "sub"); results in 1<sub>2</sub> + 4<sub>3+2</sub>.

Exclude some characters from a Lex regex

I am trying to build a regex for lex that match the bold text in mardown syntax. For example: __strong text__ I thought this:
__[A-Za-z0-9_ ]+__
And then replace the text by
<strong>Matched text</strong>
But in Lex, this rule causes the variable yytext to be __Matched Text__. How could I get rid of the underscores? It would be better to create a regex that does not match the underscores or proccess the variable yytext to remove it?
With capturing groups it would be easer, because I would only need the regex:
__([A-z0-9 ]+)__
And use \1. But Lex does not support capturing groups.
Answer
I finally take the first option offer by João Neto, but a little modified:
yytext[strlen(yytext)-len]='\0'; // exclude last len characters
yytext+=len; // exclude first len characters
I've tried with Start conditions as he mentioned as second option, but did not work.
You can process yytext by removing the first and last two characters.
yytext[strlen(yytext)-2]='\0'; // exclude last two characters
yylval.str = &yytext[2]; // exclude first two characters
Another option is to use stack
%option stack
%x bold
%%
"__" { yy_push_state(bold); yylval.str = new std::string(); }
<bold>"__" { yy_pop_state(); return BOLD_TOKEN; }
<bold>.|\n { yylval.str += yytext; }

JSFL: convert text from a textfield to a HTML-format string

I've got a deceptively simple question: how can I get the text from a text field AND include the formatting? Going through the usual docs I found out it is possible to get the text only. It is also possible to get the text formatting, but this only works if the entire text field uses only one kind of formatting. I need the precise formatting so that I convert it to a string with html-tags.
Personally I need this so I can pass it to a custom-made text field component that uses HTML for formatting. But it could also be used to simply export the contents of any text field to any other format. This could be of interest to others out there, too.
Looking for a solution elsewhere I found this:
http://labs.thesedays.com/blog/2010/03/18/jsfl-rich-text/
Which seems to do the reverse of what I need, convert HTML to Flash Text. My own attempts to reverse this have not been successful thus far. Maybe someone else sees an easy way to reverse this that I’m missing? There might also be other solutions. One might be to get the EXACT data of the text field, which should include formatting tags of some kind(XML, when looking into the contents of the stored FLA file). Then remove/convert those tags. But I have no idea how to do this, if at all possible. Another option is to cycle through every character using start- and endIndex, and storing each formatting kind in an array. Then I could apply the formatting to each character. But this will result in excess tags. Especially for hyperlinks! So can anybody help me with this?
A bit late to the party but the following function takes a JSFL static text element as input and returns a HTML string (using the Flash-friendly <font> tag) based on the styles found it its TextRuns array. It's doing a bit of basic regex to clear up some tags and double spaces etc. and convert /r and /n to <br/> tags. It's probably not perfect but hopefully you can see what's going on easy enough to change or fix it.
function tfToHTML(p_tf)
{
var textRuns = p_tf.textRuns;
var html = "";
for ( var i=0; i<textRuns.length; i++ )
{
var textRun = textRuns[i];
var chars = textRun.characters;
chars = chars.replace(/\n/g,"<br/>");
chars = chars.replace(/\r/g,"<br/>");
chars = chars.replace(/ /g," ");
chars = chars.replace(/. <br\/>/g,".<br/>");
var attrs = textRun.textAttrs;
var font = attrs.face;
var size = attrs.size;
var bold = attrs.bold;
var italic = attrs.italic;
var colour = attrs.fillColor;
if ( bold )
{
chars = "<b>"+chars+"</b>";
}
if ( italic )
{
chars = "<i>"+chars+"</i>";
}
chars = "<font size=\""+size+"\" face=\""+font+"\" color=\""+colour+"\">"+chars+"</font>";
html += chars;
}
return html;
}