@wdprlib/ast 1.1.0 → 1.1.1

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/dist/index.d.cts CHANGED
@@ -1,124 +1,283 @@
1
1
  /**
2
- * Source code position
2
+ * Source position tracking for Wikidot markup.
3
+ *
4
+ * Every token produced by the parser can carry a {@link Position} that maps it
5
+ * back to its original location in the source text. This is used for error
6
+ * reporting, source-map generation, and editor integration.
7
+ *
8
+ * Both {@link Point} and {@link Position} follow the
9
+ * [unist Position](https://github.com/syntax-tree/unist#position) convention:
10
+ * lines and columns are **1-based**, offsets are **0-based**.
11
+ *
12
+ * @module
13
+ */
14
+ /**
15
+ * A single point in the source text.
16
+ *
17
+ * Represents one end (start or end) of a {@link Position} range.
18
+ * Line and column are 1-based to match text-editor conventions;
19
+ * offset is 0-based for direct use with `String.prototype.slice()`.
20
+ *
21
+ * @group Source Position
3
22
  */
4
23
  interface Point {
5
- /** Line number (1-based) */
24
+ /** Line number in the source text (1-based: the first line is line 1) */
6
25
  line: number;
7
- /** Column number (1-based) */
26
+ /** Column number within the line (1-based: the first character is column 1) */
8
27
  column: number;
9
- /** Offset (0-based) */
28
+ /** Character offset from the beginning of the source string (0-based) */
10
29
  offset: number;
11
30
  }
12
31
  /**
13
- * Source code range
32
+ * A contiguous range in the source text, defined by a start and end {@link Point}.
33
+ *
34
+ * The range is inclusive of `start` and exclusive of `end` — i.e., the
35
+ * character at `end.offset` is **not** part of the range.
36
+ *
37
+ * @group Source Position
14
38
  */
15
39
  interface Position {
40
+ /** The first character of the range */
16
41
  start: Point;
42
+ /** One past the last character of the range */
17
43
  end: Point;
18
44
  }
19
45
  /**
20
- * Helper to create a Point
46
+ * Create a {@link Point} value.
47
+ *
48
+ * @param line - 1-based line number
49
+ * @param column - 1-based column number
50
+ * @param offset - 0-based character offset
51
+ * @returns A frozen {@link Point} object
52
+ *
53
+ * @group Source Position
21
54
  */
22
55
  declare function createPoint(line: number, column: number, offset: number): Point;
23
56
  /**
24
- * Helper to create a Position
57
+ * Create a {@link Position} range from two {@link Point}s.
58
+ *
59
+ * @param start - Beginning of the range (inclusive)
60
+ * @param end - End of the range (exclusive)
61
+ * @returns A {@link Position} spanning `start..end`
62
+ *
63
+ * @group Source Position
25
64
  */
26
65
  declare function createPosition(start: Point, end: Point): Position;
27
66
  /**
28
- * Element types for AST
67
+ * AST element types for Wikidot markup.
68
+ *
69
+ * Wikidot markup (`+ heading`, `**bold**`, `[[module ListPages]]`, etc.) is parsed into
70
+ * a structured representation defined here. Each {@link Element} is a tagged union of
71
+ * `{ element: tag, data: payload }`, where the data shape for each tag is defined in
72
+ * {@link ElementDataMap}.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * import { parse } from "@wdprlib/parser";
77
+ * const tree = parse("**Hello** world");
78
+ * // tree.elements[0] → { element: "container", data: { type: "paragraph", ... } }
79
+ * ```
80
+ *
81
+ * @module
29
82
  */
30
83
  /**
31
- * Attributes map
84
+ * Key-value map of HTML attributes.
85
+ * Populated from the Wikidot `_ class="foo" style="color:red"` attribute syntax.
86
+ *
87
+ * @group Primitives
32
88
  */
33
89
  type AttributeMap = Record<string, string>;
34
90
  /**
35
- * Variable map for includes
91
+ * Key-value map of include variables.
92
+ * Populated from `[[include page | key=value]]` pairs.
93
+ *
94
+ * @group Primitives
36
95
  */
37
96
  type VariableMap = Record<string, string>;
38
97
  /**
39
- * Alignment
98
+ * Text alignment direction.
99
+ * Maps to Wikidot alignment blocks: `[[=]]` (center), `[[<]]` (left),
100
+ * `[[>]]` (right), `[[==]]` (justify).
101
+ *
102
+ * @group Primitives
40
103
  */
41
104
  type Alignment = "left" | "right" | "center" | "justify";
42
105
  /**
43
- * Float alignment
106
+ * Image float alignment. Used in `[[image]]` positioning.
107
+ *
108
+ * When `float` is true, the image uses CSS float.
109
+ * When false, it uses text-align only.
110
+ *
111
+ * @group Primitives
44
112
  */
45
113
  interface FloatAlignment {
46
114
  align: Alignment;
115
+ /** Whether to use CSS float (true) or just text-align (false) */
47
116
  float: boolean;
48
117
  }
49
118
  /**
50
- * Heading level
119
+ * Heading level (1-6). Corresponds to Wikidot `+` (h1) through `++++++` (h6).
120
+ *
121
+ * @group Container Types
51
122
  */
52
123
  type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
53
124
  /**
54
- * Heading structure
125
+ * Heading configuration. Carries the level and whether this heading
126
+ * should appear in the table of contents.
127
+ *
128
+ * In Wikidot, `+*` (asterisk suffix) excludes the heading from the TOC.
129
+ *
130
+ * @group Container Types
55
131
  */
56
132
  interface Heading {
57
133
  level: HeadingLevel;
134
+ /** false when the heading uses `+*` syntax to opt out of the TOC */
58
135
  "has-toc": boolean;
59
136
  }
60
137
  /**
61
- * Header container type
138
+ * Discriminator for heading containers within {@link ContainerType}.
139
+ *
140
+ * @group Container Types
62
141
  */
63
142
  interface HeaderType {
64
143
  header: Heading;
65
144
  }
