Flex: Export valid HTML from the RichTextEditor
A recent post on the Flex Coders forum prompted me to create a method to clean up the HTML code produced by the Flex RichTextEditor component. Typically, the code that is produced looks like this from the line:
This is <b> Bold </b> text. <P ALIGN="LEFT"> <FONT FACE="Verdana" SIZE="10" COLOR="#0B333C"> This is <b> Bold </b>text. </FONT> </P>
Now that is a lot of extra code and some of it, though ignored by the browser, is just code used only by Flex (or Flash). What is needed is a way to clean the code and make it more standard so you can store in the database and use in more places than just Flex. Using RegExp, I created a small function that strips out the invalid code and leaves:
private function cleanHTML(str:String):String
{
var pattern:RegExp = //g;
var str:String = str.replace(pattern, "");
pattern = /<font>/g;
str = str.replace(pattern, "");
pattern = //g;
str = str.replace(pattern, "");
pattern = //g;
str = str.replace(pattern, "");
return str;
}
The function produces the following valid HTML code:
<p Align="LEFT">This is <B> Bold </B> text.</p>
Using a modified version of the same function, you could also change the code to lowercase or add span tags to replace the formatting that we removed. This gives you much more control over the way your text will be displayed in applications outside of Flex. Perhaps one day Adobe will address this issue with invalid HTML that has been a burden of working with Flash since the early days of Flash. You can view the orignal Flex Coder’s discussion
Additional discussions of this topic:
- Mister
Trackbacks & Pingbacks
- CustomRichTextEditor with XHTML text | Axelology
- Custom RichTextEditor — Thanks, Mister!
- Igor Costa » Blog Archive » #6 Flex Hack - RichTextEditor to output XHTML 1.1 valid
- Flex Tips - Obtenir un texte HTML valide ? partir du RichTextEditor (htmlText) - Adobe Flex Tutorial - Tutoriaux Flex Builder, MXML, ActionScript, AS3
- Using Adobe Flex RichTextEditor for CMS « Zero Credibility
- Fixing HTML from Adobe Flex’s RichTextEditor « Zero Credibility
- Using Adobe Flex RichTextEditor for CMS « Keith Collins
- Tweets that mention Flex: Export valid HTML from the RichTextEditor -- Topsy.com
Awesome! I was in quite the quandary on this one… on a side note… it is import to escape the forward slashes inside the html tags…
pattern = //g;
should be
pattern = //g;
Glad you found my example helpful and thanks for letting me know about the //g
You can get rid of the textformat tag by putting the following line in your css:
global{ leading:0;}
Really, I will have to check that out. Seems strange that this would magically kill the tag though. Thanks for the tip!
thank you for the code.
I’ve tried it and added some extra functionality.
private function cleanHTML(str:String):String { var pattern:RegExp = //g; var str:String = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = /<A HREF/g; str = str.replace(pattern, "<a href"); pattern = //g; str = str.replace(pattern, "</a>"); pattern= /TARGET="_blank"/g; str = str.replace(pattern, "rel=\"external\" "); pattern = /<I>/g; str = str.replace(pattern, "<em>"); pattern = //g; str = str.replace(pattern, "</em>"); pattern = /<B>/g; str = str.replace(pattern, "<strong>"); pattern = //g; str = str.replace(pattern, "</strong>"); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); return str; }so now it’s XHTML1.1 approved.
greets
johan
Thanks Johan, that is awsome!! I cleaned up your post and put back in the HTML code
.
Hey Johan,
Your code works great, but wraps each list item in it’s own unordered list (if that’s the case). This will fix it (put it at the end). It assumes you’re not putting 2 unordered lists back to back.
pattern= //g;
str = str.replace(pattern, "");
Cheers,
Aaron
Thanks Aaron for your contribution
this code does not work on increse font size
I Love you all
This one was stumping me, thanks everyone.
Cheers David
Sorry for the last post , apparently this form doesnt change htmlspecialchars
here is the fixed post
For those those of you wondering what happened to the <FONT> tags heres the answer this pattern will replace the <FONT> tag with the <span> tag change the attribute to styles making it xhtml compliant .
Just replace the current font Regular Expressions (patten) with these
Cory,
No problem, it is hard to find a blog skin that supports html code. Thanks for you comments on this post
.
nice job, thx
you all made my day … thx a lot for sharing
your font fix doesn’t always work because not always are the color size and face present.
I had to write a few more replaces to take care of that. Also, I save to database after running cleanHTML, but when I load from database I need to uncleanHTML… basically do the reverse. Otherwise it won’t recover it. However textformat was non-reversable. Luckily flash doesn’t require it be there. So why does it write it? The world may never know.
Here’s my reverse in case you need it and want to copy paste:
private function uncleanHTML(str:String):String { var pattern:RegExp = //g; var str:String = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = /<a>/g; str = str.replace(pattern, "</A>"); pattern= /rel="external" /g; str = str.replace(pattern, "TARGET=\"_blank\""); pattern = /<em>/g; str = str.replace(pattern, "<I>"); pattern = //g; str = str.replace(pattern, "</I>"); pattern = /<strong>/g; str = str.replace(pattern, "<B>"); pattern = //g; str = str.replace(pattern, "</B>"); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); return str; }Cheers =D
Thanks for your contribution to the post. One day I should compile all the code people have contributed and roll it into a new HTML text editor for Flex.
Hi all, bit of a newb here. Just dropped the code in my very basic app between the mx:script tags, registered loads of errors and now whenever i make a change to the app and re-run it, the changes i have made don’t appear. It just runs the old version. Have I put the code in the right place? Sorry I know this is very basic stuff, but thanks for reading. Even better would some button code passing in the parameter to the function. Thanx again!
Hi This is prefect for a project that I am working on! But I can not get it to work. I put the function between the script tags but how do I make it run. I am new to Flex.
Thanks
Would like to vote this being one of the most usefull posts of the year….ok..well maybe the month.
Good work.
In my case I needed to convert back and forth between flex-HTML and XHTML. I’m using the following functions in a util file to do so.
static public function convertFromXHtml(str:String):String { var pattern:RegExp; pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = /color:(.*?);/g; str = str.replace(pattern, "COLOR=\"$1\" "); pattern = /font-size:(.*?)px;/g; str = str.replace(pattern, "SIZE=\"$1\" "); pattern = /font-family:(.*?);/g; str = str.replace(pattern, "FACE=\"$1\" "); pattern = /text-align:(.*?);/g; str = str.replace(pattern, "ALIGN=\"$1\" "); pattern = //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern = /<em>/g; str = str.replace(pattern, "<I>"); pattern = //g; str = str.replace(pattern, "</I>"); pattern = /<strong>/g; str = str.replace(pattern, "<B>"); pattern = //g; str = str.replace(pattern, "</B>"); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); // Remove extra white space pattern = / /g; str = str.replace(pattern, " "); return str; } static public function convertToXHtml(str:String):String { var pattern:RegExp; pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = /COLOR=\"(.*?)\"/g; str = str.replace(pattern, "color:$1;"); pattern = /SIZE=\"(.*?)\"/g; str = str.replace(pattern, "font-size:$1px;"); pattern = /FACE=\"(.*?)\"/g; str = str.replace(pattern, "font-family:$1;"); pattern = /ALIGN=\"(.*?)\"/g; str = str.replace(pattern, "text-align:$1;"); pattern = /LETTERSPACING=\".*?\"/g; str = str.replace(pattern, ""); pattern = /KERNING=\".*?\"/g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern = /<I>/g; str = str.replace(pattern, "<em>"); pattern = //g; str = str.replace(pattern, "</em>"); pattern = /<B>/g; str = str.replace(pattern, "<strong>"); pattern = //g; str = str.replace(pattern, "</strong>"); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); return str; }I think, You all are wrong. It’s not a good place to use regular expresion. It’s a good place to use XSLT. But we doesn’t have it.
I sugest use XML trawerse:
private function cleanHtml(str:String):String { // Create XML document var xml:XML = XML(""+str+""); // temporary var t1:XML; var t2:XML; // Remove all TEXTFORMAT for( t1 = xml..TEXTFORMAT[0]; t1 != null; t1 = xml..TEXTFORMAT[0] ) { t1.parent().replace( t1.childIndex(), t1.children() ); } // Find all ALIGN and add STYLE for each ( t1 in xml..@ALIGN ) { t2 = t1.parent(); t2.@STYLE = "text-align: " + t1 + "; " + t2.@STYLE; } // Find all FACE and add STYLE for each ( t1 in xml..@FACE ) { t2 = t1.parent(); t2.@STYLE = "font-family: " + t1 + "; " + t2.@STYLE; } // Find all SIZE and add STYLE for each ( t1 in xml..@SIZE ) { t2 = t1.parent(); t2.@STYLE = "font-size: " + t1 + "px; " + t2.@STYLE; } // Find all COLOR and add STYLE for each ( t1 in xml..@COLOR ) { t2 = t1.parent(); t2.@STYLE = "color: " + t1 + "; " + t2.@STYLE; } return xml.children().toXMLString(); }Tested in IE7, Firefox, Opera
Antoni Jakubiak
Mate! I owe you a drink I swear.
Thanks
This project:
http://code.google.com/p/flex-richtexteditor-html-utils/
Hi Guys, thanks for the regexp code. My problem is a little different.
I’m trying to get a TextArea to hold more than one embedded font family, but setStyle only allows me one font family. In addition, the use of setStyle overrides all the htmltext tags.
What I’d like to do is replace the FontFamily tags with a new value. A typical html tag is:
This is the theme to Garry's Show,The theme to Garry's show.Garry called me up and asked if I would right his theme song.
Now I’d like to use a regular expression to replace all the font tags with a new FontFamily. how can I write that?
Great code but I still have a problem.
I pass accent characters (ò à è é) to php/mysql from the richTextEditor and I have several errors…
What should I do?
Roberto
private function cleanHTML(str:String):String{ var pattern:RegExp = //g; var str:String = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = /<A HREF/g; str = str.replace(pattern, "<a href"); pattern = //g; str = str.replace(pattern, "</a>"); pattern= /TARGET="_blank"/g; str = str.replace(pattern, "rel=\"external\" "); pattern = /<I>/g; str = str.replace(pattern, "<em>"); pattern = //g; str = str.replace(pattern, "</em>"); pattern = /<B>/g; str = str.replace(pattern, "<strong>"); pattern = //g; str = str.replace(pattern, "</strong>"); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); return str; }thx to all! this all post realy help me!!
Yes, It is better to do it with XML.
A whole lot of information seems to be stripped out of many of the posts above. For example, in the first post by Lukas Ruebbelke, he describes that:
pattern = //g;
should be
pattern = //g;
???
it continues in other posts, in descriptions of convertFromXHtml, for example, with reams of lines of:
[as]str = str.replace(pattern, “”);
pattern= //g;[/as]
i’m trying to hunt down a convertFromXHtml method. Can anyone with a copy of this repost or link somewhere where it can be seen in full?
I checked the posts, there was some missing information. The posts all seem to be intact now, thanks for letting me know of the issue.
beautiful thanks for that mister you’re a life saver
Thank you so much for this snippet.
I was pulling my hair out trying to determine what was going on with my text.
This version will maintain the formatting (styles)
private function cleanHTML(str:String):String { var newStr:String; var pattern:RegExp = //g; var str:String = str.replace(pattern, ""); pattern = /ALIGN="/g; var str:String = str.replace(pattern, 'style=" text-align: '); pattern = /"><FONT\sFACE?="/g; str = str.replace(pattern, '; font-family: '); pattern = /"\sSIZE?="/g; str = str.replace(pattern, '; font-size: '); pattern = /"\sCOLOR="/g; str = str.replace(pattern, 'px; color: '); pattern = /<FONT\sFACE?="/g; newStr = str.replace(pattern, '; font-familly: '); var replaced:Boolean = true; do{ replaced = false; if(newStr != str) //This is if there more occurence of FACE { str = str.replace(pattern, '<span style=" font-size: '); //REPLACE SIZE AND ADD STYLE pattern = /"\sCOLOR="/g; str = str.replace(pattern, '; color: '); // REPLACE COLOR replaced = true; } else //No FACE NO SIZE { pattern = /<span style=" color: '); // REPLACE COLOR replaced = true; } } }while(replaced == false) pattern = /"\sLETTERSPACING="\d+" KERNING="\d+"/g; str = str.replace(pattern, ';" '); pattern = //g; str = str.replace(pattern, ""); pattern = /<A HREF/g; str = str.replace(pattern, "<a href"); pattern = //g; str = str.replace(pattern, "</a>"); // pattern= /TARGET="_blank"/g; // str = str.replace(pattern, "rel=\"external\" "); pattern = /<I>/g; str = str.replace(pattern, "<em>"); pattern = //g; str = str.replace(pattern, "</em>"); pattern = /<B>/g; str = str.replace(pattern, "<strong>"); pattern = //g; str = str.replace(pattern, "</strong>"); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern= //g; str = str.replace(pattern, ""); pattern = /LEFT/g; str = str.replace(pattern, "left"); pattern = /RIGHT/g; str = str.replace(pattern, "right"); pattern = /JUSTIFY/g; str = str.replace(pattern, "justify"); pattern = /<p/g; str = str.replace(pattern, "<span "); pattern = //g; str = str.replace(pattern, ""); pattern = /<P/g; str = str.replace(pattern, "<span "); pattern = //g; str = str.replace(pattern, ""); pattern = //g; str = str.replace(pattern, ""); return str; }Sorry the blog has stripped my comment
@ Luc, be sure to use the code tags for posting code in comments, thanks!
anyone know how to replace or reformat the img tag tried this
pattern = /<IMG/gi;
str = str.replace(pattern, “/gi;
str = str.replace(pattern, “src=$1/>”);
Thanks
sorry
pattern = /<IMG/gi;
str = str.replace(pattern, "/gi;
str = str.replace(pattern, "src=$1/>");
thanks guys! I had/have a problem with bullets not appearing with (any) embedded font in a Flex app. I took this code & added:
pattern = //gi;
str = str.replace(pattern, “”);
as a (nasty) workaround.
Damn handy being able to style RichTextEditor output with css too.
Cheers!
Thanks!
In case you prefer to convert the HTML only at time of publish (in an application server), here’s Matthew’s code ported in Java – that should save you the 5 minutes it took me to do it
:
public static String convertFlashToXHtml(String str) { str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("COLOR=\"(.*?)\"", "color:$1;"); str = str.replaceAll("SIZE=\"(.*?)\"", "font-size:$1px;"); str = str.replaceAll("FACE=\"(.*?)\"", "font-family:$1;"); str = str.replaceAll("ALIGN=\"(.*?)\"", "text-align:$1;"); str = str.replaceAll("LETTERSPACING=\".*?\"", ""); str = str.replaceAll("KERNING=\".*?\"", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("", ""); str = str.replaceAll("<I>", "<em>"); str = str.replaceAll("</I>", "</em>"); str = str.replaceAll("<B>", "<strong>"); str = str.replaceAll("</B>", "</strong>"); str = str.replaceAll("", ""); return str.replaceAll("", ""); }Damn!! Didn’t see the formatting tags. Hope this is the good one:
/** Convert a flex/flash html string to the official html standard, removing custom flex tags. */ function convertFlexHtmlToStandard($string){ // Replace all textformat starting tags. Note that we replace "" by "" $result = ereg_replace("]*>", "", $string); // Replace all ending textformat ending tags $result = ereg_replace("", "", $result); // Replace all size="XXXX" by the style='XXXXpx' expression $result = ereg_replace('SIZE="([^"]*)"', "style='font-size:\\1px;'", $result); return $result; }@James,
Thanks for the contribution, this is by far my most commented post, I deleted the bad formatted version. I have to make those formatting comments more noticeable one day
.
I’m trying to insert a block of code into this manually to test it and the lack of escape characters is, of course, throwing an error. The problem is, my whole use for this script you guys have written (thank you a million times by the way) will be to insert escape characters before any and all single and double quotation marks. Quite the paradoxical quandry that I am having trouble finding my way out of.
The purpose is to add the escape charaters, then send the edited string to a php file, which would throw an error without the escape characters. Any thoughts?
Great information! If Adobe doesn’t have plans to upgrade the RTE, they should definitely do so. This information is a great help in the interim.
It has a nice work from another nice expert who has done a great work!
http://blog.flashweb.org/archives/7
package flex.common { import flash.xml.XMLDocument; import flash.xml.XMLNode; public class RteHtmlParser { public var SET_P:String = 'DIV'; public var SET_LI:String = 'LI'; public var SET_FONT:String = 'SPAN'; public var SET_UL:String = 'UL'; public var SET_BR:String = 'BR'; public var ignoreParagraphSpace:Boolean = false; private var out_xml:XML; public function RteHtmlParser() { } // not those line breaks that kills the SQL public function get StringFormat():String { if (!out_xml) return ''; XML.prettyIndent = 0; // remove the /n from the string // we want a string out! var s:String = unescape(unescape(escape(out_xml.children()).split('%0A').join(''))); XML.prettyIndent = 2; return s; } // nice looking string public function get XMLFormat():String { if (!out_xml) return ''; return unescape(out_xml.children().toXMLString()); } // the xml public function get XMLObject():XML { return out_xml; } //________________________________________________________________________________________________________ // HTML PARSER public function ParseToHTML(string:String):void { var xml_doc:XMLDocument = new XMLDocument(""+string+""); var nxml:XMLNode = (ignoreParagraphSpace) ? xml_doc.firstChild : manage_space(xml_doc.firstChild); var xml:XML = XML(nxml.toString()); var t1:XML; // Remove all TEXTFORMAT for( t1 = xml..TEXTFORMAT[0]; t1 != null; t1 = xml..TEXTFORMAT[0] ) { t1.parent().replace( t1.childIndex(), t1.children() ); } //add br tag if (SET_BR) xml = add_br_tag(xml); // add ul tag xml = add_ul_tag(xml); // format css xml = add_css(xml); // format new names xml = set_new_name(xml); out_xml = xml; } private function add_ul_tag(xml:XML):XML { var t1:XML; var t2:XML = new XML(); var el:XMLList = xml.children(); var ul:XML; for each (t1 in el) { if (t1.name().localName != 'LI') { t2.appendChild(t1.copy()); } else if (t1.childIndex() == 0) { ul = new XML(); ul.appendChild(t1.copy()); t2.appendChild(ul); } else if (el[t1.childIndex()-1].name().localName != 'LI') { ul = new XML(); ul.appendChild(t1.copy()); t2.appendChild(ul); } else { ul.appendChild(t1.copy()); } } return t2; } private function add_br_tag(xml:XML):XML { var br:XML; for each (var i:XML in xml.children()) { if (!has_text(i)) { br = copy_attributes(i.descendants('FONT')[0], new XML()); i.parent().replace(i.childIndex(), br); } } return xml; } private function set_new_name(xml:XML):XML { var t1:XML; // set new P if (SET_P == null) { for( t1 = xml..P[0]; t1 != null; t1 = xml..P[0] ) { t1.parent().replace(t1.childIndex(), t1.children()); } } else if (SET_P.toLocaleUpperCase() != 'P') { for( t1 = xml..P[0]; t1 != null; t1 = xml..P[0] ) { t1.setName(SET_P); } } // set new UL if (SET_UL == null) { for( t1 = xml..UL[0]; t1 != null; t1 = xml..UL[0] ) { t1.parent().replace(t1.childIndex(), t1.children()); } } else if (SET_UL.toLocaleUpperCase() != 'UL') { for( t1 = xml..UL[0]; t1 != null; t1 = xml..UL[0] ) { t1.setName(SET_FONT); } } // set new LI if (SET_LI == null) { for( t1 = xml..LI[0]; t1 != null; t1 = xml..LI[0] ) { t1.parent().replace(t1.childIndex(), t1.children()); } } else if (SET_LI.toLocaleUpperCase() != 'LI') { for( t1 = xml..LI[0]; t1 != null; t1 = xml..LI[0] ) { t1.setName(SET_LI); } } // set new FONT if (SET_FONT == null) { for( t1 = xml..FONT[0]; t1 != null; t1 = xml..FONT[0] ) { t1.parent().replace(t1.childIndex(), t1.children()); } } else if (SET_FONT.toLocaleUpperCase() != 'FONT') { for( t1 = xml..FONT[0]; t1 != null; t1 = xml..FONT[0] ) { t1.setName(SET_FONT); // wierd browser rendering on e.g. if (t1 == '') { //t1.setChildren(''); //or you can just replace it with nothing t1.parent().replace(t1.childIndex(), ''); } } } // set new BR if (SET_BR == null) { for( t1 = xml..BR[0]; t1 != null; t1 = xml..BR[0] ) { t1.parent().replace(t1.childIndex(), t1.children()); } } else if (SET_BR.toLocaleUpperCase() != 'BR') { for( t1 = xml..BR[0]; t1 != null; t1 = xml..BR[0] ) { t1.setName(SET_BR); // if it's closed like this in html // thebrowser might act wierd! t1.setChildren(''); } } return xml; } private function add_css(xml:XML):XML { var t1:XML; var t2:XML; // Find all ALIGN for each ( t1 in xml..@ALIGN ) { t2 = t1.parent(); t2.@STYLE = "text-align:" + t1 + ";" + t2.@STYLE; delete t2.@ALIGN; } // Find all FACE for each ( t1 in xml..@FACE ) { t2 = t1.parent(); t2.@STYLE = "font-family:'" + t1 + "';" + t2.@STYLE; delete t2.@FACE; } // Find all SIZE for each ( t1 in xml..@SIZE ) { t2 = t1.parent(); t2.@STYLE = "font-size:" + t1 + "px;" + t2.@STYLE; delete t2.@SIZE; } // Find all COLOR for each ( t1 in xml..@COLOR ) { t2 = t1.parent(); t2.@STYLE = "color:" + t1 + ";" + t2.@STYLE; delete t2.@COLOR; } // Find all LETTERSPACING for each ( t1 in xml..@LETTERSPACING ) { t2 = t1.parent(); t2.@STYLE = "letter-spacing:" + t1 + "px;" + t2.@STYLE; delete t2.@LETTERSPACING; } // Find all KERNING for each ( t1 in xml..@KERNING ) { t2 = t1.parent(); // ? css delete t2.@KERNING; } return xml; } //________________________________________________________________________________________________________ //________________________________________________________________________________________________________ // RTE PARSER public function ParseToRTE(string:String):void { var xml_doc:XMLDocument = new XMLDocument(""+string+""); var nxml:XMLNode = (ignoreParagraphSpace) ? xml_doc.firstChild : manage_space(xml_doc.firstChild); var xml:XML = new XML(nxml.toString()); // remove UL xml = remove_ul_tag(xml); // remove BR xml = remove_br_tag(xml); // format CSS xml = remove_css(xml); // format names xml = rename_tags(xml); //add TEXTFORMAT xml = add_textformat(xml); out_xml = xml; } private function remove_ul_tag(xml:XML):XML { var ul:XMLList = xml.elements(SET_UL); for each (var i:XML in ul) { i.parent().replace(i.childIndex(), i.children()); } return xml; } private function remove_br_tag(xml:XML):XML { var br:XMLList = xml.descendants(SET_BR); var p:XML; var f:XML; for each (var i:XML in br) { p = new XML(); f = copy_attributes(i, new XML()); f.setChildren(''); p.appendChild(f); i.parent().replace(i.childIndex(), p); } return xml; } private function remove_css(xml:XML):XML { var ar:Array; var ta:Array; var el:XML; var name:String; for each ( var i:XML in xml..@STYLE ) { el = i.parent(); ar = String(el.@STYLE).split(';'); for (var j:uint = 0; j < ar.length; j++) { ta = ar[j].split(':'); name = ta[0].toLocaleLowerCase().split(' ').join(''); switch (name) { case 'text-align': el.@ALIGN = ta[1]; break; case 'font-family': el.@FACE = ta[1].split("'").join('').split('"').join(''); break; case 'font-size': el.@SIZE = ta[1].split('px').join(''); break; case 'color': el.@COLOR = ta[1]; break; case 'letter-spacing': el.@LETTERSPACING = ta[1].split('px').join(''); break; } } delete el.@STYLE; } return xml; } private function rename_tags(xml:XML):XML { var t:XML; var el:XMLList; // set new P if (SET_P.toLocaleUpperCase() != 'P' && SET_P != null) { el = xml.descendants(SET_P); for each (t in el) { t.setName('P'); } } // set new LI if (SET_LI.toLocaleUpperCase() != 'LI' && SET_LI != null) { el = xml.descendants(SET_LI); for each (t in el) { t.setName('LI'); } } // set new FONT if (SET_FONT.toLocaleUpperCase() != 'FONT' && SET_FONT != null) { el = xml.descendants(SET_FONT); for each (t in el) { t.setName('FONT'); } } return xml; } private function add_textformat(xml:XML):XML { var m:XML = new XML(); var tf:XML; for each (var i:XML in xml.children()) { tf = new XML(); //tf.@LEADING = '2'; tf.appendChild(i.copy()); m.appendChild(tf); } return m; } //________________________________________________________________________________________________________ //________________________________________________________________________________________________________ // SOME TOOLS private function has_text(xml:XML):Boolean { for each (var i:XML in xml.children()) { if (i.nodeKind() == 'text') return true; else if (has_text(i)) return true; } return false; } private function copy_attributes(x1:XML, x2:XML):XML { for each (var i:XML in x1.attributes()) { x2.@[i.name().localName] = i; } return x2; } private function manage_space(node:XMLNode):XMLNode { for each (var n:XMLNode in node.childNodes) { if (n.nodeType == 3) n.nodeValue = n.nodeValue.split(' ').join('%20'); if (n.hasChildNodes()) manage_space(n); } return node; } //________________________________________________________________________________________________________ } }manpakhong@hotmail.com
Thanks for your contribution!