@projectwallace/format-css 2.0.1 → 2.1.0

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