diff --git a/README.md b/README.md index c34e4aa..1844b3a 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ Need more examples? 1. Every **Declaration** starts on a new line 1. Every **Declaration** ends with a semicolon (;) 1. An empty line is placed after a **Block**, unless it’s the last in the surrounding **Block** -1. Unknown syntax is rendered as-is +1. Multiline tokens like **Selectors, Values, etc.** are rendered on a single line +1. Unknown syntax is rendered as-is, with multi-line formatting kept intact ## Acknowledgements diff --git a/index.js b/index.js index 426ab89..93945ed 100644 --- a/index.js +++ b/index.js @@ -15,10 +15,26 @@ function indent(size) { * @returns A portion of the CSS */ function substr(node, css) { - if (node.loc) { - return css.substring(node.loc.start.offset, node.loc.end.offset) + if (node.loc === null) return '' + let str = css.substring(node.loc.start.offset, node.loc.end.offset) + + // Single-line node, most common case + if (node.loc.start.line === node.loc.end.line) { + return str } - return '' + + // Multi-line nodes, not common + return str.split('\n').map(part => part.trim()).join(' ') +} + +/** + * @param {import('css-tree').CssNode} node + * @param {string} css + * @returns A portion of the CSS + */ +function substr_raw(node, css) { + if (node.loc === null) return '' + return css.substring(node.loc.start.offset, node.loc.end.offset) } /** @@ -178,7 +194,7 @@ function print_declaration(node, indent_level, css) { * @returns {string} A formatted unknown CSS string */ function print_unknown(node, indent_level, css) { - return indent(indent_level) + substr(node, css).trim() + return indent(indent_level) + substr_raw(node, css).trim() } /** diff --git a/test.js b/test.js index 4df3b15..92172c1 100644 --- a/test.js +++ b/test.js @@ -428,4 +428,28 @@ test('empty input', () => { assert.equal(actual, expected) }) +test('formats multiline tokens on a single line', () => { + let actual = format(` +a { + background: linear-gradient( + red, + 10% blue, +20% green,100% yellow); +} + +a.b + .c .d + .e .f { +color: green } + `) + let expected = `a { + background: linear-gradient( red, 10% blue, 20% green,100% yellow); +} + +a.b .c .d .e .f { + color: green; +}` + assert.equal(actual, expected) +}) + test.run(); \ No newline at end of file