@isdk/mdast-plus 0.1.1 → 0.1.3

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 (38) hide show
  1. package/README.cn.md +62 -19
  2. package/README.md +62 -19
  3. package/dist/index.d.mts +192 -125
  4. package/dist/index.d.ts +192 -125
  5. package/dist/index.js +1 -1
  6. package/dist/index.mjs +1 -1
  7. package/docs/README.md +62 -19
  8. package/docs/_media/CONTRIBUTING.md +39 -18
  9. package/docs/_media/README.cn.md +62 -19
  10. package/docs/classes/MdastBasePipeline.md +348 -0
  11. package/docs/classes/MdastPipeline.md +531 -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 +27 -27
  21. package/docs/interfaces/MdastSub.md +4 -4
  22. package/docs/interfaces/MdastSup.md +4 -4
  23. package/docs/type-aliases/PipelineStageName.md +13 -0
  24. package/docs/variables/DefaultPipelineStage.md +13 -0
  25. package/docs/variables/astFormat.md +15 -0
  26. package/docs/variables/htmlFormat.md +16 -0
  27. package/docs/variables/markdownFormat.md +16 -0
  28. package/package.json +11 -9
  29. package/docs/classes/FluentProcessor.md +0 -194
  30. package/docs/functions/htmlFormat.md +0 -24
  31. package/docs/functions/markdownFormat.md +0 -24
  32. package/docs/interfaces/ConvertResult.md +0 -39
  33. package/docs/interfaces/MdastAsset.md +0 -41
  34. package/docs/interfaces/MdastFormatDefinition.md +0 -51
  35. package/docs/interfaces/MdastReader.md +0 -41
  36. package/docs/interfaces/MdastTransformer.md +0 -33
  37. package/docs/interfaces/MdastWriter.md +0 -47
  38. package/docs/type-aliases/Stage.md +0 -13