66
145
  /**
67
- * Align container type
146
+ * Discriminator for alignment-block containers within {@link ContainerType}.
147
+ * Produced by `[[=]]`, `[[<]]`, `[[>]]`, and `[[==]]` blocks.
148
+ *
149
+ * @group Container Types
68
150
  */
69
151
  interface AlignType {
70
152
  align: Alignment;
71
153
  }
72
154
  /**
73
- * String-only container types (formatting, structural, etc.)
155
+ * Container types expressible as plain string literals.
156
+ * Covers inline formatting (`**bold**`, `//italics//`, etc.) and
157
+ * block-level structures (`div`, `blockquote`, `table-cell`, etc.).
158
+ *
159
+ * @group Container Types
74
160
  */
75
161
  type StringContainerType = "bold" | "italics" | "underline" | "superscript" | "subscript" | "strikethrough" | "monospace" | "span" | "div" | "blockquote" | "size" | "paragraph" | "heading" | "collapsible" | "definition-list" | "definition-list-item" | "definition-list-key" | "definition-list-value" | "table-row" | "table-cell";
76
162
  /**
77
- * Container types
163
+ * Union of all container type discriminators.
164
+ * Every container element in the AST carries one of these to identify
165
+ * what kind of container it is.
166
+ *
167
+ * - String literals: inline formatting and block structures
168
+ * - {@link HeaderType}: heading elements (`+ Heading`)
169
+ * - {@link AlignType}: alignment blocks (`[[=]]...[[/=]]`)
170
+ *
171
+ * @group Container Types
78
172
  */
79
173
  type ContainerType = StringContainerType | HeaderType | AlignType;
80
174
  /**
81
- * Type guard: ContainerType is a string literal
175
+ * Type guard: checks whether a {@link ContainerType} is a plain string literal.
176
+ *
177
+ * @group Container Types
82
178
  */
83
179
  declare function isStringContainerType(type: ContainerType): type is StringContainerType;
84
180
  /**
85
- * Type guard: ContainerType is a HeaderType
181
+ * Type guard: checks whether a {@link ContainerType} is a {@link HeaderType}.
182
+ *
183
+ * @group Container Types
86
184
  */
87
185
  declare function isHeaderType(type: ContainerType): type is HeaderType;
88
186
  /**
89
- * Type guard: ContainerType is an AlignType
187
+ * Type guard: checks whether a {@link ContainerType} is an {@link AlignType}.
188
+ *
189
+ * @group Container Types
90
190
  */
91
191
  declare function isAlignType(type: ContainerType): type is AlignType;
92
192
  /**
93
- * Container data
193
+ * Data payload for container elements (paragraphs, bold, headings, divs, etc.).
194
+ *
195
+ * Every nestable Wikidot construct (`**bold**`, `[[div]]...[[/div]]`,
196
+ * `+ heading`, etc.) is represented as an `{ element: "container", data: ContainerData }`.
197
+ *
198
+ * The `_`-prefixed fields are internal parser bookkeeping that gets stripped before
199
+ * the final AST is returned. They coordinate paragraph splitting and span unwrapping
200
+ * during post-processing.
201
+ *
202
+ * @group Container Types
94
203
  */
95
204
  interface ContainerData {
205
+ /** Identifies the kind of container and determines how it renders */
96
206
  type: ContainerType;
207
+ /** HTML attributes specified via `_ class="..." style="..."` syntax */
97
208
  attributes: AttributeMap;
209
+ /** Child elements nested inside this container */
98
210
  elements: Element[];
211
+ /**
212
+ * Set on `[[span_]]` elements. Signals the post-processor to merge adjacent
213
+ * paragraphs, removing the `<p>` wrapper around the span's content.
214
+ * Consumed during post-processing; never present in the final AST.
215
+ * @internal
216
+ */
99
217
  _paragraphStrip?: boolean;
218
+ /**
219
+ * Set on empty `[[span_]][[/span_]]` elements. Acts as a line-break absorber:
220
+ * adjacent line-breaks are removed around this marker.
221
+ * Consumed during post-processing; never present in the final AST.
222
+ * @internal
223
+ */
100
224
  _emptyParagraphStrip?: boolean;
225
+ /**
226
+ * Set on content that follows a blank line inside `[[span_]]`.
227
+ * Indicates this content should be extracted outside its paragraph wrapper.
228
+ * Consumed during post-processing; never present in the final AST.
229
+ * @internal
230
+ */
101
231
  _escapedFromParagraph?: boolean;
232
+ /**
233
+ * Set on an orphaned `[[/span]]` closing tag (no matching open tag).
234
+ * The paragraph rule uses this to retroactively wrap preceding content in a span.
235
+ * Consumed during post-processing; never present in the final AST.
236
+ * @internal
237
+ */
102
238
  _closeSpan?: boolean;
239
+ /**
240
+ * Set on the 2nd+ segments of a regular `[[span]]` that was split by blank lines.
241
+ * Marks where the post-processor should split the enclosing paragraph.
242
+ * Consumed during post-processing; never present in the final AST.
243
+ * @internal
244
+ */
103
245
  _splitByBlankLine?: boolean;
104
246
  }
105
247
  /**
106
- * Anchor target
248
+ * Link target window. Maps to the HTML `target` attribute.
249
+ * In Wikidot, `*` suffix on a link (`[[[page*]]]`) sets `"new-tab"`.
250
+ *
251
+ * @group Link Types
107
252
  */
108
253
  type AnchorTarget = "new-tab" | "parent" | "top" | "same";
109
254
  /**
110
- * Page reference (for internal links)
255
+ * Reference to an internal wiki page.
256
+ * Produced by `[[[page]]]` or cross-site `[[[site:page]]]` syntax.
257
+ *
258
+ * @group Link Types
111
259
  */
112
260
  interface PageRef {
261
+ /** Site name for cross-site links; null for same-site links */
113
262
  site: string | null;
263
+ /** Page UNIX name (e.g. `"scp-001"`, `"system:page-tags"`) */
114
264
  page: string;
115
265
  }
