@isdk/mdast-plus 0.1.2 → 0.2.0

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.
Files changed (43) hide show
  1. package/README.cn.md +69 -22
  2. package/README.md +69 -22
  3. package/dist/index.d.mts +564 -199
  4. package/dist/index.d.ts +564 -199
  5. package/dist/index.js +1 -1
  6. package/dist/index.mjs +1 -1
  7. package/docs/README.md +69 -22
  8. package/docs/_media/CONTRIBUTING.md +53 -24
  9. package/docs/_media/README.cn.md +69 -22
  10. package/docs/classes/MdastBasePipeline.md +416 -0
  11. package/docs/classes/MdastPipeline.md +611 -0
  12. package/docs/enumerations/PipelineStage.md +62 -0
  13. package/docs/functions/astCompiler.md +25 -0
  14. package/docs/functions/jsonParser.md +24 -0
  15. package/docs/functions/mdast.md +4 -4
  16. package/docs/globals.md +17 -10
  17. package/docs/interfaces/MdastDataOrigin.md +8 -8
  18. package/docs/interfaces/MdastFormat.md +71 -0
  19. package/docs/interfaces/MdastMark.md +4 -4
  20. package/docs/interfaces/MdastPlugin.md +57 -25
  21. package/docs/interfaces/MdastSub.md +4 -4
  22. package/docs/interfaces/MdastSup.md +4 -4
  23. package/docs/interfaces/ReadabilityOptions.md +33 -0
  24. package/docs/type-aliases/PipelineStageName.md +13 -0
  25. package/docs/variables/DefaultPipelineStage.md +13 -0
  26. package/docs/variables/astFormat.md +15 -0
  27. package/docs/variables/htmlFormat.md +6 -4
  28. package/docs/variables/htmlReadability.md +13 -0
  29. package/docs/variables/htmlReadabilityPlugin.md +27 -0
  30. package/docs/variables/htmlReadabilityPlugins.md +13 -0
  31. package/docs/variables/markdownFormat.md +6 -4
  32. package/docs/variables/restoreReadabilityMetaPlugin.md +49 -0
  33. package/package.json +18 -9
  34. package/docs/classes/FluentProcessor.md +0 -210
  35. package/docs/functions/htmlStringify.md +0 -23
  36. package/docs/functions/markdownCommon.md +0 -23
  37. package/docs/interfaces/ConvertResult.md +0 -39
  38. package/docs/interfaces/MdastAsset.md +0 -41
  39. package/docs/interfaces/MdastFormatDefinition.md +0 -51
  40. package/docs/interfaces/MdastReader.md +0 -41
  41. package/docs/interfaces/MdastTransformer.md +0 -33
  42. package/docs/interfaces/MdastWriter.md +0 -47
  43. package/docs/type-aliases/Stage.md +0 -13
package/README.cn.md CHANGED
@@ -11,7 +11,7 @@
11
11
  ## 特性
12
12
 
13
13
  - **Fluent API**: 链式调用接口 `mdast(input).use(plugin).toHTML()`。
14
- - **分阶段插件**: 将转换组织为 `normalize`、`compile` 和 `finalize` 阶段,支持优先级排序。
14
+ - **分阶段插件**: 将转换组织为 `parse`, `normalize`, `compile`, `finalize` 和 `stringify` 阶段。
15
15
  - **语义化规范**:
16
16
  - **指令 (Directives)**: 规范化提示框 (Admonition) 名称并从标签中提取标题。
17
17
  - **表格跨行/跨列**: 支持 HTML 输出中的 `rowspan` 和 `colspan`。
@@ -40,6 +40,17 @@ const html = await mdast(':::warning[重要提示]\n请小心!\n:::')
40
40
  // 结果: <div title="重要提示" class="warning"><p>请小心!</p></div>
41
41
  ```
42
42
 
43
+ ### 配置输入选项
44
+
45
+ 您可以通过 `.from()` 的第二个参数向输入插件(如 `remark-gfm` 或 `remark-parse`)传递选项:
46
+
47
+ ```typescript
48
+ // 启用单个波浪线删除线 (~text~)
49
+ const md = await mdast('Hello ~world~')
50
+ .from('markdown', { remarkGfm: { singleTilde: true } })
51
+ .toMarkdown();
52
+ ```
53
+
43
54
  ### 图片尺寸
44
55
 
45
56
  ```typescript
