postcss-calc 11.1.1 → 11.1.2

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.
@@ -3,6 +3,7 @@
3
3
  // operator, or when a finite scalar is negative.
4
4
 
5
5
  import { num, dim } from './node.js';
6
+ import { getComponents, serializeComponents } from './opaque.js';
6
7
 
7
8
  /**
8
9
  * @typedef {import('./node.js').Node} Node
@@ -90,7 +91,7 @@ function serializeNumber(v) {
90
91
  */
91
92
  function serializeScalar(node, prec) {
92
93
  const value = round(node.value, prec);
93
- const text = `${serializeNumber(value)}${node.type === 'Dim' ? node.unit : ''}`;
94
+ const text = `${serializeNumber(value)}${node.type === 'Dim' ? (node.rawUnit ?? node.unit) : ''}`;
94
95
  return { value, text };
95
96
  }
96
97
 
@@ -109,7 +110,7 @@ function serialize(node, opts = {}) {
109
110
  return `${calcName}(${degenerateKeyword(node.value)})`;
110
111
  }
111
112
  if (node.type === 'Dim' && isDegenerate(node.value)) {
112
- return `${calcName}(${degenerateKeyword(node.value)} * 1${node.unit})`;
113
+ return `${calcName}(${degenerateKeyword(node.value)} * 1${node.rawUnit ?? node.unit})`;
113
114
  }
114
115
 
