pd-markdown 2.0.0 → 2.0.2
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 +52 -170
- package/package.json +12 -1
- package/packages/parser/dist/index.d.ts +121 -4
- package/packages/utils/dist/index.d.ts +144 -7
- package/packages/web/dist/index.d.ts +265 -8
- package/packages/parser/dist/index.d.ts.map +0 -1
- package/packages/parser/dist/plugins/index.d.ts +0 -4
- package/packages/parser/dist/plugins/index.d.ts.map +0 -1
- package/packages/parser/dist/plugins/transform/heading.d.ts +0 -6
- package/packages/parser/dist/plugins/transform/heading.d.ts.map +0 -1
- package/packages/parser/dist/plugins/transform/list.d.ts +0 -14
- package/packages/parser/dist/plugins/transform/list.d.ts.map +0 -1
- package/packages/parser/dist/plugins/transform/table.d.ts +0 -27
- package/packages/parser/dist/plugins/transform/table.d.ts.map +0 -1
- package/packages/parser/dist/processor.d.ts +0 -22
- package/packages/parser/dist/processor.d.ts.map +0 -1
- package/packages/parser/dist/types/index.d.ts +0 -55
- package/packages/parser/dist/types/index.d.ts.map +0 -1
- package/packages/utils/dist/ast/query.d.ts +0 -36
- package/packages/utils/dist/ast/query.d.ts.map +0 -1
- package/packages/utils/dist/ast/traverse.d.ts +0 -22
- package/packages/utils/dist/ast/traverse.d.ts.map +0 -1
- package/packages/utils/dist/index.d.ts.map +0 -1
- package/packages/utils/dist/string/sanitize.d.ts +0 -22
- package/packages/utils/dist/string/sanitize.d.ts.map +0 -1
- package/packages/utils/dist/string/slugify.d.ts +0 -16
- package/packages/utils/dist/string/slugify.d.ts.map +0 -1
- package/packages/utils/dist/types/index.d.ts +0 -49
- package/packages/utils/dist/types/index.d.ts.map +0 -1
- package/packages/web/dist/components/MarkdownRenderer.d.ts +0 -27
- package/packages/web/dist/components/MarkdownRenderer.d.ts.map +0 -1
- package/packages/web/dist/components/NodeRenderer.d.ts +0 -10
- package/packages/web/dist/components/NodeRenderer.d.ts.map +0 -1
- package/packages/web/dist/components/StreamMarkdownRenderer.d.ts +0 -58
- package/packages/web/dist/components/StreamMarkdownRenderer.d.ts.map +0 -1
- package/packages/web/dist/components/context.d.ts +0 -17
- package/packages/web/dist/components/context.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/Blockquote.d.ts +0 -8
- package/packages/web/dist/components/defaults/Blockquote.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/Code.d.ts +0 -13
- package/packages/web/dist/components/defaults/Code.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/Heading.d.ts +0 -8
- package/packages/web/dist/components/defaults/Heading.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/Image.d.ts +0 -7
- package/packages/web/dist/components/defaults/Image.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/Link.d.ts +0 -8
- package/packages/web/dist/components/defaults/Link.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/List.d.ts +0 -13
- package/packages/web/dist/components/defaults/List.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/Paragraph.d.ts +0 -8
- package/packages/web/dist/components/defaults/Paragraph.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/Table.d.ts +0 -19
- package/packages/web/dist/components/defaults/Table.d.ts.map +0 -1
- package/packages/web/dist/components/defaults/index.d.ts +0 -42
- package/packages/web/dist/components/defaults/index.d.ts.map +0 -1
- package/packages/web/dist/hooks/useMarkdown.d.ts +0 -11
- package/packages/web/dist/hooks/useMarkdown.d.ts.map +0 -1
- package/packages/web/dist/hooks/useStreamMarkdown.d.ts +0 -59
- package/packages/web/dist/hooks/useStreamMarkdown.d.ts.map +0 -1
- package/packages/web/dist/index.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# pd-markdown
|
|
2
2
|
|
|
3
|
-
一个现代化的 Markdown 解析和渲染工具库,基于 unified/remark
|
|
3
|
+
一个现代化的 Markdown 解析和渲染工具库,基于 unified/remark 构建,专为 React 和现代流式 Web 应用设计。
|
|
4
4
|
|
|
5
5
|
## 特性
|
|
6
6
|
|
|
7
7
|
- 🚀 **高性能解析** - 基于 unified/remark 的 Markdown 解析器
|
|
8
|
+
- ⚡ **流式渲染** - 专为 AI 场景设计的 `StreamMarkdownRenderer` 和 `useStreamMarkdown`
|
|
8
9
|
- 📝 **GFM 支持** - 完整支持 GitHub Flavored Markdown
|
|
9
10
|
- 📋 **Frontmatter** - 支持 YAML frontmatter 解析
|
|
10
11
|
- ⚛️ **React 组件** - 提供开箱即用的 React 渲染组件
|
|
11
|
-
- 🎨 **可定制** -
|
|
12
|
+
- 🎨 **可定制** - 支持自定义组件覆盖(Heading, Code, Table 等)
|
|
12
13
|
- 🔗 **自动锚点** - 标题自动生成 slug 锚点
|
|
13
14
|
- 📦 **Tree-shakable** - 支持 ESM,优化打包体积
|
|
14
15
|
|
|
@@ -30,7 +31,7 @@ yarn add pd-markdown
|
|
|
30
31
|
| 模块路径 | 描述 |
|
|
31
32
|
| --- | --- |
|
|
32
33
|
| `pd-markdown/parser` | Markdown 解析器,将 Markdown 转换为 AST |
|
|
33
|
-
| `pd-markdown/web` | React
|
|
34
|
+
| `pd-markdown/web` | React 组件和 Hooks,用于渲染 Markdown 和处理流式内容 |
|
|
34
35
|
| `pd-markdown/utils` | 工具函数库,提供 AST 操作和字符串处理 |
|
|
35
36
|
|
|
36
37
|
## 快速开始
|
|
@@ -45,19 +46,37 @@ function App() {
|
|
|
45
46
|
# Hello World
|
|
46
47
|
|
|
47
48
|
This is a **markdown** document.
|
|
48
|
-
|
|
49
|
-
## Features
|
|
50
|
-
|
|
51
|
-
- GFM support
|
|
52
|
-
- Frontmatter parsing
|
|
53
|
-
- Custom components
|
|
54
49
|
`
|
|
55
50
|
|
|
56
51
|
return <MarkdownRenderer source={markdown} />
|
|
57
52
|
}
|
|
58
53
|
```
|
|
59
54
|
|
|
60
|
-
###
|
|
55
|
+
### 流式渲染 (AI 场景)
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { StreamMarkdownRenderer, useStreamMarkdown } from 'pd-markdown/web'
|
|
59
|
+
|
|
60
|
+
function AIResponse() {
|
|
61
|
+
const stream = useStreamMarkdown()
|
|
62
|
+
|
|
63
|
+
// 模拟从流中读取数据
|
|
64
|
+
const onNewChunk = (chunk: string) => {
|
|
65
|
+
stream.append(chunk)
|
|
66
|
+
if (isLastChunk) stream.done()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<StreamMarkdownRenderer
|
|
71
|
+
source={stream.source}
|
|
72
|
+
isStreaming={stream.isStreaming}
|
|
73
|
+
showCursor={true}
|
|
74
|
+
/>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 使用预解析的 AST (SSR 优化)
|
|
61
80
|
|
|
62
81
|
```tsx
|
|
63
82
|
import { createParser } from 'pd-markdown/parser'
|
|
@@ -73,19 +92,6 @@ function Page({ ast }) {
|
|
|
73
92
|
}
|
|
74
93
|
```
|
|
75
94
|
|
|
76
|
-
### 使用 Hook
|
|
77
|
-
|
|
78
|
-
```tsx
|
|
79
|
-
import { useMarkdown, MarkdownRenderer } from 'pd-markdown/web'
|
|
80
|
-
|
|
81
|
-
function MarkdownPreview({ source }) {
|
|
82
|
-
const ast = useMarkdown(source)
|
|
83
|
-
|
|
84
|
-
// 可以对 AST 进行自定义处理
|
|
85
|
-
return <MarkdownRenderer ast={ast} />
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
95
|
## API 文档
|
|
90
96
|
|
|
91
97
|
### pd-markdown/parser
|
|
@@ -100,192 +106,68 @@ import { createParser } from 'pd-markdown/parser'
|
|
|
100
106
|
const parser = createParser({
|
|
101
107
|
gfm: true, // 启用 GFM 支持(默认 true)
|
|
102
108
|
frontmatter: true, // 启用 frontmatter 解析(默认 true)
|
|
103
|
-
plugins: [], // 自定义插件
|
|
104
109
|
})
|
|
105
110
|
|
|
106
111
|
const ast = parser.parse('# Hello World')
|
|
107
112
|
```
|
|
108
113
|
|
|
109
|
-
|
|
114
|
+
### pd-markdown/web
|
|
110
115
|
|
|
111
|
-
|
|
116
|
+
#### `<MarkdownRenderer />`
|
|
112
117
|
|
|
113
|
-
|
|
114
|
-
import { definePlugin } from 'pd-markdown/parser'
|
|
115
|
-
|
|
116
|
-
const myPlugin = definePlugin({
|
|
117
|
-
name: 'my-plugin',
|
|
118
|
-
phase: 'after', // 'before' | 'after'
|
|
119
|
-
transform: () => (tree, file) => {
|
|
120
|
-
// 处理 AST
|
|
121
|
-
console.log(tree)
|
|
122
|
-
},
|
|
123
|
-
})
|
|
124
|
-
```
|
|
118
|
+
主渲染组件。支持 `source` 字符串或预解析的 `ast`。
|
|
125
119
|
|
|
126
|
-
|
|
120
|
+
#### `<StreamMarkdownRenderer />`
|
|
127
121
|
|
|
128
|
-
|
|
122
|
+
流式渲染组件,专为实时生成的内容优化。
|
|
129
123
|
|
|
130
|
-
|
|
124
|
+
- `showCursor`: 是否显示打字机光标
|
|
125
|
+
- `enableAnimation`: 是否启用新块淡入动画
|
|
126
|
+
- `isStreaming`: 标记当前流是否仍在进行
|
|
131
127
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
/** 包装器 CSS 类名 */
|
|
141
|
-
className?: string
|
|
142
|
-
/** 包装器内联样式 */
|
|
143
|
-
style?: CSSProperties
|
|
144
|
-
/** 解析器选项(仅在使用 source 时生效) */
|
|
145
|
-
parserOptions?: ParserOptions
|
|
146
|
-
}
|
|
128
|
+
#### `useStreamMarkdown(options?)`
|
|
129
|
+
|
|
130
|
+
管理流式 Markdown 状态的 Hook。
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
const { source, ast, append, done, reset } = useStreamMarkdown({
|
|
134
|
+
parseDebounceMs: 30, // 解析防抖,优化超快流速下的性能
|
|
135
|
+
})
|
|
147
136
|
```
|
|
148
137
|
|
|
149
|
-
####
|
|
138
|
+
#### 自定义组件覆盖
|
|
150
139
|
|
|
151
140
|
```tsx
|
|
152
141
|
import { MarkdownRenderer, type ComponentMap } from 'pd-markdown/web'
|
|
153
142
|
|
|
154
143
|
const customComponents: Partial<ComponentMap> = {
|
|
155
144
|
heading: ({ node, children }) => (
|
|
156
|
-
<h2
|
|
157
|
-
),
|
|
158
|
-
code: ({ node, children }) => (
|
|
159
|
-
<pre className="custom-code-block">
|
|
160
|
-
<code>{children}</code>
|
|
161
|
-
</pre>
|
|
145
|
+
<h2 style={{ color: 'blue' }}>{children}</h2>
|
|
162
146
|
),
|
|
163
147
|
}
|
|
164
148
|
|
|
165
149
|
function App() {
|
|
166
|
-
return
|
|
167
|
-
<MarkdownRenderer
|
|
168
|
-
source={markdown}
|
|
169
|
-
components={customComponents}
|
|
170
|
-
/>
|
|
171
|
-
)
|
|
150
|
+
return <MarkdownRenderer source={md} components={customComponents} />
|
|
172
151
|
}
|
|
173
152
|
```
|
|
174
153
|
|
|
175
|
-
#### 可自定义的组件列表
|
|
176
|
-
|
|
177
|
-
| 组件名 | 对应节点 |
|
|
178
|
-
| --- | --- |
|
|
179
|
-
| `heading` | 标题 (h1-h6) |
|
|
180
|
-
| `paragraph` | 段落 |
|
|
181
|
-
| `list` | 列表 |
|
|
182
|
-
| `listItem` | 列表项 |
|
|
183
|
-
| `table` | 表格 |
|
|
184
|
-
| `tableRow` | 表格行 |
|
|
185
|
-
| `tableCell` | 表格单元格 |
|
|
186
|
-
| `code` | 代码块 |
|
|
187
|
-
| `inlineCode` | 行内代码 |
|
|
188
|
-
| `link` | 链接 |
|
|
189
|
-
| `image` | 图片 |
|
|
190
|
-
| `blockquote` | 引用块 |
|
|
191
|
-
|
|
192
154
|
### pd-markdown/utils
|
|
193
155
|
|
|
194
|
-
|
|
156
|
+
提供强大的 AST 遍历与处理工具。
|
|
195
157
|
|
|
196
158
|
```ts
|
|
197
|
-
import {
|
|
198
|
-
// AST 遍历
|
|
199
|
-
traverseAst,
|
|
200
|
-
findNodes,
|
|
201
|
-
findNode,
|
|
202
|
-
// 类型守卫
|
|
203
|
-
isParent,
|
|
204
|
-
isLiteral,
|
|
205
|
-
isNodeType,
|
|
206
|
-
// 字符串处理
|
|
207
|
-
slugify,
|
|
208
|
-
uniqueSlugify,
|
|
209
|
-
escapeHtml,
|
|
210
|
-
sanitizeHtml,
|
|
211
|
-
} from 'pd-markdown/utils'
|
|
212
|
-
|
|
213
|
-
// 查找所有标题节点
|
|
214
|
-
const headings = findNodes(ast, 'heading')
|
|
215
|
-
|
|
216
|
-
// 生成 slug
|
|
217
|
-
const slug = slugify('Hello World') // 'hello-world'
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## 示例
|
|
221
|
-
|
|
222
|
-
### 博客文章渲染
|
|
223
|
-
|
|
224
|
-
```tsx
|
|
225
|
-
import { createParser } from 'pd-markdown/parser'
|
|
226
|
-
import { MarkdownRenderer } from 'pd-markdown/web'
|
|
227
|
-
|
|
228
|
-
const parser = createParser()
|
|
229
|
-
|
|
230
|
-
function BlogPost({ content }) {
|
|
231
|
-
const ast = parser.parse(content)
|
|
232
|
-
|
|
233
|
-
return (
|
|
234
|
-
<article className="prose">
|
|
235
|
-
<MarkdownRenderer
|
|
236
|
-
ast={ast}
|
|
237
|
-
className="markdown-body"
|
|
238
|
-
/>
|
|
239
|
-
</article>
|
|
240
|
-
)
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### 代码高亮
|
|
245
|
-
|
|
246
|
-
```tsx
|
|
247
|
-
import { MarkdownRenderer, type CodeProps } from 'pd-markdown/web'
|
|
248
|
-
import Prism from 'prismjs'
|
|
249
|
-
|
|
250
|
-
function CodeBlock({ node, children }: CodeProps) {
|
|
251
|
-
const lang = node.lang || 'text'
|
|
252
|
-
const highlighted = Prism.highlight(
|
|
253
|
-
String(children),
|
|
254
|
-
Prism.languages[lang] || Prism.languages.text,
|
|
255
|
-
lang
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
return (
|
|
259
|
-
<pre className={`language-${lang}`}>
|
|
260
|
-
<code dangerouslySetInnerHTML={{ __html: highlighted }} />
|
|
261
|
-
</pre>
|
|
262
|
-
)
|
|
263
|
-
}
|
|
159
|
+
import { traverseAst, findNodes, slugify } from 'pd-markdown/utils'
|
|
264
160
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
<MarkdownRenderer
|
|
268
|
-
source={markdown}
|
|
269
|
-
components={{ code: CodeBlock }}
|
|
270
|
-
/>
|
|
271
|
-
)
|
|
272
|
-
}
|
|
161
|
+
// 提取所有标题
|
|
162
|
+
const headings = findNodes(ast, 'heading')
|
|
273
163
|
```
|
|
274
164
|
|
|
275
165
|
## 开发
|
|
276
166
|
|
|
277
167
|
```bash
|
|
278
|
-
# 安装依赖
|
|
279
168
|
pnpm install
|
|
280
|
-
|
|
281
|
-
# 构建
|
|
282
169
|
pnpm build
|
|
283
|
-
|
|
284
|
-
# 运行测试
|
|
285
170
|
pnpm test
|
|
286
|
-
|
|
287
|
-
# 类型检查
|
|
288
|
-
pnpm typecheck
|
|
289
171
|
```
|
|
290
172
|
|
|
291
173
|
## License
|
package/package.json
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pd-markdown",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"main": "./packages/web/dist/index.cjs",
|
|
6
|
+
"module": "./packages/web/dist/index.mjs",
|
|
7
|
+
"types": "./packages/web/dist/index.d.ts",
|
|
5
8
|
"description": "A modular markdown parsing and rendering library",
|
|
6
9
|
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./packages/web/dist/index.d.ts",
|
|
12
|
+
"import": "./packages/web/dist/index.mjs",
|
|
13
|
+
"require": "./packages/web/dist/index.cjs"
|
|
14
|
+
},
|
|
7
15
|
"./parser": {
|
|
8
16
|
"types": "./packages/parser/dist/index.d.ts",
|
|
9
17
|
"import": "./packages/parser/dist/index.mjs",
|
|
@@ -22,6 +30,9 @@
|
|
|
22
30
|
},
|
|
23
31
|
"typesVersions": {
|
|
24
32
|
"*": {
|
|
33
|
+
".": [
|
|
34
|
+
"./packages/web/dist/index.d.ts"
|
|
35
|
+
],
|
|
25
36
|
"parser": [
|
|
26
37
|
"./packages/parser/dist/index.d.ts"
|
|
27
38
|
],
|
|
@@ -1,4 +1,121 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { Root } from 'mdast';
|
|
2
|
+
import { VFile } from 'vfile';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parser plugin configuration
|
|
6
|
+
*/
|
|
7
|
+
interface ParserPlugin {
|
|
8
|
+
/** Unique plugin name */
|
|
9
|
+
name: string;
|
|
10
|
+
/** When to run: before or after built-in transforms */
|
|
11
|
+
phase: 'before' | 'after';
|
|
12
|
+
/** Transform function */
|
|
13
|
+
transform: (tree: Root, file: VFile) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parser options
|
|
17
|
+
*/
|
|
18
|
+
interface ParserOptions {
|
|
19
|
+
/** Custom plugins to add */
|
|
20
|
+
plugins?: ParserPlugin[];
|
|
21
|
+
/** Enable GFM syntax (default: true) */
|
|
22
|
+
gfm?: boolean;
|
|
23
|
+
/** Enable frontmatter parsing (default: true) */
|
|
24
|
+
frontmatter?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parser instance
|
|
28
|
+
*/
|
|
29
|
+
interface Parser {
|
|
30
|
+
/** Parse markdown string to AST */
|
|
31
|
+
parse(content: string): Root;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Plugin definition helper config
|
|
35
|
+
*/
|
|
36
|
+
interface PluginConfig<T = unknown> {
|
|
37
|
+
/** Plugin name */
|
|
38
|
+
name: string;
|
|
39
|
+
/** When to run */
|
|
40
|
+
phase: 'before' | 'after';
|
|
41
|
+
/** Transform function factory */
|
|
42
|
+
transform: (options?: T) => (tree: Root, file: VFile) => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Frontmatter data extracted from markdown
|
|
46
|
+
*/
|
|
47
|
+
interface FrontmatterData {
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Extended file data with frontmatter
|
|
52
|
+
*/
|
|
53
|
+
interface FileData {
|
|
54
|
+
frontmatter?: FrontmatterData;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Create a markdown parser with the specified options
|
|
59
|
+
*
|
|
60
|
+
* @param options - Parser configuration options
|
|
61
|
+
* @returns Parser instance with parse method
|
|
62
|
+
*/
|
|
63
|
+
declare function createParser(options?: ParserOptions): Parser;
|
|
64
|
+
/**
|
|
65
|
+
* Type-safe helper to define a parser plugin
|
|
66
|
+
*
|
|
67
|
+
* @param config - Plugin configuration
|
|
68
|
+
* @returns Parser plugin
|
|
69
|
+
*/
|
|
70
|
+
declare function definePlugin<T = void>(config: {
|
|
71
|
+
name: string;
|
|
72
|
+
phase: 'before' | 'after';
|
|
73
|
+
transform: (options?: T) => (tree: Root, file: VFile) => void;
|
|
74
|
+
}, options?: T): ParserPlugin;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Transform plugin that adds slug IDs to headings
|
|
78
|
+
*/
|
|
79
|
+
declare function transformHeading(tree: Root): void;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Extended list item with index
|
|
83
|
+
*/
|
|
84
|
+
declare module 'mdast' {
|
|
85
|
+
interface ListItemData {
|
|
86
|
+
index?: number;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Transform plugin that adds index to list items
|
|
91
|
+
*/
|
|
92
|
+
declare function transformList(tree: Root): void;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Extended table data
|
|
96
|
+
*/
|
|
97
|
+
declare module 'mdast' {
|
|
98
|
+
interface TableData {
|
|
99
|
+
/** Header row */
|
|
100
|
+
header?: TableRow;
|
|
101
|
+
/** Body rows */
|
|
102
|
+
body?: TableRow[];
|
|
103
|
+
}
|
|
104
|
+
interface TableCellData {
|
|
105
|
+
/** Whether this cell is in header */
|
|
106
|
+
isHeader?: boolean;
|
|
107
|
+
/** Column alignment */
|
|
108
|
+
align?: 'left' | 'center' | 'right' | null;
|
|
109
|
+
/** Column index */
|
|
110
|
+
columnIndex?: number;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Transform plugin that enhances table structure
|
|
115
|
+
* - Separates header and body rows
|
|
116
|
+
* - Adds alignment and index info to cells
|
|
117
|
+
*/
|
|
118
|
+
declare function transformTable(tree: Root): void;
|
|
119
|
+
|
|
120
|
+
export { createParser, definePlugin, transformHeading, transformList, transformTable };
|
|
121
|
+
export type { FileData, FrontmatterData, Parser, ParserOptions, ParserPlugin, PluginConfig };
|
|
@@ -1,7 +1,144 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Root, Content, Parent, Literal } from 'mdast';
|
|
2
|
+
export { Literal, Parent } from 'mdast';
|
|
3
|
+
import { Node } from 'unist';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* All possible markdown node types
|
|
7
|
+
*/
|
|
8
|
+
type MdNode = Root | Content;
|
|
9
|
+
/**
|
|
10
|
+
* Root node of markdown AST
|
|
11
|
+
*/
|
|
12
|
+
type MdRoot = Root;
|
|
13
|
+
/**
|
|
14
|
+
* Visitor function for AST traversal
|
|
15
|
+
*/
|
|
16
|
+
type Visitor<T extends Node = MdNode> = (node: T, index: number | undefined, parent: Parent | undefined) => void | boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Plugin options base interface
|
|
19
|
+
*/
|
|
20
|
+
interface PluginOptions {
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Position information in source
|
|
25
|
+
*/
|
|
26
|
+
interface Position {
|
|
27
|
+
line: number;
|
|
28
|
+
column: number;
|
|
29
|
+
offset?: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Location in source
|
|
33
|
+
*/
|
|
34
|
+
interface Location {
|
|
35
|
+
start: Position;
|
|
36
|
+
end: Position;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Type guard to check if node is a parent node
|
|
40
|
+
*/
|
|
41
|
+
declare function isParent(node: Node): node is Parent;
|
|
42
|
+
/**
|
|
43
|
+
* Type guard to check if node is a literal node
|
|
44
|
+
*/
|
|
45
|
+
declare function isLiteral(node: Node): node is Literal;
|
|
46
|
+
/**
|
|
47
|
+
* Type guard to check if node has specific type
|
|
48
|
+
*/
|
|
49
|
+
declare function isNodeType<T extends MdNode>(node: Node, type: T['type']): node is T;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Traverse AST in depth-first order
|
|
53
|
+
*
|
|
54
|
+
* @param node - Root node to start traversal
|
|
55
|
+
* @param visitor - Visitor function called for each node
|
|
56
|
+
* Return `false` to skip children of current node
|
|
57
|
+
* Return `true` or `undefined` to continue
|
|
58
|
+
*/
|
|
59
|
+
declare function traverseAst<T extends Node = MdNode>(node: T, visitor: Visitor<T>): void;
|
|
60
|
+
/**
|
|
61
|
+
* Traverse AST with enter and leave callbacks
|
|
62
|
+
*
|
|
63
|
+
* @param node - Root node to start traversal
|
|
64
|
+
* @param callbacks - Object with optional enter and leave functions
|
|
65
|
+
*/
|
|
66
|
+
declare function traverseAstWithCallbacks<T extends Node = MdNode>(node: T, callbacks: {
|
|
67
|
+
enter?: Visitor<T>;
|
|
68
|
+
leave?: Visitor<T>;
|
|
69
|
+
}): void;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Find all nodes of a specific type in the AST
|
|
73
|
+
*
|
|
74
|
+
* @param node - Root node to search from
|
|
75
|
+
* @param type - Node type to find
|
|
76
|
+
* @returns Array of matching nodes
|
|
77
|
+
*/
|
|
78
|
+
declare function findNodes<T extends Node = MdNode>(node: Node, type: string): T[];
|
|
79
|
+
/**
|
|
80
|
+
* Find the first node of a specific type in the AST
|
|
81
|
+
*
|
|
82
|
+
* @param node - Root node to search from
|
|
83
|
+
* @param type - Node type to find
|
|
84
|
+
* @returns The first matching node or undefined
|
|
85
|
+
*/
|
|
86
|
+
declare function findNode<T extends Node = MdNode>(node: Node, type: string): T | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Find all nodes matching a predicate
|
|
89
|
+
*
|
|
90
|
+
* @param node - Root node to search from
|
|
91
|
+
* @param predicate - Function to test each node
|
|
92
|
+
* @returns Array of matching nodes
|
|
93
|
+
*/
|
|
94
|
+
declare function findNodesBy<T extends Node = MdNode>(node: Node, predicate: (node: Node) => boolean): T[];
|
|
95
|
+
/**
|
|
96
|
+
* Get the parent of a node in the AST
|
|
97
|
+
* Note: This requires traversing from root, use sparingly
|
|
98
|
+
*
|
|
99
|
+
* @param root - Root node of the AST
|
|
100
|
+
* @param target - Node to find parent of
|
|
101
|
+
* @returns Parent node or undefined if not found or is root
|
|
102
|
+
*/
|
|
103
|
+
declare function findParent(root: Node, target: Node): Parent | undefined;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Convert text to URL-safe slug
|
|
107
|
+
*
|
|
108
|
+
* @param text - Text to slugify
|
|
109
|
+
* @returns URL-safe slug
|
|
110
|
+
*/
|
|
111
|
+
declare function slugify(text: string): string;
|
|
112
|
+
/**
|
|
113
|
+
* Generate unique slug with counter suffix for duplicates
|
|
114
|
+
*
|
|
115
|
+
* @param text - Text to slugify
|
|
116
|
+
* @param existingSlugs - Set of existing slugs to check against
|
|
117
|
+
* @returns Unique slug
|
|
118
|
+
*/
|
|
119
|
+
declare function uniqueSlugify(text: string, existingSlugs: Set<string>): string;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Escape HTML special characters
|
|
123
|
+
*
|
|
124
|
+
* @param text - Text to escape
|
|
125
|
+
* @returns Escaped text safe for HTML insertion
|
|
126
|
+
*/
|
|
127
|
+
declare function escapeHtml(text: string): string;
|
|
128
|
+
/**
|
|
129
|
+
* Sanitize HTML string by removing dangerous content
|
|
130
|
+
*
|
|
131
|
+
* @param html - HTML string to sanitize
|
|
132
|
+
* @returns Sanitized HTML string
|
|
133
|
+
*/
|
|
134
|
+
declare function sanitizeHtml(html: string): string;
|
|
135
|
+
/**
|
|
136
|
+
* Strip all HTML tags from a string
|
|
137
|
+
*
|
|
138
|
+
* @param html - HTML string to strip
|
|
139
|
+
* @returns Plain text without HTML tags
|
|
140
|
+
*/
|
|
141
|
+
declare function stripHtml(html: string): string;
|
|
142
|
+
|
|
143
|
+
export { escapeHtml, findNode, findNodes, findNodesBy, findParent, isLiteral, isNodeType, isParent, sanitizeHtml, slugify, stripHtml, traverseAst, traverseAstWithCallbacks, uniqueSlugify };
|
|
144
|
+
export type { Location, MdNode, MdRoot, PluginOptions, Position, Visitor };
|