npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

stream-markdown-parser

v0.0.41

Published

Pure markdown parser and renderer utilities with streaming support - framework agnostic

Readme

stream-markdown-parser

NPM version English Docs NPM downloads Bundle size License

纯 JavaScript Markdown 解析器和渲染工具,支持流式处理 - 框架无关。

该包包含从 stream-markdown-parser 中提取的核心 Markdown 解析逻辑,使其可以在任何 JavaScript/TypeScript 项目中使用,无需 Vue 依赖。

特性

  • 🚀 纯 JavaScript - 无框架依赖
  • 📦 轻量级 - 最小打包体积
  • 🔧 可扩展 - 基于插件的架构
  • 🎯 类型安全 - 完整的 TypeScript 支持
  • 高性能 - 性能优化
  • 🌊 流式友好 - 支持渐进式解析

ℹ️ 自当前版本起我们基于 markdown-it-ts(一个 TypeScript 优先的 markdown-it 发行版)进行构建。API 与 markdown-it 保持一致,但内部仅依赖其解析流程,并提供更丰富的 token 类型定义。

文档

完整的使用说明与集成教程见 markstream-vue 文档站:

  • English: https://markstream-vue-docs.simonhe.me/guide/api
  • 中文: https://markstream-vue-docs.simonhe.me/zh/guide/api

本 README 聚焦解析器 API;如需 VitePress/Vite/Nuxt 集成、Worker 流式解析、Tailwind/UnoCSS 配置等指南,请查阅上述文档。

安装

pnpm add stream-markdown-parser
# 或
npm install stream-markdown-parser
# 或
yarn add stream-markdown-parser

快速 API 速览

  • getMarkdown(options) — 返回一个预配置的 markdown-it-ts 实例;支持 pluginapplyi18n 等选项(内置任务列表、上下标、数学等插件)。
  • registerMarkdownPlugin(plugin) / clearRegisteredMarkdownPlugins() — 全局注册/清除插件,在所有 getMarkdown() 调用中生效(适合特性开关或测试环境)。
  • parseMarkdownToStructure(markdown, md, parseOptions) — 将 Markdown 转换为可供 markstream-vue 等渲染器使用的 AST。
  • processTokens(tokens) / parseInlineTokens(children, content) — 更底层的 token → 节点工具,方便自定义管线。
  • applyMathapplyContainersnormalizeStandaloneBackslashTfindMatchingClose 等 — 用于构建自定义解析、lint 或内容清洗流程。

使用

流式解析流程

Markdown 字符串
   ↓ getMarkdown() → 带插件的 markdown-it-ts 实例
parseMarkdownToStructure() → AST (ParsedNode[])
   ↓ 交给你的渲染器(markstream-vue、自定义 UI、Worker 等)

多次解析时复用同一个 md 实例可以避免重复注册插件。与 markstream-vue 一起使用时,你可以把 AST 传给 <MarkdownRender :nodes="nodes" />,或仅传入原始 content 并共享同一套解析配置。

增量 / 流式示例

处理 AI/SSE 流时,可以复用同一个 md 实例不停地对累积缓冲区解析,并把 AST 推送给 UI(例如 markstream-vue):

import { getMarkdown, parseMarkdownToStructure } from 'stream-markdown-parser'

const md = getMarkdown()
let buffer = ''

async function handleChunk(chunk: string) {
  buffer += chunk
  const nodes = parseMarkdownToStructure(buffer, md)
  postMessage({ type: 'markdown:update', nodes })
}

在前端通过 <MarkdownRender :nodes="nodes" /> 渲染即可避免重复解析。具体串联示例见文档用法指南

基础示例

import { getMarkdown, parseMarkdownToStructure } from 'stream-markdown-parser'

// 创建一个带有默认插件的 markdown-it-ts 实例
const md = getMarkdown()

// 将 Markdown 解析为流式友好的 AST 结构
const nodes = parseMarkdownToStructure('# Hello World', md)
console.log(nodes)
// [{ type: 'heading', level: 1, children: [...] }]

// 如果仍需 HTML 输出,markdown-it-ts 依旧提供 render()
const html = md.render?.('# Hello World\n\nThis is **bold**.')

配置数学公式选项

import { getMarkdown, setDefaultMathOptions } from 'stream-markdown-parser'

// 设置全局数学公式选项
setDefaultMathOptions({
  commands: ['infty', 'perp', 'alpha'],
  escapeExclamation: true
})

const md = getMarkdown()

自定义国际化

import { getMarkdown } from 'stream-markdown-parser'

// 使用翻译映射
const md = getMarkdown('editor-1', {
  i18n: {
    'common.copy': '复制',
  }
})