116
266
  /**
117
- * Link location - either a page reference or a URL string
267
+ * Link destination: either a {@link PageRef} for internal wiki links
268
+ * or a plain URL string for external links.
269
+ *
270
+ * @group Link Types
118
271
  */
119
272
  type LinkLocation = PageRef | string;
120
273
  /**
121
- * Link label types
274
+ * Link display label.
275
+ *
276
+ * - `{ text: string }` — explicit text (`[[[page | label]]]`)
277
+ * - `{ url: string | null }` — use the URL itself as the label
278
+ * - `"page"` — use the page name as the label (`[[[page]]]`)
279
+ *
280
+ * @group Link Types
122
281
  */
123
282
  type LinkLabel = {
124
283
  text: string;
@@ -126,11 +285,26 @@ type LinkLabel = {
126
285
  url: string | null;
127
286
  } | "page";
128
287
  /**
129
- * Link type
288
+ * Link classification, determined by the syntax used.
289
+ *
290
+ * - `"direct"` — bare URL (`[http://...]`)
291
+ * - `"page"` — page link (`[[[some-page]]]`)
292
+ * - `"interwiki"` — interwiki link (`[[[wikipedia:article]]]`)
293
+ * - `"anchor"` — in-page anchor (`[[# section]]`)
294
+ * - `"table-of-contents"` — TOC-generated link
295
+ *
296
+ * @group Link Types
130
297
  */
131
298
  type LinkType = "direct" | "page" | "interwiki" | "anchor" | "table-of-contents";
132
299
  /**
133
- * Image source
300
+ * Image source. Wikidot supports four resolution strategies:
301
+ *
302
+ * - `"url"` — absolute URL
303
+ * - `"file1"` — file attached to the current page (`filename`)
304
+ * - `"file2"` — file on another page (`page/filename`)
305
+ * - `"file3"` — file on another site (`site:page/filename`)
306
+ *
307
+ * @group Image Types
134
308
  */
135
309
  type ImageSource = {
136
310
  type: "url";
@@ -155,11 +329,16 @@ type ImageSource = {
155
329
  };
156
330
  };
157
331
  /**
158
- * List type
332
+ * List style. `"bullet"` for `*` items, `"numbered"` for `#` items,
333
+ * `"generic"` for `[[li]]` block items.
334
+ *
335
+ * @group List Types
159
336
  */
160
337
  type ListType = "bullet" | "numbered" | "generic";
161
338
  /**
162
- * List item - discriminated union
339
+ * A single list item. Either a leaf with inline content, or a nested sub-list.
340
+ *
341
+ * @group List Types
163
342
  */
164
343
  type ListItem = {
165
344
  "item-type": "elements";
@@ -171,7 +350,9 @@ type ListItem = {
171
350
  data: ListData;
172
351
  };
173
352
  /**
174
- * List data
353
+ * Data payload for a list element (`* item`, `# item`, or `[[li]]`).
354
+ *
355
+ * @group List Types
175
356
  */
176
357
  interface ListData {
177
358
  type: ListType;
@@ -179,95 +360,147 @@ interface ListData {
179
360
  items: ListItem[];
180
361
  }
181
362
  /**
182
- * Definition list item
363
+ * A single entry in a definition list (`: key : value`).
364
+ *
365
+ * @group List Types
183
366
  */
184
367
  interface DefinitionListItem {
368
+ /** Plain-text representation of the key (for quick lookups) */
185
369
  key_string: string;
370
+ /** Rich-content key (may contain inline formatting) */
186
371
  key: Element[];
372
+ /** Rich-content value */
187
373
  value: Element[];
188
374
  }
189
375
  /**
190
- * Table cell
376
+ * A single table cell (`||` delimited).
377
+ *
378
+ * @group Table Types
191
379
  */
192
380
  interface TableCell {
381
+ /** true if this cell is a header cell (`||~`) */
193
382
  header: boolean;
383
+ /** Number of columns this cell spans (via `||` count) */
194
384
  "column-span": number;
385
+ /** Explicit alignment, or null for default */
195
386
  align: Alignment | null;
196
387
  attributes: AttributeMap;
197
388
  elements: Element[];
198
389
  }
199
390
  /**
200
- * Table row
391
+ * A single table row.
392
+ *
393
+ * @group Table Types
201
394
  */
202
395
  interface TableRow {
203
396
  attributes: AttributeMap;
204
397
  cells: TableCell[];
205
398
  }
206
399
  /**
207
- * Table data
400
+ * Data payload for a table element.
401
+ *
402
+ * @group Table Types
208
403
  */
209
404
  interface TableData {
210
405
  attributes: AttributeMap;
211
406
  rows: TableRow[];
212
407
  }
213
408
  /**
214
- * Tab data
409
+ * A single tab in a `[[tabview]]` block.
410
+ *
411
+ * @group Block Elements
215
412
  */
216
413
  interface TabData {
414
+ /** Tab title displayed in the tab bar */
217
415
  label: string;
416
+ /** Content inside the tab panel */
218
417
  elements: Element[];
219
418
  }
220
419
  /**
221
- * Code block data
420
+ * Data for a `[[code]]` block.
421
+ *
422
+ * @group Block Elements
222
423
  */
223
424
  interface CodeBlockData {
425
+ /** Raw source text inside the code block */
224
426
  contents: string;
427
+ /** Language identifier for syntax highlighting, or null */
225
428
  language: string | null;
429
+ /** Optional name/label for the code block */
226
430
  name: string | null;
227
431
  }
228
432
  /**
229
- * Collapsible data
433
+ * Data for a `[[collapsible]]` block.
434
+ *
435
+ * @group Block Elements
230
436
  */
231
437
  interface CollapsibleData {
232
438
  elements: Element[];
233
439
  attributes: AttributeMap;
440
+ /** Whether the block starts in the expanded state */
234
441
  "start-open": boolean;
442
+ /** Custom text for the "show" toggle, or null for default */
235
443
  "show-text": string | null;
444
+ /** Custom text for the "hide" toggle, or null for default */
236
445
  "hide-text": string | null;
446
+ /** Whether to show the toggle at the top */
237
447
  "show-top": boolean;
448
+ /** Whether to show the toggle at the bottom */
238
449
  "show-bottom": boolean;
239
450
  }
240
451
  /**
241
- * Module types
452
+ * Discriminated union of all `[[module ...]]` block types.
453
+ *
454
+ * Known modules have fully typed fields; unknown modules fall back to
455
+ * `{ module: "unknown" }` with raw arguments preserved.
456
+ *
457
+ * @group Module Types
242
458
  */
243
459
  type Module = {
460
+ /** Unrecognized module — preserves raw arguments for pass-through */
244
461
  module: "unknown";
245
462
  name: string;
246
463
  arguments: AttributeMap;
247
464
  body?: string;
248
465
  } | {
466
+ /** `[[module Backlinks]]` — lists pages that link to a given page */
249
467
  module: "backlinks";
468
+ /** Target page, or null for the current page */
250
469
  page: string | null;
251
470
  } | {
471
+ /** `[[module Categories]]` — lists site categories */
252
472
  module: "categories";
473
+ /** Whether to include categories marked as hidden */
253
474
  "include-hidden": boolean;
254
475
  } | {
476
+ /** `[[module Join]]` — site membership join button */
255
477
  module: "join";
256
478
  "button-text": string | null;
257
479
  attributes: AttributeMap;
258
480
  } | {
481
+ /** `[[module PageTree]]` — hierarchical page tree */
259
482
  module: "page-tree";
483
+ /** Root page, or null for the site root */
260
484
  root: string | null;
261
485
  "show-root": boolean;
486
+ /** Max depth, or null for unlimited */
262
487
  depth: number | null;
263
488
  } | {
489
+ /** `[[module Rate]]` — page rating widget */
264
490
  module: "rate";
265
491
  } | {
492
+ /** `[[module ListUsers]]` — user listing with template body */
266
493
  module: "list-users";
494
+ /** User selector expression (e.g. `"."` for current user) */
267
495
  users: string;
496
+ /** Template body with `%%variable%%` placeholders */
268
497
  body?: string;
269
498
  attributes: AttributeMap;
270
499
  } | {
500
+ /**
501
+ * `[[module ListPages]]` — the most complex module.
502
+ * Queries pages by various criteria and renders each through a template body.
503
+ */
271
504
  module: "list-pages";
272
505
  category?: string;
273
506
  tags?: string;
@@ -296,12 +529,17 @@ type Module = {
296
529
  "rss-home"?: string;
297
530
  "rss-limit"?: number;
298
531
  "rss-only": boolean;
532
+ /** Prefix for URL path parameters (HPC support) */
299
533
  "url-attr-prefix"?: string;
534
+ /** Template body with `%%variable%%` placeholders */
300
535
  body?: string;
301
536
  attributes: AttributeMap;
302
537
  };
303
538
  /**
304
- * Embed types
539
+ * Inline embed from `[[embed]]` syntax (not `[[embed]]...[[/embed]]` blocks).
540
+ * Supports a fixed set of providers.
541
+ *
542
+ * @group Embed Types
305
543
  */
306
544
  type Embed = {
307
545
  embed: "youtube";
@@ -326,108 +564,229 @@ type Embed = {
326
564
  };
327
565
  };
328
566
  /**
329
- * Date item value
567
+ * Parsed `[[date]]` value with timezone.
568
+ *
569
+ * @group Value Types
330
570
  */
331
571
  interface DateItem {
572
+ /** Unix timestamp (seconds) */
332
573
  timestamp: number;
574
+ /** IANA timezone identifier */
333
575
  timezone: string;
334
576
  }
335
577
  /**
336
- * Clear float direction
578
+ * Direction for `[[f<]]`, `[[f>]]`, or `[[f=]]` (clear-float).
579
+ *
580
+ * @group Value Types
337
581
  */
338
582
  type ClearFloat = "left" | "right" | "both";
583
+ /**
584
+ * Data for `[[a]]` anchor element.
585
+ *
586
+ * @group Element Data
587
+ */
339
588
  interface AnchorData {
340
589
  target: AnchorTarget | null;
341
590
  attributes: AttributeMap;
342
591
  elements: Element[];
343
592
  }
593
+ /**
594
+ * Data for link elements (`[[[page]]]`, `[http://...]`, etc.).
595
+ *
596
+ * @group Element Data
597
+ */
344
598
  interface LinkData {
345
599
  type: LinkType;
346
600
  link: LinkLocation;
601
+ /** Extra path segment (e.g. anchor fragment) */
347
602
  extra: string | null;
348
603
  label: LinkLabel;
349
604
  target: AnchorTarget | null;
350
605
  }
606
+ /**
607
+ * Data for `[[image]]` elements.
608
+ *
609
+ * @group Element Data
610
+ */
351
611
  interface ImageData {
352
612
  source: ImageSource;
613
+ /** If set, the image becomes a clickable link */
353
614
  link: LinkLocation | null;
354
615
  alignment: FloatAlignment | null;
355
616
  attributes: AttributeMap;
356
617
  }
618
+ /**
619
+ * Data for `[[toc]]` (table of contents) elements.
620
+ *
621
+ * @group Element Data
622
+ */
357
623
  interface TableOfContentsData {
358
624
  attributes: AttributeMap;
359
625
  align: Alignment | null;
360
626
  }
627
+ /**
628
+ * Data for `[[footnoteblock]]` elements.
629
+ *
630
+ * @group Element Data
631
+ */
361
632
  interface FootnoteBlockData {
633
+ /** Custom title for the footnote section */
362
634
  title: string | null;
635
+ /** If true, the block is hidden (footnotes rendered inline instead) */
363
636
  hide?: boolean;
364
637
  }
638
+ /**
639
+ * Data for `[[bibcite label]]` (bibliography citation) elements.
640
+ * Renders as a numbered reference link in the text.
641
+ *
642
+ * @group Element Data
643
+ */
365
644
  interface BibliographyCiteData {
645
+ /** Citation key that matches an entry in `[[bibliography]]` */
366
646
  label: string;
647
+ /** Whether to render the citation number in brackets */
367
648
  brackets: boolean;
368
649
  }
650
+ /**
651
+ * Data for `[[bibliography]]` block elements.
652
+ * Collects all cited entries and renders as a reference list.
653
+ *
654
+ * @group Element Data
655
+ */
369
656
  interface BibliographyBlockData {
657
+ /** Definition list entries (`: label : description`) */
370
658
  entries: DefinitionListItem[];
659
+ /** Custom section title, or null for default */
371
660
  title: string | null;
661
+ /** If true, the block is hidden (for inline citation rendering) */
372
662
  hide: boolean;
373
663
  }
664
+ /**
665
+ * Data for `[[user name]]` elements.
666
+ *
667
+ * @group Element Data
668
+ */
374
669
  interface UserData {
375
670
  name: string;
671
+ /** Whether to show the user's avatar alongside the name */
376
672
  "show-avatar": boolean;
377
673
  }
674
+ /**
675
+ * Data for `[[date timestamp]]` elements.
676
+ *
677
+ * @group Element Data
678
+ */
378
679
  interface DateData {
379
680
  value: DateItem;
681
+ /** strftime-style format string, or null for default */
380
682
  format: string | null;
683
+ /** Whether to show a tooltip with the full date on hover */
381
684
  hover: boolean;
382
685
  }
686
+ /**
687
+ * Data for `##color|text##` inline color syntax.
688
+ *
689
+ * @group Element Data
690
+ */
383
691
  interface ColorData {
692
+ /** CSS color value (name, hex, rgb, etc.) */
384
693
  color: string;
385
694
  elements: Element[];
386
695
  }
696
+ /**
697
+ * Data for `[[math label]]` block math (LaTeX).
698
+ *
699
+ * @group Element Data
700
+ */
387
701
  interface MathData {
702
+ /** Optional equation label for cross-references */
388
703
  name: string | null;
704
+ /** Raw LaTeX source */
389
705
  "latex-source": string;
390
706
  }
707
+ /**
708
+ * Data for `[[$ ... $]]` inline math (LaTeX).
709
+ *
710
+ * @group Element Data
711
+ */
391
712
  interface MathInlineData {
713
+ /** Raw LaTeX source */
392
714
  "latex-source": string;
393
715
  }
716
+ /**
717
+ * Data for `[[html]]` block elements.
718
+ * Contains raw HTML that is sanitized at render time.
719
+ *
720
+ * @group Element Data
721
+ */
394
722
  interface HtmlData {
723
+ /** Raw HTML content */
395
724
  contents: string;
725
+ /** Optional `<style>` content extracted from the HTML */
396
726
  style?: string;
397
727
  }
398
728
  /**
399
- * Embed block data (Wikidot style [[embed]]..[[/embed]])
729
+ * Data for `[[embed]]...[[/embed]]` block elements.
400
730
  * Contains raw HTML that is validated against an allowlist at render time.
401
- * Unlike html element, embed-block is paragraph-safe.
731
+ * Unlike the `html` element, `embed-block` is paragraph-safe.
732
+ *
733
+ * @group Element Data
402
734
  */
403
735
  interface EmbedBlockData {
736
+ /** Raw HTML content */
404
737
  contents: string;
405
738
  }
739
+ /**
740
+ * Data for `[[iframe url]]` elements.
741
+ *
742
+ * @group Element Data
743
+ */
406
744
  interface IframeData {
407
745
  url: string;
408
746
  attributes: AttributeMap;
409
747
  }
748
+ /**
749
+ * Data for `[[include page]]` elements.
750
+ * After resolution via `resolveIncludes()`, `elements` is populated
751
+ * with the included page's parsed content.
752
+ *
753
+ * @group Element Data
754
+ */
410
755
  interface IncludeData {
756
+ /** Whether this include appeared in an inline (paragraph-safe) context */
411
757
  "paragraph-safe": boolean;
758
+ /** Variables passed to the included page (`key=value` pairs) */
412
759
  variables: VariableMap;
760
+ /** Target page reference */
413
761
  location: PageRef;
762
+ /** Parsed content of the included page (empty before resolution) */
414
763
  elements: Element[];
415
764
  }
765
+ /**
766
+ * Data for `[[iftags]]` conditional blocks.
767
+ * Content is shown/hidden based on the current page's tags.
768
+ *
769
+ * @group Element Data
770
+ */
416
771
  interface IfTagsData {
772
+ /** Tag condition expression (e.g. `"+scp -joke"`) */
417
773
  condition: string;
418
774
  elements: Element[];
419
775
  }
420
776
  /**
421
- * Expression data: [[#expr expression]]
777
+ * Data for `[[#expr expression]]` inline expressions.
422
778
  * The expression is stored as a string and evaluated at render time.
779
+ *
780
+ * @group Element Data
423
781
  */
424
782
  interface ExprData {
425
783
  expression: string;
426
784
  }
427
785
  /**
428
- * If data: [[#if value | then | else]]
429
- * Simple true/false checker that treats the value as a string.
430
- * False values: "false", "null", "", "0"
786
+ * Data for `[[#if value | then | else]]` conditionals.
787
+ * Simple truthy check false values: `"false"`, `"null"`, `""`, `"0"`.
788
+ *
789
+ * @group Element Data
431
790
  */
432
791
  interface IfCondData {
433
792
  condition: string;
@@ -435,14 +794,25 @@ interface IfCondData {
435
794
  else: Element[];
436
795
  }
437
796
  /**
438
- * IfExpr data: [[#ifexpr expression | then | else]]
439
- * Evaluates the expression and branches based on the result.
797
+ * Data for `[[#ifexpr expression | then | else]]` conditionals.
798
+ * Evaluates the expression numerically and branches on the result.
799
+ *
800
+ * @group Element Data
440
801
  */
441
802
  interface IfExprData {
442
803
  expression: string;
443
804
  then: Element[];
444
805
  else: Element[];
445
806
  }
807
+ /**
808
+ * Maps each element tag name to its data type.
809
+ *
810
+ * `void` means the element carries no data property (e.g. `line-break`).
811
+ *
812
+ * Declared as `type` (not `interface`) to prevent accidental declaration merging.
813
+ *
814
+ * @group Core
815
+ */
446
816
  type ElementDataMap = {
447
817
  container: ContainerData;
448
818
  module: Module;
@@ -489,15 +859,22 @@ type ElementDataMap = {
489
859
  ifexpr: IfExprData;
490
860
  };
491
861
  /**
492
- * All element tag names
862
+ * Union of all valid element tag names.
863
+ *
864
+ * @group Core
493
865
  */
494
866
  type ElementName = keyof ElementDataMap;
495
867
  /**
496
- * Get the data type for a given element name
868
+ * Resolves the data type for a given element tag name.
869
+ *
870
+ * @group Core
497
871
  */
498
872
  type ElementData<K extends ElementName> = ElementDataMap[K];
499
873
  /**
500
- * Get the Element variant for a given element name
874
+ * Resolves the full element shape for a given tag name.
875
+ * Elements with `void` data omit the `data` property entirely.
876
+ *
877
+ * @group Core
501
878
  */
502
879
  type ElementOf<K extends ElementName> = ElementDataMap[K] extends void ? {
503
880
  element: K;
@@ -506,61 +883,119 @@ type ElementOf<K extends ElementName> = ElementDataMap[K] extends void ? {
506
883
  data: ElementDataMap[K];
507
884
  };
508
885
  /**
509
- * Element - tagged union generated from ElementDataMap
886
+ * A single AST node. Tagged union over all element types.
887
+ *
888
+ * Use `element.element` to discriminate, then access `element.data`
889
+ * with the appropriate type.
890
+ *
891
+ * @example
892
+ * ```ts
893
+ * if (el.element === "text") {
894
+ * console.log(el.data); // string
895
+ * } else if (el.element === "container") {
896
+ * console.log(el.data.type); // ContainerType
897
+ * }
898
+ * ```
899
+ *
900
+ * @group Core
510
901
  */
511
902
  type Element = { [K in ElementName] : ElementOf<K> }[ElementName];
512
903
  /**
513
- * TOC entry collected during parsing (internal format)
904
+ * Table-of-contents entry collected during parsing.
905
+ * Used internally to build the TOC sidebar.
906
+ *
907
+ * @group Core
514
908
  */
515
909
  interface TocEntry {
910
+ /** Heading nesting level (1-6) */
516
911
  level: number;
912
+ /** Plain-text heading content */
517
913
  text: string;
518
914
  }
519
915
  /**
520
- * Syntax tree - root of the AST
916
+ * Root of the parsed AST.
917
+ *
918
+ * Besides the main `elements` array, the tree may carry extracted
919
+ * side-channel data (TOC, styles, code blocks, footnotes) that is
920
+ * collected during parsing and used at render time.
921
+ *
922
+ * @group Core
521
923
  */
522
924
  interface SyntaxTree {
925
+ /** Top-level elements of the document */
523
926
  elements: Element[];
927
+ /** Generated table-of-contents entries (if any headings have `has-toc: true`) */
524
928
  "table-of-contents"?: Element[];
929
+ /** CSS from `[[module CSS]]` blocks */
525
930
  styles?: string[];
931
+ /** Raw HTML from `[[html]]` blocks (rendered in sandboxed iframes) */
526
932
  "html-blocks"?: string[];
933
+ /** Code blocks extracted for deferred syntax highlighting */
527
934
  "code-blocks"?: CodeBlockData[];
935
+ /** Footnote content arrays, indexed by footnote number */
528
936
  footnotes?: Element[][];
529
937
  }
530
938
  /**
531
- * Create a text element
939
+ * Create a text element.
940
+ *
941
+ * @group Factories
532
942
  */
533
943
  declare function text(value: string): Element;
534
944
  /**
535
- * Create a container element
945
+ * Create a container element with the given type and children.
946
+ *
947
+ * @group Factories
536
948
  */
537
949
  declare function container(type: ContainerType, elements: Element[], attributes?: AttributeMap): Element;
538
950
  /**
539
- * Create a paragraph element
951
+ * Create a paragraph container.
952
+ *
953
+ * @group Factories
540
954
  */
541
955
  declare function paragraph(elements: Element[], attributes?: AttributeMap): Element;
542
956
  /**
543
- * Create a bold element
957
+ * Create a bold (`**...**`) container.
958
+ *
959
+ * @group Factories
544
960
  */
545
961
  declare function bold(elements: Element[], attributes?: AttributeMap): Element;
546
962
  /**
547
- * Create an italics element
963
+ * Create an italics (`//...//`) container.
964
+ *
965
+ * @group Factories
548
966
  */
549
967
  declare function italics(elements: Element[], attributes?: AttributeMap): Element;
550
968
  /**
551
- * Create a heading element
969
+ * Create a heading (`+ ...` through `++++++ ...`) container.
970
+ *
971
+ * @param level - Heading depth (1-6)
972
+ * @param elements - Heading content
973
+ * @param hasToc - Whether to include in the table of contents (default: true)
974
+ * @param attributes - Optional HTML attributes
975
+ *
976
+ * @group Factories
552
977
  */
553
978
  declare function heading(level: HeadingLevel, elements: Element[], hasToc?: boolean, attributes?: AttributeMap): Element;
554
979
  /**
555
- * Create a line break element
980
+ * Create a line-break element.
981
+ *
982
+ * @group Factories
556
983
  */
557
984
  declare function lineBreak(): Element;
558
985
  /**
559
- * Create a horizontal rule element
986
+ * Create a horizontal rule (`----`) element.
987
+ *
988
+ * @group Factories
560
989
  */
561
990
  declare function horizontalRule(): Element;
562
991
  /**
563
- * Create a link element
992
+ * Create a link element.
993
+ *
994
+ * @param linkLocation - Destination (URL string or {@link PageRef})
995
+ * @param label - Display label
996
+ * @param options - Optional type, extra path, and target overrides
997
+ *
998
+ * @group Factories
564
999
  */
565
1000
  declare function link(linkLocation: LinkLocation, label: LinkLabel, options?: {
566
1001
  type?: LinkType;
@@ -568,66 +1003,161 @@ declare function link(linkLocation: LinkLocation, label: LinkLabel, options?: {
568
1003
  target?: AnchorTarget | null;
569
1004
  }): Element;
570
1005
  /**
571
- * Create a list element
1006
+ * Create a list element.
1007
+ *
1008
+ * @group Factories
572
1009
  */
573
1010
  declare function list(type: ListType, items: ListItem[], attributes?: AttributeMap): Element;
574
1011
  /**
575
- * Create a list item (elements type)
1012
+ * Create a list item containing inline elements.
1013
+ *
1014
+ * @group Factories
576
1015
  */
577
1016
  declare function listItemElements(elements: Element[], attributes?: AttributeMap): ListItem;
578
1017
  /**
579
- * Create a list item (sub-list type)
1018
+ * Create a list item containing a nested sub-list.
1019
+ *
1020
+ * @group Factories
580
1021
  */
581
1022
  declare function listItemSubList(data: ListData): ListItem;
582
1023
  /**
583
- * Check if a container type is paragraph-safe.
1024
+ * Check whether a container type can appear inside a `<p>` element.
1025
+ *
1026
+ * Inline formatting (bold, italics, span, etc.) is paragraph-safe.
1027
+ * Block-level structures (div, blockquote, heading, etc.) are not.
1028
+ *
1029
+ * @group Utilities
584
1030
  */
585
1031
  declare function isContainerTypeParagraphSafe(type: ContainerType): boolean;
586
1032
  /**
587
- * Check if an element is paragraph-safe (can be contained within a paragraph).
1033
+ * Check whether an element can appear inside a `<p>` element.
588
1034
  *
589
- * This does a surface-level check and does not look into element interiors.
1035
+ * Performs a surface-level check on the element tag (and container type
1036
+ * for containers). Does not recurse into child elements.
1037
+ *
1038
+ * Used by the parser to decide whether to wrap adjacent inline elements
1039
+ * in a paragraph or leave them as block-level siblings.
1040
+ *
1041
+ * @group Utilities
590
1042
  */
591
1043
  declare function isParagraphSafe(element: Element): boolean;
592
1044
  /**
593
- * Wikitext parsing/rendering mode.
594
- * Each mode has different default settings for syntax availability.
1045
+ * Sentinel prefix for style slot placeholders in {@link SyntaxTree.styles}.
1046
+ *
1047
+ * When the resolver encounters an unresolved `[[iftags]]` block containing
1048
+ * `[[module CSS]]`, it inserts a sentinel string (`STYLE_SLOT_PREFIX + slotId`)
1049
+ * into the styles array to preserve source order. At render time the sentinel
1050
+ * is replaced with the actual CSS collected from the iftags block (if the
1051
+ * condition matches).
1052
+ *
1053
+ * A null-byte prefix ensures no collision with valid CSS content.
1054
+ */
1055
+ declare const STYLE_SLOT_PREFIX = "\0__IFTAGS_SLOT__";
1056
+ /**
1057
+ * Context-dependent settings for the Wikidot parser and renderer.
1058
+ *
1059
+ * Wikidot content appears in several different contexts — full wiki pages,
1060
+ * draft previews, forum posts, and direct messages — each with different
1061
+ * security and capability requirements. {@link WikitextSettings} captures
1062
+ * those differences so the parser/renderer can enable or disable features
1063
+ * accordingly.
1064
+ *
1065
+ * Use {@link createSettings} to get sane defaults for a given
1066
+ * {@link WikitextMode}, then override individual fields as needed.
1067
+ *
1068
+ * @module
1069
+ */
1070
+ /**
1071
+ * The context in which wikitext is being parsed and rendered.
1072
+ *
1073
+ * Each mode implies a different set of defaults for
1074
+ * {@link WikitextSettings}. The modes correspond to the places where
1075
+ * user-authored wikitext can appear on a Wikidot site.
1076
+ *
1077
+ * | Mode | Page syntax | Local paths | True IDs | Style elements |
1078
+ * |--------------------|:-----------:|:-----------:|:--------:|:--------------:|
1079
+ * | `"page"` | yes | yes | yes | yes |
1080
+ * | `"draft"` | yes | yes | no | no |
1081
+ * | `"forum-post"` | no | no | no | no |
1082
+ * | `"direct-message"` | no | no | no | no |
1083
+ *
1084
+ * @group Settings
595
1085
  */
596
1086
  type WikitextMode = "page" | "draft" | "forum-post" | "direct-message";
597
1087
  /**
598
- * Settings that control parser and renderer behavior based on context.
1088
+ * Controls which parser and renderer features are active.
1089
+ *
1090
+ * These flags gate syntax availability and rendering behaviour based on the
1091
+ * context where the wikitext appears. Construct via {@link createSettings}
1092
+ * and override individual fields when non-default behaviour is needed.
1093
+ *
1094
+ * @group Settings
599
1095
  */
600
1096
  interface WikitextSettings {
601
- /** Operating mode */
1097
+ /** The context mode this settings object was created for */
602
1098
  mode: WikitextMode;
603
1099
  /**
604
1100
  * Whether page-contextual syntax is permitted.
605
- * Controls: include, module, table-of-contents.
1101
+ *
1102
+ * When `true`, the parser recognises `[[include]]`, `[[module]]`, and
1103
+ * `[[toc]]` blocks. These constructs are meaningful only inside a full
1104
+ * wiki page and are disabled in forum posts and direct messages.
606
1105
  */
607
1106
  enablePageSyntax: boolean;
608
1107
  /**
609
- * Whether local file paths (file1, file2, file3) are permitted for images.
610
- * Disable in contexts without a "local" page (forum posts, direct messages).
1108
+ * Whether local file references (`file1`, `file2`, `file3`) are allowed
1109
+ * in image sources.
1110
+ *
1111
+ * Local files belong to a specific wiki page. In contexts that lack a
1112
+ * "current page" — such as forum posts and direct messages — local file
1113
+ * references are meaningless and should be rejected.
611
1114
  */
612
1115
  allowLocalPaths: boolean;
613
1116
  /**
614
- * Whether element IDs should be stable sequential values.
615
- * When false, IDs are randomized to prevent collisions
616
- * when multiple rendered fragments appear on the same page.
1117
+ * Whether heading and footnote IDs use stable sequential values
1118
+ * (`toc0`, `toc1`, ...) or randomised strings.
1119
+ *
1120
+ * Stable IDs are appropriate when a single rendered page owns the full
1121
+ * document. Randomised IDs prevent collisions when multiple rendered
1122
+ * fragments (e.g. a live draft preview) coexist on the same HTML page.
617
1123
  */
618
1124
  useTrueIds: boolean;
619
1125
  /**
620
- * Whether [[module CSS]] style elements are rendered as <style> tags.
621
- * Disable to prevent user-authored CSS from affecting the page layout
622
- * (e.g., in draft previews, forum posts).
1126
+ * Whether `[[module CSS]]` blocks are rendered as `<style>` tags.
1127
+ *
1128
+ * User-authored CSS can break page layout, so it is allowed only on
1129
+ * full wiki pages. In draft previews, forum posts, and direct messages
1130
+ * the CSS module is silently ignored.
623
1131
  */
624
1132
  allowStyleElements: boolean;
625
1133
  }
626
1134
  /**
627
- * Create WikitextSettings with defaults for the given mode.
1135
+ * Create a {@link WikitextSettings} with sensible defaults for the given mode.
1136
+ *
1137
+ * See the table on {@link WikitextMode} for which flags each mode enables.
1138
+ *
1139
+ * @param mode - The context in which wikitext will be parsed
1140
+ * @returns A new settings object with defaults for that mode
1141
+ *
1142
+ * @group Settings
628
1143
  */
629
1144
  declare function createSettings(mode: WikitextMode): WikitextSettings;
630
- /** Default settings (page mode) */
1145
+ /**
1146
+ * Pre-built settings for `"page"` mode — the most common context.
1147
+ *
1148
+ * Equivalent to `createSettings("page")`. Provided as a convenience
1149
+ * for call-sites that always operate on full wiki pages.
1150
+ *
1151
+ * @group Settings
1152
+ */
631
1153
  declare const DEFAULT_SETTINGS: WikitextSettings;
1154
+ /**
1155
+ * Identifies the source markup dialect.
1156
+ *
1157
+ * Currently only `"wikidot"` is supported. Included in {@link SyntaxTree}
1158
+ * so consumers can branch on the dialect if other formats are added later.
1159
+ *
1160
+ * @group Core
1161
+ */
632
1162
  type Version = "wikidot";
633
- export { text, paragraph, listItemSubList, listItemElements, list, link, lineBreak, italics, isStringContainerType, isParagraphSafe, isHeaderType, isContainerTypeParagraphSafe, isAlignType, horizontalRule, heading, createSettings, createPosition, createPoint, container, bold, WikitextSettings, WikitextMode, Version, VariableMap, UserData, TocEntry, TableRow, TableOfContentsData, TableData, TableCell, TabData, SyntaxTree, StringContainerType, Position, Point, PageRef, Module, MathInlineData, MathData, ListType, ListItem, ListData, LinkType, LinkLocation, LinkLabel, LinkData, IncludeData, ImageSource, ImageData, IframeData, IfTagsData, IfExprData, IfCondData, HtmlData, HeadingLevel, Heading, HeaderType, FootnoteBlockData, FloatAlignment, ExprData, EmbedBlockData, Embed, ElementOf, ElementName, ElementDataMap, ElementData, Element, DefinitionListItem, DateItem, DateData, DEFAULT_SETTINGS, ContainerType, ContainerData, ColorData, CollapsibleData, CodeBlockData, ClearFloat, BibliographyCiteData, BibliographyBlockData, AttributeMap, AnchorTarget, AnchorData, Alignment, AlignType };
1163
+ export { text, paragraph, listItemSubList, listItemElements, list, link, lineBreak, italics, isStringContainerType, isParagraphSafe, isHeaderType, isContainerTypeParagraphSafe, isAlignType, horizontalRule, heading, createSettings, createPosition, createPoint, container, bold, WikitextSettings, WikitextMode, Version, VariableMap, UserData, TocEntry, TableRow, TableOfContentsData, TableData, TableCell, TabData, SyntaxTree, StringContainerType, STYLE_SLOT_PREFIX, Position, Point, PageRef, Module, MathInlineData, MathData, ListType, ListItem, ListData, LinkType, LinkLocation, LinkLabel, LinkData, IncludeData, ImageSource, ImageData, IframeData, IfTagsData, IfExprData, IfCondData, HtmlData, HeadingLevel, Heading, HeaderType, FootnoteBlockData, FloatAlignment, ExprData, EmbedBlockData, Embed, ElementOf, ElementName, ElementDataMap, ElementData, Element, DefinitionListItem, DateItem, DateData, DEFAULT_SETTINGS, ContainerType, ContainerData, ColorData, CollapsibleData, CodeBlockData, ClearFloat, BibliographyCiteData, BibliographyBlockData, AttributeMap, AnchorTarget, AnchorData, Alignment, AlignType };