@orkestrel/markdown 0.0.5 → 0.0.7
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 +49 -64
- package/dist/src/core/index.cjs +2835 -1316
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +1822 -8
- package/dist/src/core/index.d.ts +1822 -8
- package/dist/src/core/index.js +2819 -1312
- package/dist/src/core/index.js.map +1 -1
- package/package.json +20 -15
- package/dist/src/core/Markdown.d.ts +0 -86
- package/dist/src/core/constants.d.ts +0 -17
- package/dist/src/core/factories.d.ts +0 -92
- package/dist/src/core/helpers.d.ts +0 -451
- package/dist/src/core/parsers.d.ts +0 -66
- package/dist/src/core/shapers.d.ts +0 -105
- package/dist/src/core/types.d.ts +0 -269
- package/dist/src/core/validators.d.ts +0 -287
package/dist/src/core/types.d.ts
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The horizontal alignment of a GFM table column, as declared by its delimiter row
|
|
3
|
-
* (`:---` left, `---:` right, `:---:` center) - `'none'` when the delimiter carries
|
|
4
|
-
* no alignment colon. One entry per column, in column order.
|
|
5
|
-
*/
|
|
6
|
-
export type TableAlign = 'none' | 'left' | 'right' | 'center';
|
|
7
|
-
/**
|
|
8
|
-
* The parsed parts of a single list-item line - the value the block phase's
|
|
9
|
-
* list detector returns for a `-` / `*` / `+` bullet or a `1.` / `1)` ordinal line.
|
|
10
|
-
*/
|
|
11
|
-
export interface ListItemParts {
|
|
12
|
-
/** `true` for an ordered (`1.` / `1)`) item, `false` for a bullet (`-` / `*` / `+`). */
|
|
13
|
-
readonly ordered: boolean;
|
|
14
|
-
/** The ordinal of an ordered item (its number); `1` for a bullet. */
|
|
15
|
-
readonly start: number;
|
|
16
|
-
/** The item's text after the marker. */
|
|
17
|
-
readonly content: string;
|
|
18
|
-
/** The leading-space indent of the marker. */
|
|
19
|
-
readonly indent: number;
|
|
20
|
-
/** The full marker width (indent + bullet/ordinal + the following space) - the continuation indent. */
|
|
21
|
-
readonly marker: number;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* A run of plain text - the leaf inline node. `value` is the decoded text with
|
|
25
|
-
* markdown escapes (`\*`, `\_`, …) already resolved to their literal characters; the
|
|
26
|
-
* renderer HTML-escapes it (`<` / `>` / `&` / `"`) on the way out.
|
|
27
|
-
*/
|
|
28
|
-
export interface TextNode {
|
|
29
|
-
readonly element: 'text';
|
|
30
|
-
/** The literal text content (escapes resolved, NOT yet HTML-escaped). */
|
|
31
|
-
readonly value: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Emphasized inline content - `*italic*` / `_italic_` (`strong: false`) or
|
|
35
|
-
* `**bold**` / `__bold__` (`strong: true`). `children` are the nested inline nodes,
|
|
36
|
-
* so emphasis composes (a `**bold _and italic_**` is a strong node wrapping a text
|
|
37
|
-
* node and an emphasis node).
|
|
38
|
-
*/
|
|
39
|
-
export interface EmphasisNode {
|
|
40
|
-
readonly element: 'emphasis';
|
|
41
|
-
/** `true` for strong (`**` / `__`, → `<strong>`); `false` for ordinary emphasis (`*` / `_`, → `<em>`). */
|
|
42
|
-
readonly strong: boolean;
|
|
43
|
-
/** The emphasized inline content. */
|
|
44
|
-
readonly children: readonly InlineNode[];
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* An inline code span - `` `code` ``. `value` is the verbatim span text; no inner
|
|
48
|
-
* markdown is parsed (code is literal), and the renderer HTML-escapes it inside a
|
|
49
|
-
* `<code>` element.
|
|
50
|
-
*/
|
|
51
|
-
export interface CodeSpanNode {
|
|
52
|
-
readonly element: 'codeSpan';
|
|
53
|
-
/** The verbatim code text (no inner markdown; HTML-escaped at render). */
|
|
54
|
-
readonly value: string;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* An inline link - `[text](href)`. `children` are the inline nodes of the link text;
|
|
58
|
-
* `href` is the destination, sanitized at render (a `javascript:` / other unsafe
|
|
59
|
-
* scheme is dropped to an empty `href`, and the value is HTML-attribute-escaped).
|
|
60
|
-
*/
|
|
61
|
-
export interface LinkNode {
|
|
62
|
-
readonly element: 'link';
|
|
63
|
-
/** The link destination (sanitized + attribute-escaped at render). */
|
|
64
|
-
readonly href: string;
|
|
65
|
-
/** The inline content of the link text. */
|
|
66
|
-
readonly children: readonly InlineNode[];
|
|
67
|
-
}
|
|
68
|
-
/** A node that can appear inside inline content (a heading / paragraph / cell / list item / link text). */
|
|
69
|
-
export type InlineNode = TextNode | EmphasisNode | CodeSpanNode | LinkNode;
|
|
70
|
-
/**
|
|
71
|
-
* An ATX heading - `#` … `######`. `level` is 1–6 (the number of leading `#`),
|
|
72
|
-
* `children` the inline content of the heading text.
|
|
73
|
-
*/
|
|
74
|
-
export interface HeadingNode {
|
|
75
|
-
readonly element: 'heading';
|
|
76
|
-
/** The heading level, 1 (`#`) through 6 (`######`). */
|
|
77
|
-
readonly level: number;
|
|
78
|
-
/** The inline content of the heading text. */
|
|
79
|
-
readonly children: readonly InlineNode[];
|
|
80
|
-
}
|
|
81
|
-
/** A paragraph - a run of non-blank lines that is not another block; `children` its inline content. */
|
|
82
|
-
export interface ParagraphNode {
|
|
83
|
-
readonly element: 'paragraph';
|
|
84
|
-
/** The inline content of the paragraph. */
|
|
85
|
-
readonly children: readonly InlineNode[];
|
|
86
|
-
}
|
|
87
|
-
/** One item of a {@link ListNode} - `children` the block content of the item (typically one paragraph, plus any nested list). */
|
|
88
|
-
export interface ListItemNode {
|
|
89
|
-
readonly element: 'listItem';
|
|
90
|
-
/** The block content of the list item (its text as a paragraph, plus any nested list). */
|
|
91
|
-
readonly children: readonly BlockNode[];
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* A list - bulleted (`-` / `*` / `+`, `ordered: false`) or numbered (`1.` / `1)`,
|
|
95
|
-
* `ordered: true`). `start` is the first ordinal of an ordered list (usually `1`).
|
|
96
|
-
* Nesting is expressed by a {@link ListNode} appearing in a {@link ListItemNode}'s
|
|
97
|
-
* `children`.
|
|
98
|
-
*/
|
|
99
|
-
export interface ListNode {
|
|
100
|
-
readonly element: 'list';
|
|
101
|
-
/** `true` for an ordered (numbered) list (→ `<ol>`); `false` for a bulleted list (→ `<ul>`). */
|
|
102
|
-
readonly ordered: boolean;
|
|
103
|
-
/** The starting ordinal of an ordered list (the first item's number); `1` for a bulleted list. */
|
|
104
|
-
readonly start: number;
|
|
105
|
-
/** The list's items, in order. */
|
|
106
|
-
readonly items: readonly ListItemNode[];
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* A GFM table - `header` the inline content of each header cell, `rows` the body
|
|
110
|
-
* rows (each a list of cells, each cell inline content), `align` the per-column
|
|
111
|
-
* alignment from the delimiter row. A short body row is padded with empty cells; an
|
|
112
|
-
* over-long one is truncated to the header's column count.
|
|
113
|
-
*/
|
|
114
|
-
export interface TableNode {
|
|
115
|
-
readonly element: 'table';
|
|
116
|
-
/** The header row - one cell of inline content per column. */
|
|
117
|
-
readonly header: readonly (readonly InlineNode[])[];
|
|
118
|
-
/** The body rows - each a list of cells, each cell inline content. */
|
|
119
|
-
readonly rows: readonly (readonly (readonly InlineNode[])[])[];
|
|
120
|
-
/** The per-column alignment from the delimiter row, in column order. */
|
|
121
|
-
readonly align: readonly TableAlign[];
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* A fenced code block - ```` ```lang ````. `code` is the verbatim block content (no
|
|
125
|
-
* inner markdown; the closing fence and the trailing newline are stripped), `lang`
|
|
126
|
-
* the info-string language tag (the first word after the opening fence), absent when
|
|
127
|
-
* none was given.
|
|
128
|
-
*/
|
|
129
|
-
export interface CodeBlockNode {
|
|
130
|
-
readonly element: 'codeBlock';
|
|
131
|
-
/** The info-string language tag (first word after the opening fence), if any. */
|
|
132
|
-
readonly lang?: string;
|
|
133
|
-
/** The verbatim code content (no inner markdown; HTML-escaped at render). */
|
|
134
|
-
readonly code: string;
|
|
135
|
-
}
|
|
136
|
-
/** A blockquote - `>`-prefixed lines; `children` the block content parsed from the de-quoted lines (so quotes nest). */
|
|
137
|
-
export interface BlockquoteNode {
|
|
138
|
-
readonly element: 'blockquote';
|
|
139
|
-
/** The block content of the quote (the `>`-stripped lines, re-parsed as blocks). */
|
|
140
|
-
readonly children: readonly BlockNode[];
|
|
141
|
-
}
|
|
142
|
-
/** A thematic break - a horizontal rule (`---` / `***` / `___` on its own line). */
|
|
143
|
-
export interface ThematicBreakNode {
|
|
144
|
-
readonly element: 'thematicBreak';
|
|
145
|
-
}
|
|
146
|
-
/** A node that can appear at the block level of a document (or inside a list item / blockquote). */
|
|
147
|
-
export type BlockNode = HeadingNode | ParagraphNode | ListNode | TableNode | CodeBlockNode | BlockquoteNode | ThematicBreakNode;
|
|
148
|
-
/**
|
|
149
|
-
* The root of a parsed markdown AST - the ordered block children of the whole
|
|
150
|
-
* document. The value {@link MarkdownInterface.document} holds.
|
|
151
|
-
*/
|
|
152
|
-
export interface MarkdownDocument {
|
|
153
|
-
readonly element: 'document';
|
|
154
|
-
/** The document's top-level block nodes, in source order. */
|
|
155
|
-
readonly children: readonly BlockNode[];
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Any node in a markdown AST - the {@link MarkdownDocument} root, a {@link BlockNode},
|
|
159
|
-
* a {@link ListItemNode}, or an {@link InlineNode}. The exhaustive set the renderer's
|
|
160
|
-
* `switch` covers.
|
|
161
|
-
*/
|
|
162
|
-
export type MarkdownNode = MarkdownDocument | BlockNode | ListItemNode | InlineNode;
|
|
163
|
-
/**
|
|
164
|
-
* A fold handler for one AST element - receives the node and its children
|
|
165
|
-
* ALREADY folded to `T`, and produces the node's own `T`. The building block of a
|
|
166
|
-
* {@link MarkdownHandlers} catamorphism table.
|
|
167
|
-
*/
|
|
168
|
-
export type MarkdownHandler<TNode, T> = (node: TNode, children: readonly T[]) => T;
|
|
169
|
-
/**
|
|
170
|
-
* The total catamorphism table for {@link MarkdownInterface.fold} - one
|
|
171
|
-
* {@link MarkdownHandler} per AST element, keyed by its `element` discriminant. Every
|
|
172
|
-
* key is required: a fold is total over the AST, so there is no element it can skip.
|
|
173
|
-
*/
|
|
174
|
-
export interface MarkdownHandlers<T> {
|
|
175
|
-
/** Folds a {@link MarkdownDocument} root from its already-folded block children. */
|
|
176
|
-
readonly document: MarkdownHandler<MarkdownDocument, T>;
|
|
177
|
-
/** Folds a {@link HeadingNode} from its already-folded inline children. */
|
|
178
|
-
readonly heading: MarkdownHandler<HeadingNode, T>;
|
|
179
|
-
/** Folds a {@link ParagraphNode} from its already-folded inline children. */
|
|
180
|
-
readonly paragraph: MarkdownHandler<ParagraphNode, T>;
|
|
181
|
-
/** Folds a {@link ThematicBreakNode} (leaf - always called with an empty children list). */
|
|
182
|
-
readonly thematicBreak: MarkdownHandler<ThematicBreakNode, T>;
|
|
183
|
-
/** Folds a {@link BlockquoteNode} from its already-folded block children. */
|
|
184
|
-
readonly blockquote: MarkdownHandler<BlockquoteNode, T>;
|
|
185
|
-
/** Folds a {@link CodeBlockNode} (leaf - always called with an empty children list). */
|
|
186
|
-
readonly codeBlock: MarkdownHandler<CodeBlockNode, T>;
|
|
187
|
-
/** Folds a {@link ListNode} from its already-folded item children. */
|
|
188
|
-
readonly list: MarkdownHandler<ListNode, T>;
|
|
189
|
-
/** Folds a {@link ListItemNode} from its already-folded block children. */
|
|
190
|
-
readonly listItem: MarkdownHandler<ListItemNode, T>;
|
|
191
|
-
/**
|
|
192
|
-
* Folds a {@link TableNode} from its cells' already-folded inline nodes, flattened
|
|
193
|
-
* to ONE folded `T` per inline node - header cells first (column order), then body
|
|
194
|
-
* rows' cells (row order, then column order). It is NOT a leaf: recover cell
|
|
195
|
-
* boundaries from `node.header[c].length` / `node.rows[r][c].length` against the
|
|
196
|
-
* flat `children` list.
|
|
197
|
-
*/
|
|
198
|
-
readonly table: MarkdownHandler<TableNode, T>;
|
|
199
|
-
/** Folds a {@link TextNode} (leaf - always called with an empty children list). */
|
|
200
|
-
readonly text: MarkdownHandler<TextNode, T>;
|
|
201
|
-
/** Folds an {@link EmphasisNode} from its already-folded inline children. */
|
|
202
|
-
readonly emphasis: MarkdownHandler<EmphasisNode, T>;
|
|
203
|
-
/** Folds a {@link CodeSpanNode} (leaf - always called with an empty children list). */
|
|
204
|
-
readonly codeSpan: MarkdownHandler<CodeSpanNode, T>;
|
|
205
|
-
/** Folds a {@link LinkNode} from its already-folded inline children. */
|
|
206
|
-
readonly link: MarkdownHandler<LinkNode, T>;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* A copy-on-write node rewrite applied bottom-up by {@link MarkdownInterface.map} -
|
|
210
|
-
* receives one node (its own children already rewritten) and returns its
|
|
211
|
-
* replacement (the same node, unchanged, or a new node).
|
|
212
|
-
*/
|
|
213
|
-
export type MarkdownRewriteHandler = (node: MarkdownNode) => MarkdownNode;
|
|
214
|
-
/**
|
|
215
|
-
* A stateful, parsed markdown document: the typed {@link MarkdownDocument} AST plus
|
|
216
|
-
* the query, rewrite, and fold operations over it.
|
|
217
|
-
*
|
|
218
|
-
* @remarks
|
|
219
|
-
* - **Immutable.** {@link MarkdownInterface.map} never mutates the stored AST - it
|
|
220
|
-
* returns a NEW {@link MarkdownInterface} instance; the document root invariant
|
|
221
|
-
* (`element: 'document'`) always holds.
|
|
222
|
-
* - **Traversal order.** `walk` / `find` / `filter` / `reduce` walk the AST
|
|
223
|
-
* depth-first, pre-order, root-inclusive; `stream` is shallow - only the
|
|
224
|
-
* document's direct block children.
|
|
225
|
-
* - **`stream`.** Returns a web-standard {@link ReadableStream} over the top-level
|
|
226
|
-
* blocks - a fresh, pull-based source per call: exactly one block is enqueued per
|
|
227
|
-
* `pull`, so a slow consumer's backpressure is respected and no work happens ahead
|
|
228
|
-
* of demand. Cancellable via the returned stream's own `cancel()`, async-iterable
|
|
229
|
-
* wherever the platform supports it (Node, Deno, and browsers that ship the
|
|
230
|
-
* proposal), and pipeable through any {@link TransformStream} / {@link WritableStream}.
|
|
231
|
-
* - **The seven-method surface.** `document` (the AST root), `walk` (the deep
|
|
232
|
-
* traversal), `find` / `filter` / `reduce` (queries built on `walk`), `map` (the
|
|
233
|
-
* bottom-up rewrite), `fold` (the total catamorphism), and `stream` (the shallow,
|
|
234
|
-
* backpressured top-level source).
|
|
235
|
-
*/
|
|
236
|
-
export interface MarkdownInterface {
|
|
237
|
-
/** The stored {@link MarkdownDocument} AST root. */
|
|
238
|
-
readonly document: MarkdownDocument;
|
|
239
|
-
/**
|
|
240
|
-
* THE deep traversal - a lazy, depth-first, pre-order, root-inclusive
|
|
241
|
-
* {@link Generator} over every {@link MarkdownNode} in the document. The sync
|
|
242
|
-
* `for (const node of markdown.walk())` surface is also consumable by
|
|
243
|
-
* `for await (const node of markdown.walk())` (JavaScript accepts a sync
|
|
244
|
-
* iterable in a `for await`), so async pipelines need no separate iterator.
|
|
245
|
-
* Contrast with {@link stream}: `walk` is deep, every-node, and sync; `stream`
|
|
246
|
-
* is shallow (top-level blocks only) and backpressure-respecting.
|
|
247
|
-
*/
|
|
248
|
-
walk(): Generator<MarkdownNode>;
|
|
249
|
-
/** Finds the first node (depth-first, pre-order) narrowed by a type guard. */
|
|
250
|
-
find<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): T | undefined;
|
|
251
|
-
/** Finds the first node (depth-first, pre-order) matching a predicate. */
|
|
252
|
-
find(predicate: (node: MarkdownNode) => boolean): MarkdownNode | undefined;
|
|
253
|
-
/** Collects every node (depth-first, pre-order) narrowed by a type guard. */
|
|
254
|
-
filter<T extends MarkdownNode>(guard: (node: MarkdownNode) => node is T): readonly T[];
|
|
255
|
-
/** Collects every node (depth-first, pre-order) matching a predicate. */
|
|
256
|
-
filter(predicate: (node: MarkdownNode) => boolean): readonly MarkdownNode[];
|
|
257
|
-
/** Rewrites the AST bottom-up (copy-on-write) and returns a new {@link MarkdownInterface}. */
|
|
258
|
-
map(rewrite: MarkdownRewriteHandler): MarkdownInterface;
|
|
259
|
-
/** Folds the AST depth-first, pre-order into an accumulator. */
|
|
260
|
-
reduce<T>(callback: (accumulator: T, node: MarkdownNode) => T, initial: T): T;
|
|
261
|
-
/** Runs a total catamorphism over the document using a {@link MarkdownHandlers} table. */
|
|
262
|
-
fold<T>(handlers: MarkdownHandlers<T>): T;
|
|
263
|
-
/**
|
|
264
|
-
* A web-standard {@link ReadableStream} over the document's top-level block nodes
|
|
265
|
-
* (shallow, source order) - a lazy, pull-based, backpressure-respecting source. A
|
|
266
|
-
* fresh, independently-replayable stream every call; never mutates the document.
|
|
267
|
-
*/
|
|
268
|
-
stream(): ReadableStream<BlockNode>;
|
|
269
|
-
}
|
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
import { Guard } from '@orkestrel/contract';
|
|
2
|
-
import { BlockNode, BlockquoteNode, CodeBlockNode, CodeSpanNode, EmphasisNode, HeadingNode, InlineNode, LinkNode, ListNode, MarkdownDocument, MarkdownNode, ParagraphNode, TableNode, TextNode, ThematicBreakNode } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Whether `character` is an inline whitespace character (space / tab / newline) - the
|
|
5
|
-
* emphasis flanking rule's space test.
|
|
6
|
-
*
|
|
7
|
-
* @param character - The character to test
|
|
8
|
-
* @returns `true` when it is inline whitespace
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```ts
|
|
12
|
-
* isWhitespace(' ') // true
|
|
13
|
-
* isWhitespace('a') // false
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
export declare function isWhitespace(character: string): boolean;
|
|
17
|
-
/**
|
|
18
|
-
* Whether `character` is escapable by a leading backslash - the ASCII punctuation
|
|
19
|
-
* markdown gives meaning to (so `\*` becomes `*` but `\.` stays `\.`).
|
|
20
|
-
*
|
|
21
|
-
* @param character - The single character after a backslash
|
|
22
|
-
* @returns `true` when a backslash before it is an escape
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* isEscapable('*') // true
|
|
27
|
-
* isEscapable('a') // false
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
export declare function isEscapable(character: string): boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Whether `line` is blank - empty, or containing only whitespace - the markdown
|
|
33
|
-
* definition of a blank line that block parsing uses to separate paragraphs, skip
|
|
34
|
-
* gaps, and end list continuations.
|
|
35
|
-
*
|
|
36
|
-
* @param line - The candidate line
|
|
37
|
-
* @returns `true` when the line is blank
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```ts
|
|
41
|
-
* isBlankLine(' ') // true
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export declare function isBlankLine(line: string): boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Whether `line` is a blockquote line (`>` optionally indented up to three spaces) -
|
|
47
|
-
* its content is de-quoted by {@link stripQuote}.
|
|
48
|
-
*
|
|
49
|
-
* @param line - The candidate line
|
|
50
|
-
* @returns `true` when the line begins a blockquote
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* ```ts
|
|
54
|
-
* isQuote('> quoted') // true
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
export declare function isQuote(line: string): boolean;
|
|
58
|
-
/**
|
|
59
|
-
* Whether `line` closes a fence opened by `marker` - the same fence character, a run
|
|
60
|
-
* at least as long, and nothing else but surrounding whitespace.
|
|
61
|
-
*
|
|
62
|
-
* @param line - The candidate closing line
|
|
63
|
-
* @param marker - The opening fence's marker run (from {@link extractFence})
|
|
64
|
-
* @returns `true` when `line` closes the fence
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```ts
|
|
68
|
-
* isFenceClose('```', '```') // true
|
|
69
|
-
* ```
|
|
70
|
-
*/
|
|
71
|
-
export declare function isFenceClose(line: string, marker: string): boolean;
|
|
72
|
-
/**
|
|
73
|
-
* Whether `character` is a regex-`\s`-equivalent whitespace character - the
|
|
74
|
-
* character class {@link isFenceClose}'s scan treats as surrounding padding.
|
|
75
|
-
*
|
|
76
|
-
* @param character - The single character to test, or `undefined` past the end of a line
|
|
77
|
-
* @returns `true` when it is whitespace
|
|
78
|
-
*
|
|
79
|
-
* @example
|
|
80
|
-
* ```ts
|
|
81
|
-
* isFenceWhitespace(' ') // true
|
|
82
|
-
* isFenceWhitespace(undefined) // false
|
|
83
|
-
* ```
|
|
84
|
-
*/
|
|
85
|
-
export declare function isFenceWhitespace(character: string | undefined): boolean;
|
|
86
|
-
/**
|
|
87
|
-
* Whether `line` is a thematic break (horizontal rule) - three or more of the SAME
|
|
88
|
-
* marker `-`, `*`, or `_` (optionally space-separated) and nothing else (`---`,
|
|
89
|
-
* `***`, `___`, `- - -`).
|
|
90
|
-
*
|
|
91
|
-
* @param line - The candidate line
|
|
92
|
-
* @returns `true` when the line is a thematic break
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* ```ts
|
|
96
|
-
* isThematicBreak('---') // true
|
|
97
|
-
* ```
|
|
98
|
-
*/
|
|
99
|
-
export declare function isThematicBreak(line: string): boolean;
|
|
100
|
-
/**
|
|
101
|
-
* Whether the pair (`header`, `delimiter`) opens a GFM table - `delimiter` is a row of
|
|
102
|
-
* `|`-separated cells each matching `:?-+:?`, the GFM rule that a table requires a
|
|
103
|
-
* header row IMMEDIATELY followed by a delimiter row.
|
|
104
|
-
*
|
|
105
|
-
* @param header - The candidate header line
|
|
106
|
-
* @param delimiter - The line after it (the candidate delimiter)
|
|
107
|
-
* @returns `true` when the two lines open a table
|
|
108
|
-
*
|
|
109
|
-
* @example
|
|
110
|
-
* ```ts
|
|
111
|
-
* isTableStart('| a |', '| - |') // true
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
|
-
export declare function isTableStart(header: string, delimiter: string | undefined): boolean;
|
|
115
|
-
/** Determine whether a node is a heading block. */
|
|
116
|
-
export declare function isHeadingNode(node: MarkdownNode): node is HeadingNode;
|
|
117
|
-
/**
|
|
118
|
-
* Determine whether a node is a paragraph block.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```ts
|
|
122
|
-
* isParagraphNode({ element: 'paragraph', children: [] }) // true
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
export declare function isParagraphNode(node: MarkdownNode): node is ParagraphNode;
|
|
126
|
-
/**
|
|
127
|
-
* Determine whether a node is a list block.
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* ```ts
|
|
131
|
-
* isListNode({ element: 'list', ordered: false, start: 1, items: [] }) // true
|
|
132
|
-
* ```
|
|
133
|
-
*/
|
|
134
|
-
export declare function isListNode(node: MarkdownNode): node is ListNode;
|
|
135
|
-
/** Determine whether a node is a GFM table block. */
|
|
136
|
-
export declare function isTableNode(node: MarkdownNode): node is TableNode;
|
|
137
|
-
/**
|
|
138
|
-
* Determine whether a node is a fenced code block.
|
|
139
|
-
*
|
|
140
|
-
* @example
|
|
141
|
-
* ```ts
|
|
142
|
-
* isCodeBlockNode({ element: 'codeBlock', code: 'x' }) // true
|
|
143
|
-
* ```
|
|
144
|
-
*/
|
|
145
|
-
export declare function isCodeBlockNode(node: MarkdownNode): node is CodeBlockNode;
|
|
146
|
-
/**
|
|
147
|
-
* Determine whether a node is a blockquote block.
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```ts
|
|
151
|
-
* isBlockquoteNode({ element: 'blockquote', children: [] }) // true
|
|
152
|
-
* ```
|
|
153
|
-
*/
|
|
154
|
-
export declare function isBlockquoteNode(node: MarkdownNode): node is BlockquoteNode;
|
|
155
|
-
/**
|
|
156
|
-
* Determine whether a node is a thematic break (horizontal rule) block.
|
|
157
|
-
*
|
|
158
|
-
* @example
|
|
159
|
-
* ```ts
|
|
160
|
-
* isThematicBreakNode({ element: 'thematicBreak' }) // true
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
export declare function isThematicBreakNode(node: MarkdownNode): node is ThematicBreakNode;
|
|
164
|
-
/**
|
|
165
|
-
* Determine whether a node is a plain text run.
|
|
166
|
-
*
|
|
167
|
-
* @example
|
|
168
|
-
* ```ts
|
|
169
|
-
* isTextNode({ element: 'text', value: 'hi' }) // true
|
|
170
|
-
* ```
|
|
171
|
-
*/
|
|
172
|
-
export declare function isTextNode(node: MarkdownNode): node is TextNode;
|
|
173
|
-
/**
|
|
174
|
-
* Determine whether a node is an emphasis run (`*em*` / `**strong**`).
|
|
175
|
-
*
|
|
176
|
-
* @example
|
|
177
|
-
* ```ts
|
|
178
|
-
* isEmphasisNode({ element: 'emphasis', strong: false, children: [] }) // true
|
|
179
|
-
* ```
|
|
180
|
-
*/
|
|
181
|
-
export declare function isEmphasisNode(node: MarkdownNode): node is EmphasisNode;
|
|
182
|
-
/**
|
|
183
|
-
* Determine whether a node is an inline code span.
|
|
184
|
-
*
|
|
185
|
-
* @remarks
|
|
186
|
-
* Narrows to {@link CodeSpanNode} - the node whose `element` discriminant is
|
|
187
|
-
* `'codeSpan'`.
|
|
188
|
-
*
|
|
189
|
-
* @example
|
|
190
|
-
* ```ts
|
|
191
|
-
* isCodeSpanNode({ element: 'codeSpan', value: 'x' }) // true
|
|
192
|
-
* ```
|
|
193
|
-
*/
|
|
194
|
-
export declare function isCodeSpanNode(node: MarkdownNode): node is CodeSpanNode;
|
|
195
|
-
/** Determine whether a node is a link. */
|
|
196
|
-
export declare function isLinkNode(node: MarkdownNode): node is LinkNode;
|
|
197
|
-
/**
|
|
198
|
-
* Determine whether an arbitrary value is a valid {@link InlineNode} - a text
|
|
199
|
-
* run, emphasis, code span, or link, recursively validated.
|
|
200
|
-
*
|
|
201
|
-
* @remarks
|
|
202
|
-
* Total: never throws, even on cyclic or pathologically deep input - every
|
|
203
|
-
* combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is
|
|
204
|
-
* throw-contained per the `@orkestrel/contract` guard contract (AGENTS §14).
|
|
205
|
-
*
|
|
206
|
-
* @param value - The value to test
|
|
207
|
-
* @returns `true` when `value` is a well-formed {@link InlineNode}
|
|
208
|
-
*
|
|
209
|
-
* @example
|
|
210
|
-
* ```ts
|
|
211
|
-
* import { isInlineNode } from '@orkestrel/markdown'
|
|
212
|
-
*
|
|
213
|
-
* isInlineNode({ element: 'text', value: 'hi' }) // true
|
|
214
|
-
* isInlineNode({ element: 'text' }) // false - missing `value`
|
|
215
|
-
* ```
|
|
216
|
-
*/
|
|
217
|
-
export declare const isInlineNode: Guard<InlineNode>;
|
|
218
|
-
/**
|
|
219
|
-
* Determine whether an arbitrary value is a valid {@link BlockNode} - a
|
|
220
|
-
* heading, paragraph, list, table, code block, blockquote, or thematic break,
|
|
221
|
-
* recursively validated.
|
|
222
|
-
*
|
|
223
|
-
* @remarks
|
|
224
|
-
* Total: never throws, even on cyclic or pathologically deep input - every
|
|
225
|
-
* combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is
|
|
226
|
-
* throw-contained per the `@orkestrel/contract` guard contract (AGENTS §14).
|
|
227
|
-
* A list item's shape is inlined here (and in {@link isMarkdownNode}) rather
|
|
228
|
-
* than named separately - it is used at exactly these two sites.
|
|
229
|
-
*
|
|
230
|
-
* @param value - The value to test
|
|
231
|
-
* @returns `true` when `value` is a well-formed {@link BlockNode}
|
|
232
|
-
*
|
|
233
|
-
* @example
|
|
234
|
-
* ```ts
|
|
235
|
-
* import { isBlockNode } from '@orkestrel/markdown'
|
|
236
|
-
*
|
|
237
|
-
* isBlockNode({ element: 'thematicBreak' }) // true
|
|
238
|
-
* isBlockNode({ element: 'heading' }) // false - missing `level` / `children`
|
|
239
|
-
* ```
|
|
240
|
-
*/
|
|
241
|
-
export declare const isBlockNode: Guard<BlockNode>;
|
|
242
|
-
/**
|
|
243
|
-
* Determine whether an arbitrary value is a valid {@link MarkdownNode} - the
|
|
244
|
-
* {@link MarkdownDocument} root, a {@link BlockNode}, a {@link ListItemNode}, or
|
|
245
|
-
* an {@link InlineNode}, recursively validated.
|
|
246
|
-
*
|
|
247
|
-
* @remarks
|
|
248
|
-
* Total: never throws, even on cyclic or pathologically deep input - every
|
|
249
|
-
* combinator involved (`unionOf`, `recordOf`, `arrayOf`, `lazyOf`) is
|
|
250
|
-
* throw-contained per the `@orkestrel/contract` guard contract (AGENTS §14).
|
|
251
|
-
* A list item's shape is inlined here (and in {@link isBlockNode}) rather than
|
|
252
|
-
* named separately - it is used at exactly these two sites.
|
|
253
|
-
*
|
|
254
|
-
* @param value - The value to test
|
|
255
|
-
* @returns `true` when `value` is a well-formed {@link MarkdownNode}
|
|
256
|
-
*
|
|
257
|
-
* @example
|
|
258
|
-
* ```ts
|
|
259
|
-
* import { isMarkdownNode } from '@orkestrel/markdown'
|
|
260
|
-
*
|
|
261
|
-
* isMarkdownNode({ element: 'text', value: 'hi' }) // true
|
|
262
|
-
* isMarkdownNode({ element: 'bogus' }) // false
|
|
263
|
-
* ```
|
|
264
|
-
*/
|
|
265
|
-
export declare const isMarkdownNode: Guard<MarkdownNode>;
|
|
266
|
-
/**
|
|
267
|
-
* Determine whether an arbitrary value is a valid {@link MarkdownDocument} -
|
|
268
|
-
* the parsed-AST root {@link parseDocument} returns, recursively
|
|
269
|
-
* validated.
|
|
270
|
-
*
|
|
271
|
-
* @remarks
|
|
272
|
-
* Total: never throws, even on cyclic or pathologically deep input - every
|
|
273
|
-
* combinator involved (`recordOf`, `arrayOf`) is throw-contained per the
|
|
274
|
-
* `@orkestrel/contract` guard contract (AGENTS §14).
|
|
275
|
-
*
|
|
276
|
-
* @param value - The value to test
|
|
277
|
-
* @returns `true` when `value` is a well-formed {@link MarkdownDocument}
|
|
278
|
-
*
|
|
279
|
-
* @example
|
|
280
|
-
* ```ts
|
|
281
|
-
* import { isMarkdownDocument } from '@orkestrel/markdown'
|
|
282
|
-
*
|
|
283
|
-
* isMarkdownDocument({ element: 'document', children: [] }) // true
|
|
284
|
-
* isMarkdownDocument({ element: 'document' }) // false - missing `children`
|
|
285
|
-
* ```
|
|
286
|
-
*/
|
|
287
|
-
export declare const isMarkdownDocument: Guard<MarkdownDocument>;
|