@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/index.d.ts
CHANGED
|
@@ -1,226 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { d as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Token kinds produced by the {@link Tokenizer}.
|
|
6
|
-
*
|
|
7
|
-
* ReTeX intentionally diverges from TeX in a few places that matter for
|
|
8
|
-
* resumes:
|
|
9
|
-
* - `%` is a *literal* percent sign (so `Reduced latency by 40%` and
|
|
10
|
-
* `\column{40%}` work as written) rather than a comment marker.
|
|
11
|
-
* - Comments use `%%` to end-of-line, which never collides with percentages.
|
|
12
|
-
*/
|
|
13
|
-
declare enum TokenType {
|
|
14
|
-
/** A command such as `\section`, `\textbf`, `\item`. The lexeme excludes the backslash. */
|
|
15
|
-
Command = "Command",
|
|
16
|
-
/** `{` — begin group / argument. */
|
|
17
|
-
LBrace = "LBrace",
|
|
18
|
-
/** `}` — end group / argument. */
|
|
19
|
-
RBrace = "RBrace",
|
|
20
|
-
/** `[` — begin optional argument. */
|
|
21
|
-
LBracket = "LBracket",
|
|
22
|
-
/** `]` — end optional argument. */
|
|
23
|
-
RBracket = "RBracket",
|
|
24
|
-
/** Run of literal text. */
|
|
25
|
-
Text = "Text",
|
|
26
|
-
/** Run of inline whitespace (spaces/tabs, single newline). */
|
|
27
|
-
Whitespace = "Whitespace",
|
|
28
|
-
/** A blank line — paragraph break. */
|
|
29
|
-
ParBreak = "ParBreak",
|
|
30
|
-
/** `\\` — explicit line break. */
|
|
31
|
-
LineBreak = "LineBreak",
|
|
32
|
-
/** `%% ...` comment (stripped from output, surfaced to editor tooling). */
|
|
33
|
-
Comment = "Comment",
|
|
34
|
-
/** End of input. */
|
|
35
|
-
EOF = "EOF"
|
|
36
|
-
}
|
|
37
|
-
/** A lexical token with full source provenance. */
|
|
38
|
-
interface Token {
|
|
39
|
-
type: TokenType;
|
|
40
|
-
/** The exact source text of the token (backslash stripped for commands). */
|
|
41
|
-
value: string;
|
|
42
|
-
range: SourceRange;
|
|
43
|
-
}
|
|
44
|
-
/** Reserved single characters that the tokenizer treats specially. */
|
|
45
|
-
declare const SPECIAL_CHARS: Set<string>;
|
|
46
|
-
|
|
47
|
-
/** Severity levels, ordered the same way LSP orders them. */
|
|
48
|
-
declare enum DiagnosticSeverity {
|
|
49
|
-
Error = "error",
|
|
50
|
-
Warning = "warning",
|
|
51
|
-
Info = "info",
|
|
52
|
-
Hint = "hint"
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Stable, machine-readable diagnostic codes. Editors can key quick-fixes and
|
|
56
|
-
* documentation links off these rather than the (localizable) message text.
|
|
57
|
-
*/
|
|
58
|
-
declare enum DiagnosticCode {
|
|
59
|
-
UnexpectedToken = "RTX1001",
|
|
60
|
-
UnterminatedGroup = "RTX1002",
|
|
61
|
-
UnterminatedArgument = "RTX1003",
|
|
62
|
-
UnexpectedEOF = "RTX1004",
|
|
63
|
-
MismatchedBrace = "RTX1005",
|
|
64
|
-
UnknownCommand = "RTX2001",
|
|
65
|
-
UnknownEnvironment = "RTX2002",
|
|
66
|
-
MissingRequiredArgument = "RTX2003",
|
|
67
|
-
TooManyArguments = "RTX2004",
|
|
68
|
-
MissingEnvironmentEnd = "RTX2005",
|
|
69
|
-
MismatchedEnvironment = "RTX2006",
|
|
70
|
-
InvalidColor = "RTX3001",
|
|
71
|
-
InvalidUrl = "RTX3002",
|
|
72
|
-
InvalidDimension = "RTX3003",
|
|
73
|
-
MissingRequiredField = "RTX3004",
|
|
74
|
-
UnknownField = "RTX3005",
|
|
75
|
-
EmptyArgument = "RTX3006",
|
|
76
|
-
CommandOutsideContext = "RTX4001",
|
|
77
|
-
UnknownIcon = "RTX4002",
|
|
78
|
-
UnknownThemeColor = "RTX4003",
|
|
79
|
-
UnsafeUrlBlocked = "RTX5001"
|
|
80
|
-
}
|
|
81
|
-
/** Optional quick-fix an editor can apply. */
|
|
82
|
-
interface QuickFix {
|
|
83
|
-
title: string;
|
|
84
|
-
/** Replacement text for {@link Diagnostic.range}. */
|
|
85
|
-
replacement: string;
|
|
86
|
-
range?: SourceRange;
|
|
87
|
-
}
|
|
88
|
-
/** A single diagnostic emitted by any stage of the pipeline. */
|
|
89
|
-
interface Diagnostic {
|
|
90
|
-
severity: DiagnosticSeverity;
|
|
91
|
-
code: DiagnosticCode;
|
|
92
|
-
message: string;
|
|
93
|
-
range: SourceRange;
|
|
94
|
-
/** Stage that produced the diagnostic, for filtering. */
|
|
95
|
-
source: "tokenizer" | "parser" | "validator" | "security";
|
|
96
|
-
/** Optional editor quick-fixes. */
|
|
97
|
-
fixes?: QuickFix[];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* How a single argument should be consumed by the parser.
|
|
102
|
-
*
|
|
103
|
-
* - `content` — recursively parse markup (nested commands, text).
|
|
104
|
-
* - `string` — verbatim text; no command expansion (URLs, colors, sizes).
|
|
105
|
-
* - `keyval` — `key=value, key=value` map.
|
|
106
|
-
* - `list` — comma-separated list of trimmed strings.
|
|
107
|
-
*/
|
|
108
|
-
type ArgKind = "content" | "string" | "keyval" | "list";
|
|
109
|
-
interface ArgSpec {
|
|
110
|
-
kind: ArgKind;
|
|
111
|
-
/** When true the argument may be absent (no diagnostic if missing). */
|
|
112
|
-
optional?: boolean;
|
|
113
|
-
/**
|
|
114
|
-
* Delimiter pair. `"brace"` (default) → `{...}`; `"bracket"` → `[...]`.
|
|
115
|
-
* An optional brace argument (e.g. an entry body) is still written with
|
|
116
|
-
* `{...}` but may be omitted.
|
|
117
|
-
*/
|
|
118
|
-
delimiter?: "brace" | "bracket";
|
|
119
|
-
/** Human-readable name surfaced in hover docs / diagnostics. */
|
|
120
|
-
name?: string;
|
|
121
|
-
/** Validation hint for `string` args (drives format checks). */
|
|
122
|
-
format?: "color" | "url" | "dimension" | "text";
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Semantic category of a command. Drives default rendering and where the
|
|
126
|
-
* command is legal.
|
|
127
|
-
*
|
|
128
|
-
* - `inline` — flows within text (`\textbf`).
|
|
129
|
-
* - `block` — starts a block (`\section`, `\job`).
|
|
130
|
-
* - `switch` — a state switch that applies to the rest of its group
|
|
131
|
-
* (`\large`, `\bfseries`-style).
|
|
132
|
-
* - `meta` — document metadata that produces no inline flow on its own.
|
|
133
|
-
*/
|
|
134
|
-
type CommandCategory = "inline" | "block" | "switch" | "meta";
|
|
135
|
-
/**
|
|
136
|
-
* A factory the parser calls once arguments are consumed, to build the AST
|
|
137
|
-
* node for a command. Returning `null` drops the command from the tree.
|
|
138
|
-
*/
|
|
139
|
-
type NodeBuilder = (ctx: BuildContext) => Node | Node[] | null;
|
|
140
|
-
interface BuildContext {
|
|
141
|
-
name: string;
|
|
142
|
-
args: ArgumentNode[];
|
|
143
|
-
/** For switches: the trailing content the switch applies to. */
|
|
144
|
-
scope: Node[];
|
|
145
|
-
/** Emit a diagnostic from within a builder. */
|
|
146
|
-
report: (d: Omit<Diagnostic, "source">) => void;
|
|
147
|
-
/** Utilities exposed to plugin authors. */
|
|
148
|
-
utils: BuilderUtils;
|
|
149
|
-
}
|
|
150
|
-
interface BuilderUtils {
|
|
151
|
-
/** Flatten an argument's children into a plain string (best-effort). */
|
|
152
|
-
textOf(arg: ArgumentNode | undefined): string;
|
|
153
|
-
/** Sanitize a URL; returns `"#"` (and reports) when unsafe. */
|
|
154
|
-
safeUrl(url: string): string;
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* The contract for a command. Used by the parser (argument signature, scope
|
|
158
|
-
* behavior) and the renderers (when no native node exists, renderers consult
|
|
159
|
-
* the command's per-target `render` map).
|
|
160
|
-
*/
|
|
161
|
-
interface CommandDefinition {
|
|
162
|
-
name: string;
|
|
163
|
-
category?: CommandCategory;
|
|
164
|
-
/** Argument signature, in order. */
|
|
165
|
-
args?: ArgSpec[];
|
|
166
|
-
/**
|
|
167
|
-
* `true` for switches that swallow the remainder of their enclosing group
|
|
168
|
-
* as scoped content (`\large`, `\itshape`).
|
|
169
|
-
*/
|
|
170
|
-
scoped?: boolean;
|
|
171
|
-
/**
|
|
172
|
-
* Builds the AST node. When omitted, the parser emits a generic
|
|
173
|
-
* {@link CommandNode} carrying the parsed arguments.
|
|
174
|
-
*/
|
|
175
|
-
build?: NodeBuilder;
|
|
176
|
-
/** One-line summary for hover docs / completion detail. */
|
|
177
|
-
summary?: string;
|
|
178
|
-
/** Longer documentation (markdown) for hover. */
|
|
179
|
-
documentation?: string;
|
|
180
|
-
/** Example snippet shown in completion / hover. */
|
|
181
|
-
example?: string;
|
|
182
|
-
}
|
|
183
|
-
/** Environment (`\begin{x} … \end{x}`) contract. */
|
|
184
|
-
interface EnvironmentDefinition {
|
|
185
|
-
name: string;
|
|
186
|
-
/**
|
|
187
|
-
* Command that introduces each entry inside the environment, e.g. `item`
|
|
188
|
-
* for `itemize`, `column` for `columns`. The parser uses this to slice
|
|
189
|
-
* the body into entries.
|
|
190
|
-
*/
|
|
191
|
-
itemCommand?: string;
|
|
192
|
-
/** Commands legal as direct children (for validation). `*` allows any. */
|
|
193
|
-
allowedChildren?: string[];
|
|
194
|
-
/** Build the environment node from its parsed body. */
|
|
195
|
-
build?: (ctx: EnvBuildContext) => Node | Node[] | null;
|
|
196
|
-
summary?: string;
|
|
197
|
-
documentation?: string;
|
|
198
|
-
example?: string;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* One entry of an `itemCommand`-delimited environment. For `itemize`, the
|
|
202
|
-
* marker command is `\item`; for `columns`, it is `\column{width}`.
|
|
203
|
-
*/
|
|
204
|
-
interface EnvEntry {
|
|
205
|
-
/** The marker command that introduced the entry, with its parsed arguments. */
|
|
206
|
-
marker: CommandNode;
|
|
207
|
-
/** Content nodes belonging to this entry (up to the next marker / `\end`). */
|
|
208
|
-
content: Node[];
|
|
209
|
-
}
|
|
210
|
-
interface EnvBuildContext {
|
|
211
|
-
name: string;
|
|
212
|
-
/** Parsed body nodes of the environment (always present). */
|
|
213
|
-
body: Node[];
|
|
214
|
-
/**
|
|
215
|
-
* When the environment declares an `itemCommand`, the body sliced into
|
|
216
|
-
* entries at each marker. `undefined` for plain block environments.
|
|
217
|
-
*/
|
|
218
|
-
entries?: EnvEntry[];
|
|
219
|
-
/** Optional `[...]` arguments after `\begin{env}`. */
|
|
220
|
-
options: ArgumentNode[];
|
|
221
|
-
report: (d: Omit<Diagnostic, "source">) => void;
|
|
222
|
-
utils: BuilderUtils;
|
|
223
|
-
}
|
|
1
|
+
import { T as Token, D as Diagnostic, H as HtmlRenderFn, R as ReTeXPlugin, a as ReTeXLibrary, P as PluginHost, E as EngineCommand, b as EnvironmentDefinition, I as IconDefinition, C as CommandRegistry } from './index-DJEasLJc.js';
|
|
2
|
+
export { A as AppliedLibraries, c as ArgKind, d as ArgSpec, B as BLOCK_TYPES, e as BuildContext, f as BuilderUtils, g as CommandCategory, h as CommandDefinition, i as DiagnosticCode, j as DiagnosticSeverity, k as EnvBuildContext, l as EnvEntry, G as GATED_COMMANDS, m as HtmlRenderContext, L as LibraryLookup, N as NodeBuilder, Q as QuickFix, S as SPECIAL_CHARS, n as TokenType, o as applyLibraries, p as builtinLibraries, q as builtinLibraryNames, r as classicLibrary, s as collectLibraryOverrides, t as colorCommands, u as colorsLibrary, v as compactLibrary, w as fontCommands, x as fontStacks, y as fontTheme, z as fontsLibrary, F as getBuiltinLibrary, J as getIcon, K as hasIcon, M as iconNames, O as iconToSvg, U as isBlockNode, V as libraryDiagnostics, W as mergeLibraryTheme, X as modernLibrary, Y as palettes, Z as registerIcon, _ as resolveIconName, $ as resolveLibraryName, a0 as shapeCommands, a1 as shapesLibrary, a2 as usedLibraryNamesFromAst, a3 as usedLibraryNamesFromTokens } from './index-DJEasLJc.js';
|
|
3
|
+
import { T as Theme, D as DocumentNode, N as Node, C as ContactNode, S as SectionNode, F as FieldMap, P as PartialTheme, R as ReactRenderFn, a as ReactRenderOptions, b as SourceRange } from './react-B3tN1iWa.js';
|
|
4
|
+
export { A as ArgumentNode, c as ColorNode, d as ColumnNode, e as ColumnsNode, f as CommandNode, g as ContactField, E as EducationNode, h as ErrorNode, i as FontFamilyNode, j as FontScale, k as FontScaleNode, l as FontSizeNode, G as GroupNode, I as IconNode, J as JobNode, m as JsxFactory, L as LineBreakNode, n as LinkNode, o as ListItemNode, p as ListKind, q as ListNode, M as MarkNode, r as MarkType, s as NodeBase, t as NodeMap, u as NodeType, v as ParBreakNode, w as ParentNode, x as Position, y as ProjectNode, z as ReactRenderContext, B as ReactRenderer, H as RuleNode, K as SkillsNode, O as SpaceNode, Q as TextNode, U as ThemeColorNode, V as ThemeColors, W as ThemeFontSizes, X as ThemeFonts, Y as ThemeHeadings, Z as ThemePage, _ as ThemeSpacing, $ as UrlNode, a0 as UsePackageNode, a1 as isNode, a2 as isParent, a3 as mergeRanges, a4 as pos, a5 as range, a6 as rangeContains, a7 as renderReact } from './react-B3tN1iWa.js';
|
|
224
5
|
|
|
225
6
|
interface TokenizeResult {
|
|
226
7
|
tokens: Token[];
|
|
@@ -262,86 +43,22 @@ declare class Tokenizer {
|
|
|
262
43
|
declare function tokenize(source: string): TokenizeResult;
|
|
263
44
|
|
|
264
45
|
/**
|
|
265
|
-
*
|
|
266
|
-
* signatures and node builders; the plugin system mutates it. A registry can
|
|
267
|
-
* be cloned cheaply so an engine instance never mutates shared global state.
|
|
268
|
-
*/
|
|
269
|
-
declare class CommandRegistry {
|
|
270
|
-
private commands;
|
|
271
|
-
private environments;
|
|
272
|
-
registerCommand(def: CommandDefinition): this;
|
|
273
|
-
registerEnvironment(def: EnvironmentDefinition): this;
|
|
274
|
-
getCommand(name: string): CommandDefinition | undefined;
|
|
275
|
-
getEnvironment(name: string): EnvironmentDefinition | undefined;
|
|
276
|
-
hasCommand(name: string): boolean;
|
|
277
|
-
hasEnvironment(name: string): boolean;
|
|
278
|
-
commandNames(): string[];
|
|
279
|
-
environmentNames(): string[];
|
|
280
|
-
allCommands(): CommandDefinition[];
|
|
281
|
-
allEnvironments(): EnvironmentDefinition[];
|
|
282
|
-
/** Shallow-clone the registry (definitions are shared, maps are copied). */
|
|
283
|
-
clone(): CommandRegistry;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Icon registry. Icons are stored as the inner markup of a `0 0 24 24` SVG and
|
|
288
|
-
* use `currentColor` so they inherit surrounding text color. The set is
|
|
289
|
-
* intentionally small and extensible via {@link registerIcon} / plugins.
|
|
46
|
+
* Generate the stylesheet for a rendered resume from a {@link Theme}.
|
|
290
47
|
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
/** Resolve a (possibly aliased) icon name to its canonical key. */
|
|
303
|
-
declare function resolveIconName(name: string): string | undefined;
|
|
304
|
-
declare function hasIcon(name: string): boolean;
|
|
305
|
-
declare function getIcon(name: string): IconDefinition | undefined;
|
|
306
|
-
/** Register (or override) an icon at runtime. Used by plugins. */
|
|
307
|
-
declare function registerIcon(name: string, def: IconDefinition): void;
|
|
308
|
-
/** All canonical icon names, for completion / docs. */
|
|
309
|
-
declare function iconNames(): string[];
|
|
310
|
-
/**
|
|
311
|
-
* Render an icon to an inline SVG string. Returns `null` for unknown icons so
|
|
312
|
-
* callers can emit a diagnostic and a graceful fallback.
|
|
313
|
-
*/
|
|
314
|
-
declare function iconToSvg(name: string, opts?: {
|
|
315
|
-
size?: number | string;
|
|
316
|
-
className?: string;
|
|
317
|
-
}): string | null;
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Generate the stylesheet for a rendered resume from a {@link Theme}. Theme
|
|
321
|
-
* values become CSS custom properties so they can be overridden at runtime,
|
|
322
|
-
* and every theme color is exposed as `--retex-color-<token>` for use by
|
|
323
|
-
* `\themecolor`.
|
|
48
|
+
* Themes are **blank by default**: any field may be `undefined`. The structural
|
|
49
|
+
* layout (flex rows, list indents, spacing rhythm) is always emitted, while all
|
|
50
|
+
* *decoration* (accent colors, fonts, uppercased headings, skill chips, section
|
|
51
|
+
* rules) is driven by CSS custom properties whose fallbacks are neutral. So an
|
|
52
|
+
* unstyled theme produces a clean, browser-default document, and importing a
|
|
53
|
+
* library/theme simply fills in those variables.
|
|
54
|
+
*
|
|
55
|
+
* Every embedded theme value is vetted before it reaches the stylesheet
|
|
56
|
+
* (`isSafeColor` / `isSafeDimension` / `sanitizeStyleValue`), so even a
|
|
57
|
+
* user-supplied theme cannot inject CSS. Each color is also exposed as
|
|
58
|
+
* `--retex-color-<token>` for use by `\themecolor`.
|
|
324
59
|
*/
|
|
325
60
|
declare function themeToCss(theme: Theme, prefix?: string): string;
|
|
326
61
|
|
|
327
|
-
/** Node types that participate in block (vertical) flow. */
|
|
328
|
-
declare const BLOCK_TYPES: Set<string>;
|
|
329
|
-
declare function isBlockNode(node: Node): boolean;
|
|
330
|
-
/**
|
|
331
|
-
* Plugin HTML renderer. Receives the node, the active context, and a callback
|
|
332
|
-
* to recursively render child nodes to HTML.
|
|
333
|
-
*/
|
|
334
|
-
type HtmlRenderFn = (node: Node, ctx: HtmlRenderContext, renderChildren: (nodes: Node[]) => string) => string;
|
|
335
|
-
interface HtmlRenderContext {
|
|
336
|
-
theme: Theme;
|
|
337
|
-
classPrefix: string;
|
|
338
|
-
/** Override renderers keyed by node `type` or `command:<name>`. */
|
|
339
|
-
overrides: Map<string, HtmlRenderFn>;
|
|
340
|
-
/** Render arbitrary inline/block nodes to an HTML string. */
|
|
341
|
-
renderNodes: (nodes: Node[]) => string;
|
|
342
|
-
cls: (name: string) => string;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
62
|
interface HtmlRenderOptions {
|
|
346
63
|
theme?: Theme;
|
|
347
64
|
/** CSS class prefix. Default `"retex"`. */
|
|
@@ -350,6 +67,14 @@ interface HtmlRenderOptions {
|
|
|
350
67
|
overrides?: Map<string, HtmlRenderFn>;
|
|
351
68
|
/** Group leading contact commands into a `<header>`. Default `true`. */
|
|
352
69
|
header?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Emit source-position attributes (`data-rtx-pos="start:end"` and
|
|
72
|
+
* `data-rtx-type`) on rendered elements so a live editor can map preview
|
|
73
|
+
* clicks back to the source and vice-versa (Overleaf-style two-way sync).
|
|
74
|
+
* Offsets are zero-based UTF-16 code-unit offsets into the original source.
|
|
75
|
+
* Default `false` — final/exported HTML stays clean and unannotated.
|
|
76
|
+
*/
|
|
77
|
+
sourceMap?: boolean;
|
|
353
78
|
}
|
|
354
79
|
/**
|
|
355
80
|
* The HTML renderer. Produces clean, semantic, fully-escaped HTML. Every text
|
|
@@ -361,6 +86,7 @@ declare class HtmlRenderer {
|
|
|
361
86
|
private readonly prefix;
|
|
362
87
|
private readonly overrides;
|
|
363
88
|
private readonly useHeader;
|
|
89
|
+
private readonly sourceMap;
|
|
364
90
|
private readonly ctx;
|
|
365
91
|
constructor(options?: HtmlRenderOptions);
|
|
366
92
|
/** Render the resume body as an HTML fragment (no `<html>`/`<style>`). */
|
|
@@ -383,6 +109,16 @@ declare class HtmlRenderer {
|
|
|
383
109
|
private renderSkills;
|
|
384
110
|
private renderEntry;
|
|
385
111
|
private renderCommand;
|
|
112
|
+
/**
|
|
113
|
+
* Source-position attributes for a node — `data-rtx-pos="start:end"` plus a
|
|
114
|
+
* `data-rtx-type`. Returns an empty string unless `sourceMap` is enabled and
|
|
115
|
+
* the node carries a range. Powers the live-preview two-way sync: a client
|
|
116
|
+
* reads these to map a clicked element back to the exact source offsets (and,
|
|
117
|
+
* in reverse, to find the element for a caret offset).
|
|
118
|
+
*/
|
|
119
|
+
private src;
|
|
120
|
+
/** Like {@link src}, but spans a run of inline nodes (merges their ranges). */
|
|
121
|
+
private srcSpan;
|
|
386
122
|
private icon;
|
|
387
123
|
private dim;
|
|
388
124
|
private cls;
|
|
@@ -481,50 +217,15 @@ interface EntryParts {
|
|
|
481
217
|
declare function entryParts(fields: FieldMap, kind: string): EntryParts;
|
|
482
218
|
declare function dateRange(start?: string, end?: string, date?: string): string;
|
|
483
219
|
|
|
484
|
-
/**
|
|
485
|
-
* A command definition extended with optional per-target render functions.
|
|
486
|
-
* Passing `render.html` is shorthand for registering an HTML override keyed by
|
|
487
|
-
* `command:<name>` — the common case for a plugin command with no custom AST
|
|
488
|
-
* node (e.g. `\badge{...}`).
|
|
489
|
-
*/
|
|
490
|
-
interface EngineCommand extends CommandDefinition {
|
|
491
|
-
render?: {
|
|
492
|
-
html?: HtmlRenderFn;
|
|
493
|
-
react?: ReactRenderFn;
|
|
494
|
-
};
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* A ReTeX plugin. Everything is optional; a plugin may contribute commands,
|
|
498
|
-
* environments, icons, renderers, theme overrides, or run arbitrary setup
|
|
499
|
-
* against the engine. Plugins never touch global state — they mutate only the
|
|
500
|
-
* engine instance they are installed on.
|
|
501
|
-
*/
|
|
502
|
-
interface ReTeXPlugin {
|
|
503
|
-
name: string;
|
|
504
|
-
commands?: EngineCommand[];
|
|
505
|
-
environments?: EnvironmentDefinition[];
|
|
506
|
-
icons?: Record<string, IconDefinition>;
|
|
507
|
-
/** HTML overrides keyed by node `type` or `command:<name>`. */
|
|
508
|
-
htmlRenderers?: Record<string, HtmlRenderFn>;
|
|
509
|
-
/** React overrides keyed by node `type` or `command:<name>`. */
|
|
510
|
-
reactRenderers?: Record<string, ReactRenderFn>;
|
|
511
|
-
/** A theme patch applied when the plugin is installed. */
|
|
512
|
-
theme?: PartialTheme;
|
|
513
|
-
/** Imperative hook for advanced setup. */
|
|
514
|
-
setup?: (engine: PluginHost) => void;
|
|
515
|
-
}
|
|
516
|
-
/** The subset of the engine surface a plugin's `setup` hook may use. */
|
|
517
|
-
interface PluginHost {
|
|
518
|
-
registerCommand(def: EngineCommand): PluginHost;
|
|
519
|
-
registerEnvironment(def: EnvironmentDefinition): PluginHost;
|
|
520
|
-
registerHtmlRenderer(key: string, fn: HtmlRenderFn): PluginHost;
|
|
521
|
-
registerReactRenderer(key: string, fn: ReactRenderFn): PluginHost;
|
|
522
|
-
registerIcon(name: string, def: IconDefinition): PluginHost;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
220
|
interface EngineOptions {
|
|
526
221
|
theme?: Theme | PartialTheme;
|
|
527
222
|
plugins?: ReTeXPlugin[];
|
|
223
|
+
/**
|
|
224
|
+
* Libraries to make available to `\usepackage` *without* activating them
|
|
225
|
+
* globally. Built-in libraries (`fonts`, `shapes`, `colors`, `modern`, …) are
|
|
226
|
+
* always available; use this to register your own.
|
|
227
|
+
*/
|
|
228
|
+
libraries?: ReTeXLibrary[];
|
|
528
229
|
classPrefix?: string;
|
|
529
230
|
/** Max number of compiled documents to cache. Default 64. */
|
|
530
231
|
cacheSize?: number;
|
|
@@ -541,13 +242,15 @@ interface CompileOptions {
|
|
|
541
242
|
}
|
|
542
243
|
/**
|
|
543
244
|
* The ReTeX engine: the single entry point that wires the tokenizer, parser,
|
|
544
|
-
* validator, renderers, theming, plugins, and caching together.
|
|
245
|
+
* validator, renderers, theming, libraries, plugins, and caching together.
|
|
246
|
+
*
|
|
247
|
+
* ReTeX is blank by default. Styling is opt-in via **libraries**, activated
|
|
248
|
+
* either from the document (`\usepackage{colors}`) or from code
|
|
249
|
+
* (`engine.use(colorsLibrary)`).
|
|
545
250
|
*
|
|
546
251
|
* ```ts
|
|
547
|
-
* const engine = new ReTeXEngine(
|
|
548
|
-
* engine.
|
|
549
|
-
* render: { html: (n, ctx, kids) => `<span class="badge">${kids((n as any).args[0].children)}</span>` } });
|
|
550
|
-
* const html = engine.toHtml(source);
|
|
252
|
+
* const engine = new ReTeXEngine();
|
|
253
|
+
* engine.toHtml("\\usepackage{colors}\n\\textcolor{#7c3aed}{Hi}");
|
|
551
254
|
* ```
|
|
552
255
|
*/
|
|
553
256
|
declare class ReTeXEngine implements PluginHost {
|
|
@@ -556,11 +259,19 @@ declare class ReTeXEngine implements PluginHost {
|
|
|
556
259
|
private readonly prefix;
|
|
557
260
|
private readonly htmlOverrides;
|
|
558
261
|
private readonly reactOverrides;
|
|
262
|
+
/** Libraries available to `\usepackage` (built-ins are resolved separately). */
|
|
263
|
+
private readonly customLibraries;
|
|
559
264
|
private readonly cache;
|
|
560
265
|
private readonly cacheSize;
|
|
561
266
|
private generation;
|
|
562
267
|
constructor(options?: EngineOptions);
|
|
563
268
|
use(plugin: ReTeXPlugin): this;
|
|
269
|
+
/**
|
|
270
|
+
* Register a library so it can be activated with `\usepackage{name}`, without
|
|
271
|
+
* installing it globally. Built-in libraries are always available; use this
|
|
272
|
+
* for custom ones.
|
|
273
|
+
*/
|
|
274
|
+
provideLibrary(library: ReTeXLibrary): this;
|
|
564
275
|
registerCommand(def: EngineCommand): this;
|
|
565
276
|
registerEnvironment(def: EnvironmentDefinition): this;
|
|
566
277
|
registerHtmlRenderer(key: string, fn: HtmlRenderFn): this;
|
|
@@ -582,11 +293,22 @@ declare class ReTeXEngine implements PluginHost {
|
|
|
582
293
|
toJson(input: string | DocumentNode, options?: JsonRenderOptions): string;
|
|
583
294
|
toPrintHtml(input: string | DocumentNode, options?: PrintOptions): string;
|
|
584
295
|
toPdf(input: string | DocumentNode, options?: PdfOptions): Promise<Uint8Array>;
|
|
585
|
-
/**
|
|
586
|
-
|
|
296
|
+
/**
|
|
297
|
+
* The CSS stylesheet for the active theme. Pass the document (source or AST)
|
|
298
|
+
* to fold in any libraries it imports via `\usepackage` (so the styles match
|
|
299
|
+
* `toHtml(input)`); omit it to get the engine theme's stylesheet.
|
|
300
|
+
*/
|
|
301
|
+
styles(input?: string | DocumentNode): string;
|
|
302
|
+
/** Resolve a library name against custom libraries first, then built-ins. */
|
|
303
|
+
private lookupLibrary;
|
|
587
304
|
private astOf;
|
|
588
|
-
|
|
589
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Build the per-document render inputs: the AST, the effective theme (engine
|
|
307
|
+
* theme + any libraries the document imports), and the merged render
|
|
308
|
+
* overrides. Library use is recovered from `\usepackage` nodes in the AST, so
|
|
309
|
+
* this works whether the input was a source string or a pre-parsed document.
|
|
310
|
+
*/
|
|
311
|
+
private bundle;
|
|
590
312
|
private invalidate;
|
|
591
313
|
private remember;
|
|
592
314
|
}
|
|
@@ -666,9 +388,13 @@ declare class Parser {
|
|
|
666
388
|
declare function parse(tokens: Token[], options?: ParserOptions): ParseResult;
|
|
667
389
|
|
|
668
390
|
/**
|
|
669
|
-
* Register every built-in command and environment into a fresh registry.
|
|
670
|
-
* The
|
|
671
|
-
*
|
|
391
|
+
* Register every built-in (core) command and environment into a fresh registry.
|
|
392
|
+
* The core is intentionally minimal: document structure, basic emphasis, links,
|
|
393
|
+
* sections, entries, icons, and the `\usepackage` directive. Visual styling
|
|
394
|
+
* (color, fonts, shapes) is added by libraries — see `src/library`.
|
|
395
|
+
*
|
|
396
|
+
* The engine calls this once per instance so plugins/libraries can extend a
|
|
397
|
+
* private copy without touching global state.
|
|
672
398
|
*/
|
|
673
399
|
declare function createDefaultRegistry(): CommandRegistry;
|
|
674
400
|
|
|
@@ -729,12 +455,32 @@ declare function flattenText(input: Node | Node[]): string;
|
|
|
729
455
|
declare function normalizeWhitespace(s: string): string;
|
|
730
456
|
|
|
731
457
|
/**
|
|
732
|
-
* The default ReTeX theme
|
|
733
|
-
*
|
|
458
|
+
* The default ReTeX theme is **blank** — it defines no colors, fonts, sizes, or
|
|
459
|
+
* section decoration. A document rendered with it is a clean, browser-default
|
|
460
|
+
* page: black text, the user agent's default font, plain section headings, and
|
|
461
|
+
* no accent colors or rules. This is "just simple editing".
|
|
462
|
+
*
|
|
463
|
+
* Visual styling is opt-in. Import a library to populate this theme:
|
|
464
|
+
*
|
|
465
|
+
* - `\usepackage{fonts}` / `engine.use(fontsLibrary)` — fonts & sizes
|
|
466
|
+
* - `\usepackage{shapes}` / `engine.use(shapesLibrary)` — rules, dividers, spacing
|
|
467
|
+
* - `\usepackage{colors}` / `engine.use(colorsLibrary)` — text color & palettes
|
|
468
|
+
* - `\usepackage{modern}` / `engine.use(modernTheme)` — a full styled look
|
|
469
|
+
*
|
|
470
|
+
* Every renderer treats theme values as optional and substitutes a neutral,
|
|
471
|
+
* unstyled fallback when a field is absent, so the blank theme always produces
|
|
472
|
+
* a readable document.
|
|
734
473
|
*/
|
|
474
|
+
declare const blankTheme: Theme;
|
|
475
|
+
/** Alias kept for backwards compatibility — the default theme is the blank one. */
|
|
735
476
|
declare const defaultTheme: Theme;
|
|
736
477
|
|
|
737
|
-
/**
|
|
478
|
+
/**
|
|
479
|
+
* Deep-merge a partial theme over a base theme (sub-objects merged shallowly).
|
|
480
|
+
* The result always has defined (possibly empty) sub-objects, so consumers can
|
|
481
|
+
* safely read `theme.colors`, `theme.fonts`, … without null checks even when
|
|
482
|
+
* the base is the blank theme.
|
|
483
|
+
*/
|
|
738
484
|
declare function resolveTheme(partial?: PartialTheme, base?: Theme): Theme;
|
|
739
485
|
/** A modern, accent-forward theme with underlined section headings. */
|
|
740
486
|
declare const modernTheme: Theme;
|
|
@@ -742,9 +488,13 @@ declare const modernTheme: Theme;
|
|
|
742
488
|
declare const classicTheme: Theme;
|
|
743
489
|
/** A compact, single-accent theme that maximizes content density. */
|
|
744
490
|
declare const compactTheme: Theme;
|
|
745
|
-
/**
|
|
491
|
+
/**
|
|
492
|
+
* Built-in theme presets keyed by name. `default` and `blank` both map to the
|
|
493
|
+
* unstyled theme; the styled presets are opt-in (import them, or activate them
|
|
494
|
+
* with `\usepackage{modern}` etc.).
|
|
495
|
+
*/
|
|
746
496
|
declare const themes: Record<string, Theme>;
|
|
747
|
-
/** Look up a preset theme by name, falling back to the default. */
|
|
497
|
+
/** Look up a preset theme by name, falling back to the blank default. */
|
|
748
498
|
declare function getTheme(name: string): Theme;
|
|
749
499
|
|
|
750
500
|
/**
|
|
@@ -832,6 +582,11 @@ interface SemanticToken {
|
|
|
832
582
|
interface EditorServiceOptions {
|
|
833
583
|
registry?: CommandRegistry;
|
|
834
584
|
theme?: Theme;
|
|
585
|
+
/**
|
|
586
|
+
* Custom libraries addressable via `\usepackage{name}`. Built-in libraries
|
|
587
|
+
* (`fonts`, `shapes`, `colors`, `modern`, …) are always available.
|
|
588
|
+
*/
|
|
589
|
+
libraries?: ReTeXLibrary[];
|
|
835
590
|
}
|
|
836
591
|
/**
|
|
837
592
|
* Editor integration surface: everything a code editor (Monaco, CodeMirror, an
|
|
@@ -842,7 +597,11 @@ interface EditorServiceOptions {
|
|
|
842
597
|
declare class EditorService {
|
|
843
598
|
private readonly registry;
|
|
844
599
|
private readonly theme?;
|
|
600
|
+
private readonly customLibraries;
|
|
845
601
|
constructor(options?: EditorServiceOptions);
|
|
602
|
+
private lookupLibrary;
|
|
603
|
+
/** Build a registry that includes the libraries the source imports. */
|
|
604
|
+
private registryFor;
|
|
846
605
|
getDiagnostics(source: string): Diagnostic[];
|
|
847
606
|
/** Parse and return the AST for inspection / debugging. */
|
|
848
607
|
inspect(source: string): DocumentNode;
|
|
@@ -868,6 +627,83 @@ declare class EditorService {
|
|
|
868
627
|
*/
|
|
869
628
|
declare function printDocument(ast: DocumentNode): string;
|
|
870
629
|
|
|
630
|
+
/**
|
|
631
|
+
* Two-way preview sync — the editor-agnostic half of ReTeX's Overleaf-style
|
|
632
|
+
* "click the preview, jump to the source" feature (and its reverse).
|
|
633
|
+
*
|
|
634
|
+
* The {@link HtmlRenderer} `sourceMap` option stamps every meaningful element
|
|
635
|
+
* with a `data-rtx-pos="start:end"` attribute (zero-based UTF-16 offsets into
|
|
636
|
+
* the source) and a `data-rtx-type`. These helpers are the small, dependency-
|
|
637
|
+
* free glue a host editor uses on top of those attributes:
|
|
638
|
+
*
|
|
639
|
+
* - **Preview → code** (reverse sync): on a click in the preview, read the
|
|
640
|
+
* nearest annotated ancestor's span and select/scroll to it in the editor.
|
|
641
|
+
*
|
|
642
|
+
* ```ts
|
|
643
|
+
* preview.addEventListener("click", (e) => {
|
|
644
|
+
* const span = closestSourcePos(e.target as Element);
|
|
645
|
+
* if (span) {
|
|
646
|
+
* textarea.focus();
|
|
647
|
+
* textarea.setSelectionRange(span.start, span.end);
|
|
648
|
+
* }
|
|
649
|
+
* });
|
|
650
|
+
* ```
|
|
651
|
+
*
|
|
652
|
+
* - **Code → preview** (forward sync): on caret move, find the tightest
|
|
653
|
+
* element whose span contains the caret offset and highlight it.
|
|
654
|
+
*
|
|
655
|
+
* ```ts
|
|
656
|
+
* const el = pickElementForOffset(
|
|
657
|
+
* preview.querySelectorAll(`[${SOURCE_POS_ATTR}]`),
|
|
658
|
+
* textarea.selectionStart,
|
|
659
|
+
* );
|
|
660
|
+
* el?.scrollIntoView({ block: "center" });
|
|
661
|
+
* ```
|
|
662
|
+
*
|
|
663
|
+
* Every function is pure and works with any object exposing `getAttribute`
|
|
664
|
+
* (real DOM elements, or test doubles), so this module never touches `document`
|
|
665
|
+
* and stays usable outside the browser.
|
|
666
|
+
*/
|
|
667
|
+
/** Attribute carrying a `"start:end"` source-offset span. */
|
|
668
|
+
declare const SOURCE_POS_ATTR = "data-rtx-pos";
|
|
669
|
+
/** Attribute carrying the originating AST node type (e.g. `"section"`). */
|
|
670
|
+
declare const SOURCE_TYPE_ATTR = "data-rtx-type";
|
|
671
|
+
/** A half-open `[start, end)` span of UTF-16 offsets into the source text. */
|
|
672
|
+
interface SourceSpan {
|
|
673
|
+
start: number;
|
|
674
|
+
end: number;
|
|
675
|
+
}
|
|
676
|
+
/** The minimal shape these helpers need from a preview element. */
|
|
677
|
+
interface AttrElement {
|
|
678
|
+
getAttribute(name: string): string | null;
|
|
679
|
+
}
|
|
680
|
+
/** An element that can also walk up to its nearest matching ancestor. */
|
|
681
|
+
interface ClosestElement extends AttrElement {
|
|
682
|
+
closest(selectors: string): (AttrElement & ClosestElement) | null;
|
|
683
|
+
}
|
|
684
|
+
/** Parse a `"start:end"` attribute value into a {@link SourceSpan}. */
|
|
685
|
+
declare function parseSourcePos(value: string | null | undefined): SourceSpan | null;
|
|
686
|
+
/** Read the {@link SOURCE_POS_ATTR} span off a single element. */
|
|
687
|
+
declare function readSourcePos(el: AttrElement | null | undefined): SourceSpan | null;
|
|
688
|
+
/** Read the {@link SOURCE_TYPE_ATTR} off a single element. */
|
|
689
|
+
declare function readSourceType(el: AttrElement | null | undefined): string | null;
|
|
690
|
+
/**
|
|
691
|
+
* Reverse sync: from a clicked element, walk up to the nearest annotated
|
|
692
|
+
* ancestor and return its span. Uses the DOM `closest` when available.
|
|
693
|
+
*/
|
|
694
|
+
declare function closestSourcePos(el: ClosestElement | null | undefined): SourceSpan | null;
|
|
695
|
+
/** Width of a span; used to prefer the most specific (smallest) match. */
|
|
696
|
+
declare function spanLength(span: SourceSpan): number;
|
|
697
|
+
/** Whether `offset` falls within `span` (both ends inclusive). */
|
|
698
|
+
declare function spanContains(span: SourceSpan, offset: number): boolean;
|
|
699
|
+
/**
|
|
700
|
+
* Forward sync: from a set of annotated elements, return the single tightest
|
|
701
|
+
* one whose span contains `offset` — i.e. the most specific element under the
|
|
702
|
+
* caret. Ties on width are broken toward the later span (the deepest/innermost
|
|
703
|
+
* element rendered). Returns `null` when no span contains the offset.
|
|
704
|
+
*/
|
|
705
|
+
declare function pickElementForOffset<T extends AttrElement>(elements: Iterable<T>, offset: number): T | null;
|
|
706
|
+
|
|
871
707
|
interface Segment {
|
|
872
708
|
start: number;
|
|
873
709
|
end: number;
|
|
@@ -895,6 +731,7 @@ interface IncrementalResult {
|
|
|
895
731
|
*/
|
|
896
732
|
declare class IncrementalCompiler {
|
|
897
733
|
private readonly registry;
|
|
734
|
+
private readonly lookupLibrary;
|
|
898
735
|
/** Position-independent parse cache, keyed by exact block text. */
|
|
899
736
|
private readonly parseCache;
|
|
900
737
|
/** Position-resolved cache, keyed by `offset:line:text` (already shifted). */
|
|
@@ -903,6 +740,7 @@ declare class IncrementalCompiler {
|
|
|
903
740
|
private misses;
|
|
904
741
|
constructor(options?: {
|
|
905
742
|
registry?: CommandRegistry;
|
|
743
|
+
libraries?: ReTeXLibrary[];
|
|
906
744
|
});
|
|
907
745
|
/** Clear all caches (e.g. after registering new commands). */
|
|
908
746
|
reset(): void;
|
|
@@ -913,4 +751,4 @@ declare function splitBalancedSegments(source: string): Segment[];
|
|
|
913
751
|
/** Are braces and `\begin`/`\end` balanced in `text`? (Escapes are skipped.) */
|
|
914
752
|
declare function isBalanced(text: string): boolean;
|
|
915
753
|
|
|
916
|
-
export { type
|
|
754
|
+
export { type AttrElement, type ClosestElement, CommandRegistry, type CompileOptions, type CompileResult, type CompletionItem, type CompletionKind, ContactNode, Diagnostic, DocumentNode, EditorService, type EditorServiceOptions, EngineCommand, type EngineOptions, type EntryParts, EnvironmentDefinition, FieldMap, type HeadlessBrowser, type HeadlessPage, type HoverInfo, HtmlRenderFn, type HtmlRenderOptions, HtmlRenderer, IconDefinition, IncrementalCompiler, type IncrementalResult, type IncrementalStats, type JsonRenderOptions, Node, type ParseResult, Parser, type ParserOptions, PartialTheme, type PdfOptions, PluginHost, type PreambleParts, type PrintOptions, ReTeXEngine, ReTeXLibrary, ReTeXPlugin, ReactRenderFn, ReactRenderOptions, type Region, SOURCE_POS_ATTR, SOURCE_TYPE_ATTR, SectionNode, type SemanticToken, type SemanticTokenType, SourceRange, type SourceSpan, Theme, Token, type TokenizeResult, Tokenizer, type UrlSanitizeResult, type ValidateOptions, type VisitOptions, badgePlugin, blankTheme, childrenOf, classicTheme, closestMatch, closestSourcePos, collect, compactTheme, createDefaultRegistry, createEngine, dateRange, defaultTheme, entryParts, escapeAttribute, escapeHtml, flattenText, getTheme, isBalanced, isSafeColor, isSafeDimension, levenshtein, modernTheme, nodePathAt, normalizeWhitespace, pageCss, parse, parseKeyValArg, parseListArg, parseSourcePos, pickElementForOffset, printDocument, ratingPlugin, readSourcePos, readSourceType, renderHtml, renderHtmlDocument, renderJson, renderPdf, renderPrintHtml, resolveTheme, sanitizeStyleValue, sanitizeUrl, spanContains, spanLength, splitBalancedSegments, splitPreamble, splitTopLevel, themeToCss, themes, toJsonTree, toRegions, tokenize, validate, walk };
|