stream-markdown-parser 0.0.41 → 0.0.43
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 +17 -13
- package/README.zh-CN.md +17 -13
- package/dist/index.js +16 -27
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
[](README.zh-CN.md)
|
|
5
5
|
[](https://www.npmjs.com/package/stream-markdown-parser)
|
|
6
6
|
[](https://bundlephobia.com/package/stream-markdown-parser)
|
|
7
|
-
[](
|
|
7
|
+
[](https://github.com/Simon-He95/markstream-vue/blob/main/license)
|
|
8
8
|
|
|
9
9
|
Pure markdown parser and renderer utilities with streaming support - framework agnostic.
|
|
10
10
|
|
|
11
|
-
This package contains the core markdown parsing logic extracted from `
|
|
11
|
+
This package contains the core markdown parsing logic extracted from `markstream-vue`, making it usable in any JavaScript/TypeScript project without Vue dependencies.
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
@@ -42,7 +42,7 @@ yarn add stream-markdown-parser
|
|
|
42
42
|
|
|
43
43
|
## Quick API (TL;DR)
|
|
44
44
|
|
|
45
|
-
- `getMarkdown(options)` — create a `markdown-it-ts` instance with built-in plugins (task lists, sub/sup, math helpers, etc.). Also accepts `plugin`, `apply`, and `i18n` options.
|
|
45
|
+
- `getMarkdown(msgId?, options?)` — create a `markdown-it-ts` instance with built-in plugins (task lists, sub/sup, math helpers, etc.). Also accepts `plugin`, `apply`, and `i18n` options.
|
|
46
46
|
- `registerMarkdownPlugin(plugin)` / `clearRegisteredMarkdownPlugins()` — add or remove global plugins that run for every `getMarkdown()` call (useful for feature flags or tests).
|
|
47
47
|
- `parseMarkdownToStructure(markdown, md, parseOptions)` — convert Markdown into the streaming-friendly AST consumed by `markstream-vue` and other renderers.
|
|
48
48
|
- `processTokens(tokens)` / `parseInlineTokens(children, content)` — low-level helpers if you want to bypass the built-in AST pipeline.
|
|
@@ -59,7 +59,7 @@ parseMarkdownToStructure() → AST (ParsedNode[])
|
|
|
59
59
|
↓ feed into your renderer (markstream-vue, custom UI, workers)
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
Reuse the same `md` instance when parsing multiple documents—plugin setup is the heaviest step. When integrating with [`markstream-vue`](
|
|
62
|
+
Reuse the same `md` instance when parsing multiple documents—plugin setup is the heaviest step. When integrating with [`markstream-vue`](https://www.npmjs.com/package/markstream-vue), pass the AST to `<MarkdownRender :nodes="nodes" />` or supply raw `content` and hand it the same parser options.
|
|
63
63
|
|
|
64
64
|
### Incremental / streaming example
|
|
65
65
|
|
|
@@ -78,7 +78,7 @@ async function handleChunk(chunk: string) {
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
In the UI layer, render `nodes` with `<MarkdownRender :nodes="nodes" />` to avoid re-parsing. See the [docs usage guide](
|
|
81
|
+
In the UI layer, render `nodes` with `<MarkdownRender :nodes="nodes" />` to avoid re-parsing. See the [docs usage guide](https://markstream-vue-docs.simonhe.me/guide/usage) for end-to-end wiring.
|
|
82
82
|
|
|
83
83
|
### Basic example
|
|
84
84
|
|
|
@@ -301,7 +301,7 @@ Find the matching closing delimiter in a string, handling nested pairs.
|
|
|
301
301
|
- **Reuse parser instances**: cache `getMarkdown()` results per worker/request to avoid re-registering plugins.
|
|
302
302
|
- **Server-side parsing**: run `parseMarkdownToStructure` on the server, ship the AST to the client, and hydrate with `markstream-vue` for deterministic output.
|
|
303
303
|
- **Custom HTML widgets**: pre-extract `<MyWidget>` blocks before parsing (replace with placeholders) and reinject them during rendering instead of mutating `html_block` nodes post-parse.
|
|
304
|
-
- **Styling**: when piping nodes into `markstream-vue`, follow the docs [CSS checklist](
|
|
304
|
+
- **Styling**: when piping nodes into `markstream-vue`, follow the docs [CSS checklist](https://markstream-vue-docs.simonhe.me/guide/troubleshooting#css-looks-wrong-start-here) so Tailwind/UnoCSS don’t override library styles.
|
|
305
305
|
- **Error handling**: the `apply` hook swallows exceptions to maintain backwards compatibility. If you want strict mode, wrap your mutators before passing them in and rethrow/log as needed.
|
|
306
306
|
|
|
307
307
|
#### `parseFenceToken(token)`
|
|
@@ -424,7 +424,7 @@ This package comes with the following markdown-it plugins pre-configured:
|
|
|
424
424
|
While this package is framework-agnostic, it's designed to work seamlessly with:
|
|
425
425
|
|
|
426
426
|
- ✅ **Node.js** - Server-side rendering
|
|
427
|
-
- ✅ **Vue 3** - Use with `
|
|
427
|
+
- ✅ **Vue 3** - Use with `markstream-vue` (or your own renderer)
|
|
428
428
|
- ✅ **React** - Use parsed nodes for custom rendering
|
|
429
429
|
- ✅ **Vanilla JS** - Direct HTML rendering
|
|
430
430
|
- ✅ **Any framework** - Parse to AST and render as needed
|
|
@@ -464,26 +464,30 @@ worker.addEventListener('message', (event) => {
|
|
|
464
464
|
|
|
465
465
|
This pattern keeps Markdown-it work off the main thread and lets you reuse the same AST in any framework.
|
|
466
466
|
|
|
467
|
-
## Migration from `
|
|
467
|
+
## Migration from `markstream-vue` (parser exports)
|
|
468
468
|
|
|
469
|
-
If you're
|
|
469
|
+
If you're currently importing parser helpers from `markstream-vue`, you can switch to the dedicated package:
|
|
470
470
|
|
|
471
471
|
```typescript
|
|
472
|
+
// before
|
|
473
|
+
import { getMarkdown } from 'markstream-vue'
|
|
474
|
+
|
|
475
|
+
// after
|
|
472
476
|
import { getMarkdown } from 'stream-markdown-parser'
|
|
473
477
|
```
|
|
474
478
|
|
|
475
|
-
All APIs remain the same. See [migration guide](
|
|
479
|
+
All APIs remain the same. See the [migration guide](https://markstream-vue-docs.simonhe.me/monorepo-migration) for details.
|
|
476
480
|
|
|
477
481
|
## Performance
|
|
478
482
|
|
|
479
483
|
- **Lightweight**: ~65KB minified (13KB gzipped)
|
|
480
484
|
- **Fast**: Optimized for real-time parsing
|
|
481
485
|
- **Tree-shakeable**: Only import what you need
|
|
482
|
-
- **
|
|
486
|
+
- **Few dependencies**: `markdown-it-ts` + a small set of markdown-it plugins
|
|
483
487
|
|
|
484
488
|
## Contributing
|
|
485
489
|
|
|
486
|
-
Issues and PRs welcome! Please read the [contribution guidelines](
|
|
490
|
+
Issues and PRs welcome! Please read the [contribution guidelines](https://github.com/Simon-He95/markstream-vue/blob/main/CONTRIBUTING.md).
|
|
487
491
|
|
|
488
492
|
## License
|
|
489
493
|
|
|
@@ -491,4 +495,4 @@ MIT © Simon He
|
|
|
491
495
|
|
|
492
496
|
## Related
|
|
493
497
|
|
|
494
|
-
- [
|
|
498
|
+
- [markstream-vue](https://www.npmjs.com/package/markstream-vue) - Full-featured Vue 3 Markdown renderer
|
package/README.zh-CN.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
[](README.md)
|
|
5
5
|
[](https://www.npmjs.com/package/stream-markdown-parser)
|
|
6
6
|
[](https://bundlephobia.com/package/stream-markdown-parser)
|
|
7
|
-
[](
|
|
7
|
+
[](https://github.com/Simon-He95/markstream-vue/blob/main/license)
|
|
8
8
|
|
|
9
9
|
纯 JavaScript Markdown 解析器和渲染工具,支持流式处理 - 框架无关。
|
|
10
10
|
|
|
11
|
-
该包包含从 `
|
|
11
|
+
该包包含从 `markstream-vue` 中提取的核心 Markdown 解析逻辑,使其可以在任何 JavaScript/TypeScript 项目中使用,无需 Vue 依赖。
|
|
12
12
|
|
|
13
13
|
## 特性
|
|
14
14
|
|
|
@@ -42,7 +42,7 @@ yarn add stream-markdown-parser
|
|
|
42
42
|
|
|
43
43
|
## 快速 API 速览
|
|
44
44
|
|
|
45
|
-
- `getMarkdown(options)` — 返回一个预配置的 `markdown-it-ts` 实例;支持 `plugin`、`apply`、`i18n` 等选项(内置任务列表、上下标、数学等插件)。
|
|
45
|
+
- `getMarkdown(msgId?, options?)` — 返回一个预配置的 `markdown-it-ts` 实例;支持 `plugin`、`apply`、`i18n` 等选项(内置任务列表、上下标、数学等插件)。
|
|
46
46
|
- `registerMarkdownPlugin(plugin)` / `clearRegisteredMarkdownPlugins()` — 全局注册/清除插件,在所有 `getMarkdown()` 调用中生效(适合特性开关或测试环境)。
|
|
47
47
|
- `parseMarkdownToStructure(markdown, md, parseOptions)` — 将 Markdown 转换为可供 `markstream-vue` 等渲染器使用的 AST。
|
|
48
48
|
- `processTokens(tokens)` / `parseInlineTokens(children, content)` — 更底层的 token → 节点工具,方便自定义管线。
|
|
@@ -59,7 +59,7 @@ parseMarkdownToStructure() → AST (ParsedNode[])
|
|
|
59
59
|
↓ 交给你的渲染器(markstream-vue、自定义 UI、Worker 等)
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
-
多次解析时复用同一个 `md` 实例可以避免重复注册插件。与 [`markstream-vue`](
|
|
62
|
+
多次解析时复用同一个 `md` 实例可以避免重复注册插件。与 [`markstream-vue`](https://www.npmjs.com/package/markstream-vue) 一起使用时,你可以把 AST 传给 `<MarkdownRender :nodes="nodes" />`,或仅传入原始 `content` 并共享同一套解析配置。
|
|
63
63
|
|
|
64
64
|
### 增量 / 流式示例
|
|
65
65
|
|
|
@@ -78,7 +78,7 @@ async function handleChunk(chunk: string) {
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
在前端通过 `<MarkdownRender :nodes="nodes" />` 渲染即可避免重复解析。具体串联示例见[文档用法指南](
|
|
81
|
+
在前端通过 `<MarkdownRender :nodes="nodes" />` 渲染即可避免重复解析。具体串联示例见[文档用法指南](https://markstream-vue-docs.simonhe.me/zh/guide/usage)。
|
|
82
82
|
|
|
83
83
|
### 基础示例
|
|
84
84
|
|
|
@@ -300,7 +300,7 @@ const parseOptions = {
|
|
|
300
300
|
- **复用解析实例**:缓存 `getMarkdown()` 的结果,避免重复注册插件。
|
|
301
301
|
- **服务端解析**:在服务端运行 `parseMarkdownToStructure` 后把 AST 下发给客户端,配合 `markstream-vue` 实现确定性输出。
|
|
302
302
|
- **自定义 HTML 组件**:在解析前先把 `<MyWidget>` 这类片段替换为占位符,渲染时再注入,避免在 `html_block` 上进行脆弱的字符串操作。
|
|
303
|
-
- **样式提示**:如果将节点交给 `markstream-vue`,务必按照文档的 [CSS 排查清单](
|
|
303
|
+
- **样式提示**:如果将节点交给 `markstream-vue`,务必按照文档的 [CSS 排查清单](https://markstream-vue-docs.simonhe.me/zh/guide/troubleshooting#css-looks-wrong-start-here) 调整 reset / layer,防止 Tailwind/UnoCSS 覆盖样式。
|
|
304
304
|
- **错误处理**:`apply` 钩子内部默认捕获异常后打印日志,如需在 CI/生产中抛出错误,可在传入前自行封装并 rethrow。
|
|
305
305
|
|
|
306
306
|
#### `parseFenceToken(token)`
|
|
@@ -423,31 +423,35 @@ import type {
|
|
|
423
423
|
虽然该包与框架无关,但它被设计为可以无缝配合以下框架使用:
|
|
424
424
|
|
|
425
425
|
- ✅ **Node.js** - 服务器端渲染
|
|
426
|
-
- ✅ **Vue 3** - 配合 `
|
|
426
|
+
- ✅ **Vue 3** - 配合 `markstream-vue`(或你的自定义渲染层)使用
|
|
427
427
|
- ✅ **React** - 使用解析的节点进行自定义渲染
|
|
428
428
|
- ✅ **Vanilla JS** - 直接 HTML 渲染
|
|
429
429
|
- ✅ **任何框架** - 解析为 AST 并按需渲染
|
|
430
430
|
|
|
431
|
-
## 从 `
|
|
431
|
+
## 从 `markstream-vue` 迁移(解析器导出)
|
|
432
432
|
|
|
433
|
-
|
|
433
|
+
如果你当前是从 `markstream-vue` 引入解析器相关 helper,可以切换为使用独立包:
|
|
434
434
|
|
|
435
435
|
```typescript
|
|
436
|
+
// 之前
|
|
437
|
+
import { getMarkdown } from 'markstream-vue'
|
|
438
|
+
|
|
439
|
+
// 现在
|
|
436
440
|
import { getMarkdown } from 'stream-markdown-parser'
|
|
437
441
|
```
|
|
438
442
|
|
|
439
|
-
所有 API 保持不变。详见[迁移指南](
|
|
443
|
+
所有 API 保持不变。详见[迁移指南](https://markstream-vue-docs.simonhe.me/zh/monorepo-migration)。
|
|
440
444
|
|
|
441
445
|
## 性能
|
|
442
446
|
|
|
443
447
|
- **轻量级**: ~65KB 压缩后(13KB gzipped)
|
|
444
448
|
- **快速**: 针对实时解析优化
|
|
445
449
|
- **Tree-shakeable**: 只导入你需要的部分
|
|
446
|
-
-
|
|
450
|
+
- **依赖很少**: `markdown-it-ts` + 少量 markdown-it 插件
|
|
447
451
|
|
|
448
452
|
## 贡献
|
|
449
453
|
|
|
450
|
-
欢迎提交 Issues 和 PRs!请阅读[贡献指南](
|
|
454
|
+
欢迎提交 Issues 和 PRs!请阅读[贡献指南](https://github.com/Simon-He95/markstream-vue/blob/main/CONTRIBUTING.md)。
|
|
451
455
|
|
|
452
456
|
## 许可证
|
|
453
457
|
|
|
@@ -455,4 +459,4 @@ MIT © Simon He
|
|
|
455
459
|
|
|
456
460
|
## 相关项目
|
|
457
461
|
|
|
458
|
-
- [
|
|
462
|
+
- [markstream-vue](https://www.npmjs.com/package/markstream-vue) - 功能完整的 Vue 3 Markdown 渲染器
|
package/dist/index.js
CHANGED
|
@@ -601,7 +601,7 @@ var require_markdown_it_task_checkbox = /* @__PURE__ */ __commonJS({ "../../node
|
|
|
601
601
|
}) });
|
|
602
602
|
|
|
603
603
|
//#endregion
|
|
604
|
-
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.
|
|
604
|
+
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.3/node_modules/markdown-it-ts/dist/chunk-Bp6m_JJh.js
|
|
605
605
|
var import_markdown_it_task_checkbox = /* @__PURE__ */ __toESM(require_markdown_it_task_checkbox(), 1);
|
|
606
606
|
var __defProp = Object.defineProperty;
|
|
607
607
|
var __export = (all) => {
|
|
@@ -2187,7 +2187,7 @@ var require_punycode = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/pu
|
|
|
2187
2187
|
}) });
|
|
2188
2188
|
|
|
2189
2189
|
//#endregion
|
|
2190
|
-
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.
|
|
2190
|
+
//#region ../../node_modules/.pnpm/markdown-it-ts@0.0.3/node_modules/markdown-it-ts/dist/index.js
|
|
2191
2191
|
var import_punycode = /* @__PURE__ */ __toESM(require_punycode(), 1);
|
|
2192
2192
|
var utils_exports = /* @__PURE__ */ __export({
|
|
2193
2193
|
arrayReplaceAt: () => arrayReplaceAt,
|
|
@@ -5302,35 +5302,20 @@ var StateInline = class {
|
|
|
5302
5302
|
const { src, posMax } = this;
|
|
5303
5303
|
const marker = src.charCodeAt(start);
|
|
5304
5304
|
let pos = start;
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
count++;
|
|
5308
|
-
pos++;
|
|
5309
|
-
}
|
|
5305
|
+
while (pos < posMax && src.charCodeAt(pos) === marker) pos++;
|
|
5306
|
+
const count = pos - start;
|
|
5310
5307
|
if (count < 1) return null;
|
|
5311
5308
|
const lastChar = start > 0 ? src.charCodeAt(start - 1) : 32;
|
|
5312
5309
|
const nextChar = pos < posMax ? src.charCodeAt(pos) : 32;
|
|
5313
|
-
const isLastPunctChar = lastChar
|
|
5314
|
-
const isNextPunctChar = nextChar
|
|
5315
|
-
const isLastWhiteSpace = lastChar
|
|
5316
|
-
const isNextWhiteSpace = nextChar
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
if (isNextWhiteSpace) can_open = false;
|
|
5320
|
-
else if (isNextPunctChar) {
|
|
5321
|
-
if (!(isLastWhiteSpace || isLastPunctChar)) can_open = false;
|
|
5322
|
-
}
|
|
5323
|
-
if (isLastWhiteSpace) can_close = false;
|
|
5324
|
-
else if (isLastPunctChar) {
|
|
5325
|
-
if (!(isNextWhiteSpace || isNextPunctChar)) can_close = false;
|
|
5326
|
-
}
|
|
5327
|
-
if (!canSplitWord) {
|
|
5328
|
-
can_open = can_open && (!isLastPunctChar || isLastWhiteSpace);
|
|
5329
|
-
can_close = can_close && (!isNextPunctChar || isNextWhiteSpace);
|
|
5330
|
-
}
|
|
5310
|
+
const isLastPunctChar = isMdAsciiPunct(lastChar) || isPunctChar(String.fromCharCode(lastChar));
|
|
5311
|
+
const isNextPunctChar = isMdAsciiPunct(nextChar) || isPunctChar(String.fromCharCode(nextChar));
|
|
5312
|
+
const isLastWhiteSpace = isWhiteSpace(lastChar);
|
|
5313
|
+
const isNextWhiteSpace = isWhiteSpace(nextChar);
|
|
5314
|
+
const left_flanking = !isNextWhiteSpace && (!isNextPunctChar || isLastWhiteSpace || isLastPunctChar);
|
|
5315
|
+
const right_flanking = !isLastWhiteSpace && (!isLastPunctChar || isNextWhiteSpace || isNextPunctChar);
|
|
5331
5316
|
return {
|
|
5332
|
-
can_open,
|
|
5333
|
-
can_close,
|
|
5317
|
+
can_open: left_flanking && (canSplitWord || !right_flanking || isLastPunctChar),
|
|
5318
|
+
can_close: right_flanking && (canSplitWord || !left_flanking || isNextPunctChar),
|
|
5334
5319
|
length: count
|
|
5335
5320
|
};
|
|
5336
5321
|
}
|
|
@@ -9638,6 +9623,10 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
|
|
|
9638
9623
|
case "reference":
|
|
9639
9624
|
handleReference(token);
|
|
9640
9625
|
break;
|
|
9626
|
+
case "text_special":
|
|
9627
|
+
pushText(String(token.content ?? ""), String(token.content ?? ""));
|
|
9628
|
+
i++;
|
|
9629
|
+
break;
|
|
9641
9630
|
default:
|
|
9642
9631
|
pushToken(token);
|
|
9643
9632
|
i++;
|