postcss-calc 10.1.0 → 11.0.0-rc.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 +56 -1
- package/package.json +19 -13
- package/src/index.js +122 -27
- package/src/lib/convertUnits.js +105 -0
- package/src/lib/node.js +189 -0
- package/src/lib/parser.js +314 -0
- package/src/lib/serialize.js +226 -0
- package/src/lib/simplify/abs.js +21 -0
- package/src/lib/simplify/atan2.js +25 -0
- package/src/lib/simplify/bucket.js +48 -0
- package/src/lib/simplify/call.js +59 -0
- package/src/lib/simplify/cancel.js +39 -0
- package/src/lib/simplify/clamp.js +26 -0
- package/src/lib/simplify/exp.js +18 -0
- package/src/lib/simplify/fold.js +63 -0
- package/src/lib/simplify/hypot.js +22 -0
- package/src/lib/simplify/inverse-trig.js +29 -0
- package/src/lib/simplify/log.js +25 -0
- package/src/lib/simplify/min-max.js +23 -0
- package/src/lib/simplify/mod-rem.js +47 -0
- package/src/lib/simplify/pow.js +20 -0
- package/src/lib/simplify/product.js +133 -0
- package/src/lib/simplify/round.js +113 -0
- package/src/lib/simplify/sign.js +22 -0
- package/src/lib/simplify/sqrt.js +18 -0
- package/src/lib/simplify/sum.js +83 -0
- package/src/lib/simplify/trig.js +40 -0
- package/src/lib/simplify.js +40 -0
- package/src/lib/tokenizer.js +115 -0
- package/types/index.d.ts +15 -17
- package/types/lib/convertUnits.d.ts +16 -0
- package/types/lib/node.d.ts +90 -0
- package/types/lib/parser.d.ts +39 -0
- package/types/lib/serialize.d.ts +20 -0
- package/types/lib/simplify/abs.d.ts +7 -0
- package/types/lib/simplify/atan2.d.ts +7 -0
- package/types/lib/simplify/bucket.d.ts +19 -0
- package/types/lib/simplify/call.d.ts +12 -0
- package/types/lib/simplify/cancel.d.ts +19 -0
- package/types/lib/simplify/clamp.d.ts +7 -0
- package/types/lib/simplify/exp.d.ts +7 -0
- package/types/lib/simplify/fold.d.ts +12 -0
- package/types/lib/simplify/hypot.d.ts +7 -0
- package/types/lib/simplify/inverse-trig.d.ts +7 -0
- package/types/lib/simplify/log.d.ts +7 -0
- package/types/lib/simplify/min-max.d.ts +8 -0
- package/types/lib/simplify/mod-rem.d.ts +8 -0
- package/types/lib/simplify/pow.d.ts +7 -0
- package/types/lib/simplify/product.d.ts +16 -0
- package/types/lib/simplify/round.d.ts +8 -0
- package/types/lib/simplify/sign.d.ts +7 -0
- package/types/lib/simplify/sqrt.d.ts +7 -0
- package/types/lib/simplify/sum.d.ts +18 -0
- package/types/lib/simplify/trig.d.ts +7 -0
- package/types/lib/simplify.d.ts +18 -0
- package/types/lib/tokenizer.d.ts +19 -0
- package/types/lib/type.d.ts +16 -0
- package/src/lib/convertUnit.js +0 -160
- package/src/lib/reducer.js +0 -390
- package/src/lib/stringifier.js +0 -98
- package/src/lib/transform.js +0 -109
- package/src/parser.d.ts +0 -79
- package/src/parser.js +0 -4200
- package/types/lib/convertUnit.d.ts +0 -8
- package/types/lib/reducer.d.ts +0 -14
- package/types/lib/stringifier.d.ts +0 -5
- package/types/lib/transform.d.ts +0 -6
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// §10.4 — sin/cos/tan. <number> is radians; <angle> dim is converted.
|
|
4
|
+
|
|
5
|
+
const { num } = require('../node.js');
|
|
6
|
+
const { baseOf, convert } = require('../convertUnits.js');
|
|
7
|
+
|
|
8
|
+
/** @typedef {import('../node.js').Node} Node */
|
|
9
|
+
|
|
10
|
+
const TRIG_OPS = /** @type {const} */ ({
|
|
11
|
+
sin: Math.sin,
|
|
12
|
+
cos: Math.cos,
|
|
13
|
+
tan: Math.tan,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {'sin' | 'cos' | 'tan'} name
|
|
18
|
+
* @param {Node[]} args
|
|
19
|
+
* @return {Node}
|
|
20
|
+
*/
|
|
21
|
+
function simplifyTrig(name, args) {
|
|
22
|
+
if (args.length !== 1) {return { type: 'Call', name, args };}
|
|
23
|
+
const a = args[0];
|
|
24
|
+
/** @type {number | null} */ let radians = null;
|
|
25
|
+
if (a.type === 'Num') {
|
|
26
|
+
radians = a.value;
|
|
27
|
+
} else if (a.type === 'Dim' && a.unit !== '%' && baseOf(a.unit) === 'angle') {
|
|
28
|
+
// The `baseOf === 'angle'` check and the `inDeg !== null` guard below
|
|
29
|
+
// are observationally equivalent under current type tables (every
|
|
30
|
+
// angle unit has a TO_CANONICAL entry). Stryker flags both as
|
|
31
|
+
// equivalent-mutant survivors — keep them; they're load-bearing
|
|
32
|
+
// defense against future unit additions.
|
|
33
|
+
const inDeg = convert(a.value, a.unit, 'deg');
|
|
34
|
+
if (inDeg !== null) {radians = (inDeg * Math.PI) / 180;}
|
|
35
|
+
}
|
|
36
|
+
if (radians === null) {return { type: 'Call', name, args };}
|
|
37
|
+
return num(TRIG_OPS[name](radians));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = { simplifyTrig };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Spec: https://www.w3.org/TR/css-values-4/#calc-simplification
|
|
4
|
+
// One top-down pass over a canonical AST. Per-concern fold modules in
|
|
5
|
+
// ./simplify/; this file is the entry + dispatch only.
|
|
6
|
+
|
|
7
|
+
const { simplifySum } = require('./simplify/sum.js');
|
|
8
|
+
const { simplifyProduct } = require('./simplify/product.js');
|
|
9
|
+
const { simplifyCall } = require('./simplify/call.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {import('./node.js').Node} Node
|
|
13
|
+
*
|
|
14
|
+
* Recursive simplifier reference, threaded into Sum/Product/Call. Lets
|
|
15
|
+
* leaf fold modules avoid circular imports of the entry function.
|
|
16
|
+
* @typedef {(node: Node) => Node} SimplifyFn
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {Node} node
|
|
21
|
+
* @return {Node}
|
|
22
|
+
*/
|
|
23
|
+
function simplify(node) {
|
|
24
|
+
switch (node.type) {
|
|
25
|
+
case 'Num':
|
|
26
|
+
case 'Dim':
|
|
27
|
+
case 'Ident':
|
|
28
|
+
return node;
|
|
29
|
+
case 'Call':
|
|
30
|
+
return simplifyCall(node, simplify);
|
|
31
|
+
case 'Sum':
|
|
32
|
+
return simplifySum(node, simplify);
|
|
33
|
+
case 'Product':
|
|
34
|
+
return simplifyProduct(node, simplify);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Stryker disable next-line all: instrumenting this line breaks Node's
|
|
39
|
+
// cjs-module-lexer named-export detection for .mjs `import { x } from` consumers.
|
|
40
|
+
module.exports = { simplify };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Folds @csstools/css-tokenizer output into the calc() token subset.
|
|
4
|
+
|
|
5
|
+
// @csstools/css-tokenizer is ESM-only and this package is CJS. require(esm)
|
|
6
|
+
// must happen at first use, not at module evaluation — a consumer's ESM
|
|
7
|
+
// graph may also link the tokenizer (other csstools plugins do), and a
|
|
8
|
+
// load-time require would hit ERR_REQUIRE_CYCLE_MODULE there.
|
|
9
|
+
/** @type {typeof import('@csstools/css-tokenizer') | undefined} */
|
|
10
|
+
let cssTokenizer;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {'number' | 'dimension' | 'ident' | 'punct' | 'eof'} TokenType
|
|
14
|
+
* @typedef {object} Token
|
|
15
|
+
* @property {TokenType} type
|
|
16
|
+
* @property {string} value
|
|
17
|
+
* @property {string} [unit] Present on `dimension` tokens; `%` for percentages.
|
|
18
|
+
* @property {number} pos
|
|
19
|
+
* @property {boolean} ws Whitespace immediately before — drives the §10.1 `+`/`-` rule.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const PUNCT_DELIMS = new Set(['+', '-', '*', '/']);
|
|
23
|
+
|
|
24
|
+
const NUMERIC_RAW = /^[+-]?(?:\d+(?:\.\d+)?|\.\d+)(?:[eE][+-]?\d+)?/;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string} input
|
|
28
|
+
* @return {Token[]}
|
|
29
|
+
*/
|
|
30
|
+
function tokenize(input) {
|
|
31
|
+
cssTokenizer ??= require('@csstools/css-tokenizer');
|
|
32
|
+
const { tokenize: tokenizeCss, TokenType: CssType } = cssTokenizer;
|
|
33
|
+
/** @type {Token[]} */
|
|
34
|
+
const tokens = [];
|
|
35
|
+
let ws = true;
|
|
36
|
+
|
|
37
|
+
// CSS absorbs leading signs (`-5px` is one token); the parser expects
|
|
38
|
+
// punct sign + unsigned numeric, so split them back out.
|
|
39
|
+
/**
|
|
40
|
+
* @param {string} raw
|
|
41
|
+
* @param {string | undefined} unit
|
|
42
|
+
* @param {number} pos
|
|
43
|
+
* @return {void}
|
|
44
|
+
*/
|
|
45
|
+
function pushNumeric(raw, unit, pos) {
|
|
46
|
+
let value = /** @type {RegExpExecArray} */ (NUMERIC_RAW.exec(raw))[0];
|
|
47
|
+
const sign = value[0];
|
|
48
|
+
if (sign === '+' || sign === '-') {
|
|
49
|
+
tokens.push({ type: 'punct', value: sign, pos, ws });
|
|
50
|
+
value = value.slice(1);
|
|
51
|
+
pos += 1;
|
|
52
|
+
ws = false;
|
|
53
|
+
}
|
|
54
|
+
if (unit === undefined) {
|
|
55
|
+
tokens.push({ type: 'number', value, pos, ws });
|
|
56
|
+
} else {
|
|
57
|
+
tokens.push({ type: 'dimension', value, unit, pos, ws });
|
|
58
|
+
}
|
|
59
|
+
ws = false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const t of tokenizeCss({ css: input })) {
|
|
63
|
+
switch (t[0]) {
|
|
64
|
+
case CssType.Whitespace:
|
|
65
|
+
case CssType.Comment:
|
|
66
|
+
ws = true;
|
|
67
|
+
continue;
|
|
68
|
+
case CssType.Number:
|
|
69
|
+
pushNumeric(t[1], undefined, t[2]);
|
|
70
|
+
continue;
|
|
71
|
+
case CssType.Dimension:
|
|
72
|
+
pushNumeric(t[1], t[4].unit, t[2]);
|
|
73
|
+
continue;
|
|
74
|
+
case CssType.Percentage:
|
|
75
|
+
pushNumeric(t[1], '%', t[2]);
|
|
76
|
+
continue;
|
|
77
|
+
case CssType.Ident:
|
|
78
|
+
tokens.push({ type: 'ident', value: t[4].value, pos: t[2], ws });
|
|
79
|
+
break;
|
|
80
|
+
case CssType.Function:
|
|
81
|
+
tokens.push({ type: 'ident', value: t[4].value, pos: t[2], ws });
|
|
82
|
+
tokens.push({ type: 'punct', value: '(', pos: t[2] + t[1].length - 1, ws: false });
|
|
83
|
+
break;
|
|
84
|
+
case CssType.OpenParen:
|
|
85
|
+
tokens.push({ type: 'punct', value: '(', pos: t[2], ws });
|
|
86
|
+
break;
|
|
87
|
+
case CssType.CloseParen:
|
|
88
|
+
tokens.push({ type: 'punct', value: ')', pos: t[2], ws });
|
|
89
|
+
break;
|
|
90
|
+
case CssType.Comma:
|
|
91
|
+
tokens.push({ type: 'punct', value: ',', pos: t[2], ws });
|
|
92
|
+
break;
|
|
93
|
+
case CssType.Delim:
|
|
94
|
+
if (!PUNCT_DELIMS.has(t[4].value)) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Unexpected character "${t[4].value}" at position ${t[2]}`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
tokens.push({ type: 'punct', value: t[4].value, pos: t[2], ws });
|
|
100
|
+
break;
|
|
101
|
+
case CssType.EOF:
|
|
102
|
+
tokens.push({ type: 'eof', value: '', pos: input.length, ws });
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Unexpected character "${t[1][0] ?? ''}" at position ${t[2]}`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
ws = false;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return tokens;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = { tokenize };
|
package/types/index.d.ts
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
export = pluginCreator;
|
|
2
2
|
/**
|
|
3
|
-
* @
|
|
4
|
-
*
|
|
5
|
-
* warnWhenCannotResolve?: boolean,
|
|
6
|
-
* mediaQueries?: boolean,
|
|
7
|
-
* selectors?: boolean}} PostCssCalcOptions
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* @type {import('postcss').PluginCreator<PostCssCalcOptions>}
|
|
11
|
-
* @param {PostCssCalcOptions} opts
|
|
3
|
+
* @type {import('postcss').PluginCreator<PluginOptions>}
|
|
4
|
+
* @param {PluginOptions} [opts]
|
|
12
5
|
* @return {import('postcss').Plugin}
|
|
13
6
|
*/
|
|
14
|
-
declare function pluginCreator(opts
|
|
7
|
+
declare function pluginCreator(opts?: PluginOptions): import("postcss").Plugin;
|
|
15
8
|
declare namespace pluginCreator {
|
|
16
|
-
export { postcss,
|
|
9
|
+
export { postcss, PluginOptions, ResolvedOptions };
|
|
17
10
|
}
|
|
18
11
|
declare var postcss: true;
|
|
19
|
-
type
|
|
20
|
-
precision?: number | false;
|
|
21
|
-
preserve?: boolean;
|
|
22
|
-
warnWhenCannotResolve?: boolean;
|
|
23
|
-
mediaQueries?: boolean;
|
|
24
|
-
selectors?: boolean;
|
|
12
|
+
type PluginOptions = {
|
|
13
|
+
precision?: number | false | undefined;
|
|
14
|
+
preserve?: boolean | undefined;
|
|
15
|
+
warnWhenCannotResolve?: boolean | undefined;
|
|
16
|
+
mediaQueries?: boolean | undefined;
|
|
17
|
+
selectors?: boolean | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Invoked when parse/simplify throws. Replaces the default `result.warn`.
|
|
20
|
+
*/
|
|
21
|
+
onParseError?: ((error: Error, input: string) => void) | undefined;
|
|
25
22
|
};
|
|
23
|
+
type ResolvedOptions = Required<Omit<PluginOptions, "onParseError">> & Pick<PluginOptions, "onParseError">;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type BaseType = "length" | "angle" | "time" | "frequency" | "resolution" | "flex" | "percentage";
|
|
2
|
+
/**
|
|
3
|
+
* @param {string} unit
|
|
4
|
+
* @return {BaseType | null}
|
|
5
|
+
*/
|
|
6
|
+
export function baseOf(unit: string): BaseType | null;
|
|
7
|
+
/**
|
|
8
|
+
* Convert a value within a single conversion family. Returns null when
|
|
9
|
+
* either unit is missing from the table (em/rem/vw need runtime context)
|
|
10
|
+
* or when the units belong to different base types.
|
|
11
|
+
* @param {number} value
|
|
12
|
+
* @param {string} from
|
|
13
|
+
* @param {string} to
|
|
14
|
+
* @return {number | null}
|
|
15
|
+
*/
|
|
16
|
+
export function convert(value: number, from: string, to: string): number | null;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export type Num = {
|
|
2
|
+
type: "Num";
|
|
3
|
+
value: number;
|
|
4
|
+
};
|
|
5
|
+
export type Dim = {
|
|
6
|
+
type: "Dim";
|
|
7
|
+
value: number;
|
|
8
|
+
unit: string;
|
|
9
|
+
};
|
|
10
|
+
export type Ident = {
|
|
11
|
+
type: "Ident";
|
|
12
|
+
name: string;
|
|
13
|
+
};
|
|
14
|
+
export type Call = {
|
|
15
|
+
type: "Call";
|
|
16
|
+
name: string;
|
|
17
|
+
args: Node[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Sign is always +1 when node is Num or Dim.
|
|
21
|
+
*/
|
|
22
|
+
export type SumTerm = {
|
|
23
|
+
sign: 1 | -1;
|
|
24
|
+
node: Node;
|
|
25
|
+
};
|
|
26
|
+
export type Sum = {
|
|
27
|
+
type: "Sum";
|
|
28
|
+
terms: SumTerm[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* exponent +1 = numerator, -1 = denominator.
|
|
32
|
+
*/
|
|
33
|
+
export type ProductFactor = {
|
|
34
|
+
exponent: 1 | -1;
|
|
35
|
+
node: Node;
|
|
36
|
+
};
|
|
37
|
+
export type Product = {
|
|
38
|
+
type: "Product";
|
|
39
|
+
factors: ProductFactor[];
|
|
40
|
+
};
|
|
41
|
+
export type Node = Num | Dim | Ident | Call | Sum | Product;
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {{type: 'Num', value: number}} Num
|
|
44
|
+
* @typedef {{type: 'Dim', value: number, unit: string}} Dim
|
|
45
|
+
* @typedef {{type: 'Ident', name: string}} Ident
|
|
46
|
+
* @typedef {{type: 'Call', name: string, args: Node[]}} Call
|
|
47
|
+
* @typedef {{sign: 1 | -1, node: Node}} SumTerm Sign is always +1 when node is Num or Dim.
|
|
48
|
+
* @typedef {{type: 'Sum', terms: SumTerm[]}} Sum
|
|
49
|
+
* @typedef {{exponent: 1 | -1, node: Node}} ProductFactor exponent +1 = numerator, -1 = denominator.
|
|
50
|
+
* @typedef {{type: 'Product', factors: ProductFactor[]}} Product
|
|
51
|
+
* @typedef {Num | Dim | Ident | Call | Sum | Product} Node
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* @param {number} value
|
|
55
|
+
* @return {Num}
|
|
56
|
+
*/
|
|
57
|
+
export function num(value: number): Num;
|
|
58
|
+
/**
|
|
59
|
+
* @param {number} value
|
|
60
|
+
* @param {string} unit
|
|
61
|
+
* @return {Dim}
|
|
62
|
+
*/
|
|
63
|
+
export function dim(value: number, unit: string): Dim;
|
|
64
|
+
/**
|
|
65
|
+
* @param {string} name
|
|
66
|
+
* @return {Ident}
|
|
67
|
+
*/
|
|
68
|
+
export function ident(name: string): Ident;
|
|
69
|
+
/**
|
|
70
|
+
* @param {string} name
|
|
71
|
+
* @param {Node[]} args
|
|
72
|
+
* @return {Call}
|
|
73
|
+
*/
|
|
74
|
+
export function call(name: string, args: Node[]): Call;
|
|
75
|
+
/**
|
|
76
|
+
* @param {SumTerm[]} rawTerms
|
|
77
|
+
* @return {Node}
|
|
78
|
+
*/
|
|
79
|
+
export function mkSum(rawTerms: SumTerm[]): Node;
|
|
80
|
+
/**
|
|
81
|
+
* @param {ProductFactor[]} rawFactors
|
|
82
|
+
* @return {Node}
|
|
83
|
+
*/
|
|
84
|
+
export function mkProduct(rawFactors: ProductFactor[]): Node;
|
|
85
|
+
/**
|
|
86
|
+
* Negate any node, preserving canonical form.
|
|
87
|
+
* @param {Node} node
|
|
88
|
+
* @return {Node}
|
|
89
|
+
*/
|
|
90
|
+
export function negate(node: Node): Node;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type Token = import("./tokenizer.js").Token;
|
|
2
|
+
export type TokenType = import("./tokenizer.js").TokenType;
|
|
3
|
+
export type Node = import("./node.js").Node;
|
|
4
|
+
export type PrefixParselet = (p: Parser, token: Token) => Node;
|
|
5
|
+
export type InfixParselet = {
|
|
6
|
+
lbp: number;
|
|
7
|
+
parse: (p: Parser, left: Node, token: Token) => Node;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* @param {Token[]} tokens
|
|
11
|
+
* @return {Node}
|
|
12
|
+
*/
|
|
13
|
+
export function parse(tokens: Token[]): Node;
|
|
14
|
+
declare class Parser {
|
|
15
|
+
/**
|
|
16
|
+
* @param {Token[]} tokens
|
|
17
|
+
*/
|
|
18
|
+
constructor(tokens: Token[]);
|
|
19
|
+
/** @private */
|
|
20
|
+
private i;
|
|
21
|
+
/** @private @readonly */
|
|
22
|
+
private readonly tokens;
|
|
23
|
+
/** @return {Token} */
|
|
24
|
+
peek(): Token;
|
|
25
|
+
/** @return {Token} */
|
|
26
|
+
next(): Token;
|
|
27
|
+
/**
|
|
28
|
+
* @param {TokenType} type
|
|
29
|
+
* @param {string} [value]
|
|
30
|
+
* @return {Token}
|
|
31
|
+
*/
|
|
32
|
+
expect(type: TokenType, value?: string): Token;
|
|
33
|
+
/**
|
|
34
|
+
* @param {number} [minBp]
|
|
35
|
+
* @return {Node}
|
|
36
|
+
*/
|
|
37
|
+
parseExpr(minBp?: number): Node;
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type Node = import("./node.js").Node;
|
|
2
|
+
export type Sum = import("./node.js").Sum;
|
|
3
|
+
export type Product = import("./node.js").Product;
|
|
4
|
+
export type ProductFactor = import("./node.js").ProductFactor;
|
|
5
|
+
export type SerializeOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* Decimal places for numbers. `false` disables rounding. Default 5.
|
|
8
|
+
*/
|
|
9
|
+
precision?: number | false | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Wrapper name to use when `calc()` is needed. Default `'calc'`.
|
|
12
|
+
*/
|
|
13
|
+
calcName?: string | undefined;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* @param {Node} node
|
|
17
|
+
* @param {SerializeOptions} [opts]
|
|
18
|
+
* @return {string}
|
|
19
|
+
*/
|
|
20
|
+
export function serialize(node: Node, opts?: SerializeOptions): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type UnitBucket = {
|
|
2
|
+
unit: string;
|
|
3
|
+
total: number;
|
|
4
|
+
base: import("../convertUnits.js").BaseType | null;
|
|
5
|
+
order: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {object} UnitBucket
|
|
9
|
+
* @property {string} unit
|
|
10
|
+
* @property {number} total
|
|
11
|
+
* @property {import('../convertUnits.js').BaseType | null} base
|
|
12
|
+
* @property {number} order
|
|
13
|
+
*/
|
|
14
|
+
/** Mutates `buckets` in place — totals of survivor buckets accumulate the
|
|
15
|
+
* converted values of merged neighbors. Caller must not reuse the input.
|
|
16
|
+
* @param {UnitBucket[]} buckets
|
|
17
|
+
* @return {UnitBucket[]}
|
|
18
|
+
*/
|
|
19
|
+
export function mergeConvertibleBuckets(buckets: UnitBucket[]): UnitBucket[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Node = import("../node.js").Node;
|
|
2
|
+
export type SimplifyFn = import("../simplify.js").SimplifyFn;
|
|
3
|
+
/** @typedef {import('../node.js').Node} Node */
|
|
4
|
+
/** @typedef {import('../simplify.js').SimplifyFn} SimplifyFn */
|
|
5
|
+
/**
|
|
6
|
+
* @param {Extract<Node, { type: 'Call' }>} node
|
|
7
|
+
* @param {SimplifyFn} simplify
|
|
8
|
+
* @return {Node}
|
|
9
|
+
*/
|
|
10
|
+
export function simplifyCall(node: Extract<Node, {
|
|
11
|
+
type: "Call";
|
|
12
|
+
}>, simplify: SimplifyFn): Node;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* If `dims` contain exactly one numerator / one denominator pair with the
|
|
3
|
+
* same base type and convertible units, return the numeric factor produced
|
|
4
|
+
* by cancelling them and the list of remaining (uncancelled) dims.
|
|
5
|
+
* Otherwise return null. Used by `simplifyProduct` for typed division
|
|
6
|
+
* (§10.2). More complex cancellation (e.g. `px^2 / px`) is left
|
|
7
|
+
* unreduced — consumers rarely rely on it and the spec doesn't require it.
|
|
8
|
+
* @template {{ exponent: 1 | -1, value: number, unit: string }} D
|
|
9
|
+
* @param {D[]} dims
|
|
10
|
+
* @return {{ factor: number, remaining: D[] } | null}
|
|
11
|
+
*/
|
|
12
|
+
export function tryCancelPair<D extends {
|
|
13
|
+
exponent: 1 | -1;
|
|
14
|
+
value: number;
|
|
15
|
+
unit: string;
|
|
16
|
+
}>(dims: D[]): {
|
|
17
|
+
factor: number;
|
|
18
|
+
remaining: D[];
|
|
19
|
+
} | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Node = import("../node.js").Node;
|
|
2
|
+
export type BaseType = import("../convertUnits.js").BaseType;
|
|
3
|
+
/** @typedef {import('../node.js').Node} Node */
|
|
4
|
+
/** @typedef {import('../convertUnits.js').BaseType} BaseType */
|
|
5
|
+
/**
|
|
6
|
+
* @param {Node[]} args
|
|
7
|
+
* @return {{ values: number[], unit: string } | null}
|
|
8
|
+
*/
|
|
9
|
+
export function foldConstArgs(args: Node[]): {
|
|
10
|
+
values: number[];
|
|
11
|
+
unit: string;
|
|
12
|
+
} | null;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type Node = import("../node.js").Node;
|
|
2
|
+
export type Product = import("../node.js").Product;
|
|
3
|
+
export type ProductFactor = import("../node.js").ProductFactor;
|
|
4
|
+
export type SimplifyFn = import("../simplify.js").SimplifyFn;
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {import('../node.js').Node} Node
|
|
7
|
+
* @typedef {import('../node.js').Product} Product
|
|
8
|
+
* @typedef {import('../node.js').ProductFactor} ProductFactor
|
|
9
|
+
* @typedef {import('../simplify.js').SimplifyFn} SimplifyFn
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* @param {Product} product
|
|
13
|
+
* @param {SimplifyFn} simplify
|
|
14
|
+
* @return {Node}
|
|
15
|
+
*/
|
|
16
|
+
export function simplifyProduct(product: Product, simplify: SimplifyFn): Node;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type RoundStrategy = "nearest" | "up" | "down" | "to-zero";
|
|
2
|
+
export type Node = import("../node.js").Node;
|
|
3
|
+
/** @typedef {'nearest' | 'up' | 'down' | 'to-zero'} RoundStrategy */
|
|
4
|
+
/**
|
|
5
|
+
* @param {Node[]} args
|
|
6
|
+
* @return {Node}
|
|
7
|
+
*/
|
|
8
|
+
export function simplifyRound(args: Node[]): Node;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type Node = import("../node.js").Node;
|
|
2
|
+
export type Sum = import("../node.js").Sum;
|
|
3
|
+
export type SumTerm = import("../node.js").SumTerm;
|
|
4
|
+
export type SimplifyFn = import("../simplify.js").SimplifyFn;
|
|
5
|
+
export type UnitBucket = import("./bucket.js").UnitBucket;
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('../node.js').Node} Node
|
|
8
|
+
* @typedef {import('../node.js').Sum} Sum
|
|
9
|
+
* @typedef {import('../node.js').SumTerm} SumTerm
|
|
10
|
+
* @typedef {import('../simplify.js').SimplifyFn} SimplifyFn
|
|
11
|
+
* @typedef {import('./bucket.js').UnitBucket} UnitBucket
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @param {Sum} sum
|
|
15
|
+
* @param {SimplifyFn} simplify
|
|
16
|
+
* @return {Node}
|
|
17
|
+
*/
|
|
18
|
+
export function simplifySum(sum: Sum, simplify: SimplifyFn): Node;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursive simplifier reference, threaded into Sum/Product/Call. Lets
|
|
3
|
+
* leaf fold modules avoid circular imports of the entry function.
|
|
4
|
+
*/
|
|
5
|
+
export type Node = import("./node.js").Node;
|
|
6
|
+
export type SimplifyFn = (node: Node) => Node;
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('./node.js').Node} Node
|
|
9
|
+
*
|
|
10
|
+
* Recursive simplifier reference, threaded into Sum/Product/Call. Lets
|
|
11
|
+
* leaf fold modules avoid circular imports of the entry function.
|
|
12
|
+
* @typedef {(node: Node) => Node} SimplifyFn
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* @param {Node} node
|
|
16
|
+
* @return {Node}
|
|
17
|
+
*/
|
|
18
|
+
export function simplify(node: Node): Node;
|