@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.
@@ -1,451 +0,0 @@
1
- import { EmphasisNode, InlineNode, LinkNode, ListItemParts, MarkdownDocument, MarkdownHandlers, MarkdownNode, MarkdownRewriteHandler, TableAlign } from './types.js';
2
- /**
3
- * Normalize line endings to `\n` and split a markdown document into its lines - CRLF
4
- * (`\r\n`) and bare CR (`\r`) both collapse to `\n` first, so a Windows-origin
5
- * document parses identically. A single trailing newline does not yield a final
6
- * empty line.
7
- *
8
- * @param markdown - The raw markdown source
9
- * @returns The document's lines, line-terminators stripped
10
- *
11
- * @example
12
- * ```ts
13
- * splitLines('a\r\nb\nc') // ['a', 'b', 'c']
14
- * ```
15
- */
16
- export declare function splitLines(markdown: string): readonly string[];
17
- /**
18
- * The count of leading space / tab characters on `line` (a tab counts as one) - the
19
- * indent that decides whether a list item's continuation belongs to the item.
20
- *
21
- * @param line - The line to measure
22
- * @returns The number of leading space / tab characters
23
- *
24
- * @example
25
- * ```ts
26
- * leadingIndent(' text') // 2
27
- * ```
28
- */
29
- export declare function leadingIndent(line: string): number;
30
- /**
31
- * Extract an ATX heading line (`#` … `######` followed by text) into its
32
- * `{ level, text }`, or `undefined` when `line` is not a heading. A run of more than 6
33
- * `#`s, or `#`s not followed by whitespace + text, is not a
34
- * heading; an optional closing `###` run is stripped.
35
- *
36
- * @param line - The candidate line
37
- * @returns The heading level (1–6) and its raw inline text, or `undefined`
38
- *
39
- * @example
40
- * ```ts
41
- * extractHeading('## Title') // { level: 2, text: 'Title' }
42
- * ```
43
- */
44
- export declare function extractHeading(line: string): {
45
- readonly level: number;
46
- readonly text: string;
47
- } | undefined;
48
- /**
49
- * Extract a fenced-code opening line (```` ``` ```` or `~~~`, optionally with an info
50
- * string) into its `{ marker, lang }`, or `undefined` when `line` is not a fence
51
- * opener. `marker` is the exact fence run (the closer must match the same character +
52
- * at least the same length); `lang` is the first word of the info string.
53
- *
54
- * @param line - The candidate line
55
- * @returns The fence marker run and its language tag, or `undefined`
56
- *
57
- * @example
58
- * ```ts
59
- * extractFence('```ts') // { marker: '```', lang: 'ts' }
60
- * ```
61
- */
62
- export declare function extractFence(line: string): {
63
- readonly marker: string;
64
- readonly lang: string | undefined;
65
- } | undefined;
66
- /**
67
- * Extract a list-item line (`-` / `*` / `+` bullet, or `1.` / `1)` ordinal, followed by
68
- * a space) into its {@link ListItemParts}, or `undefined` when `line` is not a list
69
- * item. `content` is the text after the marker; `marker` is the full marker-plus-space
70
- * width (for measuring a continuation's indent).
71
- *
72
- * @param line - The candidate line
73
- * @returns The list-item parts, or `undefined` when not a list item
74
- *
75
- * @example
76
- * ```ts
77
- * extractListItem('- item') // { ordered: false, start: 1, content: 'item', indent: 0, marker: 2 }
78
- * ```
79
- */
80
- export declare function extractListItem(line: string): ListItemParts | undefined;
81
- /**
82
- * Strip one level of blockquote marker (`>` plus one optional following space) from a
83
- * blockquote line, so the de-quoted lines re-parse as nested blocks.
84
- *
85
- * @param line - A blockquote line (per {@link isQuote})
86
- * @returns The line with its leading `>` (and one space) removed
87
- *
88
- * @example
89
- * ```ts
90
- * stripQuote('> text') // 'text'
91
- * ```
92
- */
93
- export declare function stripQuote(line: string): string;
94
- /**
95
- * Split one GFM table row into its cell strings - outer pipes are optional, an escaped
96
- * pipe (`\|`) inside a cell is NOT a separator (it becomes a literal `|`), and the
97
- * empty leading / trailing cell produced by an outer `|` is dropped.
98
- *
99
- * @param row - The raw table row line
100
- * @returns The row's cells, in column order
101
- *
102
- * @example
103
- * ```ts
104
- * splitTableRow('|a|b|') // ['a', 'b']
105
- * ```
106
- */
107
- export declare function splitTableRow(row: string): readonly string[];
108
- /**
109
- * Derive the per-column {@link TableAlign} list from a GFM delimiter row - `:---`
110
- * left, `---:` right, `:---:` center, `---` none.
111
- *
112
- * @param delimiter - The table's delimiter row
113
- * @returns One alignment per column, in column order
114
- *
115
- * @example
116
- * ```ts
117
- * tableAlignments('| :--- | ---: |') // ['left', 'right']
118
- * ```
119
- */
120
- export declare function tableAlignments(delimiter: string): readonly TableAlign[];
121
- /**
122
- * Whether the line at `index` starts a NEW block kind (heading / fence / thematic
123
- * break / blockquote / list / table) - the paragraph collector stops at such a line
124
- * so a block following a paragraph without a blank line still parses (a trusted-input
125
- * caller writing a `##` heading directly under a paragraph, with no intervening blank
126
- * line).
127
- *
128
- * @param lines - The document's lines
129
- * @param index - The line index to test
130
- * @returns `true` when the line begins a different block
131
- *
132
- * @example
133
- * ```ts
134
- * startsBlock(['text', '## Heading'], 1) // true
135
- * ```
136
- */
137
- export declare function startsBlock(lines: readonly string[], index: number): boolean;
138
- /**
139
- * Resolve backslash escapes in a raw string to their literal characters - used for a
140
- * link `href` (which is not otherwise inline-parsed) and any plain text run.
141
- *
142
- * @param text - The raw text possibly carrying `\x` escapes
143
- * @returns The text with escapable `\x` reduced to `x`
144
- *
145
- * @example
146
- * ```ts
147
- * unescapeText('\\*hi\\*') // '*hi*'
148
- * ```
149
- */
150
- export declare function unescapeText(text: string): string;
151
- /**
152
- * Merge adjacent text nodes into one - the inline scanner emits a text node per
153
- * unrecognized character, so coalescing keeps the AST clean and assertion-friendly.
154
- *
155
- * @param nodes - The inline nodes (possibly with adjacent text runs)
156
- * @returns The nodes with consecutive text nodes concatenated
157
- *
158
- * @example
159
- * ```ts
160
- * coalesceText([{ element: 'text', value: 'a' }, { element: 'text', value: 'b' }])
161
- * // [{ element: 'text', value: 'ab' }]
162
- * ```
163
- */
164
- export declare function coalesceText(nodes: readonly InlineNode[]): readonly InlineNode[];
165
- /**
166
- * Scan an inline code span at `start` (a `` ` ``-run … a matching `` ` ``-run of the
167
- * SAME length, the CommonMark rule that lets a span contain backticks). Returns the
168
- * span's literal text + end index, or `undefined` when no matching closer exists (it
169
- * then degrades to literal backticks).
170
- *
171
- * @param source - The inline source text
172
- * @param start - The index of the opening backtick
173
- * @param to - The exclusive end of the scan window
174
- * @returns The span text + end index, or `undefined`
175
- *
176
- * @example
177
- * ```ts
178
- * scanCode('`code`', 0, 6) // { value: 'code', end: 6 }
179
- * ```
180
- */
181
- export declare function scanCode(source: string, start: number, to: number): {
182
- readonly value: string;
183
- readonly end: number;
184
- } | undefined;
185
- /**
186
- * Scan a link `[text](href)` at `start` - the text runs to a BALANCED `]`, then `(`
187
- * must immediately follow and the destination runs to the matching `)` (both respect
188
- * nested delimiters + escapes). Returns the link node, or `undefined` when the shape
189
- * does not hold (it then degrades to a literal `[`).
190
- *
191
- * @param source - The inline source text
192
- * @param start - The index of the opening `[`
193
- * @param to - The exclusive end of the scan window
194
- * @param depth - The current inline-recursion depth (defaults to 0 at the entry point);
195
- * at {@link MAX_DEPTH} the link's text children degrade to literal text instead of
196
- * recursing further
197
- * @returns The parsed {@link LinkNode} + end index, or `undefined`
198
- *
199
- * @example
200
- * ```ts
201
- * scanLink('[text](url)', 0, 11)
202
- * // { node: { element: 'link', href: 'url', children: [...] }, end: 11 }
203
- * ```
204
- */
205
- export declare function scanLink(source: string, start: number, to: number, depth?: number): {
206
- readonly node: LinkNode;
207
- readonly end: number;
208
- } | undefined;
209
- /**
210
- * Scan an emphasis run at `start` (`*` / `_`, doubled for strong) - finds the nearest
211
- * matching closing run of the same marker + width, requiring non-space immediately
212
- * inside both delimiters (the CommonMark flanking simplification that blocks `* x *`).
213
- * Returns the emphasis node, or `undefined` when no valid closer exists (it then
214
- * degrades to a literal marker).
215
- *
216
- * @param source - The inline source text
217
- * @param start - The index of the opening marker
218
- * @param to - The exclusive end of the scan window
219
- * @param depth - The current inline-recursion depth (defaults to 0 at the entry point);
220
- * at {@link MAX_DEPTH} the emphasis's children degrade to literal text instead of
221
- * recursing further
222
- * @returns The parsed {@link EmphasisNode} + end index, or `undefined`
223
- *
224
- * @example
225
- * ```ts
226
- * scanEmphasis('*em*', 0, 4)
227
- * // { node: { element: 'emphasis', strong: false, children: [...] }, end: 4 }
228
- * ```
229
- */
230
- export declare function scanEmphasis(source: string, start: number, to: number, depth?: number): {
231
- readonly node: EmphasisNode;
232
- readonly end: number;
233
- } | undefined;
234
- /**
235
- * Scan the window `[from, to)` of `source` into inline nodes - the single recursive
236
- * engine the inline phase runs on (emphasis / link text recurse through it). Linear:
237
- * each character is consumed once; a failed construct emits its opening character as
238
- * text and advances by one, so there is no re-scan (no ReDoS).
239
- *
240
- * @param source - The inline source text
241
- * @param from - The inclusive start of the scan window
242
- * @param to - The exclusive end of the scan window
243
- * @param depth - The current inline-recursion depth (defaults to 0 at the entry point);
244
- * incremented by one on every recursive descent through {@link scanLink} /
245
- * {@link scanEmphasis}. At {@link MAX_DEPTH} the window is never scanned for markup -
246
- * it emits as a single literal text node - so pathological nesting (`[[[[…`,
247
- * `****…`) cannot exhaust the call stack.
248
- * @returns The parsed inline nodes (NOT yet coalesced)
249
- *
250
- * @example
251
- * ```ts
252
- * scanInline('hi *there*', 0, 10) // [{ element: 'text', value: 'hi ' }, { element: 'emphasis', ... }]
253
- * ```
254
- */
255
- export declare function scanInline(source: string, from: number, to: number, depth?: number): readonly InlineNode[];
256
- /**
257
- * HTML-escape text content - `&` / `<` / `>` / `"` / `'` to their entities - so text
258
- * from a markdown document can never inject markup. The renderer applies this to every
259
- * text run, code body, and (escaped further) attribute value.
260
- *
261
- * @param text - The raw text
262
- * @returns The HTML-escaped text
263
- *
264
- * @example
265
- * ```ts
266
- * escapeHtml('<a>&"\'') // '&lt;a&gt;&amp;&quot;&#39;'
267
- * ```
268
- */
269
- export declare function escapeHtml(text: string): string;
270
- /**
271
- * Sanitize + HTML-attribute-escape a link `href` - a destination whose scheme is not
272
- * in {@link SAFE_URL_SCHEMES} (notably `javascript:` / `data:` / `vbscript:`), or that
273
- * is protocol-relative (`//host/path`, or a backslash variant a browser normalizes to
274
- * the same effect - `\\host`, `/\host`, `\/host` - inherits whatever scheme the
275
- * embedding page is served over, including an unsafe one), is dropped to an empty
276
- * string; a relative / anchor / scheme-less (and non-protocol-relative) destination
277
- * (including a SINGLE leading `/` or `\`) is kept;
278
- * the surviving value is then HTML-escaped. Defence-in-depth against an XSS `href`,
279
- * even though the input is trusted.
280
- *
281
- * @param href - The raw link destination
282
- * @returns A safe, escaped `href` (empty when the scheme is unsafe or protocol-relative)
283
- *
284
- * @example
285
- * ```ts
286
- * sanitizeUrl('javascript:alert(1)') // ''
287
- * sanitizeUrl('/path') // '/path'
288
- * ```
289
- */
290
- export declare function sanitizeUrl(href: string): string;
291
- /**
292
- * Render a {@link MarkdownNode} (typically a {@link MarkdownDocument}) to a safe HTML
293
- * string - the recursive AST → HTML engine (headings, paragraphs, lists, GFM tables,
294
- * fenced code, blockquotes, links, emphasis, inline code), escaping every text run and
295
- * sanitizing every link `href`.
296
- *
297
- * @remarks
298
- * Total: never throws. At {@link MAX_DEPTH} a value-bearing node (`text` / `codeSpan`)
299
- * degrades to its escaped `value`; any other node degrades to `''` instead of
300
- * recursing further, so pathologically deep input cannot exhaust the call stack. The
301
- * recursive engine and its per-shape sub-steps (inline concatenation, table cell,
302
- * tight list-item) are nested inner functions - the only exported surface is
303
- * `renderHTML` itself.
304
- *
305
- * @param node - The AST node to render (a full document, or any sub-node)
306
- * @returns The rendered, XSS-safe HTML string
307
- *
308
- * @example
309
- * ```ts
310
- * renderHTML({ element: 'document', children: [
311
- * { element: 'heading', level: 1, children: [{ element: 'text', value: 'Hi' }] },
312
- * ] })
313
- * // '<h1>Hi</h1>'
314
- * ```
315
- */
316
- export declare function renderHTML(node: MarkdownNode): string;
317
- /**
318
- * Render a {@link MarkdownNode} to its CANONICAL markdown source - the inverse
319
- * projection of `renderHTML`, and the serializer a `parse(renderMarkdown(doc))`
320
- * round-trip is built on. Canonical forms: `*em*` / `**strong**` (underscore emphasis
321
- * normalizes to asterisks), `- ` bullets, `N. ` sequential ordinals (from the list's
322
- * `start`), `---` thematic breaks, fenced code blocks (backtick run widened past any
323
- * 3+ backtick run inside the body), ATX headings, `> `-prefixed blockquote lines, GFM
324
- * tables (1-space-padded cells, `\|`-escaped pipes, an alignment delimiter row), and
325
- * `[text](href)` links. A `text` node's literal content is backslash-escaped wherever
326
- * it would otherwise re-parse as markup (AGENTS §14 parse↔render soundness).
327
- *
328
- * @remarks
329
- * Total: never throws. At {@link MAX_DEPTH} a value-bearing node degrades to its
330
- * escaped `value`; any other node degrades to `''`. Blocks are joined by exactly one
331
- * blank line; a document with zero blocks renders `''`.
332
- *
333
- * @param node - The AST node to render (a full document, or any sub-node)
334
- * @returns The canonical markdown source
335
- *
336
- * @example
337
- * ```ts
338
- * renderMarkdown({ element: 'document', children: [
339
- * { element: 'heading', level: 2, children: [{ element: 'text', value: 'Hi' }] },
340
- * ] })
341
- * // '## Hi'
342
- * ```
343
- */
344
- export declare function renderMarkdown(node: MarkdownNode): string;
345
- /**
346
- * Depth-first, pre-order, root-inclusive traversal of a {@link MarkdownNode} - yields
347
- * the node itself, then recurses into its children (block children, list items, table
348
- * header/row cells' inline nodes) in walk order.
349
- *
350
- * @remarks
351
- * Total: never throws. Descent stops at {@link MAX_DEPTH} (the node at the cap is
352
- * still yielded; its children are not) so pathologically deep input cannot exhaust
353
- * the call stack.
354
- *
355
- * @param node - The AST node to walk (a full document, or any sub-node)
356
- * @returns A generator yielding every visited node, pre-order
357
- *
358
- * @example
359
- * ```ts
360
- * const doc = { element: 'document', children: [{ element: 'thematicBreak' }] } as const
361
- * [...walkNodes(doc)].map((node) => node.element) // ['document', 'thematicBreak']
362
- * ```
363
- */
364
- export declare function walkNodes(node: MarkdownNode): Generator<MarkdownNode>;
365
- /**
366
- * Fold a {@link MarkdownNode} into a `T` via a total catamorphism - children are
367
- * folded first (post-order), then the node's own {@link MarkdownHandler} is invoked
368
- * with the already-folded children.
369
- *
370
- * @remarks
371
- * **Table contract.** A {@link TableNode} has no single `children` array - its cells
372
- * live in `header` (one inline-node list per column) and `rows` (a list of such
373
- * rows). The `table` handler receives ONE folded `T` per inline node, flattened in
374
- * walk order across ALL cells - every header cell's inline nodes (column order), then
375
- * every body row's cells' inline nodes (row order, then column order) - and reads
376
- * `node.header[c].length` / `node.rows[r][c].length` off the table node itself to
377
- * recover cell boundaries within the flat list.
378
- *
379
- * Total: never throws. At `depth >= {@link MAX_DEPTH}` the node's handler is invoked
380
- * with an empty children list instead of recursing further.
381
- *
382
- * @param node - The AST node to fold
383
- * @param handlers - The total {@link MarkdownHandlers} table, one handler per element
384
- * @param depth - The starting recursion depth (pass `0` at the entry point)
385
- * @returns The folded `T`
386
- *
387
- * @example
388
- * ```ts
389
- * const countHandlers: MarkdownHandlers<number> = {
390
- * document: (_, children) => children.reduce((a, b) => a + b, 1),
391
- * // ...one handler per element, each summing its folded children
392
- * }
393
- * foldNode(document, countHandlers, 0) // total node count
394
- * ```
395
- */
396
- export declare function foldNode<T>(node: MarkdownNode, handlers: MarkdownHandlers<T>, depth: number): T;
397
- /**
398
- * Rewrite a {@link MarkdownDocument} bottom-up (copy-on-write) - each node's children
399
- * are rewritten first (post-order), then `rewrite` is applied to the node itself; the
400
- * document ROOT is never passed to `rewrite` (the `element: 'document'` invariant
401
- * always holds). A table's inline cells and a list's items ARE rewritten.
402
- *
403
- * @remarks
404
- * Never mutates `document` - every level is rebuilt into a fresh object/array, even
405
- * when `rewrite` returns its input unchanged. When `rewrite` returns a node whose
406
- * `element` does not fit the slot it was called for (a block slot handed a
407
- * non-{@link BlockNode}, an inline slot handed a non-{@link InlineNode}, a list-item
408
- * slot handed a non-`listItem`), the ill-fitting result is discarded and the
409
- * freshly-rebuilt (unrewritten-at-this-level) node is kept instead - `rewriteDocument`
410
- * stays total and never produces a structurally invalid document.
411
- *
412
- * Descent is capped at {@link MAX_DEPTH}, the same cap {@link walkNodes} and
413
- * {@link foldNode} observe: at `depth >= MAX_DEPTH` the subtree is passed through
414
- * UNCHANGED (by reference, not rebuilt, and `rewrite` is not invoked on it) instead of
415
- * recursing further, so a pathologically deep adopted document cannot exhaust the
416
- * call stack. {@link MarkdownInterface.map} inherits this cap since it delegates here.
417
- *
418
- * @param document - The document AST to rewrite
419
- * @param rewrite - The bottom-up {@link MarkdownRewriteHandler}
420
- * @returns A new, rewritten {@link MarkdownDocument}
421
- *
422
- * @example
423
- * ```ts
424
- * rewriteDocument(document, (node) =>
425
- * node.element === 'text' ? { element: 'text', value: node.value.toUpperCase() } : node,
426
- * )
427
- * ```
428
- */
429
- export declare function rewriteDocument(document: MarkdownDocument, rewrite: MarkdownRewriteHandler): MarkdownDocument;
430
- /**
431
- * Concatenate the `value` / `code` content of every descendant text / code-span /
432
- * code-block node under `node`, in walk order - the plain-text projection of an AST
433
- * (search indexing, word counts, a text-only preview).
434
- *
435
- * @remarks
436
- * Total: never throws. Descent stops at {@link MAX_DEPTH} (contributes `''` past the
437
- * cap instead of recursing further).
438
- *
439
- * @param node - The AST node to flatten (a full document, or any sub-node)
440
- * @returns The concatenated text content
441
- *
442
- * @example
443
- * ```ts
444
- * flattenText({ element: 'paragraph', children: [
445
- * { element: 'text', value: 'a ' },
446
- * { element: 'codeSpan', value: 'b' },
447
- * ] })
448
- * // 'a b'
449
- * ```
450
- */
451
- export declare function flattenText(node: MarkdownNode): string;
@@ -1,66 +0,0 @@
1
- import { BlockNode, InlineNode, ListNode, MarkdownDocument, TableNode } from './types.js';
2
- /**
3
- * Parses a run of markdown lines into a block AST, recursing into nested
4
- * blockquotes, list items, and depth-capped degrade paragraphs.
5
- *
6
- * @param lines - The markdown lines to parse.
7
- * @param depth - The current recursion depth (blockquotes/lists increment it).
8
- * @returns The parsed block nodes.
9
- *
10
- * @example
11
- * ```ts
12
- * parseBlocks(['# Hi'], 0) // [{ element: 'heading', level: 1, children: [...] }]
13
- * ```
14
- */
15
- export declare function parseBlocks(lines: readonly string[], depth: number): readonly BlockNode[];
16
- /**
17
- * Collects a GFM table starting at a header row, parsing the header, the
18
- * alignment row, and every contiguous body row that follows.
19
- *
20
- * @param lines - The markdown lines to scan.
21
- * @param start - The index of the header row.
22
- * @returns The parsed table node and the index of the first line after it.
23
- *
24
- * @example
25
- * ```ts
26
- * collectTable(['| a |', '| - |'], 0) // { node: { element: 'table', ... }, next: 2 }
27
- * ```
28
- */
29
- export declare function collectTable(lines: readonly string[], start: number): {
30
- readonly node: TableNode;
31
- readonly next: number;
32
- };
33
- /**
34
- * Collects a list starting at the first item, gathering sibling items at the
35
- * same indent/ordering and recursing into each item's own block content.
36
- *
37
- * @param lines - The markdown lines to scan.
38
- * @param start - The index of the first list item.
39
- * @param depth - The current recursion depth (each item recurses at `depth + 1`).
40
- * @returns The parsed list node and the index of the first line after it.
41
- *
42
- * @example
43
- * ```ts
44
- * collectList(['- item'], 0, 0) // { node: { element: 'list', ... }, next: 1 }
45
- * ```
46
- */
47
- export declare function collectList(lines: readonly string[], start: number, depth: number): {
48
- readonly node: ListNode;
49
- readonly next: number;
50
- };
51
- /**
52
- * Parses a markdown string into a typed {@link MarkdownDocument} AST via the
53
- * block phase.
54
- *
55
- * @param markdown - The markdown source to parse.
56
- * @returns The parsed document.
57
- */
58
- export declare function parseDocument(markdown: string): MarkdownDocument;
59
- /**
60
- * Parses inline markdown text (emphasis, code spans, links) into inline AST
61
- * nodes, coalescing adjacent text runs.
62
- *
63
- * @param text - The inline markdown text to parse.
64
- * @returns The parsed inline nodes.
65
- */
66
- export declare function parseInline(text: string): readonly InlineNode[];
@@ -1,105 +0,0 @@
1
- import { ObjectShape, LiteralShape, StringShape, OptionalShape, BooleanShape, NumberShape } from '@orkestrel/contract';
2
- /**
3
- * The shape of a {@link TextNode} - a plain-text leaf inline run.
4
- *
5
- * @example
6
- * ```ts
7
- * import { createContract } from '@orkestrel/contract'
8
- * import { textShape } from '@src/core'
9
- *
10
- * const text = createContract(textShape)
11
- * text.is({ element: 'text', value: 'hi' }) // true
12
- * ```
13
- */
14
- export declare const textShape: ObjectShape<{
15
- element: LiteralShape<readonly ["text"]>;
16
- value: StringShape;
17
- }, false>;
18
- /**
19
- * The shape of a {@link CodeSpanNode} - an inline code span (`` `code` ``).
20
- *
21
- * @example
22
- * ```ts
23
- * import { createContract } from '@orkestrel/contract'
24
- * import { codeSpanShape } from '@src/core'
25
- *
26
- * const codeSpan = createContract(codeSpanShape)
27
- * codeSpan.is({ element: 'codeSpan', value: 'const x = 1' }) // true
28
- * ```
29
- */
30
- export declare const codeSpanShape: ObjectShape<{
31
- element: LiteralShape<readonly ["codeSpan"]>;
32
- value: StringShape;
33
- }, false>;
34
- /**
35
- * The shape of a {@link CodeBlockNode} - a fenced code block. `lang` is
36
- * optional (absent when the opening fence carries no info-string).
37
- *
38
- * @example
39
- * ```ts
40
- * import { createContract } from '@orkestrel/contract'
41
- * import { codeBlockShape } from '@src/core'
42
- *
43
- * const codeBlock = createContract(codeBlockShape)
44
- * codeBlock.is({ element: 'codeBlock', code: 'x' }) // true
45
- * codeBlock.is({ element: 'codeBlock', code: 'x', lang: 'ts' }) // true
46
- * ```
47
- */
48
- export declare const codeBlockShape: ObjectShape<{
49
- element: LiteralShape<readonly ["codeBlock"]>;
50
- lang: OptionalShape<StringShape>;
51
- code: StringShape;
52
- }, false>;
53
- /**
54
- * The shape of a {@link ThematicBreakNode} - a horizontal rule. Carries no
55
- * fields beyond its `element` discriminant.
56
- *
57
- * @example
58
- * ```ts
59
- * import { createContract } from '@orkestrel/contract'
60
- * import { thematicBreakShape } from '@src/core'
61
- *
62
- * const thematicBreak = createContract(thematicBreakShape)
63
- * thematicBreak.is({ element: 'thematicBreak' }) // true
64
- * ```
65
- */
66
- export declare const thematicBreakShape: ObjectShape<{
67
- element: LiteralShape<readonly ["thematicBreak"]>;
68
- }, false>;
69
- /**
70
- * The shape of a {@link TableAlign} - the per-column GFM table alignment
71
- * literal.
72
- *
73
- * @example
74
- * ```ts
75
- * import { createContract } from '@orkestrel/contract'
76
- * import { tableAlignShape } from '@src/core'
77
- *
78
- * const tableAlign = createContract(tableAlignShape)
79
- * tableAlign.is('left') // true
80
- * tableAlign.is('center') // true
81
- * tableAlign.is('top') // false
82
- * ```
83
- */
84
- export declare const tableAlignShape: LiteralShape<readonly ["none", "left", "right", "center"]>;
85
- /**
86
- * The shape of {@link ListItemParts} - the parsed parts of a single list-item
87
- * line the block phase's list detector returns. Fully non-recursive (no
88
- * nested node fields), so every field shapes directly.
89
- *
90
- * @example
91
- * ```ts
92
- * import { createContract } from '@orkestrel/contract'
93
- * import { listItemPartsShape } from '@src/core'
94
- *
95
- * const listItemParts = createContract(listItemPartsShape)
96
- * listItemParts.is({ ordered: false, start: 1, content: 'hi', indent: 0, marker: 2 }) // true
97
- * ```
98
- */
99
- export declare const listItemPartsShape: ObjectShape<{
100
- ordered: BooleanShape;
101
- start: NumberShape;
102
- content: StringShape;
103
- indent: NumberShape;
104
- marker: NumberShape;
105
- }, false>;