@orkestrel/markdown 0.0.13 → 0.0.15
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 +12 -6
- package/dist/src/core/index.cjs +124 -117
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +247 -218
- package/dist/src/core/index.d.ts +247 -218
- package/dist/src/core/index.js +124 -117
- package/dist/src/core/index.js.map +1 -1
- package/package.json +14 -15
package/dist/src/core/index.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { BooleanShape } from '@orkestrel/contract';
|
|
2
|
-
import { CommentNode } from '@orkestrel/html';
|
|
3
|
-
import { ContractInterface } from '@orkestrel/contract';
|
|
4
|
-
import { DoctypeNode } from '@orkestrel/html';
|
|
5
|
-
import { ElementNode } from '@orkestrel/html';
|
|
6
|
-
import { Guard } from '@orkestrel/contract';
|
|
7
|
-
import { HTMLDocument } from '@orkestrel/html';
|
|
8
|
-
import { HTMLNode } from '@orkestrel/html';
|
|
2
|
+
import type { CommentNode } from '@orkestrel/html';
|
|
3
|
+
import type { ContractInterface } from '@orkestrel/contract';
|
|
4
|
+
import type { DoctypeNode } from '@orkestrel/html';
|
|
5
|
+
import type { ElementNode } from '@orkestrel/html';
|
|
6
|
+
import type { Guard } from '@orkestrel/contract';
|
|
7
|
+
import type { HTMLDocument } from '@orkestrel/html';
|
|
8
|
+
import type { HTMLNode } from '@orkestrel/html';
|
|
9
9
|
import { LiteralShape } from '@orkestrel/contract';
|
|
10
10
|
import { NumberShape } from '@orkestrel/contract';
|
|
11
11
|
import { ObjectShape } from '@orkestrel/contract';
|
|
12
12
|
import { OptionalShape } from '@orkestrel/contract';
|
|
13
13
|
import { StringShape } from '@orkestrel/contract';
|
|
14
|
-
import { TextNode as TextNode_2 } from '@orkestrel/html';
|
|
14
|
+
import type { TextNode as TextNode_2 } from '@orkestrel/html';
|
|
15
15
|
|
|
16
16
|
/** Represents a node that can appear at the block level of a document (or inside a list item / blockquote). */
|
|
17
17
|
export declare type BlockNode = HeadingNode | ParagraphNode | ListNode | TableNode | CodeBlockNode | BlockquoteNode | ThematicBreakNode;
|
|
18
18
|
|
|
19
|
-
/** Represents a blockquote
|
|
19
|
+
/** Represents a blockquote — `>`-prefixed lines; `children` the block content parsed from the de-quoted lines (so quotes nest). */
|
|
20
20
|
export declare interface BlockquoteNode {
|
|
21
21
|
readonly element: 'blockquote';
|
|
22
22
|
/** Holds the block content of the quote (the `>`-stripped lines, re-parsed as blocks). */
|
|
@@ -24,7 +24,7 @@ export declare interface BlockquoteNode {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Merges adjacent text nodes into one
|
|
27
|
+
* Merges adjacent text nodes into one — the inline scanner emits a text node per
|
|
28
28
|
* unrecognized character, so coalescing keeps the AST clean and assertion-friendly.
|
|
29
29
|
*
|
|
30
30
|
* @param nodes - The inline nodes (possibly with adjacent text runs)
|
|
@@ -40,7 +40,7 @@ export declare interface BlockquoteNode {
|
|
|
40
40
|
export declare function coalesceText(nodes: readonly InlineNode[], spans?: Map<MarkdownNode, MarkdownSpan>): readonly InlineNode[];
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* Represents a fenced code block
|
|
43
|
+
* Represents a fenced code block — ```` ```lang ````. `code` is the verbatim block content (no
|
|
44
44
|
* inner markdown; the closing fence and the trailing newline are stripped), `lang`
|
|
45
45
|
* the info-string language tag (the first word after the opening fence), absent when
|
|
46
46
|
* none was given.
|
|
@@ -54,7 +54,7 @@ export declare interface CodeBlockNode {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* Describes the shape of a {@link CodeBlockNode}
|
|
57
|
+
* Describes the shape of a {@link CodeBlockNode} — a fenced code block. `lang` is
|
|
58
58
|
* optional (absent when the opening fence carries no info-string).
|
|
59
59
|
*
|
|
60
60
|
* @example
|
|
@@ -67,14 +67,14 @@ export declare interface CodeBlockNode {
|
|
|
67
67
|
* codeBlock.is({ element: 'codeBlock', code: 'x', lang: 'ts' }) // true
|
|
68
68
|
* ```
|
|
69
69
|
*/
|
|
70
|
-
export declare const codeBlockShape: ObjectShape<{
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
export declare const codeBlockShape: ObjectShape< {
|
|
71
|
+
element: LiteralShape<readonly ["codeBlock"]>;
|
|
72
|
+
lang: OptionalShape<StringShape>;
|
|
73
|
+
code: StringShape;
|
|
74
74
|
}, false>;
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
* Represents the located extent of one inline code span
|
|
77
|
+
* Represents the located extent of one inline code span — the value the inline phase's code
|
|
78
78
|
* scanner returns for a matched backtick run.
|
|
79
79
|
*/
|
|
80
80
|
export declare interface CodeSpanMatch {
|
|
@@ -85,7 +85,7 @@ export declare interface CodeSpanMatch {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* Represents an inline code span
|
|
88
|
+
* Represents an inline code span — `` `code` ``. `value` is the verbatim span text; no inner
|
|
89
89
|
* markdown is parsed (code is literal), and the renderer HTML-escapes it inside a
|
|
90
90
|
* `<code>` element.
|
|
91
91
|
*/
|
|
@@ -96,7 +96,7 @@ export declare interface CodeSpanNode {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* Describes the shape of a {@link CodeSpanNode}
|
|
99
|
+
* Describes the shape of a {@link CodeSpanNode} — an inline code span (`` `code` ``).
|
|
100
100
|
*
|
|
101
101
|
* @example
|
|
102
102
|
* ```ts
|
|
@@ -107,9 +107,9 @@ export declare interface CodeSpanNode {
|
|
|
107
107
|
* codeSpan.is({ element: 'codeSpan', value: 'const x = 1' }) // true
|
|
108
108
|
* ```
|
|
109
109
|
*/
|
|
110
|
-
export declare const codeSpanShape: ObjectShape<{
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
export declare const codeSpanShape: ObjectShape< {
|
|
111
|
+
element: LiteralShape<readonly ["codeSpan"]>;
|
|
112
|
+
value: StringShape;
|
|
113
113
|
}, false>;
|
|
114
114
|
|
|
115
115
|
/**
|
|
@@ -147,7 +147,7 @@ export declare function collectList(lines: readonly MarkdownSource[], start: num
|
|
|
147
147
|
export declare function collectTable(lines: readonly MarkdownSource[], start: number, spans?: Map<MarkdownNode, MarkdownSpan>): TableCollection;
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
|
-
* Counts the leading space / tab characters on `line` (a tab counts as one)
|
|
150
|
+
* Counts the leading space / tab characters on `line` (a tab counts as one) — the
|
|
151
151
|
* indent that decides whether a list item's continuation belongs to the item.
|
|
152
152
|
*
|
|
153
153
|
* @param line - The line to measure
|
|
@@ -162,7 +162,7 @@ export declare function countIndent(line: string): number;
|
|
|
162
162
|
|
|
163
163
|
/**
|
|
164
164
|
* Compiles the {@link codeBlockShape} into a {@link ContractInterface} for
|
|
165
|
-
* {@link CodeBlockNode}
|
|
165
|
+
* {@link CodeBlockNode} — a guard, coercing parser, JSON Schema, and seeded
|
|
166
166
|
* generator from one shape declaration.
|
|
167
167
|
*
|
|
168
168
|
* @returns A `CodeBlockNode` contract bundling `schema` / `is` / `parse` / `generate`
|
|
@@ -179,7 +179,7 @@ export declare function createCodeBlockContract(): ContractInterface<CodeBlockNo
|
|
|
179
179
|
|
|
180
180
|
/**
|
|
181
181
|
* Compiles the {@link codeSpanShape} into a {@link ContractInterface} for
|
|
182
|
-
* {@link CodeSpanNode}
|
|
182
|
+
* {@link CodeSpanNode} — a guard, coercing parser, JSON Schema, and seeded
|
|
183
183
|
* generator from one shape declaration.
|
|
184
184
|
*
|
|
185
185
|
* @returns A `CodeSpanNode` contract bundling `schema` / `is` / `parse` / `generate`
|
|
@@ -211,7 +211,7 @@ export declare function createLineBreakContract(): ContractInterface<LineBreakNo
|
|
|
211
211
|
|
|
212
212
|
/**
|
|
213
213
|
* Creates a stateful markdown handle from a markdown string or an already-parsed
|
|
214
|
-
* {@link MarkdownDocument}
|
|
214
|
+
* {@link MarkdownDocument} — a typed AST plus the query, rewrite, and fold operations
|
|
215
215
|
* {@link MarkdownInterface} exposes.
|
|
216
216
|
*
|
|
217
217
|
* @remarks
|
|
@@ -219,9 +219,9 @@ export declare function createLineBreakContract(): ContractInterface<LineBreakNo
|
|
|
219
219
|
* fenced code / blockquotes / thematic breaks) then an inline phase (emphasis /
|
|
220
220
|
* inline code / links / images / hard breaks) to build a render-agnostic
|
|
221
221
|
* {@link MarkdownDocument}. Given a
|
|
222
|
-
* {@link MarkdownDocument}, adopts it
|
|
222
|
+
* {@link MarkdownDocument}, adopts it as-is without re-validation — gate an untrusted
|
|
223
223
|
* value with `isMarkdownDocument` first. Pure + total parse (malformed markdown
|
|
224
|
-
* degrades to text, never throws) and zero-dependency
|
|
224
|
+
* degrades to text, never throws) and zero-dependency — a hand-written scanner, no
|
|
225
225
|
* regex-only structural parse, linear-time (no ReDoS).
|
|
226
226
|
*
|
|
227
227
|
* @param input - A markdown string to parse, or an already-parsed {@link MarkdownDocument}
|
|
@@ -261,7 +261,7 @@ export declare function createProjection(parts?: Partial<MarkdownProjection>): M
|
|
|
261
261
|
|
|
262
262
|
/**
|
|
263
263
|
* Compiles the {@link textShape} into a {@link ContractInterface} for
|
|
264
|
-
* {@link TextNode}
|
|
264
|
+
* {@link TextNode} — a guard, coercing parser, JSON Schema, and seeded
|
|
265
265
|
* generator from one shape declaration.
|
|
266
266
|
*
|
|
267
267
|
* @returns A `TextNode` contract bundling `schema` / `is` / `parse` / `generate`
|
|
@@ -278,7 +278,7 @@ export declare function createTextContract(): ContractInterface<TextNode>;
|
|
|
278
278
|
|
|
279
279
|
/**
|
|
280
280
|
* Compiles the {@link thematicBreakShape} into a {@link ContractInterface} for
|
|
281
|
-
* {@link ThematicBreakNode}
|
|
281
|
+
* {@link ThematicBreakNode} — a guard, coercing parser, JSON Schema, and
|
|
282
282
|
* seeded generator from one shape declaration.
|
|
283
283
|
*
|
|
284
284
|
* @returns A `ThematicBreakNode` contract bundling `schema` / `is` / `parse` / `generate`
|
|
@@ -294,7 +294,7 @@ export declare function createTextContract(): ContractInterface<TextNode>;
|
|
|
294
294
|
export declare function createThematicBreakContract(): ContractInterface<ThematicBreakNode>;
|
|
295
295
|
|
|
296
296
|
/**
|
|
297
|
-
* Derives the per-column {@link TableAlign} list from a GFM delimiter row
|
|
297
|
+
* Derives the per-column {@link TableAlign} list from a GFM delimiter row — `:---`
|
|
298
298
|
* left, `---:` right, `:---:` center, and `---` as the explicit no-alignment
|
|
299
299
|
* marker represented by `null`.
|
|
300
300
|
*
|
|
@@ -309,7 +309,7 @@ export declare function createThematicBreakContract(): ContractInterface<Themati
|
|
|
309
309
|
export declare function delimiterToAlignments(delimiter: string): ReadonlyArray<TableAlign | null>;
|
|
310
310
|
|
|
311
311
|
/**
|
|
312
|
-
* Represents the located content and syntax bounds of one emphasis run
|
|
312
|
+
* Represents the located content and syntax bounds of one emphasis run — the value the inline
|
|
313
313
|
* phase's emphasis locator returns for a matched marker run.
|
|
314
314
|
*/
|
|
315
315
|
export declare interface EmphasisBounds {
|
|
@@ -324,7 +324,7 @@ export declare interface EmphasisBounds {
|
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
/**
|
|
327
|
-
* Represents emphasized inline content
|
|
327
|
+
* Represents emphasized inline content — `*italic*` / `_italic_` (`strong: false`) or
|
|
328
328
|
* `**bold**` / `__bold__` (`strong: true`). `children` are the nested inline nodes,
|
|
329
329
|
* so emphasis composes (a `**bold _and italic_**` is a strong node wrapping a text
|
|
330
330
|
* node and an emphasis node).
|
|
@@ -338,7 +338,7 @@ export declare interface EmphasisNode {
|
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
/**
|
|
341
|
-
* Represents the scanned result of one emphasis run
|
|
341
|
+
* Represents the scanned result of one emphasis run — the node the inline phase's emphasis
|
|
342
342
|
* scanner built from {@link EmphasisBounds} and where the scan resumes.
|
|
343
343
|
*/
|
|
344
344
|
export declare interface EmphasisScan {
|
|
@@ -409,7 +409,7 @@ export declare function extractHeading(line: string): HeadingMatch | undefined;
|
|
|
409
409
|
export declare function extractListItem(line: string): ListItemMatch | undefined;
|
|
410
410
|
|
|
411
411
|
/**
|
|
412
|
-
* Represents the parsed parts of a fenced-code opening line
|
|
412
|
+
* Represents the parsed parts of a fenced-code opening line — the value the block phase's fence
|
|
413
413
|
* detector returns for a ```` ``` ```` or `~~~` opener.
|
|
414
414
|
*/
|
|
415
415
|
export declare interface FenceMatch {
|
|
@@ -421,7 +421,7 @@ export declare interface FenceMatch {
|
|
|
421
421
|
|
|
422
422
|
/**
|
|
423
423
|
* Concatenates the `value` / `code` content of every descendant text / code-span /
|
|
424
|
-
* code-block node under `node`, including image alternative content, in walk order
|
|
424
|
+
* code-block node under `node`, including image alternative content, in walk order —
|
|
425
425
|
* the plain-text projection of an AST (search indexing, word counts, a text-only
|
|
426
426
|
* preview).
|
|
427
427
|
*
|
|
@@ -444,16 +444,16 @@ export declare interface FenceMatch {
|
|
|
444
444
|
export declare function flattenText(node: MarkdownNode): string;
|
|
445
445
|
|
|
446
446
|
/**
|
|
447
|
-
* Folds a {@link MarkdownNode} into a `T` through a total catamorphism
|
|
447
|
+
* Folds a {@link MarkdownNode} into a `T` through a total catamorphism — children are
|
|
448
448
|
* folded first (post-order), then the node's own {@link MarkdownHandler} is invoked
|
|
449
449
|
* with the already-folded children.
|
|
450
450
|
*
|
|
451
451
|
* @remarks
|
|
452
|
-
* **Table contract.** A {@link TableNode} has no single `children` array
|
|
452
|
+
* **Table contract.** A {@link TableNode} has no single `children` array — its cells
|
|
453
453
|
* live in `header` (one inline-node list per column) and `rows` (a list of such
|
|
454
|
-
* rows). The `table` handler receives
|
|
455
|
-
* walk order across
|
|
456
|
-
* every body row's cells' inline nodes (row order, then column order)
|
|
454
|
+
* rows). The `table` handler receives one folded `T` per inline node, flattened in
|
|
455
|
+
* walk order across all cells — every header cell's inline nodes (column order), then
|
|
456
|
+
* every body row's cells' inline nodes (row order, then column order) — and reads
|
|
457
457
|
* `node.header[c].length` / `node.rows[r][c].length` off the table node itself to
|
|
458
458
|
* recover cell boundaries within the flat list.
|
|
459
459
|
*
|
|
@@ -477,7 +477,7 @@ export declare function flattenText(node: MarkdownNode): string;
|
|
|
477
477
|
export declare function foldNode<T>(node: MarkdownNode, handlers: MarkdownHandlerMap<T>, depth: number): T;
|
|
478
478
|
|
|
479
479
|
/**
|
|
480
|
-
* Represents the parsed parts of a single ATX heading line
|
|
480
|
+
* Represents the parsed parts of a single ATX heading line — the value the block phase's heading
|
|
481
481
|
* detector returns for a `#` … `######` line.
|
|
482
482
|
*/
|
|
483
483
|
export declare interface HeadingMatch {
|
|
@@ -490,7 +490,7 @@ export declare interface HeadingMatch {
|
|
|
490
490
|
}
|
|
491
491
|
|
|
492
492
|
/**
|
|
493
|
-
* Represents an ATX heading
|
|
493
|
+
* Represents an ATX heading — `#` … `######`. `level` is 1–6 (the number of leading `#`),
|
|
494
494
|
* `children` the inline content of the heading text.
|
|
495
495
|
*/
|
|
496
496
|
export declare interface HeadingNode {
|
|
@@ -502,36 +502,36 @@ export declare interface HeadingNode {
|
|
|
502
502
|
}
|
|
503
503
|
|
|
504
504
|
/**
|
|
505
|
-
* Projects an `@orkestrel/html` {@link HTMLNode} into a {@link MarkdownDocument}
|
|
505
|
+
* Projects an `@orkestrel/html` {@link HTMLNode} into a {@link MarkdownDocument} — the
|
|
506
506
|
* HTML→markdown direction, and the inverse of {@link markdownToHTML}.
|
|
507
507
|
*
|
|
508
508
|
* @remarks
|
|
509
|
-
* **Engine.** One total handler table
|
|
510
|
-
* {@link projectHTMLLeaf} for the leaves
|
|
509
|
+
* **Engine.** One total handler table — {@link projectHTMLNode} for the containers,
|
|
510
|
+
* {@link projectHTMLLeaf} for the leaves — folded by `@orkestrel/html`'s own `foldNode`, so
|
|
511
511
|
* depth capping, cycle safety, and bottom-up ordering are inherited rather than
|
|
512
512
|
* rebuilt. Total: hostile, cyclic, and pathologically deep input degrades instead of
|
|
513
513
|
* throwing.
|
|
514
514
|
*
|
|
515
515
|
* **Composed depth.** Both packages cap recursion at 64, and html's cap is reached
|
|
516
|
-
* first: a document nested past it projects to a chain bounded by
|
|
516
|
+
* first: a document nested past it projects to a chain bounded by that cap, with the
|
|
517
517
|
* content below it truncated before markdown ever sees it. Since the projected chain
|
|
518
518
|
* can be a level or two deeper than {@link MAX_DEPTH}, the serializer's own cap can
|
|
519
|
-
* then truncate again
|
|
519
|
+
* then truncate again — so the anchor law that follows is a law within the depth budget, and
|
|
520
520
|
* beyond it only totality is promised.
|
|
521
521
|
*
|
|
522
522
|
* **Safety.** Every `href` and `src` is re-sanitized through
|
|
523
523
|
* `sanitizeURL(value, SAFE_URL_SCHEMES)` whether or not the AST was ever sanitized,
|
|
524
524
|
* because a hand-built one never was. A refused destination empties to `''` and the
|
|
525
|
-
* link or image is
|
|
525
|
+
* link or image is kept — `[text]()` — because a bad URL is no reason to lose the words
|
|
526
526
|
* around it. An `UNSAFE_ELEMENTS` subtree contributes nothing at all, text included, so
|
|
527
527
|
* a `script` body can never resurface as prose.
|
|
528
528
|
*
|
|
529
529
|
* **The anchor law.** HTML→markdown is lossy, so the fixpoint that matters is the
|
|
530
|
-
*
|
|
530
|
+
* projected AST, not the input bytes:
|
|
531
531
|
* `parseDocument(renderMarkdown(htmlToMarkdown(x)))` deep-equals `htmlToMarkdown(x)`.
|
|
532
532
|
* The projection therefore emits canonical markdown shapes rather than literal
|
|
533
|
-
* translations
|
|
534
|
-
* break only where a line can end
|
|
533
|
+
* translations — whitespace collapsed, edges trimmed, a blank paragraph dropped, a hard
|
|
534
|
+
* break only where a line can end — because a shape markdown cannot write back is a
|
|
535
535
|
* shape this projection has no business producing.
|
|
536
536
|
*
|
|
537
537
|
* @param node - The HTML document or bare node to project
|
|
@@ -548,7 +548,7 @@ export declare interface HeadingNode {
|
|
|
548
548
|
export declare function htmlToMarkdown(node: HTMLNode): MarkdownDocument;
|
|
549
549
|
|
|
550
550
|
/**
|
|
551
|
-
* Represents an inline image
|
|
551
|
+
* Represents an inline image — ``. `children` are the inline nodes of the
|
|
552
552
|
* alternative content and `src` is the image destination.
|
|
553
553
|
*/
|
|
554
554
|
export declare interface ImageNode {
|
|
@@ -563,7 +563,7 @@ export declare interface ImageNode {
|
|
|
563
563
|
export declare type InlineNode = TextNode | EmphasisNode | CodeSpanNode | LineBreakNode | LinkNode | ImageNode;
|
|
564
564
|
|
|
565
565
|
/**
|
|
566
|
-
* Checks whether `line` is blank
|
|
566
|
+
* Checks whether `line` is blank — empty, or containing only whitespace — the markdown
|
|
567
567
|
* definition of a blank line that block parsing uses to separate paragraphs, skip
|
|
568
568
|
* gaps, and end list continuations.
|
|
569
569
|
*
|
|
@@ -578,16 +578,16 @@ export declare type InlineNode = TextNode | EmphasisNode | CodeSpanNode | LineBr
|
|
|
578
578
|
export declare function isBlankLine(line: string): boolean;
|
|
579
579
|
|
|
580
580
|
/**
|
|
581
|
-
* Determines whether an arbitrary value is a valid {@link BlockNode}
|
|
581
|
+
* Determines whether an arbitrary value is a valid {@link BlockNode} — a
|
|
582
582
|
* heading, paragraph, list, table, code block, blockquote, or thematic break,
|
|
583
583
|
* recursively validated.
|
|
584
584
|
*
|
|
585
585
|
* @remarks
|
|
586
|
-
* Total: never throws, even on cyclic or pathologically deep input
|
|
586
|
+
* Total: never throws, even on cyclic or pathologically deep input — every
|
|
587
587
|
* combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is
|
|
588
588
|
* throw-contained per the `@orkestrel/contract` guard contract.
|
|
589
589
|
* A list item's shape is inlined here (and in {@link isMarkdownNode}) rather
|
|
590
|
-
* than named separately
|
|
590
|
+
* than named separately — it is used at exactly these two sites.
|
|
591
591
|
*
|
|
592
592
|
* @param value - The value to test
|
|
593
593
|
* @returns True if `value` is a well-formed {@link BlockNode}; false otherwise
|
|
@@ -632,7 +632,7 @@ export declare function isCodeBlockNode(node: MarkdownNode): node is CodeBlockNo
|
|
|
632
632
|
* Determines whether a node is an inline code span.
|
|
633
633
|
*
|
|
634
634
|
* @remarks
|
|
635
|
-
* Narrows to {@link CodeSpanNode}
|
|
635
|
+
* Narrows to {@link CodeSpanNode} — the node whose `element` discriminant is
|
|
636
636
|
* `'codeSpan'`.
|
|
637
637
|
*
|
|
638
638
|
* @param node - The AST node to test
|
|
@@ -659,7 +659,7 @@ export declare function isCodeSpanNode(node: MarkdownNode): node is CodeSpanNode
|
|
|
659
659
|
export declare function isEmphasisNode(node: MarkdownNode): node is EmphasisNode;
|
|
660
660
|
|
|
661
661
|
/**
|
|
662
|
-
* Checks whether `character` is escapable by a leading backslash
|
|
662
|
+
* Checks whether `character` is escapable by a leading backslash — the ASCII punctuation
|
|
663
663
|
* markdown gives meaning to (so `\*` becomes `*` but `\.` stays `\.`).
|
|
664
664
|
*
|
|
665
665
|
* @param character - The single character after a backslash
|
|
@@ -674,7 +674,7 @@ export declare function isEmphasisNode(node: MarkdownNode): node is EmphasisNode
|
|
|
674
674
|
export declare function isEscapable(character: string): boolean;
|
|
675
675
|
|
|
676
676
|
/**
|
|
677
|
-
* Checks whether `line` closes a fence opened by `marker`
|
|
677
|
+
* Checks whether `line` closes a fence opened by `marker` — the same fence character, a run
|
|
678
678
|
* at least as long, and nothing else but surrounding whitespace.
|
|
679
679
|
*
|
|
680
680
|
* @param line - The candidate closing line
|
|
@@ -689,7 +689,7 @@ export declare function isEscapable(character: string): boolean;
|
|
|
689
689
|
export declare function isFenceClose(line: string, marker: string): boolean;
|
|
690
690
|
|
|
691
691
|
/**
|
|
692
|
-
* Checks whether `character` is a regex-`\s`-equivalent whitespace character
|
|
692
|
+
* Checks whether `character` is a regex-`\s`-equivalent whitespace character — the
|
|
693
693
|
* character class {@link isFenceClose}'s scan treats as surrounding padding.
|
|
694
694
|
*
|
|
695
695
|
* @param character - The single character to test, or `undefined` past the end of a line
|
|
@@ -704,7 +704,7 @@ export declare function isFenceClose(line: string, marker: string): boolean;
|
|
|
704
704
|
export declare function isFenceWhitespace(character: string | undefined): boolean;
|
|
705
705
|
|
|
706
706
|
/**
|
|
707
|
-
* Checks whether `character` is whitespace under the emphasis flanking rule
|
|
707
|
+
* Checks whether `character` is whitespace under the emphasis flanking rule — a space, a
|
|
708
708
|
* tab, or a newline.
|
|
709
709
|
*
|
|
710
710
|
* @param character - The character to test
|
|
@@ -745,11 +745,11 @@ export declare function isHeadingNode(node: MarkdownNode): node is HeadingNode;
|
|
|
745
745
|
export declare function isImageNode(node: MarkdownNode): node is ImageNode;
|
|
746
746
|
|
|
747
747
|
/**
|
|
748
|
-
* Determines whether an arbitrary value is a valid {@link InlineNode}
|
|
748
|
+
* Determines whether an arbitrary value is a valid {@link InlineNode} — a text
|
|
749
749
|
* run, emphasis, code span, hard break, link, or image, recursively validated.
|
|
750
750
|
*
|
|
751
751
|
* @remarks
|
|
752
|
-
* Total: never throws, even on cyclic or pathologically deep input
|
|
752
|
+
* Total: never throws, even on cyclic or pathologically deep input — every
|
|
753
753
|
* combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is
|
|
754
754
|
* throw-contained per the `@orkestrel/contract` guard contract.
|
|
755
755
|
*
|
|
@@ -806,12 +806,12 @@ export declare function isLinkNode(node: MarkdownNode): node is LinkNode;
|
|
|
806
806
|
export declare function isListNode(node: MarkdownNode): node is ListNode;
|
|
807
807
|
|
|
808
808
|
/**
|
|
809
|
-
* Determines whether an arbitrary value is a valid {@link MarkdownDocument}
|
|
809
|
+
* Determines whether an arbitrary value is a valid {@link MarkdownDocument} —
|
|
810
810
|
* the parsed-AST root {@link parseDocument} returns, recursively
|
|
811
811
|
* validated.
|
|
812
812
|
*
|
|
813
813
|
* @remarks
|
|
814
|
-
* Total: never throws, even on cyclic or pathologically deep input
|
|
814
|
+
* Total: never throws, even on cyclic or pathologically deep input — every
|
|
815
815
|
* combinator involved (`recordOf`, `arrayOf`) is throw-contained per the
|
|
816
816
|
* `@orkestrel/contract` guard contract.
|
|
817
817
|
*
|
|
@@ -829,16 +829,16 @@ export declare function isListNode(node: MarkdownNode): node is ListNode;
|
|
|
829
829
|
export declare const isMarkdownDocument: Guard<MarkdownDocument>;
|
|
830
830
|
|
|
831
831
|
/**
|
|
832
|
-
* Determines whether an arbitrary value is a valid {@link MarkdownNode}
|
|
832
|
+
* Determines whether an arbitrary value is a valid {@link MarkdownNode} — the
|
|
833
833
|
* {@link MarkdownDocument} root, a {@link BlockNode}, a {@link ListItemNode}, or
|
|
834
834
|
* an {@link InlineNode}, recursively validated.
|
|
835
835
|
*
|
|
836
836
|
* @remarks
|
|
837
|
-
* Total: never throws, even on cyclic or pathologically deep input
|
|
837
|
+
* Total: never throws, even on cyclic or pathologically deep input — every
|
|
838
838
|
* combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is
|
|
839
839
|
* throw-contained per the `@orkestrel/contract` guard contract.
|
|
840
840
|
* A list item's shape is inlined here (and in {@link isBlockNode}) rather than
|
|
841
|
-
* named separately
|
|
841
|
+
* named separately — it is used at exactly these two sites.
|
|
842
842
|
*
|
|
843
843
|
* @param value - The value to test
|
|
844
844
|
* @returns True if `value` is a well-formed {@link MarkdownNode}; false otherwise
|
|
@@ -867,7 +867,7 @@ export declare const isMarkdownNode: Guard<MarkdownNode>;
|
|
|
867
867
|
export declare function isParagraphNode(node: MarkdownNode): node is ParagraphNode;
|
|
868
868
|
|
|
869
869
|
/**
|
|
870
|
-
* Checks whether `line` is a blockquote line (`>` optionally indented up to three spaces)
|
|
870
|
+
* Checks whether `line` is a blockquote line (`>` optionally indented up to three spaces) —
|
|
871
871
|
* its content is de-quoted by {@link stripQuote}.
|
|
872
872
|
*
|
|
873
873
|
* @param line - The candidate line
|
|
@@ -894,9 +894,9 @@ export declare function isQuote(line: string): boolean;
|
|
|
894
894
|
export declare function isTableNode(node: MarkdownNode): node is TableNode;
|
|
895
895
|
|
|
896
896
|
/**
|
|
897
|
-
* Checks whether the pair (`header`, `delimiter`) opens a GFM table
|
|
897
|
+
* Checks whether the pair (`header`, `delimiter`) opens a GFM table — `delimiter` is a row of
|
|
898
898
|
* `|`-separated cells each matching `:?-+:?`, the GFM rule that a table requires a
|
|
899
|
-
* header row
|
|
899
|
+
* header row immediately followed by a delimiter row.
|
|
900
900
|
*
|
|
901
901
|
* @param header - The candidate header line
|
|
902
902
|
* @param delimiter - The line after it (the candidate delimiter)
|
|
@@ -923,7 +923,7 @@ export declare function isTableStart(header: string, delimiter: string | undefin
|
|
|
923
923
|
export declare function isTextNode(node: MarkdownNode): node is TextNode;
|
|
924
924
|
|
|
925
925
|
/**
|
|
926
|
-
* Checks whether `line` is a thematic break (horizontal rule)
|
|
926
|
+
* Checks whether `line` is a thematic break (horizontal rule) — three or more of the same
|
|
927
927
|
* marker `-`, `*`, or `_` (optionally space-separated) and nothing else (`---`,
|
|
928
928
|
* `***`, `___`, `- - -`).
|
|
929
929
|
*
|
|
@@ -966,13 +966,16 @@ export declare function isThematicBreakNode(node: MarkdownNode): node is Themati
|
|
|
966
966
|
*/
|
|
967
967
|
export declare function joinSources(sources: readonly MarkdownSource[], separator: string): MarkdownSource;
|
|
968
968
|
|
|
969
|
-
/**
|
|
969
|
+
/**
|
|
970
|
+
* Represents a GFM hard line break — two or more trailing spaces before a newline in
|
|
971
|
+
* markdown source, a `br` element in HTML.
|
|
972
|
+
*/
|
|
970
973
|
export declare interface LineBreakNode {
|
|
971
974
|
readonly element: 'break';
|
|
972
975
|
}
|
|
973
976
|
|
|
974
977
|
/**
|
|
975
|
-
* Describes the shape of a {@link LineBreakNode}
|
|
978
|
+
* Describes the shape of a {@link LineBreakNode} — a GFM hard line-break leaf.
|
|
976
979
|
*
|
|
977
980
|
* @example
|
|
978
981
|
* ```ts
|
|
@@ -983,12 +986,12 @@ export declare interface LineBreakNode {
|
|
|
983
986
|
* lineBreak.is({ element: 'break' }) // true
|
|
984
987
|
* ```
|
|
985
988
|
*/
|
|
986
|
-
export declare const lineBreakShape: ObjectShape<{
|
|
987
|
-
|
|
989
|
+
export declare const lineBreakShape: ObjectShape< {
|
|
990
|
+
element: LiteralShape<readonly ["break"]>;
|
|
988
991
|
}, false>;
|
|
989
992
|
|
|
990
993
|
/**
|
|
991
|
-
* Represents the located syntax bounds of one `[text](href)` link
|
|
994
|
+
* Represents the located syntax bounds of one `[text](href)` link — the value the inline phase's
|
|
992
995
|
* link locator returns for a balanced label followed by a destination.
|
|
993
996
|
*/
|
|
994
997
|
export declare interface LinkBounds {
|
|
@@ -999,7 +1002,7 @@ export declare interface LinkBounds {
|
|
|
999
1002
|
}
|
|
1000
1003
|
|
|
1001
1004
|
/**
|
|
1002
|
-
* Represents an inline link
|
|
1005
|
+
* Represents an inline link — `[text](href)`. `children` are the inline nodes of the link text.
|
|
1003
1006
|
* At render, html's floor removes a refused `href` attribute and the link keeps its
|
|
1004
1007
|
* text; {@link htmlToMarkdown} instead stores a refused destination as `''`.
|
|
1005
1008
|
*/
|
|
@@ -1012,7 +1015,7 @@ export declare interface LinkNode {
|
|
|
1012
1015
|
}
|
|
1013
1016
|
|
|
1014
1017
|
/**
|
|
1015
|
-
* Represents the scanned result of one `[text](href)` link
|
|
1018
|
+
* Represents the scanned result of one `[text](href)` link — the node the inline phase's link
|
|
1016
1019
|
* scanner built from {@link LinkBounds} and where the scan resumes.
|
|
1017
1020
|
*/
|
|
1018
1021
|
export declare interface LinkScan {
|
|
@@ -1023,7 +1026,7 @@ export declare interface LinkScan {
|
|
|
1023
1026
|
}
|
|
1024
1027
|
|
|
1025
1028
|
/**
|
|
1026
|
-
* Represents the result of collecting one list
|
|
1029
|
+
* Represents the result of collecting one list — the node the construct scanner built and where
|
|
1027
1030
|
* the block phase resumes.
|
|
1028
1031
|
*/
|
|
1029
1032
|
export declare interface ListCollection {
|
|
@@ -1034,7 +1037,7 @@ export declare interface ListCollection {
|
|
|
1034
1037
|
}
|
|
1035
1038
|
|
|
1036
1039
|
/**
|
|
1037
|
-
* Represents the parsed parts of a single list-item line
|
|
1040
|
+
* Represents the parsed parts of a single list-item line — the value the block phase's
|
|
1038
1041
|
* list detector returns for a `-` / `*` / `+` bullet or a `1.` / `1)` ordinal line.
|
|
1039
1042
|
*/
|
|
1040
1043
|
export declare interface ListItemMatch {
|
|
@@ -1046,12 +1049,12 @@ export declare interface ListItemMatch {
|
|
|
1046
1049
|
readonly content: string;
|
|
1047
1050
|
/** Holds the leading-space indent of the marker. */
|
|
1048
1051
|
readonly indent: number;
|
|
1049
|
-
/** Holds the full marker width (indent + bullet/ordinal + the following space)
|
|
1052
|
+
/** Holds the full marker width (indent + bullet/ordinal + the following space) — the continuation indent. */
|
|
1050
1053
|
readonly marker: number;
|
|
1051
1054
|
}
|
|
1052
1055
|
|
|
1053
1056
|
/**
|
|
1054
|
-
* Describes the shape of {@link ListItemMatch}
|
|
1057
|
+
* Describes the shape of {@link ListItemMatch} — the parsed parts of a single list-item
|
|
1055
1058
|
* line the block phase's list detector returns. Fully non-recursive (no
|
|
1056
1059
|
* nested node fields), so every field shapes directly.
|
|
1057
1060
|
*
|
|
@@ -1064,15 +1067,15 @@ export declare interface ListItemMatch {
|
|
|
1064
1067
|
* listItemParts.is({ ordered: false, start: 1, content: 'hi', indent: 0, marker: 2 }) // true
|
|
1065
1068
|
* ```
|
|
1066
1069
|
*/
|
|
1067
|
-
export declare const listItemMatchShape: ObjectShape<{
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1070
|
+
export declare const listItemMatchShape: ObjectShape< {
|
|
1071
|
+
ordered: BooleanShape;
|
|
1072
|
+
start: NumberShape;
|
|
1073
|
+
content: StringShape;
|
|
1074
|
+
indent: NumberShape;
|
|
1075
|
+
marker: NumberShape;
|
|
1073
1076
|
}, false>;
|
|
1074
1077
|
|
|
1075
|
-
/** Represents one item of a {@link ListNode}
|
|
1078
|
+
/** Represents one item of a {@link ListNode} — `children` the block content of the item (typically one paragraph, plus any nested list). */
|
|
1076
1079
|
export declare interface ListItemNode {
|
|
1077
1080
|
readonly element: 'listItem';
|
|
1078
1081
|
/** Holds the block content of the list item (its text as a paragraph, plus any nested list). */
|
|
@@ -1080,7 +1083,7 @@ export declare interface ListItemNode {
|
|
|
1080
1083
|
}
|
|
1081
1084
|
|
|
1082
1085
|
/**
|
|
1083
|
-
* Represents a list
|
|
1086
|
+
* Represents a list — bulleted (`-` / `*` / `+`, `ordered: false`) or numbered (`1.` / `1)`,
|
|
1084
1087
|
* `ordered: true`). `start` is the first ordinal of an ordered list (usually `1`).
|
|
1085
1088
|
* Nesting is expressed by a {@link ListNode} appearing in a {@link ListItemNode}'s
|
|
1086
1089
|
* `children`.
|
|
@@ -1096,7 +1099,7 @@ export declare interface ListNode {
|
|
|
1096
1099
|
}
|
|
1097
1100
|
|
|
1098
1101
|
/**
|
|
1099
|
-
* Locates an emphasis run at `start` (`*` / `_`, doubled for strong)
|
|
1102
|
+
* Locates an emphasis run at `start` (`*` / `_`, doubled for strong) — finds the nearest
|
|
1100
1103
|
* matching closing run of the same marker + width while skipping complete nested
|
|
1101
1104
|
* runs from the other marker family, and requires non-space immediately inside both
|
|
1102
1105
|
* delimiters (the CommonMark flanking simplification that blocks `* x *`). Returns
|
|
@@ -1116,7 +1119,7 @@ export declare interface ListNode {
|
|
|
1116
1119
|
export declare function locateEmphasis(source: string, start: number, to: number): EmphasisBounds | undefined;
|
|
1117
1120
|
|
|
1118
1121
|
/**
|
|
1119
|
-
* Locates a link `[text](href)` at `start`
|
|
1122
|
+
* Locates a link `[text](href)` at `start` — the text runs to a balanced `]`, then `(`
|
|
1120
1123
|
* must immediately follow and the destination runs to the matching `)` (both respect
|
|
1121
1124
|
* nested delimiters + escapes). Returns the label close and syntax end, or `undefined` when the shape
|
|
1122
1125
|
* does not hold (it then degrades to a literal `[`).
|
|
@@ -1140,14 +1143,14 @@ export declare function locateLink(source: string, start: number, to: number): L
|
|
|
1140
1143
|
*
|
|
1141
1144
|
* @remarks
|
|
1142
1145
|
* - **Construction.** Given a `string`, the constructor runs {@link parseProvenance} (the
|
|
1143
|
-
* block phase then the inline phase) once, keeping the AST and a
|
|
1144
|
-
* that parse recorded. Given a {@link MarkdownDocument}, the document is adopted
|
|
1145
|
-
* and is
|
|
1146
|
-
* - **Provenance.** {@link span} reads the region of the
|
|
1146
|
+
* block phase then the inline phase) once, keeping the AST and a copy of the span map
|
|
1147
|
+
* that parse recorded. Given a {@link MarkdownDocument}, the document is adopted as-is
|
|
1148
|
+
* and is not re-validated — gate an untrusted value with `isMarkdownDocument` first.
|
|
1149
|
+
* - **Provenance.** {@link span} reads the region of the original constructor string a
|
|
1147
1150
|
* node was produced from, and it is handle-relative: a string-constructed handle exposes
|
|
1148
1151
|
* the regions of the nodes it parsed, an adopted document exposes none, and a node from
|
|
1149
1152
|
* another handle reports `undefined` here whatever that handle reports. Each call
|
|
1150
|
-
* returns a fresh value. A node reports the region
|
|
1153
|
+
* returns a fresh value. A node reports the region this handle holds for its identity,
|
|
1151
1154
|
* else the region of the direct input a rewrite named for it, else `undefined`: a text
|
|
1152
1155
|
* run the parse joined from adjacent scanner output reports the region enclosing its
|
|
1153
1156
|
* parts, and only a rewrite output that holds no region of its own and was assembled
|
|
@@ -1155,23 +1158,22 @@ export declare function locateLink(source: string, start: number, to: number): L
|
|
|
1155
1158
|
* {@link map} carries provenance across the rewrite: an unchanged node keeps its
|
|
1156
1159
|
* region, a one-source replacement takes the region of the node it replaced, and a
|
|
1157
1160
|
* rebuilt parent takes its original's.
|
|
1158
|
-
* - **Immutable.** {@link map} never mutates the stored AST
|
|
1161
|
+
* - **Immutable.** {@link map} never mutates the stored AST — it returns a new `Markdown`
|
|
1159
1162
|
* instance; the document root invariant (`element: 'document'`) always holds. An
|
|
1160
1163
|
* identity rewrite still returns a new handle, over the same document tree.
|
|
1161
1164
|
* - **Traversal order.** {@link walk} and the `find` / `filter` / `reduce` queries built
|
|
1162
1165
|
* on it walk the AST depth-first, pre-order, root-inclusive (through {@link walkNodes});
|
|
1163
|
-
* `stream` is shallow
|
|
1166
|
+
* `stream` is shallow — only the document's direct block children.
|
|
1164
1167
|
*
|
|
1165
|
-
* @example
|
|
1168
|
+
* @example Construct from a string and narrow with a guard
|
|
1166
1169
|
* ```ts
|
|
1167
|
-
* import { Markdown, isHeadingNode
|
|
1170
|
+
* import { Markdown, isHeadingNode } from '@orkestrel/markdown'
|
|
1168
1171
|
*
|
|
1169
1172
|
* const markdown = new Markdown('# Title\n\nA **bold** [link](https://x.dev).')
|
|
1170
|
-
*
|
|
1171
|
-
*
|
|
1172
|
-
*
|
|
1173
|
-
* )
|
|
1174
|
-
* renderMarkdown(shouted.document) // '# TITLE\n\nA **BOLD** [LINK](https://x.dev).'
|
|
1173
|
+
* markdown.document.children[0] // { element: 'heading', level: 1, children: [...] }
|
|
1174
|
+
*
|
|
1175
|
+
* const heading = markdown.find(isHeadingNode) // HeadingNode | undefined, narrowed
|
|
1176
|
+
* if (heading !== undefined) heading.level // number — narrowed to HeadingNode
|
|
1175
1177
|
* ```
|
|
1176
1178
|
*/
|
|
1177
1179
|
export declare class Markdown implements MarkdownInterface {
|
|
@@ -1198,7 +1200,7 @@ export declare class Markdown implements MarkdownInterface {
|
|
|
1198
1200
|
*/
|
|
1199
1201
|
span(node: MarkdownNode): MarkdownSpan | undefined;
|
|
1200
1202
|
/**
|
|
1201
|
-
* Returns
|
|
1203
|
+
* Returns the deep traversal — a lazy, depth-first, pre-order, root-inclusive generator
|
|
1202
1204
|
* over every {@link MarkdownNode} in the document. `find` / `filter` / `reduce`
|
|
1203
1205
|
* all iterate this single traversal.
|
|
1204
1206
|
*
|
|
@@ -1235,7 +1237,7 @@ export declare class Markdown implements MarkdownInterface {
|
|
|
1235
1237
|
fold<T>(handlers: MarkdownHandlerMap<T>): T;
|
|
1236
1238
|
/**
|
|
1237
1239
|
* Returns a web-standard {@link ReadableStream} over the document's top-level block nodes
|
|
1238
|
-
* (shallow, source order)
|
|
1240
|
+
* (shallow, source order) — a fresh, pull-based source per call: one block is
|
|
1239
1241
|
* enqueued per `pull`, so a slow reader's backpressure is respected. Cancellable,
|
|
1240
1242
|
* async-iterable wherever the platform supports it (Node, Deno), and pipeable
|
|
1241
1243
|
* through any {@link TransformStream} / {@link WritableStream}.
|
|
@@ -1258,28 +1260,35 @@ export declare class Markdown implements MarkdownInterface {
|
|
|
1258
1260
|
stream(): ReadableStream<BlockNode>;
|
|
1259
1261
|
}
|
|
1260
1262
|
|
|
1261
|
-
/**
|
|
1263
|
+
/**
|
|
1264
|
+
* Represents one projected table cell — the inline content and alignment of a `th` / `td`.
|
|
1265
|
+
*
|
|
1266
|
+
* @remarks
|
|
1267
|
+
* {@link htmlToMarkdown} derives a projected table's header row from the source HTML
|
|
1268
|
+
* structure rather than from any flag a cell carries: the header is the first
|
|
1269
|
+
* `th`-bearing row, and every row after it becomes a body row.
|
|
1270
|
+
*/
|
|
1262
1271
|
export declare interface MarkdownCell {
|
|
1263
1272
|
/** Holds the alignment the cell's `align` attribute declared; `undefined` when it declared none. */
|
|
1264
1273
|
readonly align: TableAlign | undefined;
|
|
1265
|
-
/** Holds the cell's inline content
|
|
1274
|
+
/** Holds the cell's inline content — a table cell is inline-only, so block content flattens to text. */
|
|
1266
1275
|
readonly inlines: readonly InlineNode[];
|
|
1267
1276
|
}
|
|
1268
1277
|
|
|
1269
1278
|
/**
|
|
1270
|
-
* Pairs a rewritten value with the input node each rewritten node was produced from
|
|
1279
|
+
* Pairs a rewritten value with the input node each rewritten node was produced from —
|
|
1271
1280
|
* what `rewriteDocument` returns, so provenance survives a rewrite instead of ending at
|
|
1272
1281
|
* it. `T` is the rewritten value: the document for a whole-document rewrite.
|
|
1273
1282
|
*
|
|
1274
1283
|
* @remarks
|
|
1275
|
-
* `derivations` is keyed by the nodes of the
|
|
1284
|
+
* `derivations` is keyed by the nodes of the output, and each entry names the direct
|
|
1276
1285
|
* input the rewrite drew that output from. {@link MarkdownInterface.map} resolves each
|
|
1277
1286
|
* output node against the source handle's own spans in a fixed order, and follows no
|
|
1278
1287
|
* second derivation edge:
|
|
1279
1288
|
*
|
|
1280
|
-
* - the output identity's
|
|
1281
|
-
* so an identity the rewrite reused
|
|
1282
|
-
* node the handler moved elsewhere in the tree
|
|
1289
|
+
* - the output identity's own span in the source handle wins, whatever the map says,
|
|
1290
|
+
* so an identity the rewrite reused — one node returned for several inputs, or a
|
|
1291
|
+
* node the handler moved elsewhere in the tree — keeps the region it already had;
|
|
1283
1292
|
* - otherwise the span of the direct input the entry names, where that input has one;
|
|
1284
1293
|
* - otherwise none. Where the output identity holds no region of its own, a node mapped
|
|
1285
1294
|
* to `undefined`, a node whose direct input has no span, and a node with no entry at
|
|
@@ -1296,7 +1305,7 @@ derivations: ReadonlyMap<MarkdownNode, MarkdownNode | undefined>
|
|
|
1296
1305
|
];
|
|
1297
1306
|
|
|
1298
1307
|
/**
|
|
1299
|
-
* Represents the root of a parsed markdown AST
|
|
1308
|
+
* Represents the root of a parsed markdown AST — the ordered block children of the whole
|
|
1300
1309
|
* document. The value {@link MarkdownInterface.document} holds.
|
|
1301
1310
|
*/
|
|
1302
1311
|
export declare interface MarkdownDocument {
|
|
@@ -1306,14 +1315,14 @@ export declare interface MarkdownDocument {
|
|
|
1306
1315
|
}
|
|
1307
1316
|
|
|
1308
1317
|
/**
|
|
1309
|
-
* Represents a fold handler for one AST element
|
|
1310
|
-
*
|
|
1318
|
+
* Represents a fold handler for one AST element — receives the node and its children
|
|
1319
|
+
* already folded to `T`, and produces the node's own `T`. The building block of a
|
|
1311
1320
|
* {@link MarkdownHandlerMap} catamorphism table.
|
|
1312
1321
|
*/
|
|
1313
1322
|
export declare type MarkdownHandler<TNode, T> = (node: TNode, children: readonly T[]) => T;
|
|
1314
1323
|
|
|
1315
1324
|
/**
|
|
1316
|
-
* Represents the total catamorphism table for {@link MarkdownInterface.fold}
|
|
1325
|
+
* Represents the total catamorphism table for {@link MarkdownInterface.fold} — one
|
|
1317
1326
|
* {@link MarkdownHandler} per AST element, keyed by its `element` discriminant. Every
|
|
1318
1327
|
* key is required: a fold is total over the AST, so there is no element it can skip.
|
|
1319
1328
|
*/
|
|
@@ -1324,11 +1333,11 @@ export declare interface MarkdownHandlerMap<T> {
|
|
|
1324
1333
|
readonly heading: MarkdownHandler<HeadingNode, T>;
|
|
1325
1334
|
/** Folds a {@link ParagraphNode} from its already-folded inline children. */
|
|
1326
1335
|
readonly paragraph: MarkdownHandler<ParagraphNode, T>;
|
|
1327
|
-
/** Folds a {@link ThematicBreakNode} (leaf
|
|
1336
|
+
/** Folds a {@link ThematicBreakNode} (leaf — always called with an empty children list). */
|
|
1328
1337
|
readonly thematicBreak: MarkdownHandler<ThematicBreakNode, T>;
|
|
1329
1338
|
/** Folds a {@link BlockquoteNode} from its already-folded block children. */
|
|
1330
1339
|
readonly blockquote: MarkdownHandler<BlockquoteNode, T>;
|
|
1331
|
-
/** Folds a {@link CodeBlockNode} (leaf
|
|
1340
|
+
/** Folds a {@link CodeBlockNode} (leaf — always called with an empty children list). */
|
|
1332
1341
|
readonly codeBlock: MarkdownHandler<CodeBlockNode, T>;
|
|
1333
1342
|
/** Folds a {@link ListNode} from its already-folded item children. */
|
|
1334
1343
|
readonly list: MarkdownHandler<ListNode, T>;
|
|
@@ -1336,19 +1345,19 @@ export declare interface MarkdownHandlerMap<T> {
|
|
|
1336
1345
|
readonly listItem: MarkdownHandler<ListItemNode, T>;
|
|
1337
1346
|
/**
|
|
1338
1347
|
* Folds a {@link TableNode} from its cells' already-folded inline nodes, flattened
|
|
1339
|
-
* to
|
|
1340
|
-
* rows' cells (row order, then column order). It is
|
|
1348
|
+
* to one folded `T` per inline node — header cells first (column order), then body
|
|
1349
|
+
* rows' cells (row order, then column order). It is not a leaf: recover cell
|
|
1341
1350
|
* boundaries from `node.header[c].length` / `node.rows[r][c].length` against the
|
|
1342
1351
|
* flat `children` list.
|
|
1343
1352
|
*/
|
|
1344
1353
|
readonly table: MarkdownHandler<TableNode, T>;
|
|
1345
|
-
/** Folds a {@link TextNode} (leaf
|
|
1354
|
+
/** Folds a {@link TextNode} (leaf — always called with an empty children list). */
|
|
1346
1355
|
readonly text: MarkdownHandler<TextNode, T>;
|
|
1347
1356
|
/** Folds an {@link EmphasisNode} from its already-folded inline children. */
|
|
1348
1357
|
readonly emphasis: MarkdownHandler<EmphasisNode, T>;
|
|
1349
|
-
/** Folds a {@link CodeSpanNode} (leaf
|
|
1358
|
+
/** Folds a {@link CodeSpanNode} (leaf — always called with an empty children list). */
|
|
1350
1359
|
readonly codeSpan: MarkdownHandler<CodeSpanNode, T>;
|
|
1351
|
-
/** Folds a {@link LineBreakNode} (leaf
|
|
1360
|
+
/** Folds a {@link LineBreakNode} (leaf — always called with an empty children list). */
|
|
1352
1361
|
readonly break: MarkdownHandler<LineBreakNode, T>;
|
|
1353
1362
|
/** Folds a {@link LinkNode} from its already-folded inline children. */
|
|
1354
1363
|
readonly link: MarkdownHandler<LinkNode, T>;
|
|
@@ -1361,14 +1370,14 @@ export declare interface MarkdownHandlerMap<T> {
|
|
|
1361
1370
|
* the query, rewrite, and fold operations over it.
|
|
1362
1371
|
*
|
|
1363
1372
|
* @remarks
|
|
1364
|
-
* - **Immutable.** {@link MarkdownInterface.map} never mutates the stored AST
|
|
1365
|
-
* returns a
|
|
1373
|
+
* - **Immutable.** {@link MarkdownInterface.map} never mutates the stored AST — it
|
|
1374
|
+
* returns a new {@link MarkdownInterface} instance; the document root invariant
|
|
1366
1375
|
* (`element: 'document'`) always holds.
|
|
1367
1376
|
* - **Traversal order.** `walk` / `find` / `filter` / `reduce` walk the AST
|
|
1368
|
-
* depth-first, pre-order, root-inclusive; `stream` is shallow
|
|
1377
|
+
* depth-first, pre-order, root-inclusive; `stream` is shallow — only the
|
|
1369
1378
|
* document's direct block children.
|
|
1370
1379
|
* - **`stream`.** Returns a web-standard {@link ReadableStream} over the top-level
|
|
1371
|
-
* blocks
|
|
1380
|
+
* blocks — a fresh, pull-based source per call: exactly one block is enqueued per
|
|
1372
1381
|
* `pull`, so a slow consumer's backpressure is respected and no work happens ahead
|
|
1373
1382
|
* of demand. Cancellable through the returned stream's own `cancel()`, async-iterable
|
|
1374
1383
|
* wherever the platform supports it (Node, Deno, and browsers that ship the
|
|
@@ -1382,7 +1391,7 @@ export declare interface MarkdownInterface {
|
|
|
1382
1391
|
/** Holds the stored {@link MarkdownDocument} AST root. */
|
|
1383
1392
|
readonly document: MarkdownDocument;
|
|
1384
1393
|
/**
|
|
1385
|
-
* Returns
|
|
1394
|
+
* Returns the deep traversal — a lazy, depth-first, pre-order, root-inclusive
|
|
1386
1395
|
* {@link Generator} over every {@link MarkdownNode} in the document. The sync
|
|
1387
1396
|
* `for (const node of markdown.walk())` surface is also consumable by
|
|
1388
1397
|
* `for await (const node of markdown.walk())` (JavaScript accepts a sync
|
|
@@ -1391,11 +1400,17 @@ export declare interface MarkdownInterface {
|
|
|
1391
1400
|
* is shallow (top-level blocks only) and backpressure-respecting.
|
|
1392
1401
|
*/
|
|
1393
1402
|
walk(): Generator<MarkdownNode>;
|
|
1394
|
-
/**
|
|
1403
|
+
/**
|
|
1404
|
+
* Finds the first node (depth-first, pre-order) narrowed by a type guard, and returns
|
|
1405
|
+
* `undefined` when no node matches; a second overload takes a plain predicate.
|
|
1406
|
+
*/
|
|
1395
1407
|
find<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): T | undefined;
|
|
1396
1408
|
/** Finds the first node (depth-first, pre-order) matching a predicate. */
|
|
1397
1409
|
find(predicate: (node: MarkdownNode) => boolean): MarkdownNode | undefined;
|
|
1398
|
-
/**
|
|
1410
|
+
/**
|
|
1411
|
+
* Collects every node (depth-first, pre-order) narrowed by a type guard; a second
|
|
1412
|
+
* overload takes a plain predicate.
|
|
1413
|
+
*/
|
|
1399
1414
|
filter<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): readonly T[];
|
|
1400
1415
|
/** Collects every node (depth-first, pre-order) matching a predicate. */
|
|
1401
1416
|
filter(predicate: (node: MarkdownNode) => boolean): readonly MarkdownNode[];
|
|
@@ -1408,11 +1423,11 @@ export declare interface MarkdownInterface {
|
|
|
1408
1423
|
*
|
|
1409
1424
|
* @remarks
|
|
1410
1425
|
* Provenance is per handle and per node identity, so a node reports a region only
|
|
1411
|
-
* where
|
|
1426
|
+
* where this handle holds coordinates for it. A handle constructed from an adopted
|
|
1412
1427
|
* {@link MarkdownDocument} reports `undefined` for every node: it parsed no string,
|
|
1413
|
-
* so no coordinates exist to report. A text run the
|
|
1428
|
+
* so no coordinates exist to report. A text run the parse joined from adjacent
|
|
1414
1429
|
* scanner output reports the region enclosing its parts rather than `undefined`;
|
|
1415
|
-
* only a
|
|
1430
|
+
* only a rewrite output that holds no region of its own and was assembled from
|
|
1416
1431
|
* separate source nodes reports `undefined`. The region a node does report is the
|
|
1417
1432
|
* original source it was produced from, which can include syntax its value drops
|
|
1418
1433
|
* and characters that normalization removed. Each call returns a fresh value rather
|
|
@@ -1421,33 +1436,33 @@ export declare interface MarkdownInterface {
|
|
|
1421
1436
|
span(node: MarkdownNode): MarkdownSpan | undefined;
|
|
1422
1437
|
/** Rewrites the AST bottom-up (copy-on-write) and returns a new {@link MarkdownInterface}. */
|
|
1423
1438
|
map(rewrite: MarkdownRewriteHandler): MarkdownInterface;
|
|
1424
|
-
/** Folds the AST depth-first, pre-order into an accumulator. */
|
|
1439
|
+
/** Folds the AST depth-first, pre-order into an accumulator through a reducer callback. */
|
|
1425
1440
|
reduce<T>(callback: (accumulator: T, node: MarkdownNode) => T, initial: T): T;
|
|
1426
1441
|
/** Runs a total catamorphism over the document using a {@link MarkdownHandlerMap} table. */
|
|
1427
1442
|
fold<T>(handlers: MarkdownHandlerMap<T>): T;
|
|
1428
1443
|
/**
|
|
1429
1444
|
* Returns a web-standard {@link ReadableStream} over the document's top-level block nodes
|
|
1430
|
-
* (shallow, source order)
|
|
1445
|
+
* (shallow, source order) — a lazy, pull-based, backpressure-respecting source. A
|
|
1431
1446
|
* fresh, independently-replayable stream every call; never mutates the document.
|
|
1432
1447
|
*/
|
|
1433
1448
|
stream(): ReadableStream<BlockNode>;
|
|
1434
1449
|
}
|
|
1435
1450
|
|
|
1436
1451
|
/**
|
|
1437
|
-
* Represents any node in a markdown AST
|
|
1452
|
+
* Represents any node in a markdown AST — the {@link MarkdownDocument} root, a {@link BlockNode},
|
|
1438
1453
|
* a {@link ListItemNode}, or an {@link InlineNode}. The exhaustive set every
|
|
1439
1454
|
* projection's `switch` covers.
|
|
1440
1455
|
*/
|
|
1441
1456
|
export declare type MarkdownNode = MarkdownDocument | BlockNode | ListItemNode | InlineNode;
|
|
1442
1457
|
|
|
1443
1458
|
/**
|
|
1444
|
-
* Pairs a parsed document with the {@link MarkdownSpan} of each of its nodes
|
|
1459
|
+
* Pairs a parsed document with the {@link MarkdownSpan} of each of its nodes — what
|
|
1445
1460
|
* `parseProvenance` returns, and what `parseDocument` projects the document out of.
|
|
1446
1461
|
*
|
|
1447
1462
|
* @remarks
|
|
1448
|
-
* `spans` is keyed by node identity, so it addresses the nodes of
|
|
1449
|
-
* no other. A node the parse merged from adjacent scanner output
|
|
1450
|
-
* `coalesceText` joins
|
|
1463
|
+
* `spans` is keyed by node identity, so it addresses the nodes of that document and
|
|
1464
|
+
* no other. A node the parse merged from adjacent scanner output — the text run
|
|
1465
|
+
* `coalesceText` joins — is present and carries the region enclosing its parts, from
|
|
1451
1466
|
* the first part's `start` to the last part's `end`, which can include original text
|
|
1452
1467
|
* lying between them. Absence means the parse recorded no region for the node, not
|
|
1453
1468
|
* that the node was assembled from more than one region. Destructure it as
|
|
@@ -1459,7 +1474,7 @@ spans: ReadonlyMap<MarkdownNode, MarkdownSpan>
|
|
|
1459
1474
|
];
|
|
1460
1475
|
|
|
1461
1476
|
/**
|
|
1462
|
-
* Represents what one HTML node projects to on the way to markdown
|
|
1477
|
+
* Represents what one HTML node projects to on the way to markdown — the fold value
|
|
1463
1478
|
* `htmlToMarkdown` carries up the AST.
|
|
1464
1479
|
*
|
|
1465
1480
|
* @remarks
|
|
@@ -1469,14 +1484,14 @@ spans: ReadonlyMap<MarkdownNode, MarkdownSpan>
|
|
|
1469
1484
|
* under a `pre`. Rather than guess, each node reports every view its ancestors could
|
|
1470
1485
|
* need, and the ancestor that knows the context takes the one it wants.
|
|
1471
1486
|
*
|
|
1472
|
-
* - `blocks` / `inlines`
|
|
1487
|
+
* - `blocks` / `inlines` — the block and inline views. They are exclusive by
|
|
1473
1488
|
* construction: as soon as a node contributes a block, the inline runs around it
|
|
1474
1489
|
* are wrapped into paragraphs, so `blocks` being non-empty means `inlines` is
|
|
1475
1490
|
* empty and no interleaving is ever lost.
|
|
1476
|
-
* - `text`
|
|
1491
|
+
* - `text` — the raw, uncollapsed, unescaped subtree text a code span and a
|
|
1477
1492
|
* `pre > code` body need verbatim. An `UNSAFE_ELEMENTS` subtree contributes none
|
|
1478
1493
|
* of it, so a script body can never resurface as prose.
|
|
1479
|
-
* - `cells` / `rows`
|
|
1494
|
+
* - `cells` / `rows` — table structure in flight. A cell travels up to its `tr` and a
|
|
1480
1495
|
* row up to its `table`, passing through the `thead` / `tbody` wrappers between
|
|
1481
1496
|
* them untouched; whatever never reaches a table degrades to paragraphs.
|
|
1482
1497
|
*/
|
|
@@ -1489,25 +1504,25 @@ export declare interface MarkdownProjection {
|
|
|
1489
1504
|
readonly text: string;
|
|
1490
1505
|
/** Holds the cells this node contributes to an enclosing row. */
|
|
1491
1506
|
readonly cells: readonly MarkdownCell[];
|
|
1492
|
-
/** Holds the rows this node contributes to an enclosing table
|
|
1507
|
+
/** Holds the rows this node contributes to an enclosing table — each its cells, in column order. */
|
|
1493
1508
|
readonly rows: ReadonlyArray<readonly MarkdownCell[]>;
|
|
1494
1509
|
}
|
|
1495
1510
|
|
|
1496
1511
|
/**
|
|
1497
|
-
* Represents a copy-on-write node rewrite applied bottom-up by {@link MarkdownInterface.map}
|
|
1512
|
+
* Represents a copy-on-write node rewrite applied bottom-up by {@link MarkdownInterface.map} —
|
|
1498
1513
|
* receives one node (its own children already rewritten) and returns its
|
|
1499
1514
|
* replacement (the same node, unchanged, or a new node).
|
|
1500
1515
|
*/
|
|
1501
1516
|
export declare type MarkdownRewriteHandler = (node: MarkdownNode) => MarkdownNode;
|
|
1502
1517
|
|
|
1503
1518
|
/**
|
|
1504
|
-
* Maps one run of a {@link MarkdownSource} back to the region of the
|
|
1519
|
+
* Maps one run of a {@link MarkdownSource} back to the region of the original
|
|
1505
1520
|
* markdown string it was taken from.
|
|
1506
1521
|
*
|
|
1507
1522
|
* @remarks
|
|
1508
1523
|
* `offset` addresses {@link MarkdownSource.text}; `start` and `end` address the
|
|
1509
1524
|
* original string. The run's original length derives from `end - start` rather than
|
|
1510
|
-
* being stored beside them, so no length member exists to drift. The run's
|
|
1525
|
+
* being stored beside them, so no length member exists to drift. The run's derived
|
|
1511
1526
|
* extent ends where the next segment's `offset` begins, so a run may cover more of the
|
|
1512
1527
|
* original than it holds derived: the separator run `joinSources` records over a
|
|
1513
1528
|
* normalized `\r\n` terminator is one derived code unit over a two-unit original
|
|
@@ -1518,10 +1533,10 @@ export declare type MarkdownRewriteHandler = (node: MarkdownNode) => MarkdownNod
|
|
|
1518
1533
|
*
|
|
1519
1534
|
* - strictly inside the run, `p` projects to `start + (p - offset)`;
|
|
1520
1535
|
* - at the run's derived end, `p` projects to `end`, so the boundary claims the run's
|
|
1521
|
-
* whole original region instead of the prefix an affine step would reach
|
|
1536
|
+
* whole original region instead of the prefix an affine step would reach — which is
|
|
1522
1537
|
* how the one-unit `\r\n` separator run above reports its two-unit region;
|
|
1523
1538
|
* - a zero-width `p` that coincides with a later segment's `offset` resolves through the
|
|
1524
|
-
*
|
|
1539
|
+
* last segment whose `offset` equals `p`, skipping every earlier segment at that
|
|
1525
1540
|
* position whatever its extent, so a discontinuous abutment reports that final run's
|
|
1526
1541
|
* `start` rather than the earlier run's `end`.
|
|
1527
1542
|
*
|
|
@@ -1538,7 +1553,7 @@ export declare interface MarkdownSegment {
|
|
|
1538
1553
|
|
|
1539
1554
|
/**
|
|
1540
1555
|
* Pairs a piece of derived markdown text with the runs mapping it back to the
|
|
1541
|
-
* original string
|
|
1556
|
+
* original string — what `splitLines` returns per line, so every phase downstream of
|
|
1542
1557
|
* it keeps original coordinates instead of reconstructing them from node values.
|
|
1543
1558
|
*
|
|
1544
1559
|
* @remarks
|
|
@@ -1563,14 +1578,14 @@ export declare interface MarkdownSource {
|
|
|
1563
1578
|
}
|
|
1564
1579
|
|
|
1565
1580
|
/**
|
|
1566
|
-
* Addresses a half-open region of the
|
|
1581
|
+
* Addresses a half-open region of the original markdown string, in UTF-16 code units —
|
|
1567
1582
|
* `start` inclusive, `end` exclusive. The provenance a parse records for a node and
|
|
1568
1583
|
* {@link MarkdownInterface.span} reads back.
|
|
1569
1584
|
*
|
|
1570
1585
|
* @remarks
|
|
1571
1586
|
* The coordinates address the string the handle was constructed from, never the line
|
|
1572
1587
|
* text a later phase walks, so `markdown.slice(span.start, span.end)` returns the
|
|
1573
|
-
*
|
|
1588
|
+
* original source region the node was produced from. That region is not the node's
|
|
1574
1589
|
* value: it carries the syntax the value drops, such as a `\` escape marker, and the
|
|
1575
1590
|
* characters that normalization removed, such as a trailing space the paragraph phase
|
|
1576
1591
|
* trimmed. The text node of `'a \nb'` has the `value` `a\nb` and reports
|
|
@@ -1610,7 +1625,7 @@ export declare function markdownToHTML(node: MarkdownNode): HTMLDocument;
|
|
|
1610
1625
|
* Caps the recursion depth the parse pipeline (`parseDocument` and its
|
|
1611
1626
|
* `parsers.ts` helpers), the `helpers.ts` traversal / projection functions
|
|
1612
1627
|
* (`markdownToHTML`, `renderMarkdown`, `walkNodes`, `foldNode`, `rewriteDocument`),
|
|
1613
|
-
* and the `compilers.ts` renderer (`renderHTML`) honor before degrading. It bounds blockquote nesting, inline
|
|
1628
|
+
* and the `compilers.ts` renderer (`renderHTML`) honor before degrading, at 64. It bounds blockquote nesting, inline
|
|
1614
1629
|
* nesting (emphasis / links), and traversal / projection recursion so pathological
|
|
1615
1630
|
* or hostile input cannot exhaust the call stack. {@link htmlToMarkdown} is the
|
|
1616
1631
|
* inherited exception: its fold and depth cap belong to `@orkestrel/html`.
|
|
@@ -1618,14 +1633,14 @@ export declare function markdownToHTML(node: MarkdownNode): HTMLDocument;
|
|
|
1618
1633
|
export declare const MAX_DEPTH = 64;
|
|
1619
1634
|
|
|
1620
1635
|
/**
|
|
1621
|
-
* Combines the projections of one node's children into the projection of that node
|
|
1636
|
+
* Combines the projections of one node's children into the projection of that node —
|
|
1622
1637
|
* the single place inline runs become paragraphs, so no ancestor has to decide it
|
|
1623
1638
|
* twice.
|
|
1624
1639
|
*
|
|
1625
1640
|
* @remarks
|
|
1626
1641
|
* A child is either inline or block, never both, so merging preserves source order
|
|
1627
1642
|
* exactly: an inline run is held pending until a block arrives, then written out as a
|
|
1628
|
-
* paragraph
|
|
1643
|
+
* paragraph before it. That is what keeps `<div>lead<p>a</p></div>` two paragraphs in
|
|
1629
1644
|
* the order they were written rather than two lists that lost their interleaving. A
|
|
1630
1645
|
* pending run carrying no text is dropped rather than becoming a blank paragraph.
|
|
1631
1646
|
* Direct cells become one row before a later row, while cells/rows before a block
|
|
@@ -1651,11 +1666,11 @@ export declare function mergeProjections(children: readonly MarkdownProjection[]
|
|
|
1651
1666
|
* ending or spent as a space.
|
|
1652
1667
|
*
|
|
1653
1668
|
* @remarks
|
|
1654
|
-
* A hard break is ` \n` in markdown source, so it survives a re-parse only
|
|
1669
|
+
* A hard break is ` \n` in markdown source, so it survives a re-parse only between
|
|
1655
1670
|
* two lines of content and only with no whitespace touching it: a leading or trailing
|
|
1656
1671
|
* break has no line to end, a run of breaks reads as one blank line (which would end
|
|
1657
1672
|
* the paragraph), and a space beside one is eaten by the parser's line trimming. Where
|
|
1658
|
-
* a break cannot be written at all
|
|
1673
|
+
* a break cannot be written at all — a heading and a table cell are one line each — it
|
|
1659
1674
|
* becomes the space it stood for.
|
|
1660
1675
|
*
|
|
1661
1676
|
* @param nodes - The inline run to normalize
|
|
@@ -1687,7 +1702,7 @@ export declare function normalizeInlines(nodes: readonly InlineNode[], breaks: b
|
|
|
1687
1702
|
*/
|
|
1688
1703
|
export declare function normalizeParagraphLine(source: MarkdownSource, breaks: boolean): MarkdownSource;
|
|
1689
1704
|
|
|
1690
|
-
/** Represents a paragraph
|
|
1705
|
+
/** Represents a paragraph — a run of non-blank lines that is not another block; `children` its inline content. */
|
|
1691
1706
|
export declare interface ParagraphNode {
|
|
1692
1707
|
readonly element: 'paragraph';
|
|
1693
1708
|
/** Holds the inline content of the paragraph. */
|
|
@@ -1713,7 +1728,8 @@ export declare function parseBlocks(lines: readonly MarkdownSource[], depth: num
|
|
|
1713
1728
|
|
|
1714
1729
|
/**
|
|
1715
1730
|
* Parses a markdown string into a typed {@link MarkdownDocument} AST through the
|
|
1716
|
-
* block phase.
|
|
1731
|
+
* block phase — the document half of what {@link parseProvenance} returns. Malformed
|
|
1732
|
+
* markdown degrades to literal text, so the parse never throws.
|
|
1717
1733
|
*
|
|
1718
1734
|
* @param markdown - The markdown source to parse.
|
|
1719
1735
|
* @returns The parsed document.
|
|
@@ -1727,7 +1743,8 @@ export declare function parseDocument(markdown: string): MarkdownDocument;
|
|
|
1727
1743
|
|
|
1728
1744
|
/**
|
|
1729
1745
|
* Parses inline markdown text (emphasis, code spans, links, images, and hard
|
|
1730
|
-
* breaks) into inline AST nodes, coalescing adjacent text runs
|
|
1746
|
+
* breaks) into inline AST nodes, coalescing adjacent text runs and reading no block
|
|
1747
|
+
* structure. Malformed markdown degrades to literal text, so the parse never throws.
|
|
1731
1748
|
*
|
|
1732
1749
|
* @param text - The inline markdown text to parse.
|
|
1733
1750
|
* @returns The parsed inline nodes.
|
|
@@ -1740,7 +1757,8 @@ export declare function parseDocument(markdown: string): MarkdownDocument;
|
|
|
1740
1757
|
export declare function parseInline(text: string): readonly InlineNode[];
|
|
1741
1758
|
|
|
1742
1759
|
/**
|
|
1743
|
-
* Parses a markdown string into a document and its original-source spans.
|
|
1760
|
+
* Parses a markdown string into a document and its original-source spans. Malformed
|
|
1761
|
+
* markdown degrades to literal text, so the parse never throws.
|
|
1744
1762
|
*
|
|
1745
1763
|
* @param markdown - The markdown source to parse.
|
|
1746
1764
|
* @returns The parsed document and its node-identity span map.
|
|
@@ -1754,7 +1772,7 @@ export declare function parseInline(text: string): readonly InlineNode[];
|
|
|
1754
1772
|
export declare function parseProvenance(markdown: string): MarkdownParseResult;
|
|
1755
1773
|
|
|
1756
1774
|
/**
|
|
1757
|
-
* Projects one HTML leaf
|
|
1775
|
+
* Projects one HTML leaf — a text node, a comment, or a doctype — to its
|
|
1758
1776
|
* {@link MarkdownProjection}.
|
|
1759
1777
|
*
|
|
1760
1778
|
* @remarks
|
|
@@ -1775,8 +1793,8 @@ export declare function parseProvenance(markdown: string): MarkdownParseResult;
|
|
|
1775
1793
|
export declare function projectHTMLLeaf(leaf: CommentNode | DoctypeNode | TextNode_2): MarkdownProjection;
|
|
1776
1794
|
|
|
1777
1795
|
/**
|
|
1778
|
-
* Projects one HTML container
|
|
1779
|
-
* already-computed projections.
|
|
1796
|
+
* Projects one HTML container — the document root or an element — from its children's
|
|
1797
|
+
* already-computed projections. The element mapping, and the only place that decides
|
|
1780
1798
|
* what an HTML tag becomes in markdown.
|
|
1781
1799
|
*
|
|
1782
1800
|
* @remarks
|
|
@@ -1788,13 +1806,13 @@ export declare function projectHTMLLeaf(leaf: CommentNode | DoctypeNode | TextNo
|
|
|
1788
1806
|
* inline runs wrapped in paragraphs; `ul` / `ol` a list, ordered from the tag and
|
|
1789
1807
|
* numbered from `start`; `th` / `td`, `tr`, and `table` a GFM table whose column
|
|
1790
1808
|
* alignment comes from each header-position cell's `align` attribute. Every
|
|
1791
|
-
* `UNSAFE_ELEMENTS` subtree contributes nothing at all, text included. Every
|
|
1809
|
+
* `UNSAFE_ELEMENTS` subtree contributes nothing at all, text included. Every other
|
|
1792
1810
|
* element unwraps to its children, so wrapper soup melts while its content keeps its
|
|
1793
|
-
* shape
|
|
1811
|
+
* shape — `<div><p>a</p><p>b</p></div>` stays two paragraphs.
|
|
1794
1812
|
*
|
|
1795
1813
|
* Three mappings read their own node rather than only their children's projections,
|
|
1796
1814
|
* because HTML puts the fact in a position rather than in a value: a `pre` takes its
|
|
1797
|
-
* body from its `code` child's raw text, and a list takes one item per `li` child
|
|
1815
|
+
* body from its `code` child's raw text, and a list takes one item per `li` child — so
|
|
1798
1816
|
* an empty `<li>` is still an item, while the whitespace between two of them is not.
|
|
1799
1817
|
* A `tr` accepts only its own direct cells, and a table derives the first `th`-bearing
|
|
1800
1818
|
* row from its own source structure.
|
|
@@ -1812,7 +1830,7 @@ export declare function projectHTMLLeaf(leaf: CommentNode | DoctypeNode | TextNo
|
|
|
1812
1830
|
export declare function projectHTMLNode(node: ElementNode | HTMLDocument, children: readonly MarkdownProjection[]): MarkdownProjection;
|
|
1813
1831
|
|
|
1814
1832
|
/**
|
|
1815
|
-
* Reads a projection as
|
|
1833
|
+
* Reads a projection as block content — the view a document, a blockquote, and a list
|
|
1816
1834
|
* item each need.
|
|
1817
1835
|
*
|
|
1818
1836
|
* @remarks
|
|
@@ -1833,7 +1851,7 @@ export declare function projectHTMLNode(node: ElementNode | HTMLDocument, childr
|
|
|
1833
1851
|
export declare function projectionToBlocks(projection: MarkdownProjection): readonly BlockNode[];
|
|
1834
1852
|
|
|
1835
1853
|
/**
|
|
1836
|
-
* Reads a projection as
|
|
1854
|
+
* Reads a projection as inline content — the view a link, an emphasis, and a table cell
|
|
1837
1855
|
* each need.
|
|
1838
1856
|
*
|
|
1839
1857
|
* @remarks
|
|
@@ -1874,6 +1892,9 @@ export declare function projectSpan(source: MarkdownSource, from: number, to: nu
|
|
|
1874
1892
|
* Renders a {@link MarkdownNode} to sanitized canonical HTML.
|
|
1875
1893
|
*
|
|
1876
1894
|
* @remarks
|
|
1895
|
+
* Sanitization is unconditional: the function takes one argument and declares no
|
|
1896
|
+
* options, so no call shape opts out of it.
|
|
1897
|
+
*
|
|
1877
1898
|
* Markdown widens `@orkestrel/html`'s attribute floor by exactly `src`, because image
|
|
1878
1899
|
* syntax is meaningless without its source. `src` is still a URL attribute, so the
|
|
1879
1900
|
* floor refuses `javascript:`, `data:`, `vbscript:`, and `file:` values. A stricter
|
|
@@ -1892,15 +1913,15 @@ export declare function projectSpan(source: MarkdownSource, from: number, to: nu
|
|
|
1892
1913
|
export declare function renderHTML(node: MarkdownNode): string;
|
|
1893
1914
|
|
|
1894
1915
|
/**
|
|
1895
|
-
* Renders a {@link MarkdownNode} to its
|
|
1896
|
-
* projection of `renderHTML
|
|
1916
|
+
* Renders a {@link MarkdownNode} to its canonical markdown source — the inverse
|
|
1917
|
+
* projection of `renderHTML`. It is the serializer a `parse(renderMarkdown(doc))`
|
|
1897
1918
|
* round-trip is built on. Canonical forms: `*` / `**` emphasis at even emphasis
|
|
1898
1919
|
* nesting depths and `_` / `__` at odd depths, `- ` bullets, `N. ` sequential
|
|
1899
1920
|
* ordinals (from the list's `start`), `---` thematic breaks, fenced code blocks
|
|
1900
1921
|
* (backtick run widened past any 3+ backtick run inside the body), ATX headings,
|
|
1901
|
-
* `> `-prefixed blockquote lines, GFM tables (1-space-padded cells,
|
|
1902
|
-
*
|
|
1903
|
-
* and two-space hard breaks. A `text` node's literal content is backslash-escaped
|
|
1922
|
+
* `> `-prefixed blockquote lines, GFM tables (1-space-padded cells, a backslash
|
|
1923
|
+
* before each literal pipe, an alignment delimiter row), `[text](href)` links,
|
|
1924
|
+
* `` images, and two-space hard breaks. A `text` node's literal content is backslash-escaped
|
|
1904
1925
|
* wherever it would otherwise re-parse as markup, so parsing the rendered source
|
|
1905
1926
|
* returns the node it was rendered from.
|
|
1906
1927
|
*
|
|
@@ -1923,10 +1944,10 @@ export declare function renderHTML(node: MarkdownNode): string;
|
|
|
1923
1944
|
export declare function renderMarkdown(node: MarkdownNode): string;
|
|
1924
1945
|
|
|
1925
1946
|
/**
|
|
1926
|
-
* Rewrites a {@link MarkdownDocument} bottom-up (copy-on-write)
|
|
1947
|
+
* Rewrites a {@link MarkdownDocument} bottom-up (copy-on-write) — each node's children
|
|
1927
1948
|
* are rewritten first (post-order), then `rewrite` is applied to the node itself; the
|
|
1928
|
-
* document
|
|
1929
|
-
* always holds). A table's inline cells and a list's items
|
|
1949
|
+
* document root is never passed to `rewrite` (the `element: 'document'` invariant
|
|
1950
|
+
* always holds). A table's inline cells and a list's items are rewritten too.
|
|
1930
1951
|
*
|
|
1931
1952
|
* @remarks
|
|
1932
1953
|
* Never mutates `document`. An unchanged subtree keeps its input identity. A parent
|
|
@@ -1935,12 +1956,12 @@ export declare function renderMarkdown(node: MarkdownNode): string;
|
|
|
1935
1956
|
* whose `element` does not fit the slot it was called for (a block slot handed a
|
|
1936
1957
|
* non-{@link BlockNode}, an inline slot handed a non-{@link InlineNode}, a list-item
|
|
1937
1958
|
* slot handed a non-`listItem`), the ill-fitting result is discarded and the accepted
|
|
1938
|
-
* input child is reused
|
|
1959
|
+
* input child is reused — `rewriteDocument` stays total and never produces a
|
|
1939
1960
|
* structurally invalid document.
|
|
1940
1961
|
*
|
|
1941
1962
|
* Descent is capped at {@link MAX_DEPTH}, the same cap {@link walkNodes} and
|
|
1942
1963
|
* {@link foldNode} observe: at `depth >= MAX_DEPTH` the subtree is passed through
|
|
1943
|
-
*
|
|
1964
|
+
* unchanged (by reference, not rebuilt, and `rewrite` is not invoked on it) instead of
|
|
1944
1965
|
* recursing further, so a pathologically deep adopted document cannot exhaust the
|
|
1945
1966
|
* call stack. {@link MarkdownInterface.map} inherits this cap since it delegates here.
|
|
1946
1967
|
*
|
|
@@ -1959,7 +1980,7 @@ export declare function rewriteDocument(document: MarkdownDocument, rewrite: Mar
|
|
|
1959
1980
|
|
|
1960
1981
|
/**
|
|
1961
1982
|
* Scans an inline code span at `start` (a `` ` ``-run … a matching `` ` ``-run of the
|
|
1962
|
-
*
|
|
1983
|
+
* same length, the CommonMark rule that lets a span contain backticks). Returns the
|
|
1963
1984
|
* span's literal text + end index, or `undefined` when no matching closer exists (it
|
|
1964
1985
|
* then degrades to literal backticks).
|
|
1965
1986
|
*
|
|
@@ -1976,7 +1997,7 @@ export declare function rewriteDocument(document: MarkdownDocument, rewrite: Mar
|
|
|
1976
1997
|
export declare function scanCode(source: string, start: number, to: number): CodeSpanMatch | undefined;
|
|
1977
1998
|
|
|
1978
1999
|
/**
|
|
1979
|
-
* Scans an emphasis run at `start` (`*` / `_`, doubled for strong)
|
|
2000
|
+
* Scans an emphasis run at `start` (`*` / `_`, doubled for strong) — finds the nearest
|
|
1980
2001
|
* matching closing run of the same marker + width while skipping complete nested runs
|
|
1981
2002
|
* from the other marker family, and requires non-space immediately inside both
|
|
1982
2003
|
* delimiters (the CommonMark flanking simplification that blocks `* x *`) through
|
|
@@ -2000,7 +2021,7 @@ export declare function scanCode(source: string, start: number, to: number): Cod
|
|
|
2000
2021
|
export declare function scanEmphasis(source: string, start: number, to: number, depth?: number): EmphasisScan | undefined;
|
|
2001
2022
|
|
|
2002
2023
|
/**
|
|
2003
|
-
* Scans the window `[from, to)` of `source` into inline nodes
|
|
2024
|
+
* Scans the window `[from, to)` of `source` into inline nodes — the single recursive
|
|
2004
2025
|
* engine the inline phase runs on (emphasis, link text, and image alternative
|
|
2005
2026
|
* content recurse through it). Linear:
|
|
2006
2027
|
* each character is consumed once; a failed construct emits its opening character as
|
|
@@ -2012,10 +2033,10 @@ export declare function scanEmphasis(source: string, start: number, to: number,
|
|
|
2012
2033
|
* @param depth - The current inline-recursion depth (defaults to 0 at the entry point);
|
|
2013
2034
|
* incremented by one on every recursive descent {@link scanInlineSource} makes into
|
|
2014
2035
|
* itself for a link's text, an image's alternative content, or an emphasis run's
|
|
2015
|
-
* children. At {@link MAX_DEPTH} the window is never scanned for markup
|
|
2016
|
-
* a single literal text node
|
|
2036
|
+
* children. At {@link MAX_DEPTH} the window is never scanned for markup — it emits as
|
|
2037
|
+
* a single literal text node — so pathological nesting (`[[[[…`, `****…`) cannot
|
|
2017
2038
|
* exhaust the call stack.
|
|
2018
|
-
* @returns The parsed inline nodes (
|
|
2039
|
+
* @returns The parsed inline nodes (not yet coalesced)
|
|
2019
2040
|
*
|
|
2020
2041
|
* @example
|
|
2021
2042
|
* ```ts
|
|
@@ -2051,7 +2072,7 @@ export declare function scanInline(source: string, from: number, to: number, dep
|
|
|
2051
2072
|
export declare function scanInlineSource(source: MarkdownSource, from: number, to: number, spans: Map<MarkdownNode, MarkdownSpan>, depth?: number): readonly InlineNode[];
|
|
2052
2073
|
|
|
2053
2074
|
/**
|
|
2054
|
-
* Scans a link `[text](href)` at `start`
|
|
2075
|
+
* Scans a link `[text](href)` at `start` — the text runs to a balanced `]`, then `(`
|
|
2055
2076
|
* must immediately follow and the destination runs to the matching `)` (both respect
|
|
2056
2077
|
* nested delimiters + escapes) through {@link locateLink}, and returns the parsed node
|
|
2057
2078
|
* and end index. Returns `undefined` when the shape does not hold (it then degrades to
|
|
@@ -2106,10 +2127,11 @@ export declare function sliceSource(source: MarkdownSource, from: number, to: nu
|
|
|
2106
2127
|
export declare function splitLines(markdown: string): readonly MarkdownSource[];
|
|
2107
2128
|
|
|
2108
2129
|
/**
|
|
2109
|
-
* Splits one GFM table row into its cell strings
|
|
2110
|
-
*
|
|
2111
|
-
* empty leading / trailing cell
|
|
2112
|
-
* form from {@link splitTableSources}, which owns the
|
|
2130
|
+
* Splits one GFM table row into its cell strings — outer pipes are optional, a pipe
|
|
2131
|
+
* escaped by a leading backslash inside a cell is not a separator (it becomes a literal
|
|
2132
|
+
* pipe character), and the empty leading / trailing cell an outer pipe produces is
|
|
2133
|
+
* dropped. Derives the string form from {@link splitTableSources}, which owns the
|
|
2134
|
+
* escaped-pipe splitting rule.
|
|
2113
2135
|
*
|
|
2114
2136
|
* @param row - The raw table row line
|
|
2115
2137
|
* @returns The row's cells, in column order
|
|
@@ -2136,8 +2158,8 @@ export declare function splitTableRow(row: string): readonly string[];
|
|
|
2136
2158
|
export declare function splitTableSources(row: MarkdownSource): readonly MarkdownSource[];
|
|
2137
2159
|
|
|
2138
2160
|
/**
|
|
2139
|
-
* Checks whether the line at `index` starts a
|
|
2140
|
-
* break / blockquote / list / table)
|
|
2161
|
+
* Checks whether the line at `index` starts a new block kind (heading / fence / thematic
|
|
2162
|
+
* break / blockquote / list / table) — the paragraph collector stops at such a line
|
|
2141
2163
|
* so a block following a paragraph without a blank line still parses (a trusted-input
|
|
2142
2164
|
* caller writing a `##` heading directly under a paragraph, with no intervening blank
|
|
2143
2165
|
* line).
|
|
@@ -2175,12 +2197,19 @@ export declare function stripQuote(source: MarkdownSource): MarkdownSource;
|
|
|
2175
2197
|
* by `null` in {@link TableNode.align}: the positional array requires one entry per
|
|
2176
2198
|
* column, JSON cannot carry `undefined` in an array, and the bare delimiter is an
|
|
2177
2199
|
* explicit no-alignment marker rather than an omitted value.
|
|
2200
|
+
*
|
|
2201
|
+
* @remarks
|
|
2202
|
+
* The other place absence appears is {@link MarkdownCell.align}, which holds
|
|
2203
|
+
* `undefined` when the projected cell declared no alignment. That member is a plain
|
|
2204
|
+
* optional property on one cell rather than an entry in a positional array, so it
|
|
2205
|
+
* takes the ordinary `undefined` instead of the in-band `null` marker.
|
|
2178
2206
|
*/
|
|
2179
2207
|
export declare type TableAlign = 'left' | 'right' | 'center';
|
|
2180
2208
|
|
|
2181
2209
|
/**
|
|
2182
|
-
* Describes the shape of a {@link TableAlign}
|
|
2183
|
-
* literal.
|
|
2210
|
+
* Describes the shape of a {@link TableAlign} — the per-column GFM table alignment
|
|
2211
|
+
* literal. Absence is no member of it, so the shape refuses the `null` a bare `---`
|
|
2212
|
+
* delimiter takes in a `TableNode`'s `align` list.
|
|
2184
2213
|
*
|
|
2185
2214
|
* @example
|
|
2186
2215
|
* ```ts
|
|
@@ -2196,7 +2225,7 @@ export declare type TableAlign = 'left' | 'right' | 'center';
|
|
|
2196
2225
|
export declare const tableAlignShape: LiteralShape<readonly ["left", "right", "center"]>;
|
|
2197
2226
|
|
|
2198
2227
|
/**
|
|
2199
|
-
* Represents the result of collecting one GFM table
|
|
2228
|
+
* Represents the result of collecting one GFM table — the node the construct scanner built and
|
|
2200
2229
|
* where the block phase resumes.
|
|
2201
2230
|
*/
|
|
2202
2231
|
export declare interface TableCollection {
|
|
@@ -2207,16 +2236,16 @@ export declare interface TableCollection {
|
|
|
2207
2236
|
}
|
|
2208
2237
|
|
|
2209
2238
|
/**
|
|
2210
|
-
* Represents a GFM table
|
|
2239
|
+
* Represents a GFM table — `header` the inline content of each header cell, `rows` the body
|
|
2211
2240
|
* rows (each a list of cells, each cell inline content), `align` the per-column
|
|
2212
2241
|
* alignment from the delimiter row. A short body row is padded with empty cells; an
|
|
2213
2242
|
* over-long one is truncated to the header's column count.
|
|
2214
2243
|
*/
|
|
2215
2244
|
export declare interface TableNode {
|
|
2216
2245
|
readonly element: 'table';
|
|
2217
|
-
/** Holds the header row
|
|
2246
|
+
/** Holds the header row — one cell of inline content per column. */
|
|
2218
2247
|
readonly header: ReadonlyArray<readonly InlineNode[]>;
|
|
2219
|
-
/** Holds the body rows
|
|
2248
|
+
/** Holds the body rows — each a list of cells, each cell inline content. */
|
|
2220
2249
|
readonly rows: ReadonlyArray<ReadonlyArray<readonly InlineNode[]>>;
|
|
2221
2250
|
/**
|
|
2222
2251
|
* Holds the per-column alignment from the delimiter row, in column order. `null`
|
|
@@ -2228,19 +2257,19 @@ export declare interface TableNode {
|
|
|
2228
2257
|
}
|
|
2229
2258
|
|
|
2230
2259
|
/**
|
|
2231
|
-
* Represents a run of plain text
|
|
2260
|
+
* Represents a run of plain text — the leaf inline node. `value` is the decoded text with
|
|
2232
2261
|
* markdown escapes (`\*`, `\_`, …) already resolved to their literal characters;
|
|
2233
2262
|
* html's text encoder escapes `&`, `<`, `>` on the way out; `"` and `'` stay literal
|
|
2234
2263
|
* in character data.
|
|
2235
2264
|
*/
|
|
2236
2265
|
export declare interface TextNode {
|
|
2237
2266
|
readonly element: 'text';
|
|
2238
|
-
/** Holds the literal text content (escapes resolved,
|
|
2267
|
+
/** Holds the literal text content (escapes resolved, not yet HTML-escaped). */
|
|
2239
2268
|
readonly value: string;
|
|
2240
2269
|
}
|
|
2241
2270
|
|
|
2242
2271
|
/**
|
|
2243
|
-
* Describes the shape of a {@link TextNode}
|
|
2272
|
+
* Describes the shape of a {@link TextNode} — a plain-text leaf inline run.
|
|
2244
2273
|
*
|
|
2245
2274
|
* @example
|
|
2246
2275
|
* ```ts
|
|
@@ -2251,18 +2280,18 @@ export declare interface TextNode {
|
|
|
2251
2280
|
* text.is({ element: 'text', value: 'hi' }) // true
|
|
2252
2281
|
* ```
|
|
2253
2282
|
*/
|
|
2254
|
-
export declare const textShape: ObjectShape<{
|
|
2255
|
-
|
|
2256
|
-
|
|
2283
|
+
export declare const textShape: ObjectShape< {
|
|
2284
|
+
element: LiteralShape<readonly ["text"]>;
|
|
2285
|
+
value: StringShape;
|
|
2257
2286
|
}, false>;
|
|
2258
2287
|
|
|
2259
|
-
/** Represents a thematic break
|
|
2288
|
+
/** Represents a thematic break — a horizontal rule (`---` / `***` / `___` on its own line). */
|
|
2260
2289
|
export declare interface ThematicBreakNode {
|
|
2261
2290
|
readonly element: 'thematicBreak';
|
|
2262
2291
|
}
|
|
2263
2292
|
|
|
2264
2293
|
/**
|
|
2265
|
-
* Describes the shape of a {@link ThematicBreakNode}
|
|
2294
|
+
* Describes the shape of a {@link ThematicBreakNode} — a horizontal rule. Carries no
|
|
2266
2295
|
* fields beyond its `element` discriminant.
|
|
2267
2296
|
*
|
|
2268
2297
|
* @example
|
|
@@ -2274,13 +2303,13 @@ export declare interface ThematicBreakNode {
|
|
|
2274
2303
|
* thematicBreak.is({ element: 'thematicBreak' }) // true
|
|
2275
2304
|
* ```
|
|
2276
2305
|
*/
|
|
2277
|
-
export declare const thematicBreakShape: ObjectShape<{
|
|
2278
|
-
|
|
2306
|
+
export declare const thematicBreakShape: ObjectShape< {
|
|
2307
|
+
element: LiteralShape<readonly ["thematicBreak"]>;
|
|
2279
2308
|
}, false>;
|
|
2280
2309
|
|
|
2281
2310
|
/**
|
|
2282
|
-
* Trims the whitespace at the two ends of an inline run
|
|
2283
|
-
* leading text node and the trailing whitespace of a trailing one
|
|
2311
|
+
* Trims the whitespace at the two ends of an inline run — the leading whitespace of a
|
|
2312
|
+
* leading text node and the trailing whitespace of a trailing one — dropping either
|
|
2284
2313
|
* node when nothing survives.
|
|
2285
2314
|
*
|
|
2286
2315
|
* @remarks
|
|
@@ -2313,7 +2342,7 @@ export declare function trimInlines(nodes: readonly InlineNode[]): readonly Inli
|
|
|
2313
2342
|
export declare function trimSource(source: MarkdownSource): MarkdownSource;
|
|
2314
2343
|
|
|
2315
2344
|
/**
|
|
2316
|
-
* Resolves backslash escapes in a raw string to their literal characters
|
|
2345
|
+
* Resolves backslash escapes in a raw string to their literal characters — used for a
|
|
2317
2346
|
* link `href` (which is not otherwise inline-parsed) and any plain text run.
|
|
2318
2347
|
*
|
|
2319
2348
|
* @param text - The raw text possibly carrying `\x` escapes
|
|
@@ -2327,7 +2356,7 @@ export declare function trimSource(source: MarkdownSource): MarkdownSource;
|
|
|
2327
2356
|
export declare function unescapeText(text: string): string;
|
|
2328
2357
|
|
|
2329
2358
|
/**
|
|
2330
|
-
* Walks a {@link MarkdownNode} depth-first, pre-order, root-inclusive
|
|
2359
|
+
* Walks a {@link MarkdownNode} depth-first, pre-order, root-inclusive — yields
|
|
2331
2360
|
* the node itself, then recurses into its children (block children, list items,
|
|
2332
2361
|
* image/link inline children, table header/row cells' inline nodes) in walk order.
|
|
2333
2362
|
*
|