Skip to content

Commit 26e105b

Browse files
authored
feat: add tab_size option to use N spaces instead of tabs (#125)
closes #124
1 parent 6af7056 commit 26e105b

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ let minified = minify("a {}");
7979
let formatted_mini = format("a {}", { minify: true });
8080
```
8181

82+
## Tab size
83+
84+
For cases where you cannot control the tab size with CSS there is an option to override the default tabbed indentation with N spaces.
85+
86+
```js
87+
import { format } from "@projectwallace/format-css";
88+
89+
let formatted = format("a { color: red; }", {
90+
tab_size: 2
91+
});
92+
```
93+
8294
## Acknowledgements
8395

8496
- Thanks to [CSSTree](https://github.com/csstree/csstree) for providing the necessary parser and the interfaces for our CSS Types (the **bold** elements in the list above)

index.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,22 @@ function lowercase(str) {
3434
/**
3535
* @typedef {Object} Options
3636
* @property {boolean} [minify] Whether to minify the CSS or keep it formatted
37+
* @property {number} [tab_size] Tell the formatter to use N spaces instead of tabs
3738
*
3839
* Format a string of CSS using some simple rules
3940
* @param {string} css The original CSS
4041
* @param {Options} options
4142
* @returns {string} The formatted CSS
4243
*/
43-
export function format(css, { minify = false } = {}) {
44+
export function format(css, {
45+
minify = false,
46+
tab_size = undefined,
47+
} = Object.create(null)) {
48+
49+
if (tab_size !== undefined && Number(tab_size) < 1) {
50+
throw new TypeError('tab_size must be a number greater than 0')
51+
}
52+
4453
/** @type {number[]} */
4554
let comments = []
4655

@@ -64,10 +73,16 @@ export function format(css, { minify = false } = {}) {
6473
/**
6574
* Indent a string
6675
* @param {number} size
67-
* @returns {string} A string with {size} tabs
76+
* @returns {string} A string with [size] tabs/spaces
6877
*/
6978
function indent(size) {
70-
return minify ? EMPTY_STRING : '\t'.repeat(size)
79+
if (minify) return EMPTY_STRING
80+
81+
if (tab_size) {
82+
return SPACE.repeat(tab_size * size)
83+
}
84+
85+
return '\t'.repeat(size)
7186
}
7287

7388
/** @param {import('css-tree').CssNode} node */

test/tab-size.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { suite } from 'uvu'
2+
import * as assert from 'uvu/assert'
3+
import { format } from '../index.js'
4+
5+
let test = suite('Tab Size')
6+
7+
let fixture = `
8+
selector {
9+
color: red;
10+
}
11+
`
12+
13+
test('tab_size: 2', () => {
14+
let actual = format(`
15+
selector {
16+
color: red;
17+
}
18+
19+
@media (min-width: 100px) {
20+
selector {
21+
color: blue;
22+
}
23+
}
24+
`, { tab_size: 2 })
25+
let expected = `selector {
26+
color: red;
27+
}
28+
29+
@media (min-width: 100px) {
30+
selector {
31+
color: blue;
32+
}
33+
}`
34+
assert.equal(actual, expected)
35+
})
36+
37+
test('invalid tab_size: 0', () => {
38+
assert.throws(() => format(fixture, { tab_size: 0 }))
39+
})
40+
41+
test('invalid tab_size: negative', () => {
42+
assert.throws(() => format(fixture, { tab_size: -1 }))
43+
})
44+
45+
test('combine tab_size and minify', () => {
46+
let actual = format(fixture, {
47+
tab_size: 2,
48+
minify: true
49+
})
50+
let expected = `selector{color:red}`
51+
assert.equal(actual, expected)
52+
})
53+
54+
test.run()

0 commit comments

Comments
 (0)