// 或使用翻译函数
const md = getMarkdown('editor-1', {
  i18n: (key: string) => translateFunction(key)
})

使用插件

import customPlugin from 'markdown-it-custom-plugin'
import { getMarkdown } from 'stream-markdown-parser'

const md = getMarkdown('editor-1', {
  plugin: [
    [customPlugin, { /* 选项 */ }]
  ]
})

高级:自定义规则

import { getMarkdown } from 'stream-markdown-parser'

const md = getMarkdown('editor-1', {
  apply: [
    (md) => {
      // 添加自定义内联规则
      md.inline.ruler.before('emphasis', 'custom', (state, silent) => {
        // 你的自定义逻辑
        return false
      })
    }
  ]
})

全局扩展

想在所有 getMarkdown() 实例上启用同一个插件,而无需修改调用点?可使用内置 helper:

import {
  clearRegisteredMarkdownPlugins,
  registerMarkdownPlugin,
} from 'stream-markdown-parser'

registerMarkdownPlugin(myPlugin)

const md = getMarkdown()
// 现在 md 会自动包含 myPlugin

// 测试或清理阶段:
clearRegisteredMarkdownPlugins()
  • plugin 选项 → 针对单次 getMarkdown 调用传入 md.use(...)
  • apply 选项 → 直接操作实例(如 md.inline.ruler.before(...))。如果需要严格模式,可自行包裹 try/catch;默认会打印错误保持兼容。
  • registerMarkdownPlugin → 全局注册表,适用于 SSR / Worker 等场景统一开启功能。

API

主要函数

getMarkdown(msgId?, options?)

创建一个配置好的 markdown-it-ts 实例(与 markdown-it API 兼容)。

参数:

  • msgId (string, 可选): 该实例的唯一标识符。默认值:editor-${Date.now()}
  • options (GetMarkdownOptions, 可选): 配置选项

选项:

interface GetMarkdownOptions {
  // 要使用的 markdown-it / markdown-it-ts 插件数组
  plugin?: Array<Plugin | [Plugin, any]>

  // 修改 md 实例的函数数组
  apply?: Array<(md: MarkdownIt) => void>

  // 翻译函数或翻译映射
  i18n?: ((key: string) => string) | Record<string, string>
}

parseMarkdownToStructure(content, md?, options?)

将 Markdown 内容解析为结构化节点树。

参数:

  • content (string): 要解析的 Markdown 内容
  • md (MarkdownItCore, 可选): markdown-it-ts 实例。如果未提供,则使用 getMarkdown() 创建
  • options (ParseOptions, 可选): 带有钩子的解析选项

返回值: ParsedNode[] - 解析后的节点数组

processTokens(tokens)

将原始 markdown-it tokens 处理为扁平数组。

parseInlineTokens(tokens, md)

解析内联 markdown-it-ts tokens。

配置函数

setDefaultMathOptions(options)

设置全局数学公式渲染选项。

参数:

  • options (MathOptions): 数学公式配置选项
interface MathOptions {
  commands?: readonly string[] // 要转义的 LaTeX 命令
  escapeExclamation?: boolean // 转义独立的 '!' (默认: true)
}

解析钩子(精细化变换)

parseMarkdownToStructure()<MarkdownRender :parse-options> 可使用相同的钩子:

interface ParseOptions {
  preTransformTokens?: (tokens: Token[]) => Token[]
  postTransformTokens?: (tokens: Token[]) => Token[]
  postTransformNodes?: (nodes: ParsedNode[]) => ParsedNode[]
}

示例 —— 标记 AI “思考” 块:

const parseOptions = {
  postTransformNodes(nodes) {
    return nodes.map(node =>
      node.type === 'html_block' && /<thinking>/.test(node.value)
        ? { ...node, meta: { type: 'thinking' } }
        : node,
    )
  },
}

在渲染器中读取 node.meta 即可渲染自定义 UI,而无需直接修改 Markdown 文本。

工具函数

isMathLike(content)

启发式函数,用于检测内容是否类似数学符号。

参数:

  • content (string): 要检查的内容

返回值: boolean

findMatchingClose(src, startIdx, open, close)

在字符串中查找匹配的闭合分隔符,处理嵌套对。

参数:

  • src (string): 源字符串
  • startIdx (number): 开始搜索的索引
  • open (string): 开启分隔符
  • close (string): 闭合分隔符

返回值: number - 匹配闭合的索引,如果未找到则返回 -1

