Reputation: 65805
I am trying to beautify CSS code using JavaScript.
A minified CSS code looks like this:
str = 'body{margin:0;padding:0;}section,article,.class{font-size:2em;}'
So far I could beautify the code by using multiple replaces:
str.replace(/{/g, " {\n")
.replace(/}/g, "}\n")
.replace(/;/g,";\n")
.replace(/,/g, ",\n")
This is working but I want to improve it
Upvotes: 4
Views: 1155
Reputation: 4193
I don't know if CSS is a regular language (my guess is yes), but this should doable with regex regardless.
There's no need to match a last property, whether it contains a semicolon or not. First match all closing curly braces, like you've done, except add a newline both before and after each:
.replace(/}/g, "\n}\n")
Then match all semicolons except those that come before a newline (which were inserted by the regex above) and add a newline and tab using the \t
character after each:
.replace(/;([^\n])/g, ";\n\t$1")
This is just the tip of the iceberg, unfortunately. Don't forget to look for all the different types of selectors, such as those containing :
or >
, if you plan to add spaces around those. There's probably lots of other stuff you'll need to consider, too.
Upvotes: 1
Reputation: 44269
I think it's hard to reduce the number of regular expressions, since sometimes you need only a line break, sometimes you need a tab, too. Sometimes you need to write back one and sometimes two characters. But here is a list of replacements that makes the CSS look quite nice:
str.replace(/\{/g, " {\n\t") // Line-break and tab after opening {
.replace(/;([^}])/g, ";\n\t$1") // Line-break and tab after every ; except
// for the last one
.replace(/;\}/g, ";\n}\n\n") // Line-break only after the last ; then two
// line-breaks after the }
.replace(/([^\n])\}/g, "$1;\n}") // Line-break before and two after } that
// have not been affected yet
.replace(/,/g, ",\n") // line break after comma
.trim() // remove leading and trailing whitespace
Makes this:
str = 'body{margin:0;padding:0}section,article,.class{font-size:2em;}'
Look like this:
body {
margin:0;
padding:0;
}
section,
article,
.class {
font-size:2em;
}
If you don't care about those omitted semicolons being put back in place, you can shorten this a bit though, by changing the order:
str.replace(/\{/g, " {\n\t")
.replace(/\}/g, "\n}\n\n") // 1 \n before and 2 \n after each }
.replace(/;(?!\n)/g, ";\n\t") // \n\t after each ; that was not affected
.replace(/,/g, ",\n")
.trim()
Upvotes: 3