写点什么

扒一扒互联网 Markdown 的那些事儿

作者:Java研究者
  • 2023-11-06
    浙江
  • 本文字数:3494 字

    阅读完需:约 11 分钟

扒一扒互联网Markdown的那些事儿

最近感觉到 Markdown 似乎已成为各大社区的编辑器标配所支持的格式,侧面看来其设计之初的目标 “ to be used as a format for writing for the web.” 已经成为了现实。不妨就扒一扒互联网 Markdown 的这些事儿。

Markdown 的演进


Markdown 是一种标记语言,对比于 HTML 这样的标记语言来说简洁很多,因此其描述为轻量级的标记语言(lightweight markup language,简称 LML)更为合适。当然,轻量级标记语言并非只有 Markdown,在其之前就有很多种。比如:Setext (Structure Enhanced Text) 用于一些纯文本的场景比如 Email、Usenet(新闻组)等。



也有能把格式文本转换为 HTML 类似早期语言 reStructuredText(rST),为了更好的阅读 Python 源码和 Python 技术源码而设计。



Markdown 就是在这样的背景下诞生,在 2004 年由 John Gruber 和 Aaron Swartz 共同创建出来,有兴趣的可以看下最初文章《Introducing Markdown》。这两个作者也有很多故事,比如 Gruber 是《The Talk Show》播客节目主持人;Swartz 2013 年已经故去,其曾因使用麻省理工颁发给他的访客用户帐户从 JSTOR 系统下载学术期刊文章,随后被麻省理工院警方以违反国家和进入国家的指控逮捕。(PS:笔者并非八卦博主就不多赘述了,感兴趣的自行了解)


到了 2008 年时候 Stack Overflow 的联合创始人 Jeff Atwood 推其成为 Stack Overflow 的编辑方式,并且非常认同其设计;也就是这个时候开始大规模的在程序员中流行起来。Github 大概在 2009 年开始使用 Markdown,并推出扩展版 GitHub Flavored Markdown (GFM)。


2012 年,Jeff 提议 Stack Exchange、GitHub、Meteor、Reddit 等一些访问量大的公司组织一起制定出 Markdown 的标准规范和其实现的标准测试用例。2014 年的时候发布了一个 Standard Markdown 的项目,不过 Gruber 反对使用 Markdown 的名字,后来最终改成了 CommonMark,其中包含了 600+个测试用例以及 C 语言和 JavaScript 的实现。


2016 年时候 IETF 也发布了征求意见稿 RFC7763,在 media type 中定义了 test/markdown 的类型;2017 年 GFM 基于 CommonMark Spec 正式发布了 GitHub Flavored Markdown Spec,支持表格、任务列表、禁止 HTML 等等。


当然到目前 Markdown 演进也远未结束,除开 GFM 其实还有更多的 基于 CommonMark 的扩展,比如微软的 Markdown for Microsoft Learn 有 [!NOTE] 的扩展语法。

Markdown 解析引擎


Markdown 解析引擎也是非常多的,这里主要介绍一些 JavaScript 开源项目。

Showdown


正如演进提到的 2004 年的时候,Gruber 写了第一个版本的 Markdown 解析引擎 Markdown.pl; 2007 年时候 John Fraser 基于 Gruber 的工作成果创建了 Showdown;不过,似乎 Fraser 早已经不再维护了,Corey Innis 将其迁移到了 Github , 从迁移后的提交看 Santos 维护比较多。它除开实现了 Markdown 原始标准外,也支持一些 Atx、Setset 的语法规则。比如:# My Heading #等。


var showdown  = require('showdown'),converter = new showdown.Converter(),text      = '# hello, markdown!',html      = converter.makeHtml(text);
复制代码


Marked


Marked 同样也是非常早的 Markdown 解析引擎,Christopher Jeffrey 在 2011 年最早创建的,目前 GitHub 上已经 30k+ 的收藏。很多产品都在使用,不过虽然其支持 CommonMark 以及 GFM,但是似乎支持的还不够完整,截至到 2022 年 11 月的 V4.2.3 还并没有 100% 支持到两大标准。有个有意思的现象,今年其版本更新非常快 2023 年 3 月份还是 V4.3.0 到如今 11 月份版本迭代到了 V9.1.5。


import { marked } from 'marked';// or const { marked } = require('marked');const html = marked.parse('# Marked in Node.js');
复制代码



Commonmark


应该说是 Commonmark Spec 的亲闺女,John MacFarlane 2014 年时候最早创建的,他同时也是标准制定人之一,还是 Pandoc 的作者。将 Markdown 文档解析成 抽象语法树(AST),并通过渲染(AST)转换成 HTML 或者 XML;从笔者测试看其性能非常优异。


var reader = new commonmark.Parser();var writer = new commonmark.HtmlRenderer();
// parsed is a 'Node' treevar parsed = reader.parse("Hello world");var result = writer.render(parsed);
复制代码


Remarkable 与 Markdown-it


