@projectwallace/format-css 2.2.4 → 2.2.6

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
@@ -41,10 +41,10 @@ npm install @projectwallace/format-css
41
41
  ## Usage
42
42
 
43
43
  ```js
44
- import { format } from "@projectwallace/format-css";
44
+ import { format } from '@projectwallace/format-css'
45
45
 
46
- let old_css = "/* Your old CSS here */";
47
- let new_css = format(old_css);
46
+ let old_css = '/* Your old CSS here */'
47
+ let new_css = format(old_css)
48
48
  ```
49
49
 
50
50
  Need more examples?
@@ -70,13 +70,13 @@ Need more examples?
70
70
  This package also exposes a minifier function since minifying CSS follows many of the same rules as formatting.
71
71
 
72
72
  ```js
73
- import { format, minify } from "@projectwallace/format-css";
73
+ import { format, minify } from '@projectwallace/format-css'
74
74
 
75
- let minified = minify("a {}");
75
+ let minified = minify('a {}')
76
76
 
77
77
  // which is an alias for
78
78
 
79
- let formatted_mini = format("a {}", { minify: true });
79
+ let formatted_mini = format('a {}', { minify: true })
80
80
  ```
81
81
 
82
82
  ## Tab size
@@ -84,17 +84,13 @@ let formatted_mini = format("a {}", { minify: true });
84
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
85
 
86
86
  ```js
87
- import { format } from "@projectwallace/format-css";
87
+ import { format } from '@projectwallace/format-css'
88
88
 
89
- let formatted = format("a { color: red; }", {
90
- tab_size: 2
91
- });
89
+ let formatted = format('a { color: red; }', {
90
+ tab_size: 2,
91
+ })
92
92
  ```
93
93
 
94
- ## Acknowledgements
95
-
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)
97
-
98
94
  ## Related projects
99
95
 
