Skip to content

Commit 228bec6

Browse files
authored
pretty-print values (#11)
1 parent 1dd76e2 commit 228bec6

File tree

2 files changed

+88
-10
lines changed

2 files changed

+88
-10
lines changed

index.js

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ function print_atrule(node, indent_level, css) {
246246
let buffer = indent(indent_level) + '@' + node.name
247247

248248
// @font-face has no prelude
249-
if (node.prelude) {
249+
if (node.prelude !== null) {
250250
buffer += ' ' + substr(node.prelude, css)
251251
}
252252

@@ -267,7 +267,63 @@ function print_atrule(node, indent_level, css) {
267267
* @returns {string} A formatted Declaration
268268
*/
269269
function print_declaration(node, indent_level, css) {
270-
return indent(indent_level) + node.property + ': ' + substr(node.value, css) + ';'
270+
return indent(indent_level) + node.property.toLowerCase() + ': ' + print_value(node.value, indent_level, css).trim() + ';'
271+
}
272+
273+
/**
274+
* @param {import('css-tree').List} children
275+
* @param {number} indent_level
276+
* @param {string} css
277+
*/
278+
function print_list(children, indent_level, css) {
279+
let buffer = ''
280+
281+
for (let node of children) {
282+
if (node !== children.first && node.type !== 'Operator') {
283+
buffer += ' '
284+
}
285+
286+
if (node.type === 'Identifier') {
287+
// TODO: new CSS keywork NaN should not be lowercased
288+
buffer += node.name.toLowerCase()
289+
} else if (node.type === 'Function') {
290+
buffer += print_function(node, 0, css)
291+
} else if (node.type === 'Dimension') {
292+
buffer += node.value + node.unit.toLowerCase()
293+
} else if (node.type === 'Value') {
294+
// Values can be inside var() as fallback
295+
// var(--prop, VALUE)
296+
buffer += print_value(node, 0, css)
297+
} else {
298+
buffer += print_unknown(node, 0, css)
299+
}
300+
}
301+
return buffer
302+
}
303+
304+
/**
305+
* @param {import('css-tree').Value | import('css-tree').Raw} node
306+
* @param {number} indent_level
307+
* @param {string} css
308+
*/
309+
function print_value(node, indent_level, css) {
310+
if (node.type === 'Raw') {
311+
return print_unknown(node, 0, css)
312+
}
313+
314+
return print_list(node.children, 0, css)
315+
}
316+
317+
/**
318+
* @param {import('css-tree').FunctionNode} node
319+
* @param {number} indent_level
320+
* @param {string} css
321+
*/
322+
function print_function(node, indent_level, css) {
323+
let buffer = node.name.toLowerCase() + '('
324+
buffer += print_list(node.children, 0, css)
325+
buffer += ')'
326+
return buffer
271327
}
272328

273329
/**
@@ -316,8 +372,8 @@ export function format(css) {
316372
let ast = parse(css, {
317373
positions: true,
318374
parseAtrulePrelude: false,
319-
parseCustomProperty: false,
320-
parseValue: false,
375+
parseCustomProperty: true,
376+
parseValue: true,
321377
})
322378
return print(ast, 0, css)
323379
}

test.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ test('Declarations end with a semicolon (;)', () => {
117117
`)
118118
let expected = `@font-face {
119119
src: url('test');
120-
font-family: Test;
120+
font-family: test;
121121
}
122122
123123
css {
@@ -277,7 +277,7 @@ test { a: 1}
277277
no-layer-2 {
278278
color: red;
279279
font-size: 1rem;
280-
COLOR: green;
280+
color: green;
281281
}
282282
283283
@layer components, deep;
@@ -443,7 +443,7 @@ a.b
443443
color: green }
444444
`)
445445
let expected = `a {
446-
background: linear-gradient( red, 10% blue, 20% green,100% yellow);
446+
background: linear-gradient(red, 10% blue, 20% green, 100% yellow);
447447
}
448448
449449
a.b .c .d .e .f {
@@ -499,32 +499,54 @@ test('formats selectors with Nth', () => {
499499
}
500500
})
501501

502-
test.skip('formats simple value lists', () => {
502+
test('formats simple value lists', () => {
503503
let actual = format(`
504504
a {
505505
transition-property: all,opacity;
506506
transition: all 100ms ease,opacity 10ms 20ms linear;
507+
transition: all 100ms ease;
508+
ANIMATION: COLOR 123MS EASE-OUT;
507509
color: rgb(0,0,0);
510+
color: HSL(0%,10%,50%);
511+
content: 'Test';
512+
background-image: url("EXAMPLE.COM");
508513
}
509514
`)
510515
let expected = `a {
511516
transition-property: all, opacity;
512517
transition: all 100ms ease, opacity 10ms 20ms linear;
518+
transition: all 100ms ease;
519+
animation: color 123ms ease-out;
513520
color: rgb(0, 0, 0);
521+
color: hsl(0%, 10%, 50%);
522+
content: 'Test';
523+
background-image: url("EXAMPLE.COM");
514524
}`
515525
assert.equal(actual, expected)
516526
})
517527

518-
test.skip('formats nested value lists', () => {
528+
test('formats nested value lists', () => {
519529
let actual = format(`
520530
a {
521531
background: red,linear-gradient(to bottom,red 10%,green 50%,blue 100%);
522-
color: var(--test1,var(--test2,green));
523532
}
524533
`)
525534
let expected = `a {
526535
background: red, linear-gradient(to bottom, red 10%, green 50%, blue 100%);
536+
}`
537+
assert.equal(actual, expected)
538+
})
539+
540+
test('formats nested var()', () => {
541+
let actual = format(`
542+
a {
543+
color: var(--test1,var(--test2,green));
544+
color: var(--test3,rgb(0,0,0));
545+
}
546+
`)
547+
let expected = `a {
527548
color: var(--test1, var(--test2, green));
549+
color: var(--test3, rgb(0, 0, 0));
528550
}`
529551
assert.equal(actual, expected)
530552
})

0 commit comments

Comments
 (0)