115
116
  if (node.type === 'Num' || node.type === 'Dim') {
@@ -176,14 +177,21 @@ function serializeExpr(node, prec) {
176
177
  // Nested degenerate Dim wraps in calc() so the `<kw> * 1<unit>` form
177
178
  // parses back as one Dim factor. The bare form round-trips wrong
178
179
  // inside a Product — `0 * Dim(Infinity, px)` would re-fold as NaN.
179
- return `calc(${degenerateKeyword(node.value)} * 1${node.unit})`;
180
+ return `calc(${degenerateKeyword(node.value)} * 1${node.rawUnit ?? node.unit})`;
180
181
  }
181
182
  return serializeScalar(node, prec).text;
182
183
  case 'Ident':
183
- return node.name;
184
+ return node.rawName ?? node.name;
184
185
  case 'Call': {
186
+ const components = getComponents(node);
187
+ if (components) {
188
+ const args = node.args
189
+ .map((arg) => serializeExpr(arg, prec))
190
+ .join(', ');
191
+ return `${node.rawName ?? node.name}(${args}${serializeComponents(components, (child) => serialize(child, { precision: prec }))})`;
192
+ }
185
193
  const args = node.args.map((a) => serializeExpr(a, prec)).join(', ');
186
- return `${node.name}(${args})`;
194
+ return `${node.rawName ?? node.name}(${args})`;
187
195
  }
188
196
  case 'Sum':
189
197
  return serializeSum(node, prec);
@@ -212,7 +220,7 @@ function displaySign(term) {
212
220
  if (node.type === 'Dim' && Number.isFinite(node.value) && node.value < 0) {
213
221
  return {
214
222
  sign: /** @type {1 | -1} */ (-sign),
215
- magnitude: dim(-node.value, node.unit),
223
+ magnitude: dim(-node.value, node.unit, node.rawUnit),
216
224
  };
217
225
  }
218
226
  return { sign, magnitude: node };
@@ -15,7 +15,7 @@ function simplifyAbs(args) {
15
15
  return num(Math.abs(a.value));
16
16
  }
17
17
  if (a.type === 'Dim' && a.unit !== '%') {
18
- return dim(Math.abs(a.value), a.unit);
18
+ return dim(Math.abs(a.value), a.unit, a.rawUnit);
19
19
  }
20
20
  return call('abs', [a]);
21
21
  }
@@ -9,10 +9,10 @@ import { convert } from '../convertUnits.js';
9
9
  /**
10
10
  * @typedef {object} UnitBucket
11
11
  * @property {string} unit
12
+ * @property {string} [rawUnit]
12
13
  * @property {number} total
13
14
  * @property {number} scale largest |term| accumulated into `total`, for noise detection
14
15
  * @property {import('../convertUnits.js').BaseType | null} base
15
- * @property {number} order
16
16
  */
17
17
 
18
18
  /** Mutates `buckets` in place — totals of survivor buckets accumulate the
@@ -21,32 +21,27 @@ import { convert } from '../convertUnits.js';
21
21
  * @return {UnitBucket[]}
22
22
  */
23
23
  function mergeConvertibleBuckets(buckets) {
24
- const ordered = buckets.sort((a, b) => a.order - b.order);
25
- /** @type {Set<string>} */ const merged = new Set();
24
+ /** @type {Map<import('../convertUnits.js').BaseType, UnitBucket>} */ const representative =
25
+ new Map();
26
26
  /** @type {UnitBucket[]} */ const out = [];
27
- for (const b of ordered) {
28
- const keyB = b.unit.toLowerCase();
29
- if (merged.has(keyB)) {
27
+ for (const b of buckets) {
28
+ if (b.base === null) {
29
+ out.push(b);
30
30
  continue;
31
31
  }
32
- merged.add(keyB);
33
- if (b.base !== null) {
34
- for (const other of ordered) {
35
- const keyO = other.unit.toLowerCase();
36
- if (merged.has(keyO)) {
37
- continue;
38
- }
39
- if (other.base !== b.base) {
40
- continue;
41
- }
42
- const converted = convert(other.total, other.unit, b.unit);
43
- if (converted !== null) {
44
- b.total += converted;
45
- merged.add(keyO);
46
- }
47
- }
32
+ const first = representative.get(b.base);
33
+ if (!first) {
34
+ representative.set(b.base, b);
35
+ out.push(b);
36
+ continue;
37
+ }
38
+ const converted = convert(b.total, b.unit, first.unit);
39
+ if (converted === null) {
40
+ out.push(b);
41
+ continue;
48
42
  }
49
- out.push(b);
43
+ first.total += converted;
44
+ first.scale = Math.max(first.scale, Math.abs(converted));
50
45
  }
51
46
  return out;
52
47
  }
@@ -17,6 +17,7 @@ import { simplifyLog } from './log.js';
17
17
  import { simplifyHypot } from './hypot.js';
18
18
 
19
19
  import { call } from '../node.js';
20
+ import { getComponents, setComponents, simplifyComponents } from '../opaque.js';
20
21
 
21
22
  /** @typedef {import('../node.js').Node} Node */
22
23
  /** @typedef {import('../simplify.js').SimplifyFn} SimplifyFn */
@@ -101,6 +102,12 @@ function simplifyCall(node, simplify) {
101
102
 
102
103
  const args = node.args.map((a) => simplify(a));
103
104
 
105
+ const components = getComponents(node);
106
+ if (components) {
107
+ const result = call(node.name, args, node.rawName);
108
+ return setComponents(result, simplifyComponents(components, simplify));
109
+ }
110
+
104
111
  const simplifier = MATH_SIMPLIFIERS.get(name);
105
112
  if (simplifier) {
106
113
  // min/max preserve the call's original casing in their opaque-args
@@ -111,7 +118,7 @@ function simplifyCall(node, simplify) {
111
118
  );
112
119
  }
113
120
 
114
- return call(node.name, args);
121
+ return call(node.name, args, node.rawName);
115
122
  }
116
123
 
117
124
  export {
@@ -15,7 +15,7 @@ import { tryCancelPair } from './cancel.js';
15
15
  */
16
16
  function simplifyProduct(product, simplify) {
17
17
  let coeff = 1;
18
- /** @type {{exponent: 1 | -1, value: number, unit: string}[]} */
18
+ /** @type {{exponent: 1 | -1, value: number, unit: string, rawUnit?: string}[]} */
19
19
  const dims = [];
20
20
  /** @type {ProductFactor[]} */
21
21
  const opaque = [];
@@ -54,7 +54,7 @@ function simplifyProduct(product, simplify) {
54
54
  return;
55
55
  }
56
56
  if (n.type === 'Dim') {
57
- dims.push({ exponent, value: n.value, unit: n.unit });
57
+ dims.push({ exponent, value: n.value, unit: n.unit, rawUnit: n.rawUnit });
58
58
  scalarChain.push({ exponent, value: n.value });
59
59
  return;
60
60
  }
@@ -112,7 +112,7 @@ function simplifyProduct(product, simplify) {
112
112
  value = value / f.value;
113
113
  }
114
114
  }
115
- return dim(value, d.unit);
115
+ return dim(value, d.unit, d.rawUnit);
116
116
  }
117
117
 
118
118
  if (remainingDims.length === 0 && opaque.length === 0) {
@@ -125,7 +125,10 @@ function simplifyProduct(product, simplify) {
125
125
  factors.push({ exponent: 1, node: num(coeff) });
126
126
  }
127
127
  for (const d of remainingDims) {
128
- factors.push({ exponent: d.exponent, node: dim(d.value, d.unit) });
128
+ factors.push({
129
+ exponent: d.exponent,
130
+ node: dim(d.value, d.unit, d.rawUnit),
131
+ });
129
132
  }
130
133
  factors.push(...opaque);
131
134
 
@@ -1,5 +1,5 @@
1
1
  import { mkSum, num, dim } from '../node.js';
2
- import { baseOf } from '../convertUnits.js';
2
+ import { staticBaseOf } from '../convertUnits.js';
3
3
  import { mergeConvertibleBuckets } from './bucket.js';
4
4
 
5
5
  /**
@@ -39,7 +39,6 @@ function simplifySum(sum, simplify) {
39
39
  const byUnit = new Map();
40
40
  /** @type {SumTerm[]} */
41
41
  const opaque = [];
42
- let bucketOrder = 0;
43
42
 
44
43
  /**
45
44
  * @param {1 | -1} sign
@@ -78,10 +77,10 @@ function simplifySum(sum, simplify) {
78
77
  } else {
79
78
  byUnit.set(key, {
80
79
  unit: n.unit,
80
+ rawUnit: n.rawUnit,
81
81
  total: sign * n.value,
82
82
  scale: Math.abs(n.value),
83
- base: baseOf(n.unit),
84
- order: bucketOrder++,
83
+ base: staticBaseOf(n.unit),
85
84
  });
86
85
  }
87
86
  return;
@@ -101,7 +100,11 @@ function simplifySum(sum, simplify) {
101
100
  for (const bucket of mergeConvertibleBuckets([...byUnit.values()])) {
102
101
  terms.push({
103
102
  sign: 1,
104
- node: dim(denoise(bucket.total, bucket.scale), bucket.unit),
103
+ node: dim(
104
+ denoise(bucket.total, bucket.scale),
105
+ bucket.unit,
106
+ bucket.rawUnit
107
+ ),
105
108
  });
106
109
  }
107
110
  terms.push(...opaque);
@@ -1,139 +1,10 @@
1
- // Folds @csstools/css-tokenizer output into the calc() token subset.
1
+ // Thin project-local entry point for the CSS Syntax tokenizer. The parser
2
+ // consumes native tokens directly so decoded values and source spelling remain available.
3
+ import { tokenize as tokenizeCss } from '@csstools/css-tokenizer';
2
4
 
3
- import {
4
- tokenize as tokenizeCss,
5
- TokenType as CssType,
6
- } from '@csstools/css-tokenizer';
7
- /**
8
- * @typedef {'number' | 'dimension' | 'ident' | 'punct' | 'eof'} TokenType
9
- * @typedef {object} Token
10
- * @property {TokenType} type
11
- * @property {string} value
12
- * @property {string} [unit] Present on `dimension` tokens; `%` for percentages.
13
- * @property {number} pos
14
- * @property {boolean} ws Whitespace immediately before — drives the §10.1 `+`/`-` rule.
15
- */
16
-
17
- const PUNCT_DELIMS = new Set(['+', '-', '*', '/']);
18
-
19
- const NUMERIC_RAW = /^[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?/;
20
-
21
- /**
22
- * @param {string} input
23
- * @return {Token[]}
24
- */
5
+ /** @param {string} input @return {import('@csstools/css-tokenizer').CSSToken[]} */
25
6
  function tokenize(input) {
26
- return tokenizeTokens(tokenizeCss({ css: input }), input.length);
27
- }
28
-
29
- /**
30
- * CSS absorbs leading signs (`-5px` is one token); the parser expects
31
- * punct sign + unsigned numeric, so split them back out.
32
- * @param {Token[]} tokens
33
- * @param {string} raw
34
- * @param {string | undefined} unit
35
- * @param {number} pos
36
- * @param {boolean} ws
37
- * @return {void}
38
- */
39
- function pushNumeric(tokens, raw, unit, pos, ws) {
40
- let value = /** @type {RegExpExecArray} */ (NUMERIC_RAW.exec(raw))[0];
41
- const sign = value[0];
42
- if (sign === '+' || sign === '-') {
43
- tokens.push({ type: 'punct', value: sign, pos, ws });
44
- value = value.slice(1);
45
- pos += 1;
46
- ws = false;
47
- }
48
- if (unit === undefined) {
49
- tokens.push({ type: 'number', value, pos, ws });
50
- } else {
51
- tokens.push({ type: 'dimension', value, unit, pos, ws });
52
- }
53
- }
54
-
55
- /**
56
- * Convert a slice of an existing CSS token stream into the token subset used
57
- * by the calculation parser. Token positions remain relative to the original
58
- * source text, which keeps parse errors useful to adapter callers.
59
- *
60
- * @param {import('@csstools/css-tokenizer').CSSToken[]} cssTokens
61
- * @param {number} eofPosition
62
- * @param {number} [start]
63
- * @param {number} [end]
64
- * @return {Token[]}
65
- */
66
- function tokenizeTokens(
67
- cssTokens,
68
- eofPosition,
69
- start = 0,
70
- end = cssTokens.length
71
- ) {
72
- /** @type {Token[]} */
73
- const tokens = [];
74
- let ws = true;
75
-
76
- for (let i = start; i < end; i++) {
77
- const t = cssTokens[i];
78
- switch (t[0]) {
79
- case CssType.Whitespace:
80
- case CssType.Comment:
81
- ws = true;
82
- continue;
83
- case CssType.Number:
84
- pushNumeric(tokens, t[1], undefined, t[2], ws);
85
- ws = false;
86
- continue;
87
- case CssType.Dimension:
88
- pushNumeric(tokens, t[1], t[4].unit, t[2], ws);
89
- ws = false;
90
- continue;
91
- case CssType.Percentage:
92
- pushNumeric(tokens, t[1], '%', t[2], ws);
93
- ws = false;
94
- continue;
95
- case CssType.Ident:
96
- tokens.push({ type: 'ident', value: t[4].value, pos: t[2], ws });
97
- break;
98
- case CssType.Function:
99
- tokens.push({ type: 'ident', value: t[4].value, pos: t[2], ws });
100
- tokens.push({
101
- type: 'punct',
102
- value: '(',
103
- pos: t[2] + t[1].length - 1,
104
- ws: false,
105
- });
106
- break;
107
- case CssType.OpenParen:
108
- tokens.push({ type: 'punct', value: '(', pos: t[2], ws });
109
- break;
110
- case CssType.CloseParen:
111
- tokens.push({ type: 'punct', value: ')', pos: t[2], ws });
112
- break;
113
- case CssType.Comma:
114
- tokens.push({ type: 'punct', value: ',', pos: t[2], ws });
115
- break;
116
- case CssType.Delim:
117
- if (!PUNCT_DELIMS.has(t[4].value)) {
118
- throw new Error(
119
- `Unexpected character "${t[4].value}" at position ${t[2]}`
120
- );
121
- }
122
- tokens.push({ type: 'punct', value: t[4].value, pos: t[2], ws });
123
- break;
124
- case CssType.EOF:
125
- continue;
126
- default:
127
- throw new Error(
128
- `Unexpected character "${t[1][0] ?? ''}" at position ${t[2]}`
129
- );
130
- }
131
- ws = false;
132
- }
133
-
134
- tokens.push({ type: 'eof', value: '', pos: eofPosition, ws });
135
-
136
- return tokens;
7
+ return tokenizeCss({ css: input });
137
8
  }
138
9
 
139
- export { tokenize, tokenizeTokens };
10
+ export { tokenize };
package/src/reduce.js CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  tokenize as cssTokenize,
6
6
  TokenType as CssType,
7
7
  } from '@csstools/css-tokenizer';
8
- import { tokenizeTokens } from './lib/tokenizer.js';
9
8
  import { parse } from './lib/parser.js';
10
9
  import { simplify } from './lib/simplify.js';
11
10
  import {
@@ -95,9 +94,7 @@ function walkTokens(start, expectedClose, ctx, transform) {
95
94
  const inputEnd = closed && isCalc ? ctx.tokens[close][2] : end;
96
95
  const contents = ctx.value.slice(inputStart, inputEnd);
97
96
  try {
98
- const node = simplify(
99
- parse(tokenizeTokens(ctx.tokens, end, sliceStart, sliceEnd))
100
- );
97
+ const node = simplify(parse(ctx.tokens, sliceStart, sliceEnd));
101
98
  ctx.replacements.push({
102
99
  start: token[2],
103
100
  end,
@@ -14,4 +14,11 @@ declare function baseOf(unit: string): BaseType | null;
14
14
  * @return {number | null}
15
15
  */
16
16
  declare function convert(value: number, from: string, to: string): number | null;
17
- export { baseOf, convert };
17
+ /**
18
+ * Return a base type only for units present in the static conversion table.
19
+ * Units with context-dependent values (em, rem, vw, etc.) return null.
20
+ * @param {string} unit
21
+ * @return {BaseType | null}
22
+ */
23
+ declare function staticBaseOf(unit: string): BaseType | null;
24
+ export { baseOf, staticBaseOf, convert };
@@ -6,15 +6,18 @@ export type Dim = {
6
6
  type: 'Dim';
7
7
  value: number;
8
8
  unit: string;
9
+ rawUnit?: string;
9
10
  };
10
11
  export type Ident = {
11
12
  type: 'Ident';
12
13
  name: string;
14
+ rawName?: string;
13
15
  };
14
16
  export type Call = {
15
17
  type: 'Call';
16
18
  name: string;
17
19
  args: Node[];
20
+ rawName?: string;
18
21
  };
19
22
  export type SumTerm = {
20
23
  sign: 1 | -1;
@@ -36,9 +39,9 @@ export type Product = {
36
39
  export type Node = Num | Dim | Ident | Call | Sum | Product;
37
40
  /**
38
41
  * @typedef {{type: 'Num', value: number}} Num
39
- * @typedef {{type: 'Dim', value: number, unit: string}} Dim
40
- * @typedef {{type: 'Ident', name: string}} Ident
41
- * @typedef {{type: 'Call', name: string, args: Node[]}} Call
42
+ * @typedef {{type: 'Dim', value: number, unit: string, rawUnit?: string}} Dim
43
+ * @typedef {{type: 'Ident', name: string, rawName?: string}} Ident
44
+ * @typedef {{type: 'Call', name: string, args: Node[], rawName?: string}} Call
42
45
  * @typedef {{sign: 1 | -1, node: Node}} SumTerm Sign is always +1 when node is Num or Dim.
43
46
  * @typedef {{type: 'Sum', terms: SumTerm[], grouped?: boolean}} Sum
44
47
  * @typedef {{exponent: 1 | -1, node: Node}} ProductFactor exponent +1 = numerator, -1 = denominator.
@@ -53,20 +56,23 @@ declare function num(value: number): Num;
53
56
  /**
54
57
  * @param {number} value
55
58
  * @param {string} unit
59
+ * @param {string} [rawUnit]
56
60
  * @return {Dim}
57
61
  */
58
- declare function dim(value: number, unit: string): Dim;
62
+ declare function dim(value: number, unit: string, rawUnit?: string): Dim;
59
63
  /**
60
64
  * @param {string} name
65
+ * @param {string} [rawName]
61
66
  * @return {Ident}
62
67
  */
63
- declare function ident(name: string): Ident;
68
+ declare function ident(name: string, rawName?: string): Ident;
64
69
  /**
65
70
  * @param {string} name
66
71
  * @param {Node[]} args
72
+ * @param {string} [rawName]
67
73
  * @return {Call}
68
74
  */
69
- declare function call(name: string, args: Node[]): Call;
75
+ declare function call(name: string, args: Node[], rawName?: string): Call;
70
76
  /**
71
77
  * @param {SumTerm[]} rawTerms
72
78
  * @return {Node}
@@ -0,0 +1,15 @@
1
+ export type Node = import('./node.js').Node;
2
+ export type Component = string | Node | Component[];
3
+ /** @param {Extract<Node, {type: 'Call'}>} node @param {Component[]} tree */
4
+ declare function setComponents(node: Extract<Node, {
5
+ type: 'Call';
6
+ }>, tree: Component[]): import("./node.js").Call;
7
+ /** @param {Extract<Node, {type: 'Call'}>} node */
8
+ declare function getComponents(node: Extract<Node, {
9
+ type: 'Call';
10
+ }>): Component[] | undefined;
11
+ /** @param {Component[]} tree @param {(node: Node) => Node} simplify @return {Component[]} */
12
+ declare function simplifyComponents(tree: Component[], simplify: (node: Node) => Node): Component[];
13
+ /** @param {Component[]} tree @param {(node: Node) => string} serialize @return {string} */
14
+ declare function serializeComponents(tree: Component[], serialize: (node: Node) => string): string;
15
+ export { getComponents, setComponents, simplifyComponents, serializeComponents, };
@@ -1,51 +1,55 @@
1
- export type Token = import('./tokenizer.js').Token;
2
- export type TokenType = import('./tokenizer.js').TokenType;
1
+ export type CSSToken = import('@csstools/css-tokenizer').CSSToken;
3
2
  export type Node = import('./node.js').Node;
3
+ export type Component = string | Node | Component[];
4
+ export type Token = {
5
+ type: 'number' | 'dimension' | 'ident' | 'function' | 'punct' | 'eof';
6
+ value: string | number;
7
+ raw: string;
8
+ unit?: string;
9
+ rawUnit?: string;
10
+ signCharacter?: '+' | '-';
11
+ pos: number;
12
+ ws: boolean;
13
+ };
4
14
  export type PrefixParselet = (p: Parser, token: Token) => Node;
15
+ /** Bounded cursor that skips trivia but records whether it preceded a token. */
5
16
  declare class Parser {
6
- /** @private */
7
- i;
8
- /** @private @readonly */
9
- tokens;
17
+ #private;
10
18
  /**
11
- * @param {Token[]} tokens
19
+ * @param {CSSToken[]} tokens
20
+ * @param {number} start
21
+ * @param {number} end
22
+ * @param {Map<number, number>} [ends]
12
23
  */
13
- constructor(tokens: Token[]);
24
+ constructor(tokens: CSSToken[], start: number, end: number, ends?: Map<number, number>);
25
+ /** @return {Map<number, number>} */
26
+ get ends(): Map<number, number>;
27
+ /** @return {number} */
28
+ eofPosition(): number;
29
+ /** @return {Token} */
30
+ read(): Token;
14
31
  /** @return {Token} */
15
32
  peek(): Token;
16
33
  /** @return {Token} */
17
34
  next(): Token;
18
- /**
19
- * @param {TokenType} type
20
- * @param {string} [value]
21
- * @return {Token}
22
- */
23
- expect(type: TokenType, value?: string): Token;
24
- /**
25
- * @param {string} value
26
- * @param {string} [value2]
27
- * @return {boolean}
28
- */
35
+ /** @return {{start: number, close: number, tokens: CSSToken[], ends: Map<number, number>}} */
36
+ functionRange(): {
37
+ start: number;
38
+ close: number;
39
+ tokens: CSSToken[];
40
+ ends: Map<number, number>;
41
+ };
42
+ /** @param {number} index */
43
+ consumeThrough(index: number): void;
44
+ /** @param {string} value @param {string} [value2] @return {boolean} */
29
45
  isPunct(value: string, value2?: string): boolean;
30
- /**
31
- * @param {string} value
32
- * @return {boolean}
33
- */
46
+ /** @param {string} value @return {boolean} */
34
47
  matchPunct(value: string): boolean;
35
- /**
36
- * @param {string} value
37
- * @return {Token}
38
- */
48
+ /** @param {string} value @return {Token} */
39
49
  expectPunct(value: string): Token;
40
- /**
41
- * @param {number} [minBp]
42
- * @return {Node}
43
- */
50
+ /** @param {number} [minBp] @return {Node} */
44
51
  parseExpr(minBp?: number): Node;
45
52
  }
46
- /**
47
- * @param {Token[]} tokens
48
- * @return {Node}
49
- */
50
- declare function parse(tokens: Token[]): Node;
53
+ /** @param {CSSToken[]} tokens @param {number} [start] @param {number} [end] @return {Node} */
54
+ declare function parse(tokens: CSSToken[], start?: number, end?: number): Node;
51
55
  export { parse };
@@ -1,20 +1,20 @@
1
1
  export type UnitBucket = {
2
2
  unit: string;
3
+ rawUnit?: string;
3
4
  total: number;
4
5
  /**
5
6
  * largest |term| accumulated into `total`, for noise detection
6
7
  */
7
8
  scale: number;
8
9
  base: import('../convertUnits.js').BaseType | null;
9
- order: number;
10
10
  };
11
11
  /**
12
12
  * @typedef {object} UnitBucket
13
13
  * @property {string} unit
14
+ * @property {string} [rawUnit]
14
15
  * @property {number} total
15
16
  * @property {number} scale largest |term| accumulated into `total`, for noise detection
16
17
  * @property {import('../convertUnits.js').BaseType | null} base
17
- * @property {number} order
18
18
  */
19
19
  /** Mutates `buckets` in place — totals of survivor buckets accumulate the
20
20
  * converted values of merged neighbors. Caller must not reuse the input.
@@ -1,32 +1,3 @@
1
- export type TokenType = 'number' | 'dimension' | 'ident' | 'punct' | 'eof';
2
- export type Token = {
3
- type: TokenType;
4
- value: string;
5
- /**
6
- * Present on `dimension` tokens; `%` for percentages.
7
- */
8
- unit?: string;
9
- pos: number;
10
- /**
11
- * Whitespace immediately before — drives the §10.1 `+`/`-` rule.
12
- */
13
- ws: boolean;
14
- };
15
- /**
16
- * @param {string} input
17
- * @return {Token[]}
18
- */
19
- declare function tokenize(input: string): Token[];
20
- /**
21
- * Convert a slice of an existing CSS token stream into the token subset used
22
- * by the calculation parser. Token positions remain relative to the original
23
- * source text, which keeps parse errors useful to adapter callers.
24
- *
25
- * @param {import('@csstools/css-tokenizer').CSSToken[]} cssTokens
26
- * @param {number} eofPosition
27
- * @param {number} [start]
28
- * @param {number} [end]
29
- * @return {Token[]}
30
- */
31
- declare function tokenizeTokens(cssTokens: import('@csstools/css-tokenizer').CSSToken[], eofPosition: number, start?: number, end?: number): Token[];
32
- export { tokenize, tokenizeTokens };
1
+ /** @param {string} input @return {import('@csstools/css-tokenizer').CSSToken[]} */
2
+ declare function tokenize(input: string): import('@csstools/css-tokenizer').CSSToken[];
3
+ export { tokenize };