Remarkable 是 2014 年左右的开源项目,目前已更新很少了;Markdown-it 是 Remarkable 核心两个作者后面开的开源项目,同时借鉴参考了 MacFarlane 的 Commonmark 的一些实现,也是功能、扩展性都非常不错的 Markdown 解析引擎 目前有 16.2k 的收藏。


var md = require('markdown-it')();var result = md.render('# markdown-it rulezz!');
复制代码


Micromark 与 Remark


Micromark 和 Remark 创建者都是 Titus Wormer(wooorm),14 年毕业于阿姆斯特丹大学,同时也是 unified 研发生态的创建者。unified 是一个文本处理库、插件和工具的生态系统,其生态内有 500+的开源库,在 Github 有 1.3m+的项目在使用。


Remark 目前就是 unified 生态中的一员,严格说来它还早于 unified,是一个 Monorepo 风格的管理库,主要包含 remark-parse 、remark-stringify、remark、remark-cli ,其功能相信从命名也能看出一二。


  • remark-parse — 用于将 Markdown 文本转化为语法树(mdast)的插件

  • remark-stringify — 用于将语法树(mdast)转化为 Markdown 文本的插件

  • remark — 包括 unified、remark-parse 和 remark-stringify,适用于输入和输出都是 Markdown 的情况

  • remark-cli — 基于 remark 的命令行界面工具,用于在脚本中检查和格式化 Markdown

PS:Markdown Abstract Syntax Tree 简称为 mdast


其中最被广泛使用的是 remark-parse,其解析上也应用了 Micromark 一些库。


// micromark
import {micromark} from 'micromark'console.log(micromark('## Hello, world!'))
// remarkimport {unified} from "unified";import remarkParse from 'remark-parse'import remarkRehype from 'remark-rehype'import rehypeStringify from 'rehype-stringify'
console.log( unified() .use(remarkParse) .use(remarkRehype) .use(rehypeStringify) .processSync("Hellow,world").value);
复制代码

其他


或许会疑惑为什么没有看到 Tiptap、ProseMirror、React-markdown? Tiptap 围绕 PoroseMirror 研发的开源项目,ProseMirror 主要聚焦在富文本编辑器领域 对于 Markdown 解析引擎默认使用的是 Markdown-it;React-markdown 聚焦在 React component 领域上,Markdown 解析引擎用的是 Remark,其实类似还有 Milkdown 等等。而且围绕 Markdown 解析引擎研发的开源项目非常之多,仅 reamrk-parse 在写本文时就有 100w+代码库,2k+ Packages 在使用。



当然受限于笔者知识也必然会有遗漏的 Markdown 解析引擎,行文见谅。

要用,选哪个?


这个问题比较直接也比较实际,但其实很难一言论断。应当从多方面考虑,比如是否需要 100%支持 GFM?是否有自定义扩展语法的需要?自定义扩展语法是否比较复杂?又是否需要兼容 Atx 之类的写法?是否对性能有很高要求?是否需要使用到 AST 抽象语法树?等等;作为一个向往和平与爱的博主,更多的建议还是根据自身需求来选择开源 Markdown 引擎,其实每一个产品都有自己独特的优劣。


当然什么也不考虑,就只是随意看看,可能 Commonmark 、unified 生态会是一个不错的选择。


附上一张文章中提及到的 Markdown 解析引擎的 NPM 下载趋势图,可以看到近些年来发展非常迅速,特别注意下其数值大小并非代表项目好坏。客观上说每个项目定位不同、使用范围不同、年限长度不同,其 npm 上下载量的自然也就不同;根据自身需求来选择合适的 Markdown 解析引擎最为重要。



PS:这图为什么每年都有个陡降点?12 月 25 日圣诞节

未来呢?


从大量轻量语言的出现,到 Gruber 和 Swartz 创建 Markdown;从 Jeff 对 Markdown 设计的热爱,推其广泛应用与制定标准 到 Gruber 反对标准使用 Markdown 之名;从 CommonMark、GFM 的出现,到 ETF 征求意见稿发布;还有贯穿其中的各种 Markdown 扩展、应用到各种场景的开源项目,演进到如今不可谓不热闹,颇有一番春秋战国百家争鸣的味道。


即使今天这场“百家争鸣”也还未停息,目前最热的技术莫过于 AI、AIGC,ChatGPT 默认显示就是 Markdown 语法;由于 Markdown 轻量的语法、结构化的文本,助其可能成为了 AI 时代文本格式的首选之一;此外轻量语言之间仍在相互借鉴,新的扩展语法还在不断涌现,各大开源生态的战场仍在继续书写历史。


但在 Markdown 演进中可以看到标准制定、基础解析引擎整体国内身影较少,但随着国内云社区、开源社区发展日益火热,更多的有志青年投身其中,相信未来也是璀璨的;也或许某天会有 Tencent Flavored Markdown Spec(TFM) 的出现。


欢迎关注 Java 研究者专栏、博客、公众号。

发布于: 刚刚阅读数: 5
用户头像

Java研究者

关注

还未添加个人签名 2020-09-27 加入

还未添加个人简介

评论

发布
暂无评论
扒一扒互联网Markdown的那些事儿_互联网_Java研究者_InfoQ写作社区