@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 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,27 +1,32 @@
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: 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
- O.push(e.start.offset, e.end.offset);
18
+ T.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 === !0 ? c : S !== void 0 ? a.repeat(S * n) : " ".repeat(n);
21
26
  }
22
- function A(n) {
27
+ function P(n) {
23
28
  let e = n.loc;
24
- return e ? y.slice(e.start.offset, e.end.offset) : c;
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 (P || n === void 0 || e === void 0)
38
+ if (O === !0 || 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 < T.length; r += 2) {
42
+ let l = T[r];
38
43
  if (l === void 0 || l < n) continue;
39
- let f = O[r + 1];
44
+ let f = T[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) + 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 += a(s) + f + u);
61
+ f && (e += i(s) + f + u);
57
62
  }), e;
58
63
  }
59
- function S(n) {
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 += 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 !== null && (e += I + A(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 += 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
- 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);
90
- } else
91
- e += A(l);
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 += 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;
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 += A(r);
108
+ e += P(r);
101
109
  break;
102
110
  }
103
111
  }
104
112
  }), e;
105
113
  }
106
- function M(n) {
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 += H + u, t += a(s + 1) + f, t += u + a(s) + V, t) : t + te;
118
+ return f ? (t += V + u, t += i(s + 1) + f, t += u + i(s) + W, t) : t + re;
111
119
  }
112
- t += H + u, s++;
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 += 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);
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 === 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));
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 + a(s) + l), s--, t += u + a(s) + V, t;
136
+ return l && (t += u + i(s) + l), s--, t += u + i(s) + W, t;
129
137
  }
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;
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 q(n) {
135
- let e = A(n);
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 i = l === "+" || l === "-" ? o : p;
138
- return `calc(${r.trim()}${i}${l}${i}${f.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 J(n) {
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 = 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;
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 R(n) {
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) + 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);
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 X(n) {
161
+ function z(n) {
154
162
  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;
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 U(n) {
158
- return n.type === "Raw" ? k(n, 0) : R(n.children);
165
+ function D(n) {
166
+ return n.type === "Raw" ? R(n, 0) : N(n.children);
159
167
  }
160
- function k(n, e) {
161
- return a(e) + A(n).trim();
168
+ function R(n, e) {
169
+ return i(e) + P(n).trim();
162
170
  }
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) {
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 && (_ += a(s) + l), _ += u;
178
+ l && (_ += i(s) + l), _ += u;
171
179
  }
172
180
  });
173
181
  let e = m(E(
174
182
  /** @type {import('css-tree').CssNode} */
175
- T.last
176
- ), E(v));
183
+ L.last
184
+ ), E(k));
177
185
  e && (_ += u + e);
178
186
  } else
179
- _ += m(0, E(v));
187
+ _ += m(0, E(k));
180
188
  return _;
181
189
  }
182
- function le(y) {
183
- return re(y, { minify: !0 });
190
+ function fe(y) {
191
+ return ne(y, { minify: !0 });
184
192
  }
185
193
  export {
186
- re as format,
187
- le as minify
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
- 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.1",
4
4
  "description": "Fast, small, zero-config library to format or minify CSS with basic rules.",
5
5
  "repository": {
6
6
  "type": "git",