使用建议与排障

  • 复用解析实例:缓存 getMarkdown() 的结果,避免重复注册插件。
  • 服务端解析:在服务端运行 parseMarkdownToStructure 后把 AST 下发给客户端,配合 markstream-vue 实现确定性输出。
  • 自定义 HTML 组件:在解析前先把 <MyWidget> 这类片段替换为占位符,渲染时再注入,避免在 html_block 上进行脆弱的字符串操作。
  • 样式提示:如果将节点交给 markstream-vue,务必按照文档的 CSS 排查清单 调整 reset / layer,防止 Tailwind/UnoCSS 覆盖样式。
  • 错误处理apply 钩子内部默认捕获异常后打印日志,如需在 CI/生产中抛出错误,可在传入前自行封装并 rethrow。

parseFenceToken(token)

将代码围栏 token 解析为 CodeBlockNode。

参数:

  • token (MarkdownToken): markdown-it token

返回值: CodeBlockNode

normalizeStandaloneBackslashT(content, options?)

规范化数学内容中的反斜杠-t 序列。

参数:

  • content (string): 要规范化的内容
  • options (MathOptions, 可选): 数学选项

返回值: string

低阶辅助函数

需要更细粒度地控制 token → AST 流程时,可直接使用以下导出:

import type { MarkdownToken } from 'stream-markdown-parser'
import {

  parseInlineTokens,
  processTokens
} from 'stream-markdown-parser'

const tokens: MarkdownToken[] = md.parse(markdown, {})
const nodes = processTokens(tokens)
// 或仅解析内联内容:
const inlineNodes = parseInlineTokens(tokens[0].children ?? [], tokens[0].content ?? '')

processTokensparseMarkdownToStructure 内部使用的同一个转换器,可在自定义管线中复用,避免重复实现 Markdown-it 遍历。

插件函数

applyMath(md, options?)

将数学插件应用到 markdown-it 实例。

参数:

  • md (MarkdownIt): markdown-it 实例
  • options (MathOptions, 可选): 数学渲染选项

applyContainers(md)

将容器插件应用到 markdown-it 实例。

参数:

  • md (MarkdownIt): markdown-it 实例

常量

KATEX_COMMANDS

用于转义的常用 KaTeX 命令数组。

TEX_BRACE_COMMANDS

使用大括号的 TeX 命令数组。

ESCAPED_TEX_BRACE_COMMANDS

用于正则表达式的 TEX_BRACE_COMMANDS 转义版本。

类型

所有 TypeScript 类型都已导出:

import type {
  // 节点类型
  CodeBlockNode,
  GetMarkdownOptions,
  HeadingNode,
  ListItemNode,
  ListNode,
  MathOptions,
  ParagraphNode,
  ParsedNode,
  ParseOptions,
  // ... 更多
} from 'stream-markdown-parser'

节点类型

解析器导出各种表示不同 Markdown 元素的节点类型:

  • TextNode, HeadingNode, ParagraphNode
  • ListNode, ListItemNode
  • CodeBlockNode, InlineCodeNode
  • LinkNode, ImageNode
  • BlockquoteNode, TableNode
  • MathBlockNode, MathInlineNode
  • 以及更多...

默认插件

该包预配置了以下 markdown-it 插件:

  • markdown-it-sub - 下标支持(H~2~O
  • markdown-it-sup - 上标支持(x^2^
  • markdown-it-mark - 高亮/标记支持(==highlighted==
  • markdown-it-task-checkbox - 任务列表支持(- [ ] Todo
  • markdown-it-ins - 插入标签支持(++inserted++
  • markdown-it-footnote - 脚注支持
  • markdown-it-container - 自定义容器支持(::: warning, ::: tip 等)
  • 数学公式支持 - 使用 $...$$$...$$ 渲染 LaTeX 数学公式

框架集成

虽然该包与框架无关,但它被设计为可以无缝配合以下框架使用:

  • Node.js - 服务器端渲染
  • Vue 3 - 配合 stream-markdown-parser 使用
  • React - 使用解析的节点进行自定义渲染
  • Vanilla JS - 直接 HTML 渲染
  • 任何框架 - 解析为 AST 并按需渲染

stream-markdown-parser 迁移

如果你正在从 stream-markdown-parser 中的 markdown 工具迁移:

import { getMarkdown } from 'stream-markdown-parser'

所有 API 保持不变。详见迁移指南

性能

  • 轻量级: ~65KB 压缩后(13KB gzipped)
  • 快速: 针对实时解析优化
  • Tree-shakeable: 只导入你需要的部分
  • 零依赖: 除了 markdown-it 及其插件

贡献

欢迎提交 Issues 和 PRs!请阅读贡献指南

许可证

MIT © Simon He

相关项目