I thought some people may appreciate this PHP I wrote to take a CSS file and output XML in the format required by FCKEditor.
Please note that this code assumes the CSS is of a specific format; lines containing selectors are not indented by tabs and all other lines have a tab as the first character except closing curly brackets or 'braces' { }. Technicaly, only lines containing #s or .s need be indented with a tab.. all other lines will not cause problems.
It can handle multiple comma and space separated selectors on the same line.
It will ignore generic selectors as FCKEditor cant handle them.
If your CSS has a class and an ID sharing the same name it will break FCKeditor (or you might get two styles of the same name?? i dont know, i havnt tested)
You probably dont want your users using ids anyway.. id stick with classes.
The following CSS:
... will produce the following XML:
So heres the PHP:
There may well be better ways to do this but I didnt do this as an intelectual exercise.. i just wanted something that works.
If someone has a better/more efficient solution then great! please post it here.
Please note that this code assumes the CSS is of a specific format; lines containing selectors are not indented by tabs and all other lines have a tab as the first character except closing curly brackets or 'braces' { }. Technicaly, only lines containing #s or .s need be indented with a tab.. all other lines will not cause problems.
It can handle multiple comma and space separated selectors on the same line.
It will ignore generic selectors as FCKEditor cant handle them.
If your CSS has a class and an ID sharing the same name it will break FCKeditor (or you might get two styles of the same name?? i dont know, i havnt tested)
You probably dont want your users using ids anyway.. id stick with classes.
The following CSS:
body { text-align: center; background-color: #003300 !important; } a:link { text-decoration:none; } a:visited { text-decoration:none; } a img { border: 0; } div.test1 { height: 100px; width: 100px; } div.test1 div.test2 a#test3 { right: 100px; } div#test4 a:hover, div#test5 a.test5,div#test6 a:hover { color: #000000; font-weight: bold; text-decoration: none; } .test7 { color: #000000; font-weight: bold; text-decoration: none; }
... will produce the following XML:
<?xml version="1.0" encoding="utf-8" ?> <Styles> <Style name="test1" element="div"> <Attribute name="class" value="test1" /> </Style> <Style name="test2" element="div"> <Attribute name="class" value="test2" /> </Style> <Style name="test3" element="a"> <Attribute name="id" value="test3" /> </Style> <Style name="test4" element="div"> <Attribute name="id" value="test4" /> </Style> <Style name="test5" element="div"> <Attribute name="id" value="test5" /> </Style> <Style name="test5" element="a"> <Attribute name="class" value="test5" /> </Style> <Style name="test6" element="div"> <Attribute name="id" value="test6" /> </Style> </Styles>
So heres the PHP:
<?php header('Content-type: text/xml'); //Not needed but makes browser render output nicely for debuging echo "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<Styles>\n"; $lines = file("URL of CSS file"); //Do whatever database query etc you need before here and pass the file() function the URL. $ids = Array(); //These two arrays are to keep track of classes and ids allready parsed so the XML doesnt contain duplicates $classes = Array(); foreach ($lines as $line) { if (sub_str($line,0,1)!="\t") { //REMOVE THE '_' !! This crappy forum doesnt like the phrase 'sub'+'str' apparantly!?! $line = str_replace(',',' ',$line); $exploded = explode(' ',$line); foreach ($exploded as $element) { if (eregi('([a-zA-Z]+[a-zA-Z0-9]*)+(\.|#)([a-zA-Z_]+[a-zA-Z0-9_]*)+',trim($element,","),$regs)){ //I didnt look up the format of legal class/id names or HTML elements so please correct me if im wrong. if (($regs[1]=='.') && !(in_array($regs[2],$classes))){ echo "\t<Style name=\"{$regs[2]}\" element=\"\">\n"; echo "\t\t<Attribute name=\"class\" value=\"{$regs[2]}\" />\n"; echo "\t</Style>\n"; $classes[count($classes)] = $regs[2]; } else if (($regs[1]=='#') && !(in_array($regs[2],$ids))) { echo "\t<Style name=\"{$regs[2]}\" element=\"\">\n"; echo "\t\t<Attribute name=\"id\" value=\"{$regs[2]}\" />\n"; echo "\t</Style>\n"; $ids[count($ids)] = $regs[2]; } else if (($regs[2]=='.') && !(in_array($regs[3],$classes))) { echo "\t<Style name=\"{$regs[3]}\" element=\"{$regs[1]}\">\n"; echo "\t\t<Attribute name=\"class\" value=\"{$regs[3]}\" />\n"; echo "\t</Style>\n"; $classes[count($classes)] = $regs[3]; } else if (($regs[2]=='#') && !(in_array($regs[3],$ids))) { echo "\t<Style name=\"{$regs[3]}\" element=\"{$regs[1]}\">\n"; echo "\t\t<Attribute name=\"id\" value=\"{$regs[3]}\" />\n"; echo "\t</Style>\n"; $ids[count($ids)] = $regs[3]; } } } } } echo "</Styles>"; ?>
There may well be better ways to do this but I didnt do this as an intelectual exercise.. i just wanted something that works.
If someone has a better/more efficient solution then great! please post it here.