@@ -50,23 +61,46 @@ const html = await mdast('![Cat](cat.png#=500x300)').toHTML();
50
61
  ### AST 输出
51
62
 
52
63
  ```typescript
64
+ // 获取处理后的完整 AST (在 normalization 之后)
53
65
  const ast = await mdast('==高亮内容==').toAST();
54
- // 返回 mdast Root 对象
66
+
67
+ // 获取原始 AST (在 parse 之后, normalization 之前)
68
+ const rawAst = await mdast('==高亮内容==').toAST({ stage: 'parse' });
55
69
  ```
56
70
 
57
71
  ### 高级工作流
58
72
 
59
73
  ```typescript
60
- const { content, assets } = await mdast(myInput)
74
+ import { htmlReadabilityPlugins } from '@isdk/mdast-plus';
75
+
76
+ const vfile = await mdast(myInput)
61
77
  .data({ myGlobal: 'value' })
62
- .use({
63
- name: 'my-plugin',
64
- stage: 'compile',
65
- transform: async (tree) => {
66
- // 转换 AST
67
- }
68
- })
78
+ // 以数组形式在 'compile' 阶段添加多个插件
79
+ .use([pluginA, pluginB])
80
+ // 或在特定阶段添加一组插件
81
+ .useAt('parse', htmlReadabilityPlugins)
82
+ .priority(10) // 比默认插件更晚执行
69
83
  .to('html');
84
+
85
+ console.log(vfile.value); // 序列化后的 HTML 字符串
86
+ ```
87
+
88
+ ### 插件行为
89
+
90
+ `mdast-plus` 内部使用 [unified](https://github.com/unifiedjs/unified)。如果您多次添加同一个插件函数,最后的配置将**覆盖**之前的配置。
91
+
92
+ ```typescript
93
+ // 插件将只执行一次,且选项为: 2
94
+ pipeline.use(myPlugin, { option: 1 });
95
+ pipeline.use(myPlugin, { option: 2 });
96
+ ```
97
+
98
+ 若要多次运行相同的插件逻辑(例如用于不同目的),请提供不同的函数引用:
99
+
100
+ ```typescript
101
+ // 插件将执行两次
102
+ pipeline.use(myPlugin, { option: 1 });
103
+ pipeline.use(myPlugin.bind({}), { option: 2 });
70
104
  ```
71
105
 
72
106
  ### 任意格式支持
@@ -74,16 +108,20 @@ const { content, assets } = await mdast(myInput)
74
108
  您可以注册自定义的输入或输出格式:
75
109
 
76
110
  ```typescript
77
- import { FluentProcessor, mdast } from '@isdk/mdast-plus';
111
+ import { MdastPipeline, mdast, PipelineStage } from '@isdk/mdast-plus';
78
112
 
79
113
  // 注册自定义输出格式
80
- FluentProcessor.registerFormat('reverse', {
81
- stringify: (p) => {
82
- p.Compiler = (tree) => {
83
- // 您的自定义序列化逻辑
84
- return '...';
85
- };
86
- }
114
+ MdastPipeline.register({
115
+ id: 'reverse',
116
+ output: [{
117
+ plugin: function() {
118
+ this.Compiler = (tree) => {
119
+ // 您的自定义序列化逻辑
120
+ return '...';
121
+ };
122
+ },
123
+ stage: PipelineStage.stringify
124
+ }]
87
125
  });
88
126
 
89
127
  const result = await mdast('Hello').to('reverse');
@@ -93,11 +131,19 @@ const result = await mdast('Hello').to('reverse');
93
131
 
94
132
  ## 分阶段处理
95
133
 
96
- 插件根据它们的 `stage` (阶段) 和 `order` (顺序) 执行:
134
+ 插件根据它们的 `stage` (阶段)、`order` (顺序) 以及语义约束 (`before`/`after`) 执行:
135
+
136
+ 1. **parse** (0): 输入解析 (例如 `remark-parse`)。
137
+ 2. **normalize** (100): 清理并规范化树。
138
+ 3. **compile** (200): 高级语义转换。
139
+ 4. **finalize** (300): 输出前的最后准备 (例如 `rehype-sanitize`)。
140
+ 5. **stringify** (400): 输出生成。
141
+
142
+ ### 主插件替换 (Main Plugin Replacement)
143
+
144
+ 每个阶段可以有一个“主”插件。如果一个插件被标记为 `main: true`,它将 **替换** 该阶段中的第一个插件。这对于在保持管道其余部分不变的情况下更换默认解析器或编译器非常有用。
97
145
 
98
- 1. **normalize** (order 0-100): 清理并规范化树。
99
- 2. **compile** (order 0-100): 高级语义转换。
100
- 3. **finalize** (order 0-100): 输出前的最后准备。
146
+ > **注意**: 每个阶段只允许存在一个主插件。如果多个插件被标记为 main,则只有最后定义的那个会作为替换生效。
101
147
 
102
148
  ## 内置核心插件
103
149
 
@@ -108,6 +154,7 @@ const result = await mdast('Hello').to('reverse');
108
154
  | `extract-code-meta` | normalize | 从代码块元数据中解析 `title="foo"`。 |
109
155
  | `image-size` | normalize | 从图片 URL 中解析 `#=WxH`。 |
110
156
  | `normalize-inline-styles` | normalize | 标准化 `==mark==`、`~sub~` 和 `^sup^`。 |
157
+ | `html-readability` | parse | 使用 Mozilla 的 Readability 从 HTML 中提取主体内容。使用 `htmlReadabilityPlugins` 数组可以简化配置。 |
111
158
 
112
159
  ## 贡献
113
160
 
package/README.md CHANGED
@@ -11,7 +11,7 @@ English | [简体中文](./README.cn.md) | [GitHub](https://github.com/isdk/mdas
11
11
  ## Features
12
12
 
13
13
  - **Fluent API**: Chainable interface `mdast(input).use(plugin).toHTML()`.
14
- - **Staged Plugins**: Organize transformations into `normalize`, `compile`, and `finalize` stages with priority ordering.
14
+ - **Staged Plugins**: Organize transformations into `parse`, `normalize`, `compile`, `finalize`, and `stringify` stages.
15
15
  - **Semantic Normalization**:
16
16
  - **Directives**: Canonicalizes admonition names and extracts titles from labels.
17
17
  - **Table Spans**: Support for `rowspan` and `colspan` in HTML output.
@@ -40,6 +40,17 @@ const html = await mdast(':::warning[Special Note]\nBe careful!\n:::')
40
40
  // Result: <div title="Special Note" class="warning"><p>Be careful!</p></div>
41
41
  ```
42
42
 
43
+ ### Configure Input Options
44
+
45
+ You can pass options to input plugins (like `remark-gfm` or `remark-parse`) using the second argument of `.from()`:
46
+
47
+ ```typescript
48
+ // Enable single tilde strikethrough (~text~)
49
+ const md = await mdast('Hello ~world~')
50
+ .from('markdown', { remarkGfm: { singleTilde: true } })
51
+ .toMarkdown();
52
+ ```
53
+
43
54
  ### Image Sizing
44
55
 
45
56
  ```typescript
@@ -50,23 +61,46 @@ const html = await mdast('![Cat](cat.png#=500x300)').toHTML();
50
61
  ### AST Output
51
62
 
52
63
  ```typescript
64
+ // Get the fully processed AST (after normalization)
53
65
  const ast = await mdast('==Highlighted==').toAST();
54
- // Returns the mdast Root object
66
+
67
+ // Get the raw AST (after parsing, before normalization)
68
+ const rawAst = await mdast('==Highlighted==').toAST({ stage: 'parse' });
55
69
  ```
56
70
 
57
71
  ### Advanced Pipeline
58
72
 
59
73
  ```typescript
60
- const { content, assets } = await mdast(myInput)
74
+ import { htmlReadabilityPlugins } from '@isdk/mdast-plus';
75
+
76
+ const vfile = await mdast(myInput)
61
77
  .data({ myGlobal: 'value' })
62
- .use({
63
- name: 'my-plugin',
64
- stage: 'compile',
65
- transform: async (tree) => {
66
- // transform the AST
67
- }
68
- })
78
+ // Add multiple plugins as an array at the 'compile' stage
79
+ .use([pluginA, pluginB])
80
+ // Or add a set of plugins at a specific stage
81
+ .useAt('parse', htmlReadabilityPlugins)
82
+ .priority(10) // Run later than default plugins
69
83
  .to('html');
84
+
85
+ console.log(vfile.value); // The serialized HTML string
86
+ ```
87
+
88
+ ### Plugin Behavior
89
+
90
+ `mdast-plus` uses [unified](https://github.com/unifiedjs/unified) internally. If you add the same plugin function multiple times, the last configuration **overrides** the previous ones.
91
+
92
+ ```typescript
93
+ // The plugin will run ONCE with option: 2
94
+ pipeline.use(myPlugin, { option: 1 });
95
+ pipeline.use(myPlugin, { option: 2 });
96
+ ```
97
+
98
+ To run the same plugin logic multiple times (e.g., for different purposes), provide a distinct function reference:
99
+
100
+ ```typescript
101
+ // The plugin will run TWICE
102
+ pipeline.use(myPlugin, { option: 1 });
103
+ pipeline.use(myPlugin.bind({}), { option: 2 });
70
104
  ```
71
105
 
72
106
  ### Arbitrary Formats
@@ -74,16 +108,20 @@ const { content, assets } = await mdast(myInput)
74
108
  You can register custom input or output formats:
75
109
 
76
110
  ```typescript
77
- import { FluentProcessor, mdast } from '@isdk/mdast-plus';
111
+ import { MdastPipeline, mdast, PipelineStage } from '@isdk/mdast-plus';
78
112
 
79
113
  // Register a custom output format
80
- FluentProcessor.registerFormat('reverse', {
81
- stringify: (p) => {
82
- p.Compiler = (tree) => {
83
- // your custom stringification logic
84
- return '...';
85
- };
86
- }
114
+ MdastPipeline.register({
115
+ id: 'reverse',
116
+ output: [{
117
+ plugin: function() {
118
+ this.Compiler = (tree) => {
119
+ // your custom stringification logic
120
+ return '...';
121
+ };
122
+ },
123
+ stage: PipelineStage.stringify
124
+ }]
87
125
  });
88
126
 
89
127
  const result = await mdast('Hello').to('reverse');
@@ -93,11 +131,19 @@ const result = await mdast('Hello').to('reverse');
93
131
 
94
132
  ## Staged Processing
95
133
 
96
- Plugins are executed based on their `stage` and `order`:
134
+ Plugins are executed based on their `stage`, `order`, and semantic constraints (`before`/`after`):
135
+
136
+ 1. **parse** (0): Input parsing (e.g., `remark-parse`).
137
+ 2. **normalize** (100): Cleanup and canonicalize the tree.
138
+ 3. **compile** (200): High-level semantic transformations.
139
+ 4. **finalize** (300): Final preparation before output (e.g. `rehype-sanitize`).
140
+ 5. **stringify** (400): Output generation.
141
+
142
+ ### Main Plugin Replacement
143
+
144
+ Each stage can have one "main" plugin. If a plugin is marked with `main: true`, it will **replace** the first plugin in that same stage. This is useful for swapping out default parsers or compilers while keeping the rest of the pipeline intact.
97
145
 
98
- 1. **normalize** (order 0-100): Cleanup and canonicalize the tree.
99
- 2. **compile** (order 0-100): High-level semantic transformations.
100
- 3. **finalize** (order 0-100): Final preparation before output.
146
+ > **Note**: Only one main plugin is allowed per stage. If multiple plugins are marked as main, only the last one defined will take effect as the replacement.
101
147
 
102
148
  ## Core Plugins Included
103
149
 
@@ -108,6 +154,7 @@ Plugins are executed based on their `stage` and `order`:
108
154
  | `extract-code-meta` | normalize | Parses `title="foo"` from code block meta. |
109
155
  | `image-size` | normalize | Parses `#=WxH` from image URLs. |
110
156
  | `normalize-inline-styles` | normalize | Standardizes `==mark==`, `~sub~`, and `^sup^`. |
157
+ | `html-readability` | parse | Uses Mozilla's Readability to extract main content from HTML. Use `htmlReadabilityPlugins` array for easier setup. |
111
158
 
112
159
  ## Contributing
113
160