package/docs/README.md CHANGED
@@ -15,12 +15,13 @@ English | [简体中文](_media/README.cn.md) | [GitHub](https://github.com/isdk
15
15
  ## Features
16
16
 
17
17
  - **Fluent API**: Chainable interface `mdast(input).use(plugin).toHTML()`.
18
- - **Staged Plugins**: Organize transformations into `normalize`, `compile`, and `finalize` stages with priority ordering.
18
+ - **Staged Plugins**: Organize transformations into `parse`, `normalize`, `compile`, `finalize`, and `stringify` stages.
19
19
  - **Semantic Normalization**:
20
20
  - **Directives**: Canonicalizes admonition names and extracts titles from labels.
21
21
  - **Table Spans**: Support for `rowspan` and `colspan` in HTML output.
22
22
  - **Code Meta**: Structured parsing of code block metadata strings.
23
23
  - **Image Sizing**: URL "sugar" support (e.g., `image.png#=500x300`) for image dimensions.
24
+ - **Inline Styles**: Built-in support for `==Highlight==`, `~Subscript~`, and `^Superscript^`.
24
25
  - **Deeply Typed**: Built on TypeScript with full support for unist/mdast module augmentation.
25
26
 
26
27
  ## Installation
@@ -43,6 +44,17 @@ const html = await mdast(':::warning[Special Note]\nBe careful!\n:::')
43
44
  // Result: <div title="Special Note" class="warning"><p>Be careful!</p></div>
44
45
  ```
45
46
 
47
+ ### Configure Input Options
48
+
49
+ You can pass options to input plugins (like `remark-gfm` or `remark-parse`) using the second argument of `.from()`:
50
+
51
+ ```typescript
52
+ // Enable single tilde strikethrough (~text~)
53
+ const md = await mdast('Hello ~world~')
54
+ .from('markdown', { remarkGfm: { singleTilde: true } })
55
+ .toMarkdown();
56
+ ```
57
+
46
58
  ### Image Sizing
47
59
 
48
60
  ```typescript
@@ -50,36 +62,64 @@ const html = await mdast('![Cat](cat.png#=500x300)').toHTML();
50
62
  // Result: <img src="cat.png" alt="Cat" width="500" height="300">
51
63
  ```
52
64
 
65
+ ### AST Output
66
+
67
+ ```typescript
68
+ // Get the fully processed AST (after normalization)
69
+ const ast = await mdast('==Highlighted==').toAST();
70
+
71
+ // Get the raw AST (after parsing, before normalization)
72
+ const rawAst = await mdast('==Highlighted==').toAST({ stage: 'parse' });
73
+ ```
74
+
53
75
  ### Advanced Pipeline
54
76
 
55
77
  ```typescript
56
78
  const { content, assets } = await mdast(myInput)
57
79
  .data({ myGlobal: 'value' })
58
- .use({
59
- name: 'my-plugin',
60
- stage: 'compile',
61
- transform: async (tree) => {
62
- // transform the AST
63
- }
64
- })
80
+ // Add a custom plugin at the 'compile' stage
81
+ .useAt('compile', myPlugin, { option: 1 })
82
+ .priority(10) // Run later than default plugins
65
83
  .to('html');
66
84
  ```
67
85
 
86
+ ### Plugin Behavior
87
+
88
+ `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.
89
+
90
+ ```typescript
91
+ // The plugin will run ONCE with option: 2
92
+ pipeline.use(myPlugin, { option: 1 });
93
+ pipeline.use(myPlugin, { option: 2 });
94
+ ```
95
+
96
+ To run the same plugin logic multiple times (e.g., for different purposes), provide a distinct function reference:
97
+
98
+ ```typescript
99
+ // The plugin will run TWICE
100
+ pipeline.use(myPlugin, { option: 1 });
101
+ pipeline.use(myPlugin.bind({}), { option: 2 });
102
+ ```
103
+
68
104
  ### Arbitrary Formats
69
105
 
70
106
  You can register custom input or output formats:
71
107
 
72
108
  ```typescript
73
- import { FluentProcessor, mdast } from '@isdk/mdast-plus';
109
+ import { MdastPipeline, mdast, PipelineStage } from '@isdk/mdast-plus';
74
110
 
75
111
  // Register a custom output format
76
- FluentProcessor.registerFormat('reverse', {
77
- stringify: (p) => {
78
- p.Compiler = (tree) => {
79
- // your custom stringification logic
80
- return '...';
81
- };
82
- }
112
+ MdastPipeline.register({
113
+ id: 'reverse',
114
+ output: [{
115
+ plugin: function() {
116
+ this.Compiler = (tree) => {
117
+ // your custom stringification logic
118
+ return '...';
119
+ };
120
+ },
121
+ stage: PipelineStage.stringify
122
+ }]
83
123
  });
84
124
 
85
125
  const result = await mdast('Hello').to('reverse');
@@ -91,9 +131,11 @@ const result = await mdast('Hello').to('reverse');
91
131
 
92
132
  Plugins are executed based on their `stage` and `order`:
93
133
 
94
- 1. **normalize** (order 0-100): Cleanup and canonicalize the tree.
95
- 2. **compile** (order 0-100): High-level semantic transformations.
96
- 3. **finalize** (order 0-100): Final preparation before output.
134
+ 1. **parse** (0): Input parsing (e.g., `remark-parse`).
135
+ 2. **normalize** (100): Cleanup and canonicalize the tree.
136
+ 3. **compile** (200): High-level semantic transformations.
137
+ 4. **finalize** (300): Final preparation before output (e.g. `rehype-sanitize`).
138
+ 5. **stringify** (400): Output generation.
97
139
 
98
140
  ## Core Plugins Included
99
141
 
@@ -103,6 +145,7 @@ Plugins are executed based on their `stage` and `order`:
103
145
  | `normalize-table-span` | normalize | Migrates table cell spans to `hProperties`. |
104
146
  | `extract-code-meta` | normalize | Parses `title="foo"` from code block meta. |
105
147
  | `image-size` | normalize | Parses `#=WxH` from image URLs. |
148
+ | `normalize-inline-styles` | normalize | Standardizes `==mark==`, `~sub~`, and `^sup^`. |
106
149
 
107
150
  ## Contributing
108
151
 
@@ -8,11 +8,13 @@ Thank you for your interest in contributing to `@isdk/mdast-plus`! This document
8
8
 
9
9
  ### Core Concepts
10
10
 
11
- 1. **Fluent API**: The main entry point is the `mdast()` function in `src/pipeline.ts`.
12
- 2. **Staged Plugins**: Plugins are categorized into three stages:
11
+ 1. **Fluent API**: The main entry point is the `mdast()` function in `src/pipeline.ts`, backed by `MdastPipeline`.
12
+ 2. **Staged Plugins**: Plugins are categorized into 5 stages (`PipelineStage`):
13
+ * `parse`: Parsing input to AST.
13
14
  * `normalize`: Cleanup and canonicalize the tree.
14
15
  * `compile`: High-level semantic transformations.
15
16
  * `finalize`: Final preparation before output.
17
+ * `stringify`: Serializing AST to output.
16
18
  3. **Universal Data Protocols**: Nodes use `node.data` for metadata, and `node.data.hProperties` for HTML attributes.
17
19
 
18
20
  ## Getting Started
@@ -55,39 +57,58 @@ pnpm run lint
55
57
  ## Adding a New Plugin
56
58
 
57
59
  1. Create your plugin in `src/plugins/`.
58
- 2. Implement the `MdastPlugin` interface:
60
+ 2. Implement the `MdastPlugin` interface. The `plugin` property should be a standard unified plugin.
59
61
 
60
62
  ```typescript
61
- import { MdastPlugin } from '../types';
63
+ import { MdastPlugin, PipelineStage } from '../types';
64
+ import { visit } from 'unist-util-visit';
65
+
66
+ const myUnifiedPlugin = (options) => {
67
+ return (tree) => {
68
+ visit(tree, 'text', (node) => {
69
+ // transform logic
70
+ });
71
+ };
72
+ };
62
73
 
63
74
  export const myPlugin: MdastPlugin = {
64
- name: 'my-plugin',
65
- stage: 'normalize', // 'normalize' | 'compile' | 'finalize'
75
+ plugin: myUnifiedPlugin,
76
+ stage: PipelineStage.normalize, // or 'compile', 'finalize'
66
77
  order: 50, // 0-100
67
- transform: async (tree, processor) => {
68
- // Visit nodes and transform the tree
69
- }
70
78
  };
71
79
  ```
72
80
 
73
- 3. Register your plugin in `src/pipeline.ts` in the `FluentProcessor` constructor if it should be a default plugin.
81
+ 3. If it's a default plugin, add it to the `input` or `output` list of the relevant format in `src/formats/`.
74
82
 
75
83
  ## Adding a New Format
76
84
 
77
- 1. Implement the `MdastFormatDefinition` interface.
78
- 2. Register it using `FluentProcessor.registerFormat(name, definition)`.
85
+ 1. Define a `MdastFormat` object.
86
+ 2. Register it using `MdastPipeline.register(format)`.
79
87
 
80
88
  ```typescript
81
- import { FluentProcessor } from '../pipeline';
82
-
83
- FluentProcessor.registerFormat('json', {
84
- stringify: (processor) => {
85
- processor.Compiler = (tree) => JSON.stringify(tree);
86
- }
89
+ import { MdastPipeline, PipelineStage } from '../src/pipeline';
90
+
91
+ MdastPipeline.register({
92
+ id: 'json',
93
+ title: 'JSON Format',
94
+ output: [{
95
+ plugin: function() {
96
+ this.Compiler = (tree) => JSON.stringify(tree);
97
+ },
98
+ stage: PipelineStage.stringify
99
+ }]
87
100
  });
88
101
  ```
89
102
 
90
103
  > **Note**: Format names are case-insensitive.
104
+ >
105
+ > **Important**: `unified` requires a `Compiler` to be attached for the process to complete successfully. If your format is intended to return an object (like the AST itself) rather than a string, you must provide a "pass-through" compiler:
106
+ >
107
+ > ```typescript
108
+ > function astCompiler() {
109
+ > this.Compiler = (tree) => tree;
110
+ > }
111
+ > ```
91
112
 
92
113
  ## Coding Standards
93
114
 
@@ -11,12 +11,13 @@
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`。
18
18
  - **代码元数据**: 对代码块元数据字符串进行结构化解析。
19
19
  - **图片尺寸**: 支持 URL 糖语法 (例如 `image.png#=500x300`) 来设置图片尺寸。
20
+ - **行内样式**: 内置对 `==高亮==`、`~下标~` 和 `^上标^` 的支持。
20
21
  - **深度类型支持**: 基于 TypeScript 构建,完整支持 unist/mdast 的模块扩充。
21
22
 
22
23
  ## 安装
@@ -39,6 +40,17 @@ const html = await mdast(':::warning[重要提示]\n请小心!\n:::')
39
40
  // 结果: <div title="重要提示" class="warning"><p>请小心!</p></div>
40
41
  ```
41
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
+
42
54
  ### 图片尺寸
43
55
 
44
56
  ```typescript
@@ -46,36 +58,64 @@ const html = await mdast('![Cat](cat.png#=500x300)').toHTML();
46
58
  // 结果: <img src="cat.png" alt="Cat" width="500" height="300">
47
59
  ```
48
60
 
61
+ ### AST 输出
62
+
63
+ ```typescript
64
+ // 获取处理后的完整 AST (在 normalization 之后)
65
+ const ast = await mdast('==高亮内容==').toAST();
66
+
67
+ // 获取原始 AST (在 parse 之后, normalization 之前)
68
+ const rawAst = await mdast('==高亮内容==').toAST({ stage: 'parse' });
69
+ ```
70
+
49
71
  ### 高级工作流
50
72
 
51
73
  ```typescript
52
74
  const { content, assets } = await mdast(myInput)
53
75
  .data({ myGlobal: 'value' })
54
- .use({
55
- name: 'my-plugin',
56
- stage: 'compile',
57
- transform: async (tree) => {
58
- // 转换 AST
59
- }
60
- })
76
+ // 在 'compile' 阶段添加自定义插件
77
+ .useAt('compile', myPlugin, { option: 1 })
78
+ .priority(10) // 比默认插件更晚执行
61
79
  .to('html');
62
80
  ```
63
81
 
82
+ ### 插件行为
83
+
84
+ `mdast-plus` 内部使用 [unified](https://github.com/unifiedjs/unified)。如果您多次添加同一个插件函数,最后的配置将**覆盖**之前的配置。
85
+
86
+ ```typescript
87
+ // 插件将只执行一次,且选项为: 2
88
+ pipeline.use(myPlugin, { option: 1 });
89
+ pipeline.use(myPlugin, { option: 2 });
90
+ ```
91
+
92
+ 若要多次运行相同的插件逻辑(例如用于不同目的),请提供不同的函数引用:
93
+
94
+ ```typescript
95
+ // 插件将执行两次
96
+ pipeline.use(myPlugin, { option: 1 });
97
+ pipeline.use(myPlugin.bind({}), { option: 2 });
98
+ ```
99
+
64
100
  ### 任意格式支持
65
101
 
66
102
  您可以注册自定义的输入或输出格式:
67
103
 
68
104
  ```typescript
69
- import { FluentProcessor, mdast } from '@isdk/mdast-plus';
105
+ import { MdastPipeline, mdast, PipelineStage } from '@isdk/mdast-plus';
70
106
 
71
107
  // 注册自定义输出格式
72
- FluentProcessor.registerFormat('reverse', {
73
- stringify: (p) => {
74
- p.Compiler = (tree) => {
75
- // 您的自定义序列化逻辑
76
- return '...';
77
- };
78
- }
108
+ MdastPipeline.register({
109
+ id: 'reverse',
110
+ output: [{
111
+ plugin: function() {
112
+ this.Compiler = (tree) => {
113
+ // 您的自定义序列化逻辑
114
+ return '...';
115
+ };
116
+ },
117
+ stage: PipelineStage.stringify
118
+ }]
79
119
  });
80
120
 
81
121
  const result = await mdast('Hello').to('reverse');
@@ -87,9 +127,11 @@ const result = await mdast('Hello').to('reverse');
87
127
 
88
128
  插件根据它们的 `stage` (阶段) 和 `order` (顺序) 执行:
89
129
 
90
- 1. **normalize** (order 0-100): 清理并规范化树。
91
- 2. **compile** (order 0-100): 高级语义转换。
92
- 3. **finalize** (order 0-100): 输出前的最后准备。
130
+ 1. **parse** (0): 输入解析 (例如 `remark-parse`)。
131
+ 2. **normalize** (100): 清理并规范化树。
132
+ 3. **compile** (200): 高级语义转换。
133
+ 4. **finalize** (300): 输出前的最后准备 (例如 `rehype-sanitize`)。
134
+ 5. **stringify** (400): 输出生成。
93
135
 
94
136
  ## 内置核心插件
95
137
 
@@ -99,6 +141,7 @@ const result = await mdast('Hello').to('reverse');
99
141
  | `normalize-table-span` | normalize | 将表格单元格跨度迁移到 `hProperties`。 |
100
142
  | `extract-code-meta` | normalize | 从代码块元数据中解析 `title="foo"`。 |
101
143
  | `image-size` | normalize | 从图片 URL 中解析 `#=WxH`。 |
144
+ | `normalize-inline-styles` | normalize | 标准化 `==mark==`、`~sub~` 和 `^sup^`。 |
102
145
 
103
146
  ## 贡献
104
147