更新记录

1.0.0(2025-11-18) 下载此版本

第一版


平台兼容性

uni-app x(4.85)

Chrome Chrome插件版本 Safari Safari插件版本 Android Android插件版本 iOS iOS插件版本 鸿蒙 微信小程序 微信小程序插件版本
1.0.0 1.0.0 1.0.0 1.0.0 - 1.0.0

其他

多语言 暗黑模式 宽屏模式

uni-cmark

一个由 AI 基于 C 语言库 cmark-gfm 封装的 Markdown 解析 UTS 插件,适用于 uni-app 生态。

功能特点

  • 高性能解析:底层采用 C 语言实现的 cmark-gfm 库,确保了卓越的解析性能和效率。
  • 全平台支持:支持 uni-app 及 uni-app x 项目,并可运行于 Android、iOS、Web 及微信小程序等平台。
  • 流式解析能力:支持实时流式 Markdown 解析,非常适合集成到 AI 聊天等需要增量显示内容的场景中。详情可参考 uni-ai-x
  • 完整语法兼容:全面支持标准 Markdown 语法以及 GitHub Flavored Markdown (GFM) 扩展语法。

基本使用

在使用 md2json 进行解析之前,必须先调用 initCmark 进行初始化。该初始化在应用生命周期内调用一次即可。

import { md2json, initCmark } from '@/uni_modules/uni-cmark'

// 初始化 cmark-gfm 库(仅 Web 和微信小程序端需要此操作,其他平台为空实现)
await initCmark()

// 待解析的 Markdown 文本
const markdownText = `# 标题
这是一个**粗体**文本和*斜体*文本。

\`\`\`javascript
console.log('Hello World')
\`\`\`
`

// 解析 Markdown 文本
// 根据平台差异,返回值的类型会有所不同
// #ifdef APP-IOS
// iOS 端:为优化性能,返回的是一个 JSON 字符串
const jsonString = md2json(markdownText) as string;
const jsonList = JSON.parse(jsonString) as MarkdownToken[];
// #endif

// #ifndef APP-IOS
// 非 iOS 端:返回一个包含数据和错误信息的对象
const parseMdRes = md2json(markdownText) as ParseMdRes;
if (parseMdRes.errorMsg) {
    console.error('解析失败:', parseMdRes.errorMsg);
}
const jsonList = parseMdRes.data;
// #endif

console.log(jsonList);

参数

  • markdownText: string - 必需。需要被解析的原始 Markdown 格式文本。

返回值

md2json 函数的返回值类型会根据运行平台的不同而变化:

  • iOS 平台: 返回值为 string 类型。这是一个 JSON 格式的字符串。这样做是为了减少 UTS 插件层与 JS 层之间的通信开销,在 JS 层统一进行 JSON.parse 通常能获得更好的整体性能。

  • 非 iOS 平台 (Android, Web, 微信小程序等): 返回值为 ParseMdRes 对象类型,其结构如下:

    type ParseMdRes = {
        data: MarkdownToken[],  // 解析成功后得到的 Markdown 抽象语法树(AST)
        errorMsg: string        // 解析过程中产生的错误信息。如果解析成功,该字段为空字符串
    }

数据结构

MarkdownToken

MarkdownToken 是 Markdown 文本被解析后生成的抽象语法树(AST)中的节点。每个节点代表一个 Markdown 元素。

