remark

插件驱动的体系架构。以AST为默认输出标准。可以进行lint等操作。

命令行为remark。

不同的措辞树可搭配不同的转换器

  • mdast搭配remark给markdown用
  • nlcst搭配retext给prose用
  • hast搭配rehype给HTML用

以上属于unified.js范畴

remark github

仓库包含四个料包:

  • remark-parse,解析用
  • remark-stringify,将mdast措辞树转为markdown输出
  • remark,包含unified, remark-parse和remark-stringify,适用于输入和输出都是markdown的情况
  • remark-cli,围绕着remark的命令行

也就是说,如果输入himarkdown,那么搭配unified使用remark-parse; 如果输出是markdown,那么搭配unified使用remark-stringify; 如果输入和输出都是markdown,那么使用remark本身。

插件概览

  • remark-gfm
  • remark-lint
  • remark-toc
  • remark-html

https://github.com/remarkjs/awesome-remark

看了一下 https://github.com/remarkjs/remark/tree/main/packages/remark-parse, 基本就是包装

https://github.com/remarkjs/remark-gfm

https://github.com/syntax-tree/mdast

micromark github

最小化的遵循CommonMark的解析器,带有位置信息和具体的符号。

  • 100% CommonMark
  • 通过扩展可以支持GFM、directives、frontmatter、math、MDX.js等
  • 默认安全
  • 最小的CM解析器
  • 100% 测试覆盖

使用状态机来将整个markdown解析成具体的号牌。用作remark-parse内部。

API包括两部分,一部分是micromark另一部分是micromark/stream

可以通过node --conditions development module.js来获得https://nodejs.org/api/packages.html#packages_resolving_user_conditions

micromark(value[, encoding][, options])将markdown转为HTML。 stream(options?)也将markdown转为HTML,不够采用的是流式处理。

接收两种扩展,一种是SyntaxExtension,另一种是HtmlExtension。

gfm作为扩展提供micromark-extension-gfm github

可以扩展markdown语法,但是通常有现成的解决方案。

Architecture

micromark仓库有以下料包

  • micromark-build,从开发代码构建生产代码
  • micromark-core-commonmar,CommonMark 相关的构造
  • micromark-factory-*,可以重用的子过程
  • micromark-util-*,可以重用的实用工具
  • micromark,核心部件

整个处理过程:

                                            micromark
+-----------------------------------------------------------------------------------------------+
|            +------------+         +-------+         +-------------+         +---------+       |
| -markdown->+ preprocess +-chunks->+ parse +-events->+ postprocess +-events->+ compile +-html- |
|            +------------+         +-------+         +-------------+         +---------+       |
+-----------------------------------------------------------------------------------------------+

预处理器micromark/dev/lib/preprocess.js将markdown撕成分块(chunk),由单个字符码或者字符串构成。

micromark/dev/lib/parse.js将分块转化为事件。事件是号牌的开始或者结束。号牌可以嵌套。号牌跨一到多个字符码。号牌可以互相链接。

micromark/dev/lib/postprocess.js接收所有的事件,保证所有的内容都被解析。

micromark/dev/lib/compile.js将事件转为HTML。

Examples

Syntax tree

micromark-extension-math可以用katex渲染数学公式。

mdast-util-from-markdown可以给出AST。

Markdown

一开始markdown只是用一个perl文件markdown.pl实现。 随后有了CommonMark标准。然后不同的平台又自定义了一些语法,比如Github就有了Github Flavored Markdown,俗称GFM。

Project

Comparison

micromark是底层引擎

remark聚焦在AST

marked是经典的markdown解析器,但是对CommonMark和GFM的支持不够好,默认允许不安全的内容。

markdown-it是经典的CommonMark解析器,措辞上有很多扩展,可以自定义语法,支持不同风格的markdown。

Security

安全性是指https://en.wikipedia.org/wiki/Cross-site_scripting,可能来自于内嵌的HTML或者links/images中的可疑协议。 通过allowDangerousHtml allowDangerousProtocol 选项可以关闭默认的安全性。

unifiedjs

Github网址是https://github.com/unifiedjs/unified

用于remark、rehype等等,提供通用的处理接口。

https://github.com/vfile/vfile是其对文件的抽象。

其他markdown parser

markdown-it

支持 CommonMark

marked

底层级的markdown编译器。

prosemirror-markdown

处理CommonMark和Markdown之间的转化。

md4c

prosemirorr base markdown

主页在https://noteworthy.ink/

其他对比

mentioned unistd/mdast syntax tree

Markdown Editor

相关工具

(草草了事)

2022-06-19更新:markdown-it

markdown-it是一款老牌的基于JS的Markdown解析器,特点如下:

  • 解析方式基于规则,则不是基于状态机
    • 可以方便自定义新的解析规则
  • 中间产物是一个号牌流,而不是AST
  • 具有很多扩展

一些限制:

  • 似乎一次必须解析整块markdown文本

一些参考:

一些思考:

  • 其实并不需要每次都过一堆规则,根据当前的状态,适合的规则其实有限
    • 但是需要预先的编译,才能减少不必要的规则匹配
  • https://github.com/markdown-it/markdown-ast-spec/issues/5对增量处理做了一些讨论
    • 如果要增量处理,一方面要能够设置解析器状态,以适配增量解析的开始位置
    • 架构上或许需要改变一下,比如像remark那样按输入的字符进行状态变迁,然后通过事件的方式来产生token

(更新完)