@projectwallace/format-css 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/format-css.js +85 -77
- package/dist/index.d.ts +8 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,6 +79,18 @@ let minified = minify("a {}");
|
|
|
79
79
|
let formatted_mini = format("a {}", { minify: true });
|
|
80
80
|
```
|
|
81
81
|
|
|
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
|
+
|
|
82
94
|
## Acknowledgements
|
|
83
95
|
|
|
84
96
|
- 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)
|
package/dist/format-css.js
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
1
|
+
import d from "css-tree/parser";
|
|
2
|
+
const a = " ", c = "", $ = ":", x = ";", g = '"', I = "(", v = ")", ee = "[", te = "]", V = "{", W = "}", re = "{}", Z = ",", j = "Atrule", F = "Rule", G = "Block", Q = "SelectorList", Y = "Selector", w = "Declaration", B = "Operator";
|
|
3
3
|
function C(y) {
|
|
4
4
|
return /[A-Z]/.test(y) ? y.toLowerCase() : y;
|
|
5
5
|
}
|
|
6
|
-
function
|
|
7
|
-
|
|
6
|
+
function ne(y, {
|
|
7
|
+
minify: O = !1,
|
|
8
|
+
tab_size: S = void 0
|
|
9
|
+
} = /* @__PURE__ */ Object.create(null)) {
|
|
10
|
+
if (S !== void 0 && Number(S) < 1)
|
|
11
|
+
throw new TypeError("tab_size must be a number greater than 0");
|
|
12
|
+
let T = [], k = d(y, {
|
|
8
13
|
positions: !0,
|
|
9
14
|
parseAtrulePrelude: !1,
|
|
10
15
|
parseCustomProperty: !0,
|
|
11
16
|
parseValue: !0,
|
|
12
17
|
onComment: (n, e) => {
|
|
13
|
-
|
|
18
|
+
T.push(e.start.offset, e.end.offset);
|
|
14
19
|
}
|
|
15
20
|
});
|
|
16
|
-
const u =
|
|
17
|
-
`, p =
|
|
21
|
+
const u = O ? c : `
|
|
22
|
+
`, p = O ? c : a, h = O ? c : x;
|
|
18
23
|
let s = 0;
|
|
19
|
-
function
|
|
20
|
-
return
|
|
24
|
+
function i(n) {
|
|
25
|
+
return O === !0 ? c : S !== void 0 ? a.repeat(S * n) : " ".repeat(n);
|
|
21
26
|
}
|
|
22
|
-
function
|
|
27
|
+
function P(n) {
|
|
23
28
|
let e = n.loc;
|
|
24
|
-
return e ? y.slice(e.start.offset, e.end.offset)
|
|
29
|
+
return e == null ? c : y.slice(e.start.offset, e.end.offset);
|
|
25
30
|
}
|
|
26
31
|
function b(n) {
|
|
27
32
|
return /** @type {import('css-tree').CssLocation} */ n.loc.start.offset;
|
|
@@ -30,33 +35,33 @@ function re(y, { minify: P = !1 } = {}) {
|
|
|
30
35
|
return /** @type {import('css-tree').CssLocation} */ n.loc.end.offset;
|
|
31
36
|
}
|
|
32
37
|
function m(n, e) {
|
|
33
|
-
if (
|
|
38
|
+
if (O === !0 || n === void 0 || e === void 0)
|
|
34
39
|
return c;
|
|
35
40
|
let t = "";
|
|
36
|
-
for (let r = 0; r <
|
|
37
|
-
let l =
|
|
41
|
+
for (let r = 0; r < T.length; r += 2) {
|
|
42
|
+
let l = T[r];
|
|
38
43
|
if (l === void 0 || l < n) continue;
|
|
39
|
-
let f =
|
|
44
|
+
let f = T[r + 1];
|
|
40
45
|
if (f === void 0 || f > e) break;
|
|
41
|
-
t.length > 0 && (t += u +
|
|
46
|
+
t.length > 0 && (t += u + i(s)), t += y.slice(l, f);
|
|
42
47
|
}
|
|
43
48
|
return t;
|
|
44
49
|
}
|
|
45
|
-
function
|
|
50
|
+
function M(n) {
|
|
46
51
|
let e, t = n.prelude, r = n.block;
|
|
47
|
-
t.type ===
|
|
52
|
+
t.type === Q && (e = q(t));
|
|
48
53
|
let l = m(E(t), b(r));
|
|
49
|
-
return l && (e += u +
|
|
54
|
+
return l && (e += u + i(s) + l), r.type === G && (e += K(r)), e;
|
|
50
55
|
}
|
|
51
|
-
function
|
|
56
|
+
function q(n) {
|
|
52
57
|
let e = c;
|
|
53
58
|
return n.children.forEach((t, r) => {
|
|
54
|
-
t.type ===
|
|
59
|
+
t.type === Y && (e += i(s) + A(t)), r.next !== null && (e += Z + u);
|
|
55
60
|
let l = r.next !== null ? b(r.next.data) : E(n), f = m(E(t), l);
|
|
56
|
-
f && (e +=
|
|
61
|
+
f && (e += i(s) + f + u);
|
|
57
62
|
}), e;
|
|
58
63
|
}
|
|
59
|
-
function
|
|
64
|
+
function A(n) {
|
|
60
65
|
let e = c;
|
|
61
66
|
return (n.children || []).forEach((r) => {
|
|
62
67
|
switch (r.type) {
|
|
@@ -65,124 +70,127 @@ function re(y, { minify: P = !1 } = {}) {
|
|
|
65
70
|
break;
|
|
66
71
|
}
|
|
67
72
|
case "Combinator": {
|
|
68
|
-
e +=
|
|
73
|
+
e += a, r.name !== " " && (e += r.name + a);
|
|
69
74
|
break;
|
|
70
75
|
}
|
|
71
76
|
case "PseudoClassSelector":
|
|
72
77
|
case "PseudoElementSelector": {
|
|
73
|
-
e +=
|
|
78
|
+
e += $;
|
|
74
79
|
let l = C(r.name);
|
|
75
|
-
(l === "before" || l === "after" || r.type === "PseudoElementSelector") && (e +=
|
|
80
|
+
(l === "before" || l === "after" || r.type === "PseudoElementSelector") && (e += $), e += l, r.children !== null && (e += I + A(r) + v);
|
|
76
81
|
break;
|
|
77
82
|
}
|
|
78
|
-
case
|
|
83
|
+
case Q: {
|
|
79
84
|
r.children.forEach((l, f) => {
|
|
80
|
-
l.type ===
|
|
85
|
+
l.type === Y && (e += A(l)), f.next !== null && f.next.data.type === Y && (e += Z + p);
|
|
81
86
|
});
|
|
82
87
|
break;
|
|
83
88
|
}
|
|
84
89
|
case "Nth": {
|
|
85
90
|
let l = r.nth;
|
|
86
|
-
if (l)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
r.selector !== null && (e += o + "of" + o + S(r.selector));
|
|
91
|
+
if (l.type === "AnPlusB") {
|
|
92
|
+
let f = l.a, o = l.b;
|
|
93
|
+
f !== null && (e += f + "n"), f !== null && o !== null && (e += a), o !== null && (f !== null && !o.startsWith("-") && (e += "+" + a), e += o);
|
|
94
|
+
} else
|
|
95
|
+
e += P(l);
|
|
96
|
+
r.selector !== null && (e += a + "of" + a + A(r.selector));
|
|
93
97
|
break;
|
|
94
98
|
}
|
|
95
99
|
case "AttributeSelector": {
|
|
96
|
-
e +=
|
|
100
|
+
e += ee, e += r.name.name, r.matcher !== null && r.value !== null && (e += r.matcher, e += g, r.value.type === "String" ? e += r.value.value : r.value.type === "Identifier" && (e += r.value.name), e += g), r.flags !== null && (e += a + r.flags), e += te;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
case "NestingSelector": {
|
|
104
|
+
e += "&";
|
|
97
105
|
break;
|
|
98
106
|
}
|
|
99
107
|
default: {
|
|
100
|
-
e +=
|
|
108
|
+
e += P(r);
|
|
101
109
|
break;
|
|
102
110
|
}
|
|
103
111
|
}
|
|
104
112
|
}), e;
|
|
105
113
|
}
|
|
106
|
-
function
|
|
114
|
+
function K(n) {
|
|
107
115
|
let e = n.children, t = p;
|
|
108
116
|
if (e.isEmpty) {
|
|
109
117
|
let f = m(b(n), E(n));
|
|
110
|
-
return f ? (t +=
|
|
118
|
+
return f ? (t += V + u, t += i(s + 1) + f, t += u + i(s) + W, t) : t + re;
|
|
111
119
|
}
|
|
112
|
-
t +=
|
|
120
|
+
t += V + u, s++;
|
|
113
121
|
let r = m(b(n), b(
|
|
114
122
|
/** @type {import('css-tree').CssNode} */
|
|
115
123
|
e.first
|
|
116
124
|
));
|
|
117
|
-
r && (t +=
|
|
118
|
-
if (
|
|
119
|
-
let
|
|
120
|
-
|
|
125
|
+
r && (t += i(s) + r + u), e.forEach((f, o) => {
|
|
126
|
+
if (o.prev !== null) {
|
|
127
|
+
let H = m(E(o.prev.data), b(f));
|
|
128
|
+
H && (t += i(s) + H + u);
|
|
121
129
|
}
|
|
122
|
-
f.type ===
|
|
130
|
+
f.type === w ? (t += X(f), o.next === null ? t += h : t += x) : (o.prev !== null && o.prev.data.type === w && (t += u), f.type === F ? t += M(f) : f.type === j ? t += U(f) : t += R(f, s)), o.next !== null && (t += u, f.type !== w && (t += u));
|
|
123
131
|
});
|
|
124
132
|
let l = m(E(
|
|
125
133
|
/** @type {import('css-tree').CssNode} */
|
|
126
134
|
e.last
|
|
127
135
|
), E(n));
|
|
128
|
-
return l && (t += u +
|
|
136
|
+
return l && (t += u + i(s) + l), s--, t += u + i(s) + W, t;
|
|
129
137
|
}
|
|
130
|
-
function
|
|
131
|
-
let e =
|
|
132
|
-
return e += C(n.name), t !== null && (e +=
|
|
138
|
+
function U(n) {
|
|
139
|
+
let e = i(s) + "@", t = n.prelude, r = n.block;
|
|
140
|
+
return e += C(n.name), t !== null && (e += a + J(t)), r === null ? e += x : r.type === G && (e += K(r)), e;
|
|
133
141
|
}
|
|
134
|
-
function
|
|
135
|
-
let e =
|
|
142
|
+
function J(n) {
|
|
143
|
+
let e = P(n);
|
|
136
144
|
return e.replace(/\s*([:,])/g, e.toLowerCase().includes("selector(") ? "$1" : "$1 ").replace(/\)([a-zA-Z])/g, ") $1").replace(/\s*(=>|<=)\s*/g, " $1 ").replace(/([^<>=\s])([<>])([^<>=\s])/g, `$1${p}$2${p}$3`).replace(/\s+/g, p).replace(/calc\(\s*([^()+\-*/]+)\s*([*/+-])\s*([^()+\-*/]+)\s*\)/g, (t, r, l, f) => {
|
|
137
|
-
let
|
|
138
|
-
return `calc(${r.trim()}${
|
|
145
|
+
let o = l === "+" || l === "-" ? a : p;
|
|
146
|
+
return `calc(${r.trim()}${o}${l}${o}${f.trim()})`;
|
|
139
147
|
}).replace(/selector|url|supports|layer\(/ig, (t) => C(t));
|
|
140
148
|
}
|
|
141
|
-
function
|
|
149
|
+
function X(n) {
|
|
142
150
|
let e = n.property;
|
|
143
151
|
e.charCodeAt(0) === 45 && e.charCodeAt(1) === 45 || (e = C(e));
|
|
144
|
-
let t =
|
|
145
|
-
return e === "font" && (t = t.replace(/\s*\/\s*/, "/")), t === c &&
|
|
152
|
+
let t = D(n.value);
|
|
153
|
+
return e === "font" && (t = t.replace(/\s*\/\s*/, "/")), t === c && O === !0 && (t += a), n.important === !0 ? t += p + "!important" : typeof n.important == "string" && (t += p + "!" + C(n.important)), i(s) + e + $ + p + t;
|
|
146
154
|
}
|
|
147
|
-
function
|
|
155
|
+
function N(n) {
|
|
148
156
|
let e = c;
|
|
149
157
|
return n.forEach((t, r) => {
|
|
150
|
-
t.type === "Identifier" ? e += t.name : t.type === "Function" ? e += C(t.name) +
|
|
158
|
+
t.type === "Identifier" ? e += t.name : t.type === "Function" ? e += C(t.name) + I + N(t.children) + v : t.type === "Dimension" ? e += t.value + C(t.unit) : t.type === "Value" ? e += D(t) : t.type === B ? e += z(t) : t.type === "Parentheses" ? e += I + N(t.children) + v : t.type === "Url" ? e += "url(" + g + t.value + g + v : e += P(t), t.type !== B && r.next !== null && r.next.data.type !== B && (e += a);
|
|
151
159
|
}), e;
|
|
152
160
|
}
|
|
153
|
-
function
|
|
161
|
+
function z(n) {
|
|
154
162
|
let e = c, t = n.value.trim(), r = t.charCodeAt(0);
|
|
155
|
-
return r === 43 || r === 45 ? e +=
|
|
163
|
+
return r === 43 || r === 45 ? e += a : r !== 44 && (e += p), e += t, r === 43 || r === 45 ? e += a : e += p, e;
|
|
156
164
|
}
|
|
157
|
-
function
|
|
158
|
-
return n.type === "Raw" ?
|
|
165
|
+
function D(n) {
|
|
166
|
+
return n.type === "Raw" ? R(n, 0) : N(n.children);
|
|
159
167
|
}
|
|
160
|
-
function
|
|
161
|
-
return
|
|
168
|
+
function R(n, e) {
|
|
169
|
+
return i(e) + P(n).trim();
|
|
162
170
|
}
|
|
163
|
-
let
|
|
164
|
-
if (
|
|
165
|
-
let n = m(0, b(
|
|
166
|
-
n && (_ += n + u),
|
|
167
|
-
if (t.type ===
|
|
171
|
+
let L = k.children, _ = c;
|
|
172
|
+
if (L.first !== null) {
|
|
173
|
+
let n = m(0, b(L.first));
|
|
174
|
+
n && (_ += n + u), L.forEach((t, r) => {
|
|
175
|
+
if (t.type === F ? _ += M(t) : t.type === j ? _ += U(t) : _ += R(t, s), r.next !== null) {
|
|
168
176
|
_ += u;
|
|
169
177
|
let l = m(E(t), b(r.next.data));
|
|
170
|
-
l && (_ +=
|
|
178
|
+
l && (_ += i(s) + l), _ += u;
|
|
171
179
|
}
|
|
172
180
|
});
|
|
173
181
|
let e = m(E(
|
|
174
182
|
/** @type {import('css-tree').CssNode} */
|
|
175
|
-
|
|
176
|
-
), E(
|
|
183
|
+
L.last
|
|
184
|
+
), E(k));
|
|
177
185
|
e && (_ += u + e);
|
|
178
186
|
} else
|
|
179
|
-
_ += m(0, E(
|
|
187
|
+
_ += m(0, E(k));
|
|
180
188
|
return _;
|
|
181
189
|
}
|
|
182
|
-
function
|
|
183
|
-
return
|
|
190
|
+
function fe(y) {
|
|
191
|
+
return ne(y, { minify: !0 });
|
|
184
192
|
}
|
|
185
193
|
export {
|
|
186
|
-
|
|
187
|
-
|
|
194
|
+
ne as format,
|
|
195
|
+
fe as minify
|
|
188
196
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @typedef {Object} Options
|
|
3
3
|
* @property {boolean} [minify] Whether to minify the CSS or keep it formatted
|
|
4
|
+
* @property {number} [tab_size] Tell the formatter to use N spaces instead of tabs
|
|
4
5
|
*
|
|
5
6
|
* Format a string of CSS using some simple rules
|
|
6
7
|
* @param {string} css The original CSS
|
|
7
|
-
* @param {Options} options
|
|
8
|
+
* @param {Options} [options]
|
|
8
9
|
* @returns {string} The formatted CSS
|
|
9
10
|
*/
|
|
10
|
-
export function format(css: string, { minify }?: Options): string;
|
|
11
|
+
export function format(css: string, { minify, tab_size, }?: Options): string;
|
|
11
12
|
/**
|
|
12
13
|
* Minify a string of CSS
|
|
13
14
|
* @param {string} css The original CSS
|
|
@@ -17,8 +18,12 @@ export function minify(css: string): string;
|
|
|
17
18
|
export type Options = {
|
|
18
19
|
/**
|
|
19
20
|
* Whether to minify the CSS or keep it formatted
|
|
21
|
+
*/
|
|
22
|
+
minify?: boolean | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Tell the formatter to use N spaces instead of tabs
|
|
20
25
|
*
|
|
21
26
|
* Format a string of CSS using some simple rules
|
|
22
27
|
*/
|
|
23
|
-
|
|
28
|
+
tab_size?: number | undefined;
|
|
24
29
|
};
|