@regmisatyam/retex 0.1.0 → 0.2.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 +189 -37
- package/dist/index-DJEasLJc.d.ts +492 -0
- package/dist/index-DXTDYNCI.d.cts +492 -0
- package/dist/index.cjs +1198 -591
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +196 -358
- package/dist/index.d.ts +196 -358
- package/dist/index.js +1166 -592
- package/dist/index.js.map +1 -1
- package/dist/library.cjs +649 -0
- package/dist/library.cjs.map +1 -0
- package/dist/library.d.cts +2 -0
- package/dist/library.d.ts +2 -0
- package/dist/library.js +625 -0
- package/dist/library.js.map +1 -0
- package/dist/{react-v8gyKEAs.d.cts → react-B3tN1iWa.d.cts} +74 -38
- package/dist/{react-v8gyKEAs.d.ts → react-B3tN1iWa.d.ts} +74 -38
- package/dist/react.cjs +113 -74
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +113 -74
- package/dist/react.js.map +1 -1
- package/package.json +7 -1
package/dist/library.cjs
ADDED
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/security/sanitize.ts
|
|
4
|
+
function isSafeColor(value) {
|
|
5
|
+
const v = value.trim();
|
|
6
|
+
if (/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v)) return true;
|
|
7
|
+
if (/^(rgb|rgba|hsl|hsla)\(\s*[0-9.,%\s/]+\)$/i.test(v)) return true;
|
|
8
|
+
return CSS_NAMED_COLORS.has(v.toLowerCase());
|
|
9
|
+
}
|
|
10
|
+
function isSafeDimension(value) {
|
|
11
|
+
return /^-?\d*\.?\d+(px|pt|em|rem|ex|ch|vw|vh|vmin|vmax|cm|mm|in|pc|%|fr)?$/.test(
|
|
12
|
+
value.trim()
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
var CSS_NAMED_COLORS = /* @__PURE__ */ new Set([
|
|
16
|
+
"black",
|
|
17
|
+
"silver",
|
|
18
|
+
"gray",
|
|
19
|
+
"grey",
|
|
20
|
+
"white",
|
|
21
|
+
"maroon",
|
|
22
|
+
"red",
|
|
23
|
+
"purple",
|
|
24
|
+
"fuchsia",
|
|
25
|
+
"green",
|
|
26
|
+
"lime",
|
|
27
|
+
"olive",
|
|
28
|
+
"yellow",
|
|
29
|
+
"navy",
|
|
30
|
+
"blue",
|
|
31
|
+
"teal",
|
|
32
|
+
"aqua",
|
|
33
|
+
"cyan",
|
|
34
|
+
"magenta",
|
|
35
|
+
"orange",
|
|
36
|
+
"pink",
|
|
37
|
+
"brown",
|
|
38
|
+
"gold",
|
|
39
|
+
"indigo",
|
|
40
|
+
"violet",
|
|
41
|
+
"tan",
|
|
42
|
+
"beige",
|
|
43
|
+
"ivory",
|
|
44
|
+
"coral",
|
|
45
|
+
"salmon",
|
|
46
|
+
"khaki",
|
|
47
|
+
"crimson",
|
|
48
|
+
"turquoise",
|
|
49
|
+
"lavender",
|
|
50
|
+
"plum",
|
|
51
|
+
"orchid",
|
|
52
|
+
"slateblue",
|
|
53
|
+
"slategray",
|
|
54
|
+
"steelblue",
|
|
55
|
+
"skyblue",
|
|
56
|
+
"royalblue",
|
|
57
|
+
"midnightblue",
|
|
58
|
+
"darkblue",
|
|
59
|
+
"darkgreen",
|
|
60
|
+
"darkred",
|
|
61
|
+
"darkgray",
|
|
62
|
+
"darkgrey",
|
|
63
|
+
"lightgray",
|
|
64
|
+
"lightgrey",
|
|
65
|
+
"lightblue",
|
|
66
|
+
"transparent",
|
|
67
|
+
"currentcolor",
|
|
68
|
+
"inherit"
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
// src/library/colors.ts
|
|
72
|
+
var zero = { offset: 0, line: 1, column: 1 };
|
|
73
|
+
var ZERO_RANGE = { start: zero, end: zero };
|
|
74
|
+
var colorCommands = [
|
|
75
|
+
{
|
|
76
|
+
name: "textcolor",
|
|
77
|
+
category: "inline",
|
|
78
|
+
args: [
|
|
79
|
+
{ kind: "string", name: "color", format: "color" },
|
|
80
|
+
{ kind: "content", name: "content" }
|
|
81
|
+
],
|
|
82
|
+
summary: "Color text with a hex/named color.",
|
|
83
|
+
example: "\\textcolor{#2563eb}{OpenAI}",
|
|
84
|
+
build: ({ args, utils, report }) => {
|
|
85
|
+
const color = utils.textOf(args[0]).trim();
|
|
86
|
+
if (color && !isSafeColor(color)) {
|
|
87
|
+
report({
|
|
88
|
+
severity: "warning" /* Warning */,
|
|
89
|
+
code: "RTX3001" /* InvalidColor */,
|
|
90
|
+
message: `"${color}" is not a recognized color; it will be ignored.`,
|
|
91
|
+
range: args[0]?.range ?? ZERO_RANGE
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
type: "color",
|
|
96
|
+
color: isSafeColor(color) ? color : "",
|
|
97
|
+
children: args[1]?.children ?? []
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "themecolor",
|
|
103
|
+
category: "inline",
|
|
104
|
+
args: [
|
|
105
|
+
{ kind: "string", name: "token" },
|
|
106
|
+
{ kind: "content", name: "content" }
|
|
107
|
+
],
|
|
108
|
+
summary: "Color text using a token from the active theme.",
|
|
109
|
+
example: "\\themecolor{primary}{Highlighted}",
|
|
110
|
+
build: ({ args, utils }) => ({
|
|
111
|
+
type: "themecolor",
|
|
112
|
+
token: utils.textOf(args[0]).trim() || "primary",
|
|
113
|
+
children: args[1]?.children ?? []
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
];
|
|
117
|
+
var palettes = {
|
|
118
|
+
slate: {
|
|
119
|
+
primary: "#0f172a",
|
|
120
|
+
secondary: "#475569",
|
|
121
|
+
text: "#1e293b",
|
|
122
|
+
muted: "#64748b",
|
|
123
|
+
border: "#cbd5e1",
|
|
124
|
+
accent: "#0f172a"
|
|
125
|
+
},
|
|
126
|
+
blue: {
|
|
127
|
+
primary: "#2563eb",
|
|
128
|
+
secondary: "#64748b",
|
|
129
|
+
text: "#1e293b",
|
|
130
|
+
muted: "#64748b",
|
|
131
|
+
border: "#e2e8f0",
|
|
132
|
+
accent: "#2563eb"
|
|
133
|
+
},
|
|
134
|
+
violet: {
|
|
135
|
+
primary: "#7c3aed",
|
|
136
|
+
secondary: "#6b7280",
|
|
137
|
+
text: "#111827",
|
|
138
|
+
muted: "#6b7280",
|
|
139
|
+
border: "#e5e7eb",
|
|
140
|
+
accent: "#7c3aed"
|
|
141
|
+
},
|
|
142
|
+
emerald: {
|
|
143
|
+
primary: "#059669",
|
|
144
|
+
secondary: "#6b7280",
|
|
145
|
+
text: "#111827",
|
|
146
|
+
muted: "#6b7280",
|
|
147
|
+
border: "#d1fae5",
|
|
148
|
+
accent: "#059669"
|
|
149
|
+
},
|
|
150
|
+
rose: {
|
|
151
|
+
primary: "#e11d48",
|
|
152
|
+
secondary: "#6b7280",
|
|
153
|
+
text: "#111827",
|
|
154
|
+
muted: "#6b7280",
|
|
155
|
+
border: "#fecdd3",
|
|
156
|
+
accent: "#e11d48"
|
|
157
|
+
},
|
|
158
|
+
amber: {
|
|
159
|
+
primary: "#d97706",
|
|
160
|
+
secondary: "#6b7280",
|
|
161
|
+
text: "#111827",
|
|
162
|
+
muted: "#6b7280",
|
|
163
|
+
border: "#fde68a",
|
|
164
|
+
accent: "#d97706"
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
var colorsLibrary = {
|
|
168
|
+
name: "colors",
|
|
169
|
+
summary: "Text color (\\textcolor, \\themecolor) and named palettes.",
|
|
170
|
+
commands: colorCommands
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// src/library/fonts.ts
|
|
174
|
+
var zero2 = { offset: 0, line: 1, column: 1 };
|
|
175
|
+
var ZERO_RANGE2 = { start: zero2, end: zero2 };
|
|
176
|
+
var scaleSwitch = (name, scale) => ({
|
|
177
|
+
name,
|
|
178
|
+
category: "switch",
|
|
179
|
+
scoped: true,
|
|
180
|
+
summary: `Set the font size to "${name}" for the rest of the group.`,
|
|
181
|
+
example: `{\\${name} ...}`,
|
|
182
|
+
build: ({ scope }) => ({ type: "fontscale", scale, children: scope })
|
|
183
|
+
});
|
|
184
|
+
var fontCommands = [
|
|
185
|
+
{
|
|
186
|
+
name: "fontsize",
|
|
187
|
+
category: "inline",
|
|
188
|
+
args: [
|
|
189
|
+
{ kind: "string", name: "size", format: "dimension" },
|
|
190
|
+
{ kind: "content", name: "content" }
|
|
191
|
+
],
|
|
192
|
+
summary: "Set an explicit font size for the wrapped content.",
|
|
193
|
+
example: "\\fontsize{14pt}{Custom Size}",
|
|
194
|
+
build: ({ args, utils, report }) => {
|
|
195
|
+
const size = utils.textOf(args[0]).trim();
|
|
196
|
+
if (size && !isSafeDimension(size)) {
|
|
197
|
+
report({
|
|
198
|
+
severity: "warning" /* Warning */,
|
|
199
|
+
code: "RTX3003" /* InvalidDimension */,
|
|
200
|
+
message: `"${size}" is not a valid dimension.`,
|
|
201
|
+
range: args[0]?.range ?? ZERO_RANGE2
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
type: "fontsize",
|
|
206
|
+
size: isSafeDimension(size) ? size : "1em",
|
|
207
|
+
children: args[1]?.children ?? []
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: "fontfamily",
|
|
213
|
+
category: "inline",
|
|
214
|
+
args: [
|
|
215
|
+
{ kind: "string", name: "family" },
|
|
216
|
+
{ kind: "content", name: "content" }
|
|
217
|
+
],
|
|
218
|
+
summary: "Set the font family for the wrapped content.",
|
|
219
|
+
example: "\\fontfamily{Georgia}{Serif text}",
|
|
220
|
+
build: ({ args, utils }) => ({
|
|
221
|
+
type: "fontfamily",
|
|
222
|
+
family: utils.textOf(args[0]).trim() || "inherit",
|
|
223
|
+
children: args[1]?.children ?? []
|
|
224
|
+
})
|
|
225
|
+
},
|
|
226
|
+
scaleSwitch("small", "small"),
|
|
227
|
+
scaleSwitch("large", "large"),
|
|
228
|
+
scaleSwitch("Large", "Large"),
|
|
229
|
+
scaleSwitch("Huge", "Huge"),
|
|
230
|
+
{
|
|
231
|
+
name: "normalsize",
|
|
232
|
+
category: "switch",
|
|
233
|
+
scoped: true,
|
|
234
|
+
summary: "Reset the font size to the document base size.",
|
|
235
|
+
build: ({ scope }) => ({ type: "fontscale", scale: "normal", children: scope })
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: "ttfamily",
|
|
239
|
+
category: "switch",
|
|
240
|
+
scoped: true,
|
|
241
|
+
summary: "Switch to a monospace font for the rest of the group.",
|
|
242
|
+
build: ({ scope }) => ({
|
|
243
|
+
type: "fontfamily",
|
|
244
|
+
family: "monospace",
|
|
245
|
+
children: scope
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
];
|
|
249
|
+
var fontStacks = {
|
|
250
|
+
inter: '"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
251
|
+
system: 'system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif',
|
|
252
|
+
helvetica: '"Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
253
|
+
georgia: 'Georgia, "Times New Roman", Times, serif',
|
|
254
|
+
times: '"Times New Roman", Times, serif',
|
|
255
|
+
garamond: '"EB Garamond", Garamond, Georgia, serif',
|
|
256
|
+
spaceGrotesk: '"Space Grotesk", system-ui, sans-serif',
|
|
257
|
+
sourceSerif: '"Source Serif 4", Georgia, serif',
|
|
258
|
+
jetbrainsMono: '"JetBrains Mono", "SF Mono", "Fira Code", Consolas, monospace',
|
|
259
|
+
firaCode: '"Fira Code", "JetBrains Mono", Consolas, monospace',
|
|
260
|
+
ibmPlexMono: '"IBM Plex Mono", "SF Mono", Consolas, monospace'
|
|
261
|
+
};
|
|
262
|
+
function fontTheme(spec) {
|
|
263
|
+
const resolve = (v) => v == null ? void 0 : fontStacks[v] ?? v;
|
|
264
|
+
return {
|
|
265
|
+
heading: resolve(spec.heading),
|
|
266
|
+
body: resolve(spec.body),
|
|
267
|
+
mono: resolve(spec.mono)
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
var fontsLibrary = {
|
|
271
|
+
name: "fonts",
|
|
272
|
+
summary: "Font family & size control (\\fontfamily, \\fontsize, \\small \u2026 \\Huge).",
|
|
273
|
+
commands: fontCommands
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
// src/library/shapes.ts
|
|
277
|
+
var rule = (name, style, summary) => ({
|
|
278
|
+
name,
|
|
279
|
+
category: "block",
|
|
280
|
+
summary,
|
|
281
|
+
example: `\\${name}`,
|
|
282
|
+
build: () => style ? { type: "rule", style } : { type: "rule" }
|
|
283
|
+
});
|
|
284
|
+
var shapeCommands = [
|
|
285
|
+
rule("hrule", "solid", "A horizontal rule / divider."),
|
|
286
|
+
rule("divider", "solid", "A horizontal rule / divider."),
|
|
287
|
+
rule("dashrule", "dashed", "A dashed horizontal rule."),
|
|
288
|
+
rule("dotrule", "dotted", "A dotted horizontal rule."),
|
|
289
|
+
rule("thickrule", "thick", "A thick horizontal rule."),
|
|
290
|
+
rule("doublerule", "double", "A double horizontal rule."),
|
|
291
|
+
{
|
|
292
|
+
name: "vspace",
|
|
293
|
+
category: "block",
|
|
294
|
+
args: [{ kind: "string", name: "size", format: "dimension" }],
|
|
295
|
+
summary: "Vertical space.",
|
|
296
|
+
example: "\\vspace{1em}",
|
|
297
|
+
build: ({ args, utils }) => ({
|
|
298
|
+
type: "space",
|
|
299
|
+
axis: "vertical",
|
|
300
|
+
size: utils.textOf(args[0]).trim() || "1em"
|
|
301
|
+
})
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: "hspace",
|
|
305
|
+
category: "inline",
|
|
306
|
+
args: [{ kind: "string", name: "size", format: "dimension" }],
|
|
307
|
+
summary: "Horizontal space.",
|
|
308
|
+
example: "\\hspace{1em}",
|
|
309
|
+
build: ({ args, utils }) => ({
|
|
310
|
+
type: "space",
|
|
311
|
+
axis: "horizontal",
|
|
312
|
+
size: utils.textOf(args[0]).trim() || "1em"
|
|
313
|
+
})
|
|
314
|
+
}
|
|
315
|
+
];
|
|
316
|
+
var shapesLibrary = {
|
|
317
|
+
name: "shapes",
|
|
318
|
+
summary: "Horizontal rules / dividers (\\hrule, \\dashrule, \u2026) and spacing.",
|
|
319
|
+
commands: shapeCommands
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// src/theme/default.ts
|
|
323
|
+
var blankTheme = {
|
|
324
|
+
name: "blank"
|
|
325
|
+
};
|
|
326
|
+
var defaultTheme = blankTheme;
|
|
327
|
+
|
|
328
|
+
// src/theme/themes.ts
|
|
329
|
+
function resolveTheme(partial, base = defaultTheme) {
|
|
330
|
+
return {
|
|
331
|
+
name: partial?.name ?? base.name,
|
|
332
|
+
colors: { ...base.colors, ...partial?.colors },
|
|
333
|
+
fonts: { ...base.fonts, ...partial?.fonts },
|
|
334
|
+
fontSizes: { ...base.fontSizes, ...partial?.fontSizes },
|
|
335
|
+
spacing: { ...base.spacing, ...partial?.spacing },
|
|
336
|
+
page: { ...base.page, ...partial?.page },
|
|
337
|
+
sectionStyle: partial?.sectionStyle ?? base.sectionStyle,
|
|
338
|
+
headings: { ...base.headings, ...partial?.headings }
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
var styledBase = {
|
|
342
|
+
fonts: {
|
|
343
|
+
heading: '"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
344
|
+
body: '"Inter", "Helvetica Neue", Helvetica, Arial, sans-serif',
|
|
345
|
+
mono: '"JetBrains Mono", "SF Mono", "Fira Code", Consolas, monospace'
|
|
346
|
+
},
|
|
347
|
+
fontSizes: {
|
|
348
|
+
base: "10.5pt",
|
|
349
|
+
small: "9pt",
|
|
350
|
+
large: "12pt",
|
|
351
|
+
Large: "15pt",
|
|
352
|
+
Huge: "22pt",
|
|
353
|
+
name: "26pt",
|
|
354
|
+
section: "13pt"
|
|
355
|
+
},
|
|
356
|
+
spacing: { unit: "4px", section: "1.1rem", item: "0.28rem", page: "0.55in" },
|
|
357
|
+
page: { size: "Letter", margin: "0.55in", maxWidth: "8.5in" },
|
|
358
|
+
headings: { transform: "uppercase", tracking: "0.06em", nameTracking: "-0.01em" }
|
|
359
|
+
};
|
|
360
|
+
var modernTheme = resolveTheme({
|
|
361
|
+
...styledBase,
|
|
362
|
+
name: "modern",
|
|
363
|
+
colors: {
|
|
364
|
+
primary: "#7c3aed",
|
|
365
|
+
secondary: "#64748b",
|
|
366
|
+
text: "#111827",
|
|
367
|
+
muted: "#64748b",
|
|
368
|
+
background: "#ffffff",
|
|
369
|
+
border: "#e2e8f0",
|
|
370
|
+
accent: "#7c3aed"
|
|
371
|
+
},
|
|
372
|
+
sectionStyle: "underline"
|
|
373
|
+
});
|
|
374
|
+
var classicTheme = resolveTheme({
|
|
375
|
+
...styledBase,
|
|
376
|
+
name: "classic",
|
|
377
|
+
colors: {
|
|
378
|
+
primary: "#111827",
|
|
379
|
+
secondary: "#4b5563",
|
|
380
|
+
text: "#1e293b",
|
|
381
|
+
muted: "#4b5563",
|
|
382
|
+
background: "#ffffff",
|
|
383
|
+
border: "#cbd5e1",
|
|
384
|
+
accent: "#111827"
|
|
385
|
+
},
|
|
386
|
+
fonts: {
|
|
387
|
+
heading: 'Georgia, "Times New Roman", serif',
|
|
388
|
+
body: 'Georgia, "Times New Roman", serif',
|
|
389
|
+
mono: 'Consolas, "Courier New", monospace'
|
|
390
|
+
},
|
|
391
|
+
sectionStyle: "rule"
|
|
392
|
+
});
|
|
393
|
+
var compactTheme = resolveTheme({
|
|
394
|
+
...styledBase,
|
|
395
|
+
name: "compact",
|
|
396
|
+
colors: {
|
|
397
|
+
primary: "#2563eb",
|
|
398
|
+
secondary: "#64748b",
|
|
399
|
+
text: "#1e293b",
|
|
400
|
+
muted: "#64748b",
|
|
401
|
+
background: "#ffffff",
|
|
402
|
+
border: "#e2e8f0",
|
|
403
|
+
accent: "#2563eb"
|
|
404
|
+
},
|
|
405
|
+
fontSizes: {
|
|
406
|
+
base: "9.5pt",
|
|
407
|
+
small: "8pt",
|
|
408
|
+
large: "11pt",
|
|
409
|
+
Large: "13pt",
|
|
410
|
+
Huge: "18pt",
|
|
411
|
+
name: "20pt",
|
|
412
|
+
section: "11pt"
|
|
413
|
+
},
|
|
414
|
+
spacing: { unit: "3px", section: "0.7rem", item: "0.18rem", page: "0.4in" },
|
|
415
|
+
sectionStyle: "bar"
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// src/library/themes.ts
|
|
419
|
+
var stylingCommands = [...colorCommands, ...fontCommands, ...shapeCommands];
|
|
420
|
+
var modernLibrary = {
|
|
421
|
+
name: "modern",
|
|
422
|
+
summary: "A modern, accent-forward theme (violet, underlined headings).",
|
|
423
|
+
theme: modernTheme,
|
|
424
|
+
commands: stylingCommands
|
|
425
|
+
};
|
|
426
|
+
var classicLibrary = {
|
|
427
|
+
name: "classic",
|
|
428
|
+
summary: "A classic serif theme with ruled section headings.",
|
|
429
|
+
theme: classicTheme,
|
|
430
|
+
commands: stylingCommands
|
|
431
|
+
};
|
|
432
|
+
var compactLibrary = {
|
|
433
|
+
name: "compact",
|
|
434
|
+
summary: "A compact, single-accent theme maximizing content density.",
|
|
435
|
+
theme: compactTheme,
|
|
436
|
+
commands: stylingCommands
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
// src/types/ast.ts
|
|
440
|
+
function isParent(node) {
|
|
441
|
+
return Array.isArray(node.children);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// src/ast/walk.ts
|
|
445
|
+
function childrenOf(node) {
|
|
446
|
+
if (node.type === "list") return node.items;
|
|
447
|
+
if (node.type === "columns") return node.columns;
|
|
448
|
+
if (isParent(node)) return node.children;
|
|
449
|
+
return [];
|
|
450
|
+
}
|
|
451
|
+
function walk(root, opts) {
|
|
452
|
+
const visit = (node, parent) => {
|
|
453
|
+
const descend = opts.enter ? opts.enter(node, parent) : void 0;
|
|
454
|
+
if (descend !== false) {
|
|
455
|
+
for (const child of childrenOf(node)) visit(child, node);
|
|
456
|
+
}
|
|
457
|
+
opts.exit?.(node, parent);
|
|
458
|
+
};
|
|
459
|
+
visit(root, null);
|
|
460
|
+
}
|
|
461
|
+
function collect(root, pred) {
|
|
462
|
+
const out = [];
|
|
463
|
+
walk(root, {
|
|
464
|
+
enter(n) {
|
|
465
|
+
if (pred(n)) out.push(n);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
return out;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// src/library/registry.ts
|
|
472
|
+
var builtinLibraries = {
|
|
473
|
+
colors: colorsLibrary,
|
|
474
|
+
fonts: fontsLibrary,
|
|
475
|
+
shapes: shapesLibrary,
|
|
476
|
+
modern: modernLibrary,
|
|
477
|
+
classic: classicLibrary,
|
|
478
|
+
compact: compactLibrary
|
|
479
|
+
};
|
|
480
|
+
var ALIASES = {
|
|
481
|
+
color: "colors",
|
|
482
|
+
font: "fonts",
|
|
483
|
+
shape: "shapes"
|
|
484
|
+
};
|
|
485
|
+
function resolveLibraryName(name) {
|
|
486
|
+
const key = name.trim().toLowerCase();
|
|
487
|
+
if (builtinLibraries[key]) return key;
|
|
488
|
+
if (ALIASES[key]) return ALIASES[key];
|
|
489
|
+
return void 0;
|
|
490
|
+
}
|
|
491
|
+
function getBuiltinLibrary(name) {
|
|
492
|
+
const key = resolveLibraryName(name);
|
|
493
|
+
return key ? builtinLibraries[key] : void 0;
|
|
494
|
+
}
|
|
495
|
+
function builtinLibraryNames() {
|
|
496
|
+
return Object.keys(builtinLibraries);
|
|
497
|
+
}
|
|
498
|
+
var GATED_COMMANDS = (() => {
|
|
499
|
+
const map = {};
|
|
500
|
+
const add = (lib) => {
|
|
501
|
+
for (const c of lib.commands ?? []) map[c.name] = lib.name;
|
|
502
|
+
};
|
|
503
|
+
add(colorsLibrary);
|
|
504
|
+
add(fontsLibrary);
|
|
505
|
+
add(shapesLibrary);
|
|
506
|
+
return map;
|
|
507
|
+
})();
|
|
508
|
+
var dedupe = (names) => [...new Set(names)];
|
|
509
|
+
function usedLibraryNamesFromTokens(tokens) {
|
|
510
|
+
const names = [];
|
|
511
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
512
|
+
const t = tokens[i];
|
|
513
|
+
if (t.type !== "Command" /* Command */ || t.value !== "usepackage" && t.value !== "use") {
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
let j = i + 1;
|
|
517
|
+
while (tokens[j] && (tokens[j].type === "Whitespace" /* Whitespace */ || tokens[j].type === "Comment" /* Comment */)) {
|
|
518
|
+
j++;
|
|
519
|
+
}
|
|
520
|
+
if (!tokens[j] || tokens[j].type !== "LBrace" /* LBrace */) continue;
|
|
521
|
+
j++;
|
|
522
|
+
let raw = "";
|
|
523
|
+
let depth = 0;
|
|
524
|
+
while (tokens[j] && !(depth === 0 && tokens[j].type === "RBrace" /* RBrace */)) {
|
|
525
|
+
const tj = tokens[j];
|
|
526
|
+
if (tj.type === "LBrace" /* LBrace */) depth++;
|
|
527
|
+
else if (tj.type === "RBrace" /* RBrace */) depth--;
|
|
528
|
+
raw += tj.type === "Command" /* Command */ ? `\\${tj.value}` : tj.value;
|
|
529
|
+
j++;
|
|
530
|
+
}
|
|
531
|
+
for (const part of raw.split(",")) {
|
|
532
|
+
const name = part.trim();
|
|
533
|
+
if (name) names.push(name);
|
|
534
|
+
}
|
|
535
|
+
i = j;
|
|
536
|
+
}
|
|
537
|
+
return dedupe(names);
|
|
538
|
+
}
|
|
539
|
+
function usedLibraryNamesFromAst(root) {
|
|
540
|
+
const names = [];
|
|
541
|
+
for (const node of collect(root, (n) => n.type === "usepackage")) {
|
|
542
|
+
for (const name of node.names) {
|
|
543
|
+
const trimmed = name.trim();
|
|
544
|
+
if (trimmed) names.push(trimmed);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return dedupe(names);
|
|
548
|
+
}
|
|
549
|
+
function applyLibraries(base, names, lookup = getBuiltinLibrary) {
|
|
550
|
+
const registry = base.clone();
|
|
551
|
+
const libraries = [];
|
|
552
|
+
const missing = [];
|
|
553
|
+
for (const name of names) {
|
|
554
|
+
const lib = lookup(name);
|
|
555
|
+
if (!lib) {
|
|
556
|
+
missing.push(name);
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
libraries.push(lib);
|
|
560
|
+
for (const cmd of lib.commands ?? []) registry.registerCommand(cmd);
|
|
561
|
+
for (const env of lib.environments ?? []) registry.registerEnvironment(env);
|
|
562
|
+
}
|
|
563
|
+
return { registry, libraries, missing };
|
|
564
|
+
}
|
|
565
|
+
function mergeLibraryTheme(base, libraries) {
|
|
566
|
+
let theme = base;
|
|
567
|
+
for (const lib of libraries) {
|
|
568
|
+
if (lib.theme) theme = resolveTheme(lib.theme, theme);
|
|
569
|
+
}
|
|
570
|
+
return theme;
|
|
571
|
+
}
|
|
572
|
+
var ZERO_RANGE3 = {
|
|
573
|
+
start: { offset: 0, line: 1, column: 1 },
|
|
574
|
+
end: { offset: 0, line: 1, column: 1 }
|
|
575
|
+
};
|
|
576
|
+
function libraryDiagnostics(ast, diagnostics, lookup = getBuiltinLibrary) {
|
|
577
|
+
const gated = collect(
|
|
578
|
+
ast,
|
|
579
|
+
(n) => n.type === "command" && n.name in GATED_COMMANDS
|
|
580
|
+
);
|
|
581
|
+
const gatedOffsets = new Set(
|
|
582
|
+
gated.map((n) => n.range?.start.offset).filter((o) => o != null)
|
|
583
|
+
);
|
|
584
|
+
const out = diagnostics.filter(
|
|
585
|
+
(d) => !(d.code === "RTX2001" /* UnknownCommand */ && gatedOffsets.has(d.range.start.offset))
|
|
586
|
+
);
|
|
587
|
+
for (const node of gated) {
|
|
588
|
+
const lib = GATED_COMMANDS[node.name];
|
|
589
|
+
out.push({
|
|
590
|
+
source: "parser",
|
|
591
|
+
severity: "warning" /* Warning */,
|
|
592
|
+
code: "RTX4005" /* LibraryRequired */,
|
|
593
|
+
message: `\\${node.name} requires the "${lib}" library. Add \\usepackage{${lib}} to the preamble (or engine.use(${lib}Library)).`,
|
|
594
|
+
range: node.range ?? ZERO_RANGE3
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
for (const node of collect(ast, (n) => n.type === "usepackage")) {
|
|
598
|
+
for (const name of node.names) {
|
|
599
|
+
if (lookup(name)) continue;
|
|
600
|
+
out.push({
|
|
601
|
+
source: "parser",
|
|
602
|
+
severity: "warning" /* Warning */,
|
|
603
|
+
code: "RTX4004" /* UnknownLibrary */,
|
|
604
|
+
message: `Unknown library "${name}". Available: ${builtinLibraryNames().join(", ")}.`,
|
|
605
|
+
range: node.range ?? ZERO_RANGE3
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return out;
|
|
610
|
+
}
|
|
611
|
+
function collectLibraryOverrides(libraries) {
|
|
612
|
+
const html = /* @__PURE__ */ new Map();
|
|
613
|
+
const react = /* @__PURE__ */ new Map();
|
|
614
|
+
for (const lib of libraries) {
|
|
615
|
+
for (const cmd of lib.commands ?? []) {
|
|
616
|
+
if (cmd.render?.html) html.set(`command:${cmd.name}`, cmd.render.html);
|
|
617
|
+
if (cmd.render?.react) react.set(`command:${cmd.name}`, cmd.render.react);
|
|
618
|
+
}
|
|
619
|
+
for (const [k, fn] of Object.entries(lib.htmlRenderers ?? {})) html.set(k, fn);
|
|
620
|
+
for (const [k, fn] of Object.entries(lib.reactRenderers ?? {})) react.set(k, fn);
|
|
621
|
+
}
|
|
622
|
+
return { html, react };
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
exports.GATED_COMMANDS = GATED_COMMANDS;
|
|
626
|
+
exports.applyLibraries = applyLibraries;
|
|
627
|
+
exports.builtinLibraries = builtinLibraries;
|
|
628
|
+
exports.builtinLibraryNames = builtinLibraryNames;
|
|
629
|
+
exports.classicLibrary = classicLibrary;
|
|
630
|
+
exports.collectLibraryOverrides = collectLibraryOverrides;
|
|
631
|
+
exports.colorCommands = colorCommands;
|
|
632
|
+
exports.colorsLibrary = colorsLibrary;
|
|
633
|
+
exports.compactLibrary = compactLibrary;
|
|
634
|
+
exports.fontCommands = fontCommands;
|
|
635
|
+
exports.fontStacks = fontStacks;
|
|
636
|
+
exports.fontTheme = fontTheme;
|
|
637
|
+
exports.fontsLibrary = fontsLibrary;
|
|
638
|
+
exports.getBuiltinLibrary = getBuiltinLibrary;
|
|
639
|
+
exports.libraryDiagnostics = libraryDiagnostics;
|
|
640
|
+
exports.mergeLibraryTheme = mergeLibraryTheme;
|
|
641
|
+
exports.modernLibrary = modernLibrary;
|
|
642
|
+
exports.palettes = palettes;
|
|
643
|
+
exports.resolveLibraryName = resolveLibraryName;
|
|
644
|
+
exports.shapeCommands = shapeCommands;
|
|
645
|
+
exports.shapesLibrary = shapesLibrary;
|
|
646
|
+
exports.usedLibraryNamesFromAst = usedLibraryNamesFromAst;
|
|
647
|
+
exports.usedLibraryNamesFromTokens = usedLibraryNamesFromTokens;
|
|
648
|
+
//# sourceMappingURL=library.cjs.map
|
|
649
|
+
//# sourceMappingURL=library.cjs.map
|