type MarkdownToken = {
    type?: string;           // 节点类型 (例如: 'heading', 'paragraph', 'strong', 'list')
    raw?: string;            // 该节点对应的原始 Markdown 文本片段
    text?: string;           // 节点的纯文本内容(如果适用)
    html?: string;           // 节点对应的 HTML 字符串表示(如果适用)
    tokens?: MarkdownToken[];// 子节点数组,用于表示复合元素(如列表、加粗文本等)
    checked?: number;        // 仅用于任务列表项,表示是否被选中。0 为未选中,1 为选中。
    escaped?: number;        // (内部使用) 标记文本是否已转义
    pre?: number;            // (内部使用) 标记是否处于预格式化块中
    block?: number;          // 标记该节点是否为块级元素。0 为行内元素,1 为块级元素。
    ordered?: number;        // 仅用于列表,表示是否为有序列表。0 为无序列表,1 为有序列表。
    loose?: number;          // 仅用于列表,表示列表的紧凑程度。0 为紧凑列表,1 为松散列表。
    task?: number;           // 仅用于列表项,表示是否为任务列表项。0 或 1。
    inLink?: number;         // (内部使用) 标记节点是否位于链接内部
    inRawBlock?: number;     // (内部使用) 标记节点是否位于原始文本块内部
    isClose?: number;        // (内部使用) 标记是否为闭合标签
    codeBlockStyle?: 'indented'; // 仅用于代码块,表示代码块的样式(如 'indented' 表示缩进式)
    lang?: string;           // 仅用于代码块,表示代码的编程语言(如 'javascript', 'python')
    tag?: string;            // 节点对应的 HTML 标签名(如 'h1', 'p', 'strong')
    href?: string;           // 仅用于链接或图片,存储 URL 地址
    title?: string;          // 仅用于链接或图片,存储标题(hover 时显示)
    depth?: number;          // 节点在 AST 中的嵌套深度
    start?: number | string; // 仅用于有序列表,表示列表的起始编号
    items?: MarkdownToken[]; // 仅用于列表,包含列表项的数组
    align?: 'center' | 'left' | 'right' | null; // 仅用于表格单元格,表示对齐方式。
    codeTokens?: MarkdownToken[][]; // (内部使用) 用于语法高亮的代码标记
    deepIndex?: number;      // (内部使用) 深度索引
    orderedIndex?: number;   // (内部使用) 有序索引
    className?: string;      // 建议的 CSS 类名
    uniqueId?: string;       // 节点的唯一标识符
    start_column?: number;   // 节点在原始文本中的起始列号
    end_column?: number;     // 节点在原始文本中的结束列号
    width?: number;          // (较少使用) 宽度信息
    height?: number;         // (较少使用) 高度信息
}

  1. 带有 (内部使用) 标记的字段主要用于插件内部逻辑,在大多数上层应用场景中,你可能不需要关注这些字段。
  2. 在 Swift + UTS 环境中部分情况下布尔值存在限制,本插件用数字 0 和 1 替代布尔值的 true false

相关项目

  • uni-ai-x - 一个基于 uni-cmark 构建的 AI 聊天 UI 套件。
  • cmark-gfm - uni-cmark 插件所依赖的底层 C 语言 Markdown 解析库。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

uni-cmark(以下简称软件)源码使用许可协议

2022年10月

本许可协议,是数字天堂(北京)网络技术有限公司(以下简称DCloud)对其所拥有著作权的“软件”,提供的使用许可协议。

您对“软件”的复制、使用、修改及分发受本许可协议的条款的约束,如您不接受本协议,则不能使用、复制、修改本软件。

授权许可范围

a) 授予您永久性的、全球性的、免费的、非独占的、不可撤销的本软件的源码使用许可,您可以使用这些源码制作自己的应用。

b) 您只能在DCloud产品体系内使用本软件及其源码。您不能将源码修改后运行在DCloud产品体系之外的环境,比如客户端脱离uni-app,或服务端脱离uniCloud(如涉及uniCloud)。

c) DCloud未向您授权商标使用许可。您在根据本软件源码制作自己的应用时,需以自己的名义发布软件,而不是以DCloud名义发布。

d) 本协议不构成代理关系。

DCloud的责任限制 “软件”在提供时不带任何明示或默示的担保。在任何情况下,DCloud不对任何人因使用“软件”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。

您的责任限制

a) 您需要在授权许可范围内使用软件。

b) 您在分发自己的应用时,不得侵犯DCloud商标和名誉权利。

c) 您不得进行破解、反编译、套壳等侵害DCloud知识产权的行为。您不得利用DCloud系统漏洞谋利或侵害DCloud利益,如您发现DCloud系统漏洞应第一时间通知DCloud。您不得进行攻击DCloud的服务器、网络等妨碍DCloud运营的行为。未经书面许可,您不得利用DCloud的产品进行与DCloud争夺开发者的行为。

d) 如您违反本许可协议,需承担因此给DCloud造成的损失。

本协议签订地点为中华人民共和国北京市海淀区。

根据发展,DCloud可能会对本协议进行修改。修改时,DCloud会在产品或者网页中显著的位置发布相关信息以便及时通知到用户。如果您选择继续使用本框架,即表示您同意接受这些修改。

条款结束