atdoc-core 0.1.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.
@@ -0,0 +1,265 @@
1
+ // Node registry — the single source of truth the Lexer and Parser both consult
2
+ // to know what `@word` means and what shape its slots take.
3
+ //
4
+ // Mirrors `configs/atdoc-setting.json`'s tokenGroups / specialRules groupings
5
+ // (structuralKeywords, containerKeywords, calloutKeywords, widgetKeywords,
6
+ // formatKeywords, semanticKeywords, footnoteKeywords, specialKeywords,
7
+ // metaKeywords, contextNodes, voidNodes, rawNodes, rawEscapeNodes,
8
+ // escapeSymbols, rawEscapeSymbols, strongQuote). JSON carries no comments, so
9
+ // what those last few mean lives here: `rawNodes` is every node whose content
10
+ // the Lexer scans opaquely (the four raw-family ContentModes below), which is
11
+ // also exactly the set that accepts the `strongQuote` delimiters;
12
+ // `rawEscapeNodes` is the subset that additionally honours
13
+ // `rawEscapeSymbols` (only @raw — @code/@mermaid/@svg define no escapes at
14
+ // all). tests/config-sync.test.ts enforces all of this rather than trusting
15
+ // the hand-sync. Content-mode/paren/styles details below come from
16
+ // Block-Syntax-Specification.md §3 and Inline-Syntax-Specification.md §4.
17
+ /**
18
+ * How a "(...)" slot's raw text becomes the convenience field its `parenRole`
19
+ * implies. Lives here rather than in the Parser because `parenRole` does —
20
+ * the Serializer needs the same mapping to check that a hand-built node's
21
+ * `level`/`imgOptions`/... actually agree with its `paren`, and a second copy
22
+ * of the rules is exactly how the two would drift apart.
23
+ */
24
+ export function parseImgOptions(raw) {
25
+ const options = {};
26
+ const parts = raw.split(',').map(s => s.trim()).filter(Boolean);
27
+ parts.forEach((part, idx) => {
28
+ const eq = part.indexOf('=');
29
+ if (eq === -1) {
30
+ if (idx === 0)
31
+ options.src = part; // first bare option defaults to src — Block Syntax Spec §5 Image
32
+ return;
33
+ }
34
+ const key = part.slice(0, eq).trim();
35
+ const value = part.slice(eq + 1).trim();
36
+ if (key)
37
+ options[key] = value;
38
+ });
39
+ return options;
40
+ }
41
+ /** @heading's level, defaulting a missing or out-of-range "(...)" to 1. */
42
+ export function clampLevel(raw) {
43
+ const lvl = parseInt(raw ?? '1', 10);
44
+ return Number.isFinite(lvl) && lvl >= 1 && lvl <= 6 ? lvl : 1;
45
+ }
46
+ /** @list's "(ordered)" flag. */
47
+ export function isOrderedParen(raw) {
48
+ return /^\s*ordered\s*$/i.test(raw ?? '');
49
+ }
50
+ /**
51
+ * What a "(...)" slot implies, in exactly the shape the Parser records it.
52
+ *
53
+ * Note which keys are *present with an undefined value*: the Parser assigns
54
+ * `title`/`language`/`uri`/`id` unconditionally, so `@card[x]` really does
55
+ * carry `title: undefined` rather than no key at all. Reproducing that
56
+ * faithfully is what lets a canonicalized node compare deep-equal to a parsed
57
+ * one — `{ title: undefined }` and `{}` are different objects to
58
+ * assert.deepStrictEqual.
59
+ *
60
+ * `ordered` is the exception the Parser sets only when true, per DocASTNode's
61
+ * own documentation ("unset/false renders as a bullet list"), so a non-ordered
62
+ * @list has no key at all.
63
+ */
64
+ export function deriveParenFields(role, paren) {
65
+ switch (role) {
66
+ case 'level': return { level: clampLevel(paren) };
67
+ case 'title': return { title: paren };
68
+ case 'language': return { language: paren };
69
+ case 'uri': return { uri: paren };
70
+ case 'id': return { id: paren };
71
+ case 'options': return { imgOptions: parseImgOptions(paren ?? '') };
72
+ case 'ordered': return isOrderedParen(paren) ? { ordered: true } : {};
73
+ default: return {};
74
+ }
75
+ }
76
+ function def(partial) {
77
+ return partial;
78
+ }
79
+ const REGISTRY = [
80
+ // Metadata — Block Syntax Specification §9
81
+ def({ name: 'meta', kind: 'meta', content: 'meta', paren: 'none' }),
82
+ // Structural Blocks — §5
83
+ def({ name: 'heading', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'level' }),
84
+ def({ name: 'paragraph', kind: 'block', content: 'generic', paren: 'none' }),
85
+ def({ name: 'quote', kind: 'block', content: 'generic', paren: 'none' }),
86
+ def({ name: 'list', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'ordered' }),
87
+ def({ name: 'code', kind: 'block', content: 'raw', paren: 'optional', parenRole: 'language' }),
88
+ def({ name: 'img', kind: 'block', content: 'generic', paren: 'required', parenRole: 'options', styles: 'image' }),
89
+ def({ name: 'table', kind: 'block', content: 'table', paren: 'none' }),
90
+ def({ name: 'cols', kind: 'block', content: 'comma-list', paren: 'none', restrictedTo: 'table' }),
91
+ def({ name: 'data', kind: 'block', content: 'rows', paren: 'none', restrictedTo: 'table' }),
92
+ def({ name: 'hr', kind: 'block', content: 'none', paren: 'none' }),
93
+ def({ name: 'svg', kind: 'block', content: 'raw', paren: 'none' }),
94
+ // Container Blocks — §6
95
+ def({ name: 'details', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'title', styles: 'color' }),
96
+ def({ name: 'card', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'title', styles: 'card' }),
97
+ // Callout Blocks — §7
98
+ def({ name: 'note', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'title', styles: 'color' }),
99
+ def({ name: 'tip', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'title', styles: 'color' }),
100
+ def({ name: 'important', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'title', styles: 'color' }),
101
+ def({ name: 'warning', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'title', styles: 'color' }),
102
+ def({ name: 'caution', kind: 'block', content: 'generic', paren: 'optional', parenRole: 'title', styles: 'color' }),
103
+ // Widget Blocks — §8
104
+ def({ name: 'tabs', kind: 'block', content: 'tabs', paren: 'none' }),
105
+ def({ name: 'tab', kind: 'block', content: 'generic', paren: 'required', parenRole: 'title', restrictedTo: 'tabs' }),
106
+ def({ name: 'mermaid', kind: 'block', content: 'raw', paren: 'none' }),
107
+ // Text Formatting — Inline §4, §7, §9
108
+ def({ name: 'bold', kind: 'inline', content: 'generic', paren: 'none' }),
109
+ def({ name: 'italic', kind: 'inline', content: 'generic', paren: 'none' }),
110
+ def({ name: 'underline', kind: 'inline', content: 'generic', paren: 'none' }),
111
+ def({ name: 'del', kind: 'inline', content: 'generic', paren: 'none' }),
112
+ def({ name: 'mark', kind: 'inline', content: 'generic', paren: 'none', styles: 'color' }),
113
+ def({ name: 'color', kind: 'inline', content: 'generic', paren: 'none', styles: 'color' }),
114
+ // Text outline/border — shares @color's exact {styles} slot (named color
115
+ // token or literal hex) and swatch table, just painted onto a border
116
+ // instead of a foreground color.
117
+ def({ name: 'bordered', kind: 'inline', content: 'generic', paren: 'none', styles: 'color' }),
118
+ def({ name: 'raw', kind: 'inline', content: 'raw-escaped', paren: 'none' }),
119
+ // Semantic Inline — Inline §4, §8
120
+ def({ name: 'sup', kind: 'inline', content: 'generic', paren: 'none' }),
121
+ def({ name: 'sub', kind: 'inline', content: 'generic', paren: 'none' }),
122
+ def({ name: 'kbd', kind: 'inline', content: 'key', paren: 'none' }),
123
+ def({ name: 'link', kind: 'inline', content: 'generic', paren: 'required', parenRole: 'uri' }),
124
+ // Footnotes — Inline §4
125
+ def({ name: 'defn', kind: 'inline', content: 'generic', paren: 'required', parenRole: 'id' }),
126
+ def({ name: 'fn', kind: 'inline', content: 'integer', paren: 'none' }),
127
+ // Special Nodes — Inline §4
128
+ // Note: "@@" (escape) is deliberately NOT registered here. Per Inline Spec §2,
129
+ // it is resolved at Lexer step 1 by character pattern, before any Command
130
+ // Registry lookup — see Special-Nodes.md §5. Registering it as a normal
131
+ // NodeDef would misrepresent it as a registry-driven command like the rest.
132
+ def({ name: 'n', kind: 'inline', content: 'none', paren: 'none' }),
133
+ ];
134
+ const BY_NAME = new Map(REGISTRY.map(d => [d.name, d]));
135
+ const ALIASES = [
136
+ { alias: 'h', canonical: 'heading', label: 'Heading' },
137
+ { alias: 'p', canonical: 'paragraph', label: 'Paragraph' },
138
+ { alias: 'b', canonical: 'bold', label: 'Bold' },
139
+ { alias: 'i', canonical: 'italic', label: 'Italic' },
140
+ { alias: 'u', canonical: 'underline', label: 'Underline' },
141
+ ];
142
+ const ALIAS_BY_NAME = new Map(ALIASES.map(a => [a.alias, a]));
143
+ export function getNodeDef(name) {
144
+ const direct = BY_NAME.get(name);
145
+ if (direct)
146
+ return direct;
147
+ const alias = ALIAS_BY_NAME.get(name);
148
+ return alias ? BY_NAME.get(alias.canonical) : undefined;
149
+ }
150
+ export function isKnownCommand(name) {
151
+ return BY_NAME.has(name) || ALIAS_BY_NAME.has(name);
152
+ }
153
+ /** Alias metadata for `name`, or undefined if `name` isn't a short alias (including if it's already canonical). */
154
+ export function getAliasInfo(name) {
155
+ return ALIAS_BY_NAME.get(name);
156
+ }
157
+ /** The full alias table, for consumers that need to derive keyword lists including short aliases (e.g. src/editor/monarch.ts). */
158
+ export function getAllAliasDefs() {
159
+ return ALIASES;
160
+ }
161
+ /**
162
+ * The full node table, for consumers that need to derive keyword lists
163
+ * (e.g. the editor's Monarch tokenizer, src/editor/monarch.ts) instead of
164
+ * hand-copying names. Keeping this as the single export point means new
165
+ * REGISTRY entries automatically flow into anything built from it.
166
+ */
167
+ export function getAllNodeDefs() {
168
+ return REGISTRY;
169
+ }
170
+ /**
171
+ * Nodes let through inside @cols/@data cells (Structural-Blocks.md §5 Table
172
+ * only promises plain text there, but most of these just restyle text —
173
+ * bold/color/etc — without affecting the table's own structure, so authors
174
+ * can still use them for cell formatting). New nodes must opt in here
175
+ * explicitly; anything not listed (e.g. @card, @details) is Strict Mode's
176
+ * concern — Parser.ts's parseInlineCellList() throws for it rather than
177
+ * silently dropping it.
178
+ *
179
+ * @defn is deliberately excluded: it's collected document-wide and rendered
180
+ * once as a real `<li>` inside the footnotes `<ol>` (see Adapters.ts's
181
+ * renderFootnotes()), not loose inside a `<td>`.
182
+ * @fn (the footnote *reference*, a self-contained `<sup><a>` back-link) is
183
+ * fine and included — Parser.ts checks this set before its raw-family
184
+ * carve-out so @fn gets parsed as a real node instead of dumped as bare digits.
185
+ */
186
+ const CELL_ALLOWED_INLINE = new Set([
187
+ 'bold', 'italic', 'underline', 'del', 'mark', 'color', 'bordered', 'sup', 'sub', 'link', 'fn',
188
+ // @raw was left out while it was purely an escape mechanism with no visual
189
+ // identity of its own. Now that it renders as inline code (Inline Syntax
190
+ // Specification §9), excluding it means an API table — the single most
191
+ // common kind — silently loses the monospace on every identifier in it, the
192
+ // node being dropped and its text dumped in as a bare string.
193
+ 'raw',
194
+ ]);
195
+ export function isCellAllowedNode(name) {
196
+ return CELL_ALLOWED_INLINE.has(name);
197
+ }
198
+ /** Named color tokens shared by @mark/@color/@bordered and the Container/Callout Blocks (Inline Spec §7). */
199
+ const NAMED_COLOR_TOKENS = [
200
+ 'yellow', 'red', 'green', 'blue', 'orange', 'purple', 'gray',
201
+ ];
202
+ /** Languages offered for @code's "(language)" — a convenience list, not a closed set; any string is valid. */
203
+ const CODE_LANGUAGES = [
204
+ 'ts', 'tsx', 'js', 'jsx', 'json', 'html', 'css', 'scss', 'python',
205
+ 'bash', 'sql', 'go', 'rust', 'java', 'c', 'cpp', 'yaml', 'markdown', 'text',
206
+ ];
207
+ /** @img's "(image-option-list)" keys — Block Spec §5's option table. */
208
+ const IMAGE_OPTIONS = [
209
+ { label: 'src=', insert: 'src=${1}', detail: 'Image source URL (the key is optional for the first option)' },
210
+ { label: 'width=', insert: 'width=${1:200}', detail: 'Display width' },
211
+ { label: 'height=', insert: 'height=${1:150}', detail: 'Display height' },
212
+ { label: 'align=', insert: 'align=${1|left,center,right|}', detail: 'Alignment' },
213
+ { label: 'radius=', insert: 'radius=${1:8px}', detail: 'Corner radius (any CSS value; overridden by {radius-N})' },
214
+ { label: 'border=', insert: 'border=${1:1px solid #ccc}', detail: 'Border (any CSS value; overridden by {#RRGGBB})' },
215
+ ];
216
+ /**
217
+ * What to offer inside `name`'s "(...)" slot. Empty for free-text roles
218
+ * (title/uri/id) — there's nothing meaningful to enumerate, so the editor
219
+ * should stay quiet rather than guess.
220
+ */
221
+ export function getParenSuggestions(name) {
222
+ const nodeDef = getNodeDef(name);
223
+ if (!nodeDef || nodeDef.paren === 'none')
224
+ return [];
225
+ switch (nodeDef.parenRole) {
226
+ case 'level':
227
+ return [1, 2, 3, 4, 5, 6].map(n => ({ label: String(n), detail: `Level ${n} heading` }));
228
+ case 'ordered':
229
+ return [{ label: 'ordered', detail: 'Ordered list (unordered when omitted)' }];
230
+ case 'language':
231
+ return CODE_LANGUAGES.map(lang => ({ label: lang, detail: 'Syntax highlighting language' }));
232
+ case 'options':
233
+ return IMAGE_OPTIONS.map(o => ({ ...o }));
234
+ default: // 'title' | 'uri' | 'id' — free text
235
+ return [];
236
+ }
237
+ }
238
+ /**
239
+ * What to offer inside `name`'s "{styles}" slot, per its StyleSet. Empty when
240
+ * the node has no {styles} slot at all — the editor shows nothing and
241
+ * Parser.ts separately flags the slot itself as a grammar error.
242
+ */
243
+ export function getStyleSuggestions(name) {
244
+ const nodeDef = getNodeDef(name);
245
+ switch (nodeDef?.styles) {
246
+ case 'color':
247
+ return [
248
+ ...NAMED_COLOR_TOKENS.map(token => ({ label: token, detail: 'Named color token' })),
249
+ { label: '#RRGGBB', insert: '#${1:3366ff}', detail: 'Hex color value (used directly without remapping)' },
250
+ ];
251
+ case 'card':
252
+ return [
253
+ { label: '#RRGGBB', insert: '#${1:3366ff}', detail: 'Background color (Card Style v1)' },
254
+ { label: 'radius-N', insert: 'radius-${1:12}', detail: 'Corner radius in pixels (Card Style v1)' },
255
+ ];
256
+ case 'image':
257
+ return [
258
+ { label: '#RRGGBB', insert: '#${1:3366ff}', detail: 'Border color, applied as a 1px solid line (Image Style v1)' },
259
+ { label: 'radius-N', insert: 'radius-${1:12}', detail: 'Corner radius in pixels (Image Style v1)' },
260
+ ];
261
+ default:
262
+ return [];
263
+ }
264
+ }
265
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export interface DocASTNode {
2
+ type: string;
3
+ /** Top-level document nodes only — source character offset of the node's opening "@", used to map it back to an editor line for scroll sync (see pipeline.ts). */
4
+ start?: number;
5
+ /** Raw text of the "(...)" slot, if present — meaning depends on the node (see `parenRole` in registry.ts). */
6
+ paren?: string;
7
+ /** Parsed "{styles}" comma-list tokens — @mark only (Inline Syntax Specification §7). */
8
+ styles?: string[];
9
+ /** Generic nestable content — used by every node whose registry `content` mode is 'generic'. */
10
+ content: (DocASTNode | string)[];
11
+ /** Resolved raw text — used by raw-family nodes (@code, @mermaid, @raw, @kbd, @fn). */
12
+ raw?: string;
13
+ level?: number;
14
+ title?: string;
15
+ language?: string;
16
+ uri?: string;
17
+ id?: string;
18
+ imgOptions?: Record<string, string>;
19
+ color?: string;
20
+ /** @list only — true when `@list(ordered)`; unset/false renders as a bullet list. */
21
+ ordered?: boolean;
22
+ /** @fn only — parsed integer form of `raw`. */
23
+ number?: number;
24
+ /** Synthetic `type: 'list-item'` nodes only (built by Parser.buildListItems, never a real @command) — set when the item's line had an explicit "N. "/"N)" prefix, so @list(ordered) can restart/resume numbering via `<li value>`. */
25
+ marker?: number;
26
+ /** @table (from its @cols child) — each column is inline content (text + a curated set of formatting nodes, see registry.ts's isCellAllowedNode). */
27
+ columns?: (DocASTNode | string)[][];
28
+ /** @table (from its @data child) — each row is a list of cells, each cell inline content like `columns`. */
29
+ rows?: (DocASTNode | string)[][][];
30
+ tabs?: DocASTNode[];
31
+ meta?: Record<string, string>;
32
+ }
33
+ /** Non-fatal parse issue — surfaced to the editor as a marker instead of aborting the parse. */
34
+ export interface DocDiagnostic {
35
+ start: number;
36
+ end: number;
37
+ message: string;
38
+ /**
39
+ * Marker tier. Absent means 'error' (the historical behavior, and what every
40
+ * pre-existing diagnosis site still emits). 'warning' flags constructs that
41
+ * parse but almost certainly not the way the author meant (e.g. an @raw
42
+ * escape that swallowed the intended closing bracket); 'info' is a
43
+ * non-judgmental heads-up (e.g. "this @] is an escape, it won't end the
44
+ * node"). Neither blocks parsing or rendering.
45
+ */
46
+ severity?: 'error' | 'warning' | 'info';
47
+ }
48
+ export declare class DocSyntaxError extends Error {
49
+ constructor(message: string);
50
+ }
51
+ /**
52
+ * The supported preview style: index, the neutral default presentation.
53
+ */
54
+ export type PreviewStyle = 'index';
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IAEb,kKAAkK;IAClK,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,+GAA+G;IAC/G,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yFAAyF;IACzF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB,gGAAgG;IAChG,OAAO,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC;IAEjC,uFAAuF;IACvF,GAAG,CAAC,EAAE,MAAM,CAAC;IAGb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sOAAsO;IACtO,MAAM,CAAC,EAAE,MAAM,CAAC;IAGhB,qJAAqJ;IACrJ,OAAO,CAAC,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,EAAE,CAAC;IACpC,4GAA4G;IAC5G,IAAI,CAAC,EAAE,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC;IACnC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;CACzC;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ export class DocSyntaxError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'DocSyntaxError';
5
+ }
6
+ }
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA0DA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF"}