yozora
yozora 是一个零外部依赖的 Markdown 解析器和渲染器,支持 GFM 规范,具有高性能、健壮性和可扩展性。它采用中间件思想,支持自定义分词器,并能将 Markdown 转换为 React 组件。
• Copy the embed code to showcase this product on your website
• Share on X to spread the word about this amazing tool
- [yozora][]: 一个基于中间件思想的、零外部依赖的 Markdown 解析器,用于将 Markdown 字符串转成 [Markdown AST][@yozora/ast]* [yozora-react][]: 一个基于 React 的 Markdown 渲染器,用于将 [Markdown AST][@yozora/ast] 渲染成 React 组件https://user-images.githubusercontent.com/42513619/129205123-6a1983c4-6a86-4c80-83d6-02bdbf70edbf.mp4## ✨ Features* 完整支持了 [GFM 规范][gfm-spec] 中提到的所有规则,并通过了几乎所有由规范中的示 例改造成的测试用例(除了示例 https://github.github.com/gfm/#example-653,因为 [渲染器][yozora-react] 不打算支持原生的 HTML Tag,所以懒得做标签过滤,如果有需 要自行做一下过滤就好了)。 可参见 [@yozora/parser-gfm] or [@yozora/parser-gfm-ex] 以获得进一步信息。* 健壮性 - 所有代码都采用 Typescript 编写,拥有严格地静态类型检查的保障; - 使用 eslint 和 prettier 约束编码风格,规避了偏僻语法及 shadow variables 之类 易于出错的问题; - 使用了大量的测试用例进行测试;* 干净,零第三方依赖。* 高性能 - 解析复杂度为字符串长度乘以分词器列表长度,已经达到了理论复杂度的下界; - 解析器的 API 支持流式读入(采用生成器/迭代器进行输入),支持边读入边解析 (暂仅限于块级数据); - 在读入字符串时,会将其预处理成字符编码及位置信息,使用 [NodePoint][src-NodePoint] 数据类型承载。在分词阶段通过扫描 [NodePoint][src-NodePoint] 的方式完成匹配, 虽然匹配过程更麻烦些,但理论上性能比正则表达式的匹配方式少一些常数; - 小心地处理数组新建/连接操作,整个扫描阶段尽量复用数组,仅通过下标索引来圈定 匹配范围,并应用了不少策略减少重复匹配/解析操作。 * 兼容性,解析器解析出的 AST 与 [Mdast][mdast-homepage] 中定义的相兼容。即便以后 如果部分数据类型不兼容,也可以很容易通过 [@yozora/ast-util][] 中提供的 API 去 遍历 AST 以进行适配修改。* 可扩展性,yozora 采用中间件的方式,由内部算法驱动分词器列表完成解析工作,因而 易于创建并集成自定义的分词器。此项目中已实现了一些 [GFM][gfm-spec] 中未提到的 数据类型的分词器,如 [@yozora/tokenizer-admonition][], [@yozora/tokenizer-footnote][] 等,且均已内置于 [@yozora/parser][] 中。[src-NodePoint]: https://github.com/yozorajs/yozora/blob/main/packages/character/src/types.ts#L10[gfm-spec]: https://github.github.com/gfm[mdast-homepage]: https://github.com/syntax-tree/mdast[yozora-react]: https://github.com/yozorajs/yozora-react[yozora]: https://github.com/yozorajs/yozora[@yozora/ast]: https://github.com/yozorajs/yozora/tree/main/packages/ast#readme[@yozora/ast-util]: https://github.com/yozorajs/yozora/tree/main/packages/ast-util#readme[@yozora/character]: https://github.com/yozorajs/yozora/tree/main/packages/character#readme[@yozora/eslint-config]: https://github.com/yozorajs/yozora/tree/main/packages/eslint-config#readme[@yozora/core-parser]: https://github.com/yozorajs/yozora/tree/main/packages/core-parser#readme[@yozora/core-tokenizer]: https://github.com/yozorajs/yozora/tree/main/packages/core-tokenizer#readme[@yozora/invariant]: https://github.com/yozorajs/yozora/tree/main/packages/invariant#readme[@yozora/jest-for-tokenizer]: https://github.com/yozorajs/yozora/tree/main/packages/jest-for-tokenizer#readme[@yozora/parser]: https://github.com/yozorajs/yozora/tree/main/packages/parser#readme[@yozora/parser-gfm]: https://github.com/yozorajs/yozora/tree/main/packages/parser-gfm#readme[@yozora/parser-gfm-ex]: https://github.com/yozorajs/yozora/tree/main/packages/parser-gfm-ex#readme[@yozora/template-tokenizer]: https://github.com/yozorajs/yozora/tree/main/packages/template-tokenizer#readme[@yozora/tokenizer-admonition]: https://github.com/yozorajs/yozora/tree/main/tokenizers/admonition#readme[@yozora/tokenizer-autolink]: https://github.com/yozorajs/yozora/tree/main/tokenizers/autolink#readme[@yozora/tokenizer-autolink-extension]: https://github.com/yozorajs/yozora/tree/main/tokenizers/autolink-extension#readme[@yozora/tokenizer-blockquote]: https://github.com/yozorajs/yozora/tree/main/tokenizers/blockquote#readme[@yozora/tokenizer-break]: https://github.com/yozorajs/yozora/tree/main/tokenizers/break#readme[@yozora/tokenizer-definition]: https://github.com/yozorajs/yozora/tree/main/tokenizers/definition#readme[@yozora/tokenizer-delete]: https://github.com/yozorajs/yozora/tree/main/tokenizers/delete#readme[@yozora/tokenizer-emphasis]: https://github.com/yozorajs/yozora/tree/main/tokenizers/emphasis#readme[@yozora/tokenizer-fenced-block]: https://github.com/yozorajs/yozora/tree/main/tokenizers/fenced-block#readme[@yozora/tokenizer-fenced-code]: https://github.com/yozorajs/yozora/tree/main/tokenizers/fenced-code#readme[@yozora/tokenizer-footnote]: https://github.com/yozorajs/yozora/tree/main/tokenizers/footnote#readme[@yozora/tokenizer-footnote-definition]: https://github.com/yozorajs/yozora/tree/main/tokenizers/footnote-definition#readme[@yozora/tokenizer-footnote-reference]: https://github.com/yozorajs/yozora/tree/main/tokenizers/footnote-reference#readme[@yozora/tokenizer-heading]: https://github.com/yozorajs/yozora/tree/main/tokenizers/heading#readme[@yozora/tokenizer-html-block]: https://github.com/yozorajs/yozora/tree/main/tokenizers/html-block#readme[@yozora/tokenizer-html-inline]: https://github.com/yozorajs/yozora/tree/main/tokenizers/html-inline#readme[@yozora/tokenizer-image]: https://github.com/yozorajs/yozora/tree/main/tokenizers/image#readme[@yozora/tokenizer-image-reference]: https://github.com/yozorajs/yozora/tree/main/tokenizers/image-reference#readme[@yozora/tokenizer-indented-code]: https://github.com/yozorajs/yozora/tree/main/tokenizers/indented-code#readme[@yozora/tokenizer-inline-code]: https://github.com/yozorajs/yozora/tree/main/tokenizers/inline-code#readme[@yozora/tokenizer-inline-math]: https://github.com/yozorajs/yozora/tree/main/tokenizers/inline-math#readme[@yozora/tokenizer-link]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link#readme[@yozora/tokenizer-link-reference]: https://github.com/yozorajs/yozora/tree/main/tokenizers/link-reference#readme[@yozora/tokenizer-list]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list#readme[@yozora/tokenizer-list-item]: https://github.com/yozorajs/yozora/tree/main/tokenizers/list-item#readme[@yozora/tokenizer-math]: https://github.com/yozorajs/yozora/tree/main/tokenizers/math#readme[@yozora/tokenizer-paragraph]: https://github.com/yozorajs/yozora/tree/main/tokenizers/paragraph#readme[@yozora/tokenizer-setext-heading]: https://github.com/yozorajs/yozora/tree/main/tokenizers/setext-heading#readme[@yozora/tokenizer-table]: https://github.com/yozorajs/yozora/tree/main/tokenizers/table#readme[@yozora/tokenizer-text]: https://github.com/yozorajs/yozora/tree/main/tokenizers/text#readme[@yozora/tokenizer-thematic-break]: https://github.com/yozorajs/yozora/tree/main/tokenizers/thematic-break#readme