@tanstack/markdown 0.0.8 → 0.0.10
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 +15 -4
- package/dist/inline.js +52 -11
- package/dist/parser.js +22 -5
- package/package.json +22 -3
- package/skills/custom-extensions/SKILL.md +444 -0
- package/skills/docs-features/SKILL.md +436 -0
- package/skills/docs-features/references/docs-metadata.md +320 -0
- package/skills/octane-rendering/SKILL.md +351 -0
- package/skills/production-pipelines/SKILL.md +493 -0
- package/skills/react-rendering/SKILL.md +309 -0
- package/skills/render-markdown/SKILL.md +335 -0
- package/skills/render-markdown/references/ast-and-options.md +366 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# AST and Options Reference
|
|
2
|
+
|
|
3
|
+
This reference targets `@tanstack/markdown@0.0.10`. Shared public types are
|
|
4
|
+
exported from `@tanstack/markdown`.
|
|
5
|
+
|
|
6
|
+
## Entry Points
|
|
7
|
+
|
|
8
|
+
Use the narrowest entry point needed by the application:
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import {
|
|
12
|
+
parseInline,
|
|
13
|
+
parseMarkdown,
|
|
14
|
+
renderBlock,
|
|
15
|
+
renderDocument,
|
|
16
|
+
renderHtml,
|
|
17
|
+
renderInline,
|
|
18
|
+
type MarkdownDocument,
|
|
19
|
+
type ParseOptions,
|
|
20
|
+
type RenderOptions,
|
|
21
|
+
} from '@tanstack/markdown'
|
|
22
|
+
|
|
23
|
+
const options: ParseOptions = {
|
|
24
|
+
frontmatter: true,
|
|
25
|
+
headingIds: true,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const document: MarkdownDocument = parseMarkdown('# API', options)
|
|
29
|
+
const inline = parseInline('Use **stable** APIs.')
|
|
30
|
+
const blockHtml = document.children.map(node => renderBlock(node)).join('\n')
|
|
31
|
+
const inlineHtml = inline.map(node => renderInline(node)).join('')
|
|
32
|
+
const documentHtml = renderDocument(document)
|
|
33
|
+
const completeHtml = renderHtml(document, {
|
|
34
|
+
headingAnchors: true,
|
|
35
|
+
} satisfies RenderOptions)
|
|
36
|
+
|
|
37
|
+
console.log({ blockHtml, inlineHtml, documentHtml, completeHtml })
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Equivalent narrow imports are:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { parseMarkdown } from '@tanstack/markdown/parser'
|
|
44
|
+
import {
|
|
45
|
+
renderBlock,
|
|
46
|
+
renderDocument,
|
|
47
|
+
renderHtml,
|
|
48
|
+
renderInline,
|
|
49
|
+
} from '@tanstack/markdown/html'
|
|
50
|
+
|
|
51
|
+
const document = parseMarkdown('# Narrow imports')
|
|
52
|
+
const html = renderHtml(document)
|
|
53
|
+
|
|
54
|
+
console.log({
|
|
55
|
+
html,
|
|
56
|
+
documentHtml: renderDocument(document),
|
|
57
|
+
firstBlockHtml: renderBlock(document.children[0]!),
|
|
58
|
+
inlineHtml: renderInline({
|
|
59
|
+
type: 'text',
|
|
60
|
+
value: 'Inline text',
|
|
61
|
+
}),
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Function Signatures
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import type {
|
|
69
|
+
BlockNode,
|
|
70
|
+
InlineNode,
|
|
71
|
+
MarkdownDocument,
|
|
72
|
+
MarkdownInput,
|
|
73
|
+
ParseOptions,
|
|
74
|
+
RenderOptions,
|
|
75
|
+
} from '@tanstack/markdown'
|
|
76
|
+
|
|
77
|
+
declare function parseMarkdown(
|
|
78
|
+
markdown: string,
|
|
79
|
+
options?: ParseOptions,
|
|
80
|
+
): MarkdownDocument
|
|
81
|
+
|
|
82
|
+
declare function parseInline(
|
|
83
|
+
value: string,
|
|
84
|
+
options?: ParseOptions,
|
|
85
|
+
): InlineNode[]
|
|
86
|
+
|
|
87
|
+
declare function renderHtml(
|
|
88
|
+
input: MarkdownInput,
|
|
89
|
+
options?: RenderOptions,
|
|
90
|
+
): string
|
|
91
|
+
|
|
92
|
+
declare function renderDocument(
|
|
93
|
+
document: MarkdownDocument,
|
|
94
|
+
options?: RenderOptions,
|
|
95
|
+
): string
|
|
96
|
+
|
|
97
|
+
declare function renderBlock(
|
|
98
|
+
node: BlockNode,
|
|
99
|
+
options?: RenderOptions,
|
|
100
|
+
): string
|
|
101
|
+
|
|
102
|
+
declare function renderInline(
|
|
103
|
+
node: InlineNode,
|
|
104
|
+
options?: RenderOptions,
|
|
105
|
+
): string
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`MarkdownInput` is `string | MarkdownDocument`. Only complete-document
|
|
109
|
+
renderers accept source strings. `renderBlock` and `renderInline` accept one
|
|
110
|
+
already-parsed node.
|
|
111
|
+
|
|
112
|
+
## Document Shape
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import type { BlockNode, MarkdownHeading } from '@tanstack/markdown'
|
|
116
|
+
|
|
117
|
+
interface MarkdownDocument {
|
|
118
|
+
type: 'root'
|
|
119
|
+
children: BlockNode[]
|
|
120
|
+
frontmatter?: string
|
|
121
|
+
headings?: MarkdownHeading[]
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- `frontmatter` contains the raw text between leading `---` delimiters.
|
|
126
|
+
- `headings` is optional extension-derived data, not part of core parsing.
|
|
127
|
+
- The object is plain and serializable.
|
|
128
|
+
- Because the package is pre-1.0, persisted ASTs should be regenerated after
|
|
129
|
+
an upgrade that changes node contracts.
|
|
130
|
+
|
|
131
|
+
## Block Nodes
|
|
132
|
+
|
|
133
|
+
`BlockNode` is a discriminated union:
|
|
134
|
+
|
|
135
|
+
| `type` | Interface | Fields beyond `type` |
|
|
136
|
+
| --- | --- | --- |
|
|
137
|
+
| `heading` | `HeadingNode` | `depth`, optional `id`, optional `framework`, inline `children` |
|
|
138
|
+
| `paragraph` | `ParagraphNode` | inline `children` |
|
|
139
|
+
| `code` | `CodeBlockNode` | raw `value`; optional `lang`, `meta`, `title`, `file`, `framework`, `highlightLines` |
|
|
140
|
+
| `list` | `ListNode` | `ordered`, optional `start`, optional `loose`, `items` |
|
|
141
|
+
| `blockquote` | `BlockquoteNode` | block `children` |
|
|
142
|
+
| `table` | `TableNode` | per-column `align`, `header`, body `rows` |
|
|
143
|
+
| `footnotes` | `FootnotesNode` | `items` |
|
|
144
|
+
| `thematicBreak` | `ThematicBreakNode` | no additional fields |
|
|
145
|
+
| `html` | `HtmlBlockNode` | raw `value` |
|
|
146
|
+
| `callout` | `CalloutNode` | `kind`, `title`, block `children` |
|
|
147
|
+
| `component` | `ComponentNode` | `name`, `attributes`, block `children`, optional `tagName`, optional `properties` |
|
|
148
|
+
|
|
149
|
+
Supporting block shapes:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import type { BlockNode, InlineNode } from '@tanstack/markdown'
|
|
153
|
+
|
|
154
|
+
interface ListItemNode {
|
|
155
|
+
type: 'listItem'
|
|
156
|
+
checked?: boolean
|
|
157
|
+
children: BlockNode[]
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface TableCellNode {
|
|
161
|
+
type: 'tableCell'
|
|
162
|
+
children: InlineNode[]
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface FootnoteItemNode {
|
|
166
|
+
id: string
|
|
167
|
+
number: number
|
|
168
|
+
referenceCount?: number
|
|
169
|
+
children: BlockNode[]
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Important rendering invariants:
|
|
174
|
+
|
|
175
|
+
- `ListNode.loose: true` preserves paragraph wrappers for every list item.
|
|
176
|
+
- `ListItemNode.checked` controls task-list checkbox rendering.
|
|
177
|
+
- A non-`1` ordered-list `start` renders the corresponding `<ol start>`.
|
|
178
|
+
- `HtmlBlockNode` is created only when parsing with `allowHtml: true`.
|
|
179
|
+
- `CalloutNode` and `ComponentNode` are extension-oriented public nodes.
|
|
180
|
+
|
|
181
|
+
## Inline Nodes
|
|
182
|
+
|
|
183
|
+
`InlineNode` is a discriminated union:
|
|
184
|
+
|
|
185
|
+
| `type` | Interface | Fields beyond `type` |
|
|
186
|
+
| --- | --- | --- |
|
|
187
|
+
| `text` | `TextNode` | `value` |
|
|
188
|
+
| `inlineCode` | `CodeSpanNode` | `value` |
|
|
189
|
+
| `strong` | `StrongNode` | inline `children` |
|
|
190
|
+
| `emphasis` | `EmphasisNode` | inline `children` |
|
|
191
|
+
| `strike` | `StrikeNode` | inline `children` |
|
|
192
|
+
| `footnoteReference` | `FootnoteReferenceNode` | normalized `id`, display `number`, optional `referenceIndex` |
|
|
193
|
+
| `link` | `LinkNode` | sanitized `href`, optional `title`, inline `children` |
|
|
194
|
+
| `image` | `ImageNode` | sanitized `src`, text `alt`, optional `title` |
|
|
195
|
+
| `break` | `BreakNode` | no additional fields |
|
|
196
|
+
| `inlineHtml` | `HtmlInlineNode` | raw `value` |
|
|
197
|
+
|
|
198
|
+
`HtmlInlineNode` is created only when parsing with `allowHtml: true`.
|
|
199
|
+
Repeated footnote references use `referenceIndex` to produce unique source
|
|
200
|
+
IDs and back links.
|
|
201
|
+
|
|
202
|
+
## Parse Options
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import type {
|
|
206
|
+
FootnoteDefinition,
|
|
207
|
+
LinkReferenceDefinition,
|
|
208
|
+
MarkdownExtension,
|
|
209
|
+
} from '@tanstack/markdown'
|
|
210
|
+
|
|
211
|
+
interface ParseOptions {
|
|
212
|
+
allowHtml?: boolean
|
|
213
|
+
frontmatter?: boolean
|
|
214
|
+
headingIds?: boolean | ((text: string, index: number) => string)
|
|
215
|
+
extensions?: MarkdownExtension[]
|
|
216
|
+
references?: Record<string, LinkReferenceDefinition>
|
|
217
|
+
footnotes?: Record<string, FootnoteDefinition>
|
|
218
|
+
footnoteOrder?: string[]
|
|
219
|
+
footnoteCounts?: Record<string, number>
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
| Option | Default | Contract |
|
|
224
|
+
| --- | --- | --- |
|
|
225
|
+
| `allowHtml` | `false` | Recognize raw block and inline HTML nodes. Rendering also requires this option to emit their raw values. |
|
|
226
|
+
| `frontmatter` | `true` | Extract one leading `---` block into `document.frontmatter`. The library does not parse YAML. |
|
|
227
|
+
| `headingIds` | `true` | Generate duplicate-safe IDs, disable IDs with `false`, or return an ID from `(text, normalizedLineIndex)`. |
|
|
228
|
+
| `extensions` | `[]` | Run block parsers and inline/document transforms in array order. |
|
|
229
|
+
| `references` | internal | Carry normalized reference definitions through nested parsing. |
|
|
230
|
+
| `footnotes` | internal | Carry normalized footnote definitions through nested parsing. |
|
|
231
|
+
| `footnoteOrder` | internal | Track first-reference order through nested parsing. |
|
|
232
|
+
| `footnoteCounts` | internal | Track repeated references for unique IDs and back links. |
|
|
233
|
+
|
|
234
|
+
Ordinary complete-document calls should leave the four parser-state fields
|
|
235
|
+
unset. They are public for extension-driven nested parsing.
|
|
236
|
+
|
|
237
|
+
The custom heading ID callback receives a zero-based line index after input
|
|
238
|
+
normalization and possible frontmatter/definition extraction. Treat it as a
|
|
239
|
+
stable parser index, not a source-location API.
|
|
240
|
+
|
|
241
|
+
## Render Options
|
|
242
|
+
|
|
243
|
+
`RenderOptions` extends every `ParseOptions` field:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import type { ParseOptions } from '@tanstack/markdown'
|
|
247
|
+
|
|
248
|
+
interface RenderOptions extends ParseOptions {
|
|
249
|
+
highlighter?: CodeHighlighter
|
|
250
|
+
codeLineNumbers?: boolean
|
|
251
|
+
headingAnchors?: boolean | HeadingAnchorOptions
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
interface HeadingAnchorOptions {
|
|
255
|
+
content?: string
|
|
256
|
+
className?: string
|
|
257
|
+
ariaHidden?: boolean
|
|
258
|
+
tabIndex?: number
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
interface CodeHighlightOptions {
|
|
262
|
+
highlightLines?: number[]
|
|
263
|
+
lineNumbers?: boolean
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
interface CodeHighlighter {
|
|
267
|
+
(
|
|
268
|
+
code: string,
|
|
269
|
+
lang?: string,
|
|
270
|
+
options?: CodeHighlightOptions,
|
|
271
|
+
): string
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
| Option | Default | Contract |
|
|
276
|
+
| --- | --- | --- |
|
|
277
|
+
| `highlighter` | none | Return trusted HTML for the contents of the emitted `<code>` element. |
|
|
278
|
+
| `codeLineNumbers` | unset | Forward the preference to the highlighter as `lineNumbers`. |
|
|
279
|
+
| `headingAnchors` | `false` | Append a default or configured anchor to headings that already have IDs. |
|
|
280
|
+
|
|
281
|
+
For a source-string input, `renderHtml(source, options)` parses and renders
|
|
282
|
+
with the same options. For a `MarkdownDocument` input, parser options cannot
|
|
283
|
+
change existing AST structure. Renderer options and extension `renderHtml`
|
|
284
|
+
hooks still apply.
|
|
285
|
+
|
|
286
|
+
## Derived Data Shapes
|
|
287
|
+
|
|
288
|
+
```ts
|
|
289
|
+
import type { BlockNode } from '@tanstack/markdown'
|
|
290
|
+
|
|
291
|
+
interface MarkdownHeading {
|
|
292
|
+
id: string
|
|
293
|
+
text: string
|
|
294
|
+
level: number
|
|
295
|
+
framework?: string
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
interface LinkReferenceDefinition {
|
|
299
|
+
href: string
|
|
300
|
+
title?: string
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
interface FootnoteDefinition {
|
|
304
|
+
label: string
|
|
305
|
+
content: string
|
|
306
|
+
id?: string
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const heading: MarkdownHeading = {
|
|
310
|
+
id: 'install',
|
|
311
|
+
text: 'Install',
|
|
312
|
+
level: 2,
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const reference: LinkReferenceDefinition = {
|
|
316
|
+
href: '/install',
|
|
317
|
+
title: 'Installation',
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const footnote: FootnoteDefinition = {
|
|
321
|
+
label: 'support',
|
|
322
|
+
content: 'Supported in maintained browsers.',
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const blocks: BlockNode[] = []
|
|
326
|
+
|
|
327
|
+
console.log({ heading, reference, footnote, blocks })
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Core parsing does not populate `document.headings`; the heading collection
|
|
331
|
+
extension does. Link and footnote definition maps are parser state and are
|
|
332
|
+
normally extracted automatically by `parseMarkdown`.
|
|
333
|
+
|
|
334
|
+
## Narrowing the AST
|
|
335
|
+
|
|
336
|
+
Use each node's `type` discriminant:
|
|
337
|
+
|
|
338
|
+
```ts
|
|
339
|
+
import {
|
|
340
|
+
parseMarkdown,
|
|
341
|
+
type HeadingNode,
|
|
342
|
+
type MarkdownDocument,
|
|
343
|
+
} from '@tanstack/markdown'
|
|
344
|
+
|
|
345
|
+
function collectHeadings(document: MarkdownDocument): HeadingNode[] {
|
|
346
|
+
return document.children.filter(
|
|
347
|
+
(node): node is HeadingNode => node.type === 'heading',
|
|
348
|
+
)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const document = parseMarkdown(`# Guide
|
|
352
|
+
|
|
353
|
+
## Install
|
|
354
|
+
|
|
355
|
+
Content`)
|
|
356
|
+
|
|
357
|
+
const headings = collectHeadings(document)
|
|
358
|
+
|
|
359
|
+
console.log(headings.map(heading => ({
|
|
360
|
+
depth: heading.depth,
|
|
361
|
+
id: heading.id,
|
|
362
|
+
})))
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
The same `MarkdownDocument` can be serialized, transformed as plain data, or
|
|
366
|
+
rendered through HTML, React, and Octane adapters.
|