100
96
  - [Format CSS online](https://www.projectwallace.com/prettify-css?utm_source=github&utm_medium=wallace_format_css_related_projects) - See this formatter in action online!
package/dist/index.d.ts CHANGED
@@ -1,16 +1,20 @@
1
- export type FormatOptions = {
2
- /** Whether to minify the CSS or keep it formatted */
3
- minify?: boolean;
4
- /** Tell the formatter to use N spaces instead of tabs */
5
- tab_size?: number;
1
+ //#region index.d.ts
2
+ type FormatOptions = {
3
+ /** Whether to minify the CSS or keep it formatted */minify?: boolean; /** Tell the formatter to use N spaces instead of tabs */
4
+ tab_size?: number;
6
5
  };
7
6
  /**
8
7
  * Format a string of CSS using some simple rules
9
8
  */
10
- export declare function format(css: string, { minify, tab_size }?: FormatOptions): string;
9
+ declare function format(css: string, {
10
+ minify,
11
+ tab_size
12
+ }?: FormatOptions): string;
11
13
  /**
12
14
  * Minify a string of CSS
13
15
  * @param {string} css The original CSS
14
16
  * @returns {string} The minified CSS
15
17
  */
16
- export declare function minify(css: string): string;
18
+ declare function minify(css: string): string;
19
+ //#endregion
20
+ export { FormatOptions, format, minify };
package/dist/index.js ADDED
@@ -0,0 +1,335 @@
1
+ import { ATTR_FLAG_NAMES, ATTR_OPERATOR_NAMES, NODE_TYPES, parse } from "@projectwallace/css-parser";
2
+ //#region index.ts
3
+ const SPACE = " ";
4
+ const EMPTY_STRING = "";
5
+ const COLON = ":";
6
+ const SEMICOLON = ";";
7
+ const QUOTE = "\"";
8
+ const OPEN_PARENTHESES = "(";
9
+ const CLOSE_PARENTHESES = ")";
10
+ const OPEN_BRACKET = "[";
11
+ const CLOSE_BRACKET = "]";
12
+ const OPEN_BRACE = "{";
13
+ const CLOSE_BRACE = "}";
14
+ const COMMA = ",";
15
+ /**
16
+ * Format a string of CSS using some simple rules
17
+ */
18
+ function format(css, { minify = false, tab_size = void 0 } = Object.create(null)) {
19
+ if (tab_size !== void 0 && Number(tab_size) < 1) throw new TypeError("tab_size must be a number greater than 0");
20
+ const NEWLINE = minify ? EMPTY_STRING : "\n";
21
+ const OPTIONAL_SPACE = minify ? EMPTY_STRING : SPACE;
22
+ const LAST_SEMICOLON = minify ? EMPTY_STRING : SEMICOLON;
23
+ let comments = [];
24
+ let ast = parse(css, {
25
+ parse_atrule_preludes: false,
26
+ on_comment: minify ? void 0 : ({ start, end }) => {
27
+ comments.push(start, end);
28
+ }
29
+ });
30
+ let depth = 0;
31
+ function indent(size) {
32
+ if (minify === true) return EMPTY_STRING;
33
+ if (tab_size !== void 0) return SPACE.repeat(tab_size * size);
34
+ return " ".repeat(size);
35
+ }
36
+ /**
37
+ * Get and format comments from the CSS string within a range
38
+ * @param after After which offset to look for comments
39
+ * @param before Before which offset to look for comments
40
+ * @param level Indentation level (uses current depth if not specified)
41
+ * @returns The formatted comment string, or empty string if no comment found
42
+ */
43
+ function get_comment(after, before, level = depth) {
44
+ if (minify || after === void 0 || before === void 0) return EMPTY_STRING;
45
+ let buffer = EMPTY_STRING;
46
+ for (let i = 0; i < comments.length; i += 2) {
47
+ let start = comments[i];
48
+ if (start === void 0 || start < after) continue;
49
+ let end = comments[i + 1];
50
+ if (end === void 0 || end > before) break;
51
+ if (buffer.length > 0) buffer += NEWLINE + indent(level);
52
+ buffer += css.slice(start, end);
53
+ }
54
+ return buffer;
55
+ }
56
+ function unquote(str) {
57
+ return str.replace(/(?:^['"])|(?:['"]$)/g, EMPTY_STRING);
58
+ }
59
+ function print_string(str) {
60
+ str = str?.toString() || "";
61
+ return QUOTE + unquote(str) + QUOTE;
62
+ }
63
+ function print_operator(node) {
64
+ let parts = [];
65
+ let operator = node.text;
66
+ let code = operator.charCodeAt(0);
67
+ if (code === 43 || code === 45) parts.push(SPACE);
68
+ else if (code !== 44) parts.push(OPTIONAL_SPACE);
69
+ parts.push(operator);
70
+ if (code === 43 || code === 45) parts.push(SPACE);
71
+ else parts.push(OPTIONAL_SPACE);
72
+ return parts.join(EMPTY_STRING);
73
+ }
74
+ function print_list(nodes) {
75
+ let parts = [];
76
+ for (let node of nodes) {
77
+ if (node.type === NODE_TYPES.FUNCTION) {
78
+ let fn = node.name?.toLowerCase();
79
+ parts.push(fn, OPEN_PARENTHESES);
80
+ parts.push(print_list(node.children));
81
+ parts.push(CLOSE_PARENTHESES);
82
+ } else if (node.type === NODE_TYPES.DIMENSION) parts.push(node.value, node.unit?.toLowerCase());
83
+ else if (node.type === NODE_TYPES.STRING) parts.push(print_string(node.text));
84
+ else if (node.type === NODE_TYPES.OPERATOR) parts.push(print_operator(node));
85
+ else if (node.type === NODE_TYPES.PARENTHESIS) parts.push(OPEN_PARENTHESES, print_list(node.children), CLOSE_PARENTHESES);
86
+ else if (node.type === NODE_TYPES.URL && typeof node.value === "string") {
87
+ parts.push("url(");
88
+ let { value } = node;
89
+ if (/^['"]?data:/i.test(value)) parts.push(unquote(value));
90
+ else parts.push(print_string(value));
91
+ parts.push(CLOSE_PARENTHESES);
92
+ } else parts.push(node.text);
93
+ if (node.type !== NODE_TYPES.OPERATOR) {
94
+ if (node.has_next) {
95
+ if (node.next_sibling?.type !== NODE_TYPES.OPERATOR) parts.push(SPACE);
96
+ }
97
+ }
98
+ }
99
+ return parts.join(EMPTY_STRING);
100
+ }
101
+ function print_value(nodes) {
102
+ if (nodes === null) return EMPTY_STRING;
103
+ return print_list(nodes);
104
+ }
105
+ function print_declaration(node) {
106
+ let important = [];
107
+ if (node.is_important) {
108
+ let text = node.text;
109
+ let has_semicolon = text.endsWith(SEMICOLON);
110
+ let start = text.lastIndexOf("!");
111
+ let end = has_semicolon ? -1 : void 0;
112
+ important.push(OPTIONAL_SPACE, text.slice(start, end).toLowerCase());
113
+ }
114
+ let value = print_value(node.value);
115
+ let property = node.property;
116
+ if (property === "font") value = value.replace(/\s*\/\s*/, "/");
117
+ if (value === EMPTY_STRING && minify === true) value += SPACE;
118
+ if (!property.startsWith("--")) property = property.toLowerCase();
119
+ return property + COLON + OPTIONAL_SPACE + value + important.join(EMPTY_STRING);
120
+ }
121
+ function print_nth(node) {
122
+ let parts = [];
123
+ let a = node.nth_a;
124
+ let b = node.nth_b;
125
+ if (a) parts.push(a);
126
+ if (a && b) parts.push(OPTIONAL_SPACE);
127
+ if (b) {
128
+ if (a && !b.startsWith("-")) parts.push("+", OPTIONAL_SPACE);
129
+ parts.push(parseFloat(b));
130
+ }
131
+ return parts.join(EMPTY_STRING);
132
+ }
133
+ function print_nth_of(node) {
134
+ let parts = [];
135
+ if (node.children[0]?.type === NODE_TYPES.NTH_SELECTOR) {
136
+ parts.push(print_nth(node.children[0]));
137
+ parts.push(SPACE, "of", SPACE);
138
+ }
139
+ if (node.children[1]?.type === NODE_TYPES.SELECTOR_LIST) parts.push(print_inline_selector_list(node.children[1]));
140
+ return parts.join(EMPTY_STRING);
141
+ }
142
+ function print_simple_selector(node, is_first = false) {
143
+ let name = node.name ?? "";
144
+ switch (node.type) {
145
+ case NODE_TYPES.TYPE_SELECTOR: return name.toLowerCase() ?? "";
146
+ case NODE_TYPES.COMBINATOR: {
147
+ let text = node.text;
148
+ if (/^\s+$/.test(text)) return SPACE;
149
+ return (is_first ? EMPTY_STRING : OPTIONAL_SPACE) + text + OPTIONAL_SPACE;
150
+ }
151
+ case NODE_TYPES.PSEUDO_ELEMENT_SELECTOR:
152
+ case NODE_TYPES.PSEUDO_CLASS_SELECTOR: {
153
+ let parts = [COLON];
154
+ name = name.toLowerCase();
155
+ if (name === "before" || name === "after" || node.type === NODE_TYPES.PSEUDO_ELEMENT_SELECTOR) parts.push(COLON);
156
+ parts.push(name);
157
+ if (node.has_children) {
158
+ parts.push(OPEN_PARENTHESES);
159
+ if (node.children.length > 0) if (name === "highlight") parts.push(print_list(node.children));
160
+ else parts.push(print_inline_selector_list(node));
161
+ parts.push(CLOSE_PARENTHESES);
162
+ }
163
+ return parts.join(EMPTY_STRING);
164
+ }
165
+ case NODE_TYPES.ATTRIBUTE_SELECTOR: {
166
+ let parts = [OPEN_BRACKET, name.toLowerCase()];
167
+ if (node.attr_operator) {
168
+ parts.push(ATTR_OPERATOR_NAMES[node.attr_operator] ?? "");
169
+ if (typeof node.value === "string") parts.push(print_string(node.value));
170
+ if (node.attr_flags) parts.push(SPACE, ATTR_FLAG_NAMES[node.attr_flags] ?? "");
171
+ }
172
+ parts.push(CLOSE_BRACKET);
173
+ return parts.join(EMPTY_STRING);
174
+ }
175
+ default: return node.text;
176
+ }
177
+ }
178
+ function print_selector(node) {
179
+ if (node.type === NODE_TYPES.NTH_SELECTOR) return print_nth(node);
180
+ if (node.type === NODE_TYPES.NTH_OF_SELECTOR) return print_nth_of(node);
181
+ if (node.type === NODE_TYPES.SELECTOR_LIST) return print_inline_selector_list(node);
182
+ if (node.type === NODE_TYPES.LANG_SELECTOR) return print_string(node.text);
183
+ let parts = [];
184
+ node.children.forEach((child, index) => {
185
+ const part = print_simple_selector(child, index === 0);
186
+ parts.push(part);
187
+ });
188
+ return parts.join(EMPTY_STRING);
189
+ }
190
+ function print_inline_selector_list(node) {
191
+ let parts = [];
192
+ for (let selector of node) {
193
+ parts.push(print_selector(selector));
194
+ if (selector.has_next) parts.push(COMMA, OPTIONAL_SPACE);
195
+ }
196
+ return parts.join(EMPTY_STRING);
197
+ }
198
+ function print_selector_list(node) {
199
+ let lines = [];
200
+ let prev_end;
201
+ for (let selector of node) {
202
+ if (prev_end !== void 0) {
203
+ let comment = get_comment(prev_end, selector.start);
204
+ if (comment) lines.push(indent(depth) + comment);
205
+ }
206
+ let printed = print_selector(selector);
207
+ if (selector.has_next) printed += COMMA;
208
+ lines.push(indent(depth) + printed);
209
+ prev_end = selector.end;
210
+ }
211
+ return lines.join(NEWLINE);
212
+ }
213
+ function print_block(node) {
214
+ let lines = [];
215
+ depth++;
216
+ let children = node.children;
217
+ if (children.length === 0) {
218
+ let comment = get_comment(node.start, node.end);
219
+ if (comment) {
220
+ lines.push(indent(depth) + comment);
221
+ depth--;
222
+ lines.push(indent(depth) + CLOSE_BRACE);
223
+ return lines.join(NEWLINE);
224
+ }
225
+ }
226
+ let first_child = children[0];
227
+ let comment_before_first = get_comment(node.start, first_child?.start);
228
+ if (comment_before_first) lines.push(indent(depth) + comment_before_first);
229
+ let prev_end;
230
+ for (let child of children) {
231
+ if (prev_end !== void 0) {
232
+ let comment = get_comment(prev_end, child.start);
233
+ if (comment) lines.push(indent(depth) + comment);
234
+ }
235
+ let is_last = child.next_sibling?.type !== NODE_TYPES.DECLARATION;
236
+ if (child.type === NODE_TYPES.DECLARATION) {
237
+ let declaration = print_declaration(child);
238
+ let semi = is_last ? LAST_SEMICOLON : SEMICOLON;
239
+ lines.push(indent(depth) + declaration + semi);
240
+ } else if (child.type === NODE_TYPES.STYLE_RULE) {
241
+ if (prev_end !== void 0 && lines.length !== 0) lines.push(EMPTY_STRING);
242
+ lines.push(print_rule(child));
243
+ } else if (child.type === NODE_TYPES.AT_RULE) {
244
+ if (prev_end !== void 0 && lines.length !== 0) lines.push(EMPTY_STRING);
245
+ lines.push(indent(depth) + print_atrule(child));
246
+ }
247
+ prev_end = child.end;
248
+ }
249
+ let comment_after_last = get_comment(prev_end, node.end);
250
+ if (comment_after_last) lines.push(indent(depth) + comment_after_last);
251
+ depth--;
252
+ lines.push(indent(depth) + CLOSE_BRACE);
253
+ return lines.join(NEWLINE);
254
+ }
255
+ function print_rule(node) {
256
+ let lines = [];
257
+ if (node.first_child?.type === NODE_TYPES.SELECTOR_LIST) {
258
+ let list = print_selector_list(node.first_child);
259
+ let comment = get_comment(node.first_child.end, node.block?.start);
260
+ if (comment) list += NEWLINE + indent(depth) + comment;
261
+ list += OPTIONAL_SPACE + OPEN_BRACE;
262
+ if (!(node.block && (node.block.has_children || get_comment(node.block.start, node.block.end)))) list += CLOSE_BRACE;
263
+ lines.push(list);
264
+ }
265
+ if (node.block) {
266
+ if (node.block.has_children || get_comment(node.block.start, node.block.end)) lines.push(print_block(node.block));
267
+ }
268
+ return lines.join(NEWLINE);
269
+ }
270
+ /**
271
+ * Pretty-printing atrule preludes takes an insane amount of rules,
272
+ * so we're opting for a couple of 'good-enough' string replacements
273
+ * here to force some nice formatting.
274
+ * Should be OK perf-wise, since the amount of atrules in most
275
+ * stylesheets are limited, so this won't be called too often.
276
+ */
277
+ function print_atrule_prelude(prelude) {
278
+ return prelude.replace(/\s*([:,])/g, prelude.toLowerCase().includes("selector(") ? "$1" : "$1 ").replace(/\)([a-zA-Z])/g, ") $1").replace(/\s*(=>|<=)\s*/g, " $1 ").replace(/([^<>=\s])([<>])([^<>=\s])/g, `$1${OPTIONAL_SPACE}$2${OPTIONAL_SPACE}$3`).replace(/\s+/g, OPTIONAL_SPACE).replace(/calc\(\s*([^()+\-*/]+)\s*([*/+-])\s*([^()+\-*/]+)\s*\)/g, (_, left, operator, right) => {
279
+ let space = operator === "+" || operator === "-" ? SPACE : OPTIONAL_SPACE;
280
+ return `calc(${left.trim()}${space}${operator}${space}${right.trim()})`;
281
+ }).replace(/selector|url|supports|layer\(/gi, (match) => match.toLowerCase());
282
+ }
283
+ function print_atrule(node) {
284
+ let lines = [];
285
+ let name = [`@`, node.name.toLowerCase()];
286
+ if (node.prelude) name.push(SPACE, print_atrule_prelude(node.prelude.text));
287
+ if (node.block === null) name.push(SEMICOLON);
288
+ else {
289
+ name.push(OPTIONAL_SPACE, OPEN_BRACE);
290
+ if (!(!node.block.is_empty || get_comment(node.block.start, node.block.end))) name.push(CLOSE_BRACE);
291
+ }
292
+ lines.push(name.join(EMPTY_STRING));
293
+ if (node.block !== null) {
294
+ if (!node.block.is_empty || get_comment(node.block.start, node.block.end)) lines.push(print_block(node.block));
295
+ }
296
+ return lines.join(NEWLINE);
297
+ }
298
+ function print_stylesheet(node) {
299
+ let lines = [];
300
+ let children = node.children;
301
+ if (children.length === 0) return get_comment(0, node.end, 0);
302
+ let first_child = children[0];
303
+ if (first_child) {
304
+ let comment_before_first = get_comment(0, first_child.start, 0);
305
+ if (comment_before_first) lines.push(comment_before_first);
306
+ }
307
+ let prev_end;
308
+ for (let child of node) {
309
+ if (prev_end !== void 0) {
310
+ let comment = get_comment(prev_end, child.start, 0);
311
+ if (comment) lines.push(comment);
312
+ }
313
+ if (child.type === NODE_TYPES.STYLE_RULE) lines.push(print_rule(child));
314
+ else if (child.type === NODE_TYPES.AT_RULE) lines.push(print_atrule(child));
315
+ prev_end = child.end;
316
+ if (child.has_next) {
317
+ if (!(child.next_sibling && get_comment(child.end, child.next_sibling.start, 0))) lines.push(EMPTY_STRING);
318
+ }
319
+ }
320
+ let comment_after_last = get_comment(prev_end, node.end, 0);
321
+ if (comment_after_last) lines.push(comment_after_last);
322
+ return lines.join(NEWLINE);
323
+ }
324
+ return print_stylesheet(ast).trimEnd();
325
+ }
326
+ /**
327
+ * Minify a string of CSS
328
+ * @param {string} css The original CSS
329
+ * @returns {string} The minified CSS
330
+ */
331
+ function minify(css) {
332
+ return format(css, { minify: true });
333
+ }
334
+ //#endregion
335
+ export { format, minify };
package/package.json CHANGED
@@ -1,65 +1,57 @@
1
1
  {
2
2
  "name": "@projectwallace/format-css",
3
- "version": "2.2.4",
3
+ "version": "2.2.6",
4
4
  "description": "Fast, small, zero-config library to format or minify CSS with basic rules.",
5
- "repository": {
6
- "type": "git",
7
- "url": "git+https://github.com/projectwallace/format-css.git"
8
- },
5
+ "keywords": [
6
+ "css",
7
+ "format",
8
+ "formatter",
9
+ "prettier",
10
+ "prettifier",
11
+ "pretty",
12
+ "print",
13
+ "style",
14
+ "stylesheet"
15
+ ],
9
16
  "homepage": "https://github.com/projectwallace/format-css",
10
- "issues": "https://github.com/projectwallace/format-css/issues",
11
17
  "license": "MIT",
12
18
  "author": "Bart Veneman <bart@projectwallace.com>",
13
- "engines": {
14
- "node": ">=18.0.0"
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/projectwallace/format-css.git"
15
22
  },
23
+ "files": [
24
+ "dist"
25
+ ],
16
26
  "type": "module",
17
- "main": "./dist/format-css.js",
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
18
29
  "exports": {
19
30
  "types": "./dist/index.d.ts",
20
- "default": "./dist/format-css.js"
31
+ "default": "./dist/index.js"
21
32
  },
22
- "types": "./dist/index.d.ts",
23
33
  "scripts": {
24
- "build": "vite build",
34
+ "build": "tsdown",
25
35
  "test": "vitest --coverage",
26
36
  "check": "tsc",
27
37
  "prettier": "prettier --check index.ts test/**/*.ts",
28
- "lint": "oxlint",
29
- "lint-package": "publint"
38
+ "lint": "oxlint && oxfmt --check"
39
+ },
40
+ "dependencies": {
41
+ "@projectwallace/css-parser": "^0.13.5"
30
42
  },
31
43
  "devDependencies": {
32
- "@codecov/vite-plugin": "^1.9.1",
44
+ "@codecov/rollup-plugin": "^1.9.1",
33
45
  "@vitest/coverage-v8": "^4.0.3",
34
- "c8": "^10.1.3",
46
+ "oxfmt": "^0.36.0",
35
47
  "oxlint": "^1.24.0",
36
- "prettier": "^3.6.2",
37
48
  "publint": "^0.3.15",
49
+ "tsdown": "^0.21.0",
38
50
  "typescript": "^5.9.3",
39
- "vite": "^6.2.6",
40
- "vite-plugin-dts": "^4.5.4",
41
51
  "vitest": "^4.0.3"
42
52
  },
43
- "files": [
44
- "dist"
45
- ],
46
- "keywords": [
47
- "css",
48
- "stylesheet",
49
- "formatter",
50
- "format",
51
- "print",
52
- "prettifier",
53
- "pretty",
54
- "prettier"
55
- ],
56
- "prettier": {
57
- "semi": false,
58
- "useTabs": true,
59
- "printWidth": 140,
60
- "singleQuote": true
53
+ "engines": {
54
+ "node": ">=18.0.0"
61
55
  },
62
- "dependencies": {
63
- "@projectwallace/css-parser": "^0.13.1"
64
- }
56
+ "issues": "https://github.com/projectwallace/format-css/issues"
65
57
  }
@@ -1,232 +0,0 @@
1
- import { parse as X, NODE_TYPES as u, ATTR_FLAG_CASE_INSENSITIVE as z, ATTR_FLAG_CASE_SENSITIVE as tt, ATTR_OPERATOR_EQUAL as et, ATTR_OPERATOR_STAR_EQUAL as rt, ATTR_OPERATOR_DOLLAR_EQUAL as st, ATTR_OPERATOR_CARET_EQUAL as it, ATTR_OPERATOR_PIPE_EQUAL as lt, ATTR_OPERATOR_TILDE_EQUAL as nt } from "@projectwallace/css-parser";
2
- const _ = " ", p = "", k = ":", b = ";", w = '"', P = "(", N = ")", ut = "[", pt = "]", d = "{", g = "}", D = ",";
3
- function ct(R, { minify: O = !1, tab_size: L = void 0 } = /* @__PURE__ */ Object.create(null)) {
4
- if (L !== void 0 && Number(L) < 1)
5
- throw new TypeError("tab_size must be a number greater than 0");
6
- const E = O ? p : `
7
- `, c = O ? p : _, M = O ? p : b;
8
- let A = [], Q = X(R, {
9
- on_comment: ({ start: t, end: e }) => {
10
- A.push(t, e);
11
- }
12
- }), a = 0;
13
- function o(t) {
14
- return O === !0 ? p : L !== void 0 ? _.repeat(L * t) : " ".repeat(t);
15
- }
16
- function f(t, e, s = a) {
17
- if (O || t === void 0 || e === void 0)
18
- return p;
19
- let r = p;
20
- for (let l = 0; l < A.length; l += 2) {
21
- let i = A[l];
22
- if (i === void 0 || i < t) continue;
23
- let n = A[l + 1];
24
- if (n === void 0 || n > e) break;
25
- r.length > 0 && (r += E + o(s)), r += R.slice(i, n);
26
- }
27
- return r;
28
- }
29
- function I(t) {
30
- return t.replace(/(?:^['"])|(?:['"]$)/g, p);
31
- }
32
- function S(t) {
33
- return t = (t == null ? void 0 : t.toString()) || "", w + I(t) + w;
34
- }
35
- function B(t) {
36
- let e = [], s = t.text, r = s.charCodeAt(0);
37
- return r === 43 || r === 45 ? e.push(_) : r !== 44 && e.push(c), e.push(s), r === 43 || r === 45 ? e.push(_) : e.push(c), e.join(p);
38
- }
39
- function m(t) {
40
- var s, r, l;
41
- let e = [];
42
- for (let i of t) {
43
- if (i.type === u.FUNCTION) {
44
- let n = (s = i.name) == null ? void 0 : s.toLowerCase();
45
- e.push(n, P), e.push(m(i.children)), e.push(N);
46
- } else if (i.type === u.DIMENSION)
47
- e.push(i.value, (r = i.unit) == null ? void 0 : r.toLowerCase());
48
- else if (i.type === u.STRING)
49
- e.push(S(i.text));
50
- else if (i.type === u.OPERATOR)
51
- e.push(B(i));
52
- else if (i.type === u.PARENTHESIS)
53
- e.push(P, m(i.children), N);
54
- else if (i.type === u.URL && typeof i.value == "string") {
55
- e.push("url(");
56
- let { value: n } = i;
57
- /^['"]?data:/i.test(n) ? e.push(I(n)) : e.push(S(n)), e.push(N);
58
- } else
59
- e.push(i.text);
60
- i.type !== u.OPERATOR && i.has_next && ((l = i.next_sibling) == null ? void 0 : l.type) !== u.OPERATOR && e.push(_);
61
- }
62
- return e.join(p);
63
- }
64
- function H(t) {
65
- return t === null ? p : m(t);
66
- }
67
- function F(t) {
68
- let e = [];
69
- if (t.is_important) {
70
- let l = t.text, i = l.endsWith(b), n = l.lastIndexOf("!"), T = i ? -1 : void 0;
71
- e.push(c, l.slice(n, T).toLowerCase());
72
- }
73
- let s = H(t.value), r = t.property;
74
- return r === "font" && (s = s.replace(/\s*\/\s*/, "/")), s === p && O === !0 && (s += _), r.startsWith("--") || (r = r.toLowerCase()), r + k + c + s + e.join(p);
75
- }
76
- function G(t) {
77
- switch (t) {
78
- case nt:
79
- return "~=";
80
- case lt:
81
- return "|=";
82
- case it:
83
- return "^=";
84
- case st:
85
- return "$=";
86
- case rt:
87
- return "*=";
88
- case et:
89
- default:
90
- return "=";
91
- }
92
- }
93
- function v(t) {
94
- let e = [], s = t.nth_a, r = t.nth_b;
95
- return s && e.push(s), s && r && e.push(c), r && (s && !r.startsWith("-") && e.push("+", c), e.push(parseFloat(r))), e.join(p);
96
- }
97
- function Y(t) {
98
- var s, r;
99
- let e = [];
100
- return ((s = t.children[0]) == null ? void 0 : s.type) === u.NTH_SELECTOR && (e.push(v(t.children[0])), e.push(_, "of", _)), ((r = t.children[1]) == null ? void 0 : r.type) === u.SELECTOR_LIST && e.push(y(t.children[1])), e.join(p);
101
- }
102
- function W(t, e = !1) {
103
- let s = t.name ?? "";
104
- switch (t.type) {
105
- case u.TYPE_SELECTOR:
106
- return s.toLowerCase() ?? "";
107
- case u.COMBINATOR: {
108
- let r = t.text;
109
- return /^\s+$/.test(r) ? _ : (e ? p : c) + r + c;
110
- }
111
- case u.PSEUDO_ELEMENT_SELECTOR:
112
- case u.PSEUDO_CLASS_SELECTOR: {
113
- let r = [k];
114
- return s = s.toLowerCase(), (s === "before" || s === "after" || t.type === u.PSEUDO_ELEMENT_SELECTOR) && r.push(k), r.push(s), t.has_children && (r.push(P), t.children.length > 0 && (s === "highlight" ? r.push(m(t.children)) : r.push(y(t))), r.push(N)), r.join(p);
115
- }
116
- case u.ATTRIBUTE_SELECTOR: {
117
- let r = [ut, s.toLowerCase()];
118
- return t.attr_operator && (r.push(G(t.attr_operator)), typeof t.value == "string" && r.push(S(t.value)), t.attr_flags === z ? r.push(_, "i") : t.attr_flags === tt && r.push(_, "s")), r.push(pt), r.join(p);
119
- }
120
- default:
121
- return t.text;
122
- }
123
- }
124
- function x(t) {
125
- if (t.type === u.NTH_SELECTOR)
126
- return v(t);
127
- if (t.type === u.NTH_OF_SELECTOR)
128
- return Y(t);
129
- if (t.type === u.SELECTOR_LIST)
130
- return y(t);
131
- if (t.type === u.LANG_SELECTOR)
132
- return S(t.text);
133
- let e = [];
134
- return t.children.forEach((s, r) => {
135
- const l = W(s, r === 0);
136
- e.push(l);
137
- }), e.join(p);
138
- }
139
- function y(t) {
140
- let e = [];
141
- for (let s of t)
142
- e.push(x(s)), s.has_next && e.push(D, c);
143
- return e.join(p);
144
- }
145
- function K(t) {
146
- let e = [], s;
147
- for (let r of t) {
148
- if (s !== void 0) {
149
- let i = f(s, r.start);
150
- i && e.push(o(a) + i);
151
- }
152
- let l = x(r);
153
- r.has_next && (l += D), e.push(o(a) + l), s = r.end;
154
- }
155
- return e.join(E);
156
- }
157
- function j(t) {
158
- var T;
159
- let e = [];
160
- a++;
161
- let s = t.children;
162
- if (s.length === 0) {
163
- let h = f(t.start, t.end);
164
- if (h)
165
- return e.push(o(a) + h), a--, e.push(o(a) + g), e.join(E);
166
- }
167
- let r = s[0], l = f(t.start, r == null ? void 0 : r.start);
168
- l && e.push(o(a) + l);
169
- let i;
170
- for (let h of s) {
171
- if (i !== void 0) {
172
- let C = f(i, h.start);
173
- C && e.push(o(a) + C);
174
- }
175
- let Z = ((T = h.next_sibling) == null ? void 0 : T.type) !== u.DECLARATION;
176
- if (h.type === u.DECLARATION) {
177
- let C = F(h), J = Z ? M : b;
178
- e.push(o(a) + C + J);
179
- } else h.type === u.STYLE_RULE ? (i !== void 0 && e.length !== 0 && e.push(p), e.push(U(h))) : h.type === u.AT_RULE && (i !== void 0 && e.length !== 0 && e.push(p), e.push(o(a) + $(h)));
180
- i = h.end;
181
- }
182
- let n = f(i, t.end);
183
- return n && e.push(o(a) + n), a--, e.push(o(a) + g), e.join(E);
184
- }
185
- function U(t) {
186
- var s, r;
187
- let e = [];
188
- if (((s = t.first_child) == null ? void 0 : s.type) === u.SELECTOR_LIST) {
189
- let l = K(t.first_child), i = f(t.first_child.end, (r = t.block) == null ? void 0 : r.start);
190
- i && (l += E + o(a) + i), l += c + d, t.block && (t.block.has_children || f(t.block.start, t.block.end)) || (l += g), e.push(l);
191
- }
192
- return t.block && (t.block.has_children || f(t.block.start, t.block.end)) && e.push(j(t.block)), e.join(E);
193
- }
194
- function V(t) {
195
- return t.replace(/\s*([:,])/g, t.toLowerCase().includes("selector(") ? "$1" : "$1 ").replace(/\)([a-zA-Z])/g, ") $1").replace(/\s*(=>|<=)\s*/g, " $1 ").replace(/([^<>=\s])([<>])([^<>=\s])/g, `$1${c}$2${c}$3`).replace(/\s+/g, c).replace(/calc\(\s*([^()+\-*/]+)\s*([*/+-])\s*([^()+\-*/]+)\s*\)/g, (e, s, r, l) => {
196
- let i = r === "+" || r === "-" ? _ : c;
197
- return `calc(${s.trim()}${i}${r}${i}${l.trim()})`;
198
- }).replace(/selector|url|supports|layer\(/gi, (e) => e.toLowerCase());
199
- }
200
- function $(t) {
201
- let e = [], s = ["@", t.name.toLowerCase()];
202
- return t.prelude && s.push(_, V(t.prelude.text)), t.block === null ? s.push(b) : (s.push(c, d), !t.block.is_empty || f(t.block.start, t.block.end) || s.push(g)), e.push(s.join(p)), t.block !== null && (!t.block.is_empty || f(t.block.start, t.block.end)) && e.push(j(t.block)), e.join(E);
203
- }
204
- function q(t) {
205
- let e = [], s = t.children;
206
- if (s.length === 0)
207
- return f(0, t.end, 0);
208
- let r = s[0];
209
- if (r) {
210
- let n = f(0, r.start, 0);
211
- n && e.push(n);
212
- }
213
- let l;
214
- for (let n of t) {
215
- if (l !== void 0) {
216
- let T = f(l, n.start, 0);
217
- T && e.push(T);
218
- }
219
- n.type === u.STYLE_RULE ? e.push(U(n)) : n.type === u.AT_RULE && e.push($(n)), l = n.end, n.has_next && (n.next_sibling && f(n.end, n.next_sibling.start, 0) || e.push(p));
220
- }
221
- let i = f(l, t.end, 0);
222
- return i && e.push(i), e.join(E);
223
- }
224
- return q(Q).trimEnd();
225
- }
226
- function ft(R) {
227
- return ct(R, { minify: !0 });
228
- }
229
- export {
230
- ct as format,
231
- ft as minify
232
- };