Skip to content

Commit

Permalink
Add content_unformatted config to avoid formatting content of an elem…
Browse files Browse the repository at this point in the history
…ent (fix beautifier#906)
  • Loading branch information
arai-a committed Dec 27, 2016
1 parent f362b78 commit 32c8e6e
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ HTML Beautifier Options:
-A, --wrap-attributes Wrap attributes to new lines [auto|force|force-aligned|force-expand-multiline] ["auto"]
-i, --wrap-attributes-indent-size Indent wrapped attributes to after N characters [indent-size] (ignored if wrap-attributes is "force-aligned")
-U, --unformatted List of tags (defaults to inline) that should not be reformatted
-T, --content_unformatted List of tags (defaults to pre) that its content should not be reformatted
-E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline before them.
--editorconfig Use EditorConfig to set up the options
```
Expand Down
8 changes: 7 additions & 1 deletion js/lib/beautify-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none"
put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are.
unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted
content_unformatted (defaults to pre tag) - list of tags, that its content shouldn't be reformatted
indent_scripts (default normal) - "keep"|"separate"|"normal"
preserve_newlines (default true) - whether existing line breaks before elements should be preserved
Only works before elements, not inside tags or for text.
Expand Down Expand Up @@ -118,6 +119,7 @@
wrap_line_length,
brace_style,
unformatted,
content_unformatted,
preserve_newlines,
max_preserve_newlines,
indent_handlebars,
Expand Down Expand Up @@ -159,6 +161,8 @@
'video', 'wbr', 'text',
// prexisting - not sure of full effect of removing, leaving in
'acronym', 'address', 'big', 'dt', 'ins', 'strike', 'tt',
];
content_unformatted = options.content_unformatted || [
'pre',
];
preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines;
Expand Down Expand Up @@ -580,7 +584,9 @@
this.indent_content = true;
this.traverse_whitespace();
}
} else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
} else if (this.is_unformatted(tag_check, unformatted) ||
this.is_unformatted(tag_check, content_unformatted)) {
// do not reformat the "unformatted" or "content_unformatted" tags
comment = this.get_unformatted('</' + tag_check + '>', tag_complete); //...delegate to get_unformatted function
content.push(comment);
tag_end = this.pos - 1;
Expand Down
3 changes: 3 additions & 0 deletions js/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ var path = require('path'),
// HTML-only
"max_char": Number, // obsolete since 1.3.5
"unformatted": [String, Array],
"content_unformatted": [String, Array],
"indent_inner_html": [Boolean],
"indent_handlebars": [Boolean],
"indent_scripts": ["keep", "separate", "normal"],
Expand Down Expand Up @@ -139,6 +140,7 @@ var path = require('path'),
"i": ["--wrap_attributes_indent_size"],
"W": ["--max_char"], // obsolete since 1.3.5
"U": ["--unformatted"],
"T": ["--content_unformatted"],
"I": ["--indent_inner_html"],
"H": ["--indent_handlebars"],
"S": ["--indent_scripts"],
Expand Down Expand Up @@ -354,6 +356,7 @@ function usage(err) {
msg.push(' -p, --preserve-newlines Preserve line-breaks (--no-preserve-newlines disables)');
msg.push(' -m, --max-preserve-newlines Number of line-breaks to be preserved in one chunk [10]');
msg.push(' -U, --unformatted List of tags (defaults to inline) that should not be reformatted');
msg.push(' -T, --content_unformatted List of tags (defaults to pre) that its content should not be reformatted');
msg.push(' -E, --extra_liners List of tags (defaults to [head,body,/html] that should have an extra newline');
break;
case "css":
Expand Down
107 changes: 106 additions & 1 deletion js/test/generated/beautify-html-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,13 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
//============================================================
// Unformatted tags
reset_options();
test_fragment('<ol>\n <li>b<pre>c</pre></li>\n</ol>');
test_fragment(
'<ol>\n <li>b<pre>c</pre></li>\n</ol>',
'<ol>\n' +
' <li>b\n' +
' <pre>c</pre>\n' +
' </li>\n' +
'</ol>');
test_fragment('<ol>\n <li>b<code>c</code></li>\n</ol>');
test_fragment('<ul>\n <li>\n <span class="octicon octicon-person"></span>\n <a href="/contact/">Kontakt</a>\n </li>\n</ul>');
test_fragment('<div class="searchform"><input type="text" value="" name="s" id="s" /><input type="submit" id="searchsubmit" value="Search" /></div>');
Expand Down Expand Up @@ -1027,6 +1033,105 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be
test_fragment('<html>\n\n<head>\n<meta>\n</head>\n\n</html>');


//============================================================
// content_unformatted to prevent formatting content
reset_options();
opts.content_unformatted = ['script', 'style', 'p', 'span', 'br'];
test_fragment(
'<html><body><h1>A</h1><script>if(1){f();}</script><style>.a{display:none;}</style></body></html>',
'<html>\n' +
'<body>\n' +
' <h1>A</h1>\n' +
' <script>if(1){f();}</script>\n' +
' <style>.a{display:none;}</style>\n' +
'</body>\n' +
'\n' +
'</html>');
test_fragment(
'<div><p>Beautify me</p></div><p><p>But not me</p></p>',
'<div>\n' +
' <p>Beautify me</p>\n' +
'</div>\n' +
'<p><p>But not me</p></p>');
test_fragment(
'<div><p\n class="beauty-me"\n>Beautify me</p></div><p><p\n class="iamalreadybeauty"\n>But not me</p></p>',
'<div>\n' +
' <p class="beauty-me">Beautify me</p>\n' +
'</div>\n' +
'<p><p\n' +
' class="iamalreadybeauty"\n' +
'>But not me</p></p>');
test_fragment('<div><span>blabla<div>something here</div></span></div>');
test_fragment('<div><br /></div>');
test_fragment(
'<div><pre>var a=1;\nvar b=a;</pre></div>',
'<div>\n' +
' <pre>var a=1; var b=a;</pre>\n' +
'</div>');
test_fragment(
'<div><pre>\nvar a=1;\nvar b=a;\n</pre></div>',
'<div>\n' +
' <pre>\n' +
' var a=1; var b=a;\n' +
' </pre>\n' +
'</div>');


//============================================================
// default content_unformatted
reset_options();
test_fragment(
'<html><body><h1>A</h1><script>if(1){f();}</script><style>.a{display:none;}</style></body></html>',
'<html>\n' +
'<body>\n' +
' <h1>A</h1>\n' +
' <script>\n' +
' if (1) {\n' +
' f();\n' +
' }\n' +
' </script>\n' +
' <style>\n' +
' .a {\n' +
' display: none;\n' +
' }\n' +
' </style>\n' +
'</body>\n' +
'\n' +
'</html>');
test_fragment(
'<div><p>Beautify me</p></div><p><p>But not me</p></p>',
'<div>\n' +
' <p>Beautify me</p>\n' +
'</div>\n' +
'<p>\n' +
' <p>But not me</p>\n' +
'</p>');
test_fragment(
'<div><p\n class="beauty-me"\n>Beautify me</p></div><p><p\n class="iamalreadybeauty"\n>But not me</p></p>',
'<div>\n' +
' <p class="beauty-me">Beautify me</p>\n' +
'</div>\n' +
'<p>\n' +
' <p class="iamalreadybeauty">But not me</p>\n' +
'</p>');
test_fragment('<div><span>blabla<div>something here</div></span></div>');
test_fragment('<div><br /></div>');
test_fragment(
'<div><pre>var a=1;\nvar b=a;</pre></div>',
'<div>\n' +
' <pre>var a=1;\n' +
'var b=a;</pre>\n' +
'</div>');
test_fragment(
'<div><pre>\nvar a=1;\nvar b=a;\n</pre></div>',
'<div>\n' +
' <pre>\n' +
'var a=1;\n' +
'var b=a;\n' +
'</pre>\n' +
'</div>');


//============================================================
// New Test Suite
reset_options();
Expand Down
151 changes: 149 additions & 2 deletions test/data/html/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,17 @@ exports.test_data = {
name: "Unformatted tags",
description: "Unformatted tag behavior",
options: [],
tests: [
{ fragment: true, unchanged: '<ol>\n <li>b<pre>c</pre></li>\n</ol>' },
tests: [{
fragment: true,
input: '<ol>\n <li>b<pre>c</pre></li>\n</ol>',
output: [
'<ol>',
' <li>b',
' <pre>c</pre>',
' </li>',
'</ol>'
]
},
{ fragment: true, unchanged: '<ol>\n <li>b<code>c</code></li>\n</ol>' },
{ fragment: true, unchanged: '<ul>\n <li>\n <span class="octicon octicon-person"></span>\n <a href="/contact/">Kontakt</a>\n </li>\n</ul>' },
{ fragment: true, unchanged: '<div class="searchform"><input type="text" value="" name="s" id="s" /><input type="submit" id="searchsubmit" value="Search" /></div>' },
Expand Down Expand Up @@ -899,6 +908,144 @@ exports.test_data = {
fragment: true,
unchanged: '<html>\n\n<head>\n<meta>\n</head>\n\n</html>'
}]
}, {
name: "content_unformatted to prevent formatting content",
description: "",
options: [
{ name: 'content_unformatted', value: "['script', 'style', 'p', 'span', 'br']" }
],
tests: [{
fragment: true,
input: '<html><body><h1>A</h1><script>if(1){f();}</script><style>.a{display:none;}</style></body></html>',
output: [
'<html>',
'<body>',
' <h1>A</h1>',
' <script>if(1){f();}</script>',
' <style>.a{display:none;}</style>',
'</body>',
'',
'</html>'
]
}, {
fragment: true,
input: '<div><p>Beautify me</p></div><p><p>But not me</p></p>',
output: [
'<div>',
' <p>Beautify me</p>',
'</div>',
'<p><p>But not me</p></p>'
]
}, {
fragment: true,
input: '<div><p\n class="beauty-me"\n>Beautify me</p></div><p><p\n class="iamalreadybeauty"\n>But not me</p></p>',
output: [
'<div>',
' <p class="beauty-me">Beautify me</p>',
'</div>',
'<p><p',
' class="iamalreadybeauty"',
'>But not me</p></p>'
]
}, {
fragment: true,
unchanged: '<div><span>blabla<div>something here</div></span></div>'
}, {
fragment: true,
unchanged: '<div><br /></div>'
}, {
fragment: true,
input: '<div><pre>var a=1;\nvar b=a;</pre></div>',
output: [
'<div>',
' <pre>var a=1; var b=a;</pre>',
'</div>'
]
}, {
fragment: true,
input: '<div><pre>\nvar a=1;\nvar b=a;\n</pre></div>',
output: [
'<div>',
' <pre>',
' var a=1; var b=a;',
' </pre>',
'</div>'
]
}]
}, {
name: "default content_unformatted",
description: "",
options: [],
tests: [{
fragment: true,
input: '<html><body><h1>A</h1><script>if(1){f();}</script><style>.a{display:none;}</style></body></html>',
output: [
'<html>',
'<body>',
' <h1>A</h1>',
' <script>',
' if (1) {',
' f();',
' }',
' </script>',
' <style>',
' .a {',
' display: none;',
' }',
' </style>',
'</body>',
'',
'</html>'
]
}, {
fragment: true,
input: '<div><p>Beautify me</p></div><p><p>But not me</p></p>',
output: [
'<div>',
' <p>Beautify me</p>',
'</div>',
'<p>',
' <p>But not me</p>',
'</p>',
]
}, {
fragment: true,
input: '<div><p\n class="beauty-me"\n>Beautify me</p></div><p><p\n class="iamalreadybeauty"\n>But not me</p></p>',
output: [
'<div>',
' <p class="beauty-me">Beautify me</p>',
'</div>',
'<p>',
' <p class="iamalreadybeauty">But not me</p>',
'</p>'
]
}, {
fragment: true,
unchanged: '<div><span>blabla<div>something here</div></span></div>'
}, {
fragment: true,
unchanged: '<div><br /></div>'
}, {
fragment: true,
input: '<div><pre>var a=1;\nvar b=a;</pre></div>',
output: [
'<div>',
' <pre>var a=1;',
'var b=a;</pre>',
'</div>'
]
}, {
fragment: true,
input: '<div><pre>\nvar a=1;\nvar b=a;\n</pre></div>',
output: [
'<div>',
' <pre>',
'var a=1;',
'var b=a;',
'</pre>',
'</div>'
]
}]
}, {
name: "New Test Suite"
}],
Expand Down

0 comments on commit 32c8e6e

Please sign in to comment.