diff --git a/README.md b/README.md index 006e10ea4..5d51f7801 100644 --- a/README.md +++ b/README.md @@ -316,9 +316,9 @@ CSS Beautifier Options: -e, --eol Character(s) to use as line terminators. (default newline - "\\n") -n, --end-with-newline End output with newline -b, --brace-style [collapse|expand] ["collapse"] - -L, --selector-separator-newline Add a newline between multiple selectors -N, --newline-between-rules Add a newline between CSS rules --indent-empty-lines Keep indentation on empty lines + --selector-separator Whitespace between selectors [none|newline|space] [space] HTML Beautifier Options: -s, --indent-size Indentation size [4] diff --git a/js/src/cli.js b/js/src/cli.js index 070f423e8..1d09cfc1b 100755 --- a/js/src/cli.js +++ b/js/src/cli.js @@ -94,11 +94,12 @@ var path = require('path'), "indent_empty_lines": Boolean, "templating": [String, Array], // CSS-only - "selector_separator_newline": Boolean, "newline_between_rules": Boolean, "space_around_combinator": Boolean, + "selector_separator": String, //deprecated - replaced with space_around_combinator, remove in future version "space_around_selector_separator": Boolean, + "selector_separator_newline": Boolean, // HTML-only "max_char": Number, // obsolete since 1.3.5 "inline": [String, Array], @@ -180,6 +181,7 @@ var path = require('path'), // no shorthand for "editorconfig" // no shorthand for "indent_empty_lines" // not shorthad for "templating" + // no shorthand for "selector_separator" }); function verifyExists(fullPath) { @@ -392,8 +394,8 @@ function usage(err) { break; case "css": msg.push(' -b, --brace-style [collapse|expand] ["collapse"]'); - msg.push(' -L, --selector-separator-newline Add a newline between multiple selectors.'); msg.push(' -N, --newline-between-rules Add a newline between CSS rules.'); + msg.push(' --selector-separator Whitespace between selectors [none|newline|space] [space]'); } if (err) { diff --git a/js/src/css/beautifier.js b/js/src/css/beautifier.js index a0fa2bd64..2c6ca9c2b 100644 --- a/js/src/css/beautifier.js +++ b/js/src/css/beautifier.js @@ -454,7 +454,7 @@ Beautifier.prototype.beautify = function() { this.print_string(this._ch); // handle scss/sass map - if (insidePropertyValue && previous_ch === "$" && this._options.selector_separator_newline) { + if (insidePropertyValue && previous_ch === "$" && this._options.selector_separator === "newline") { this._output.add_new_line(); insideScssMap = true; } else { @@ -468,7 +468,7 @@ Beautifier.prototype.beautify = function() { parenLevel--; this.outdent(); } - if (insideScssMap && this._input.peek() === ";" && this._options.selector_separator_newline) { + if (insideScssMap && this._input.peek() === ";" && this._options.selector_separator === "newline") { insideScssMap = false; this.outdent(); this._output.add_new_line(); @@ -477,8 +477,12 @@ Beautifier.prototype.beautify = function() { } else if (this._ch === ',') { this.print_string(this._ch); this.eatWhitespace(true); - if (this._options.selector_separator_newline && (!insidePropertyValue || insideScssMap) && parenLevel === 0 && !insideAtImport && !insideAtExtend) { + + if (this._options.selector_separator === "newline" && (!insidePropertyValue || insideScssMap) && + parenLevel === 0 && !insideAtImport && !insideAtExtend) { this._output.add_new_line(); + } else if (this._options.selector_separator === "none") { + this._output.space_before_token = false; } else { this._output.space_before_token = true; } diff --git a/js/src/css/options.js b/js/src/css/options.js index dc268f1eb..0136571f3 100644 --- a/js/src/css/options.js +++ b/js/src/css/options.js @@ -34,10 +34,20 @@ function Options(options) { BaseOptions.call(this, options, 'css'); this.selector_separator_newline = this._get_boolean('selector_separator_newline', true); + this.selector_separator = this._get_selection('selector_separator', [' ', 'none', 'space', 'newline']); + if (this.selector_separator === ' ') { + if (this.selector_separator_newline) { + this.selector_separator = 'newline'; + } else { + this.selector_separator = 'space'; + } + } + this.newline_between_rules = this._get_boolean('newline_between_rules', true); var space_around_selector_separator = this._get_boolean('space_around_selector_separator'); this.space_around_combinator = this._get_boolean('space_around_combinator') || space_around_selector_separator; + var brace_style_split = this._get_selection_list('brace_style', ['collapse', 'expand', 'end-expand', 'none', 'preserve-inline']); this.brace_style = 'collapse'; for (var bs = 0; bs < brace_style_split.length; bs++) { @@ -51,6 +61,4 @@ function Options(options) { } Options.prototype = new BaseOptions(); - - module.exports.Options = Options; diff --git a/python/cssbeautifier/_main.py b/python/cssbeautifier/_main.py index 88b9bf7a0..4ca74e4d9 100644 --- a/python/cssbeautifier/_main.py +++ b/python/cssbeautifier/_main.py @@ -76,8 +76,7 @@ def usage(stream=sys.stdout): (default first newline in file, otherwise "\\n") -t, --indent-with-tabs Indent with tabs, overrides -s and -c --preserve-newlines Preserve existing line breaks. - --disable-selector-separator-newline - Do not print each selector on a separate line. + --selector-separator Whitespace between selectors [none|newline|space] [space] -b, --brace-style=collapse Brace style (collapse, expand) -n, --end-with-newline End output with newline --disable-newline-between-rules @@ -128,6 +127,7 @@ def main(): "disable-newline-between-rules", "space-around-combinator", "indent-empty-lines", + "selector-separator", ], ) except getopt.GetoptError as ex: @@ -178,6 +178,8 @@ def main(): css_options.indent_empty_lines = True elif opt in ("--editorconfig",): css_options.editorconfig = True + elif opt in ("--selector-separator"): + css_options.selector_separator = arg try: filepaths, replace = get_filepaths_from_params(filepath_params, replace) diff --git a/python/cssbeautifier/css/beautifier.py b/python/cssbeautifier/css/beautifier.py index 1164d9ce4..71a696084 100644 --- a/python/cssbeautifier/css/beautifier.py +++ b/python/cssbeautifier/css/beautifier.py @@ -474,7 +474,7 @@ def beautify(self): if ( insidePropertyValue and previous_ch == "$" - and self._options.selector_separator_newline + and self._options.selector_separator == "newline" ): self._output.add_new_line() insideScssMap = True @@ -490,7 +490,7 @@ def beautify(self): if ( insideScssMap and self._input.peek() == ";" - and self._options.selector_separator_newline + and self._options.selector_separator == "newline" ): insideScssMap = False self.outdent() @@ -499,14 +499,17 @@ def beautify(self): elif self._ch == ",": self.print_string(self._ch) self.eatWhitespace(True) + if ( - self._options.selector_separator_newline + self._options.selector_separator == "newline" and (not insidePropertyValue or insideScssMap) and parenLevel == 0 and not insideAtImport and not insideAtExtend ): self._output.add_new_line() + elif self._options.selector_separator == "none": + self._output.space_before_token = False else: self._output.space_before_token = True elif ( diff --git a/python/cssbeautifier/css/options.py b/python/cssbeautifier/css/options.py index eee1d7655..e9d02634c 100644 --- a/python/cssbeautifier/css/options.py +++ b/python/cssbeautifier/css/options.py @@ -33,6 +33,16 @@ def __init__(self, options=None): self.selector_separator_newline = self._get_boolean( "selector_separator_newline", True ) + # allow "\n" and " " but treat both as default. + self.selector_separator = self._get_selection( + "selector_separator", [" ", "none", "space", "newline"] + ) + if self.selector_separator == "default": + if self.selector_separator_newline: + self.selector_separator = "newline" + else: + self.selector_separator = "space" + self.newline_between_rules = self._get_boolean("newline_between_rules", True) brace_style_split = self._get_selection_list( diff --git a/test/data/css/node.mustache b/test/data/css/node.mustache index d6bce6fb6..a35f1db47 100644 --- a/test/data/css/node.mustache +++ b/test/data/css/node.mustache @@ -40,7 +40,6 @@ function run_css_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_bea brace_style: 'collapse', space_before_conditional: true, break_chained_methods: false, - selector_separator: '\n', end_with_newline: false }; var opts; diff --git a/test/data/css/tests.js b/test/data/css/tests.js index 34703a0ec..f37fd3b5d 100644 --- a/test/data/css/tests.js +++ b/test/data/css/tests.js @@ -285,7 +285,6 @@ exports.test_data = { matrix: [{ options: [ { name: 'selector_separator_newline', value: 'false' }, - { name: 'selector_separator', value: '" "' }, { name: "newline_between_rules", value: "true" } ], separator: ' ', @@ -297,7 +296,6 @@ exports.test_data = { }, { options: [ { name: 'selector_separator_newline', value: 'false' }, - { name: 'selector_separator', value: '" "' }, { name: "newline_between_rules", value: "false" } ], separator: ' ', @@ -309,7 +307,6 @@ exports.test_data = { }, { options: [ { name: 'selector_separator_newline', value: 'false' }, - { name: 'selector_separator', value: '" "' }, { name: "newline_between_rules", value: "false" } ], // BUG: #713 @@ -322,7 +319,6 @@ exports.test_data = { }, { options: [ { name: 'selector_separator_newline', value: 'true' }, - { name: 'selector_separator', value: '" "' }, { name: "newline_between_rules", value: "true" } ], separator: '\\n', @@ -334,7 +330,6 @@ exports.test_data = { }, { options: [ { name: 'selector_separator_newline', value: 'true' }, - { name: 'selector_separator', value: '" "' }, { name: "newline_between_rules", value: "false" } ], separator: '\\n', @@ -346,7 +341,6 @@ exports.test_data = { }, { options: [ { name: 'selector_separator_newline', value: 'true' }, - { name: 'selector_separator', value: '" "' }, { name: "newline_between_rules", value: "false" } ], separator: '\\n', @@ -358,7 +352,6 @@ exports.test_data = { }, { options: [ { name: 'selector_separator_newline', value: 'true' }, - { name: 'selector_separator', value: '" "' }, { name: 'brace_style', value: '"expand"' }, { name: 'newline_between_rules', value: 'false' } ], @@ -1995,7 +1988,35 @@ exports.test_data = { unchanged: 'p {\n color: blue;\n}' }] }, { - + name: "Issue #1862 -- selector-separator option adds space between CSS selectors if value is space", + options: [ + { name: "selector_separator", value: "'space'" } + ], + description: "", + tests: [{ + input: '#main,#section,a {\n color: blue;\n}', + output: '#main, #section, a {\n color: blue;\n}' + }] + }, { + name: "Issue #1862 -- selector-separator option adds newline between CSS selectors if value is newline", + options: [ + { name: "selector_separator", value: "'newline'" } + ], + description: "", + tests: [{ + input: '#main,#section,a {\n color: blue;\n}', + output: '#main,\n#section,\na {\n color: blue;\n}' + }] + }, + { + name: "Issue #1862 -- selector-separator option adds no whitespace between CSS selectors if value is none", + options: [ + { name: "selector_separator", value: "'none'" } + ], + description: "", + tests: [{ + unchanged: '#main,#section,a {\n color: blue;\n}' + }] } ] }; diff --git a/test/data/html/node.mustache b/test/data/html/node.mustache index 638701f0d..376ee2bfa 100644 --- a/test/data/html/node.mustache +++ b/test/data/html/node.mustache @@ -40,7 +40,6 @@ function run_html_tests(test_obj, Urlencoded, js_beautify, html_beautify, css_be brace_style: 'collapse', space_before_conditional: true, break_chained_methods: false, - selector_separator: '\n', end_with_newline: false }; var opts; diff --git a/test/data/javascript/node.mustache b/test/data/javascript/node.mustache index 0681e91f2..7f2337c10 100644 --- a/test/data/javascript/node.mustache +++ b/test/data/javascript/node.mustache @@ -38,7 +38,6 @@ function run_javascript_tests(test_obj, Urlencoded, js_beautify, html_beautify, jslint_happy: false, space_before_conditional: true, break_chained_methods: false, - selector_separator: '\n', end_with_newline: false }; var opts;