摘要

  • RFC 7763 于 2016 年 3 月以 IETF 资料性 RFC 发表,登记 text/markdown 媒体类型。登记要求 charset,并允许用可选的 variant 参数标注作者预期的 Markdown 写法。
  • variant 是提示。接收端可以按它解析,也可以自行处理。RFC 7764 记录了 Original、GFM、CommonMark、Pandoc 等不同变体。
  • IANA 的媒体类型登记表收录 text/markdown,另有Markdown 变体登记表。两张表给内容和写法命名,实际解析仍要靠软件。

一张表格,到了对面变成了标点

Markdown 的吸引力是原稿本身也能读。写作者用井号标标题,用星号标列表,用反引号围住代码。很多人接着添上了自己需要的功能:表格、自动链接、更复杂的代码块。同一份文档留在同一套工具里,差异不太显眼。一旦发给另一套系统,原本藏在软件设置里的选择就跑到了读者面前。

假设一个项目用竖线写了一张费用表。旧系统把每列排好;新系统把分隔线当作普通文字。迁移报告会显示文件哈希一致,备份没有坏。读者面对的费用结构却失去了列关系。问题既不在磁盘,也不在网络,而在“哪些符号算结构”这道本来没说出口的规则。

2016 年的 RFC 7764 正视了这笔旧账。它回顾 John Gruber 与 Aaron Swartz 在 2004 年提出的 Markdown,并列出后来形成的多种变体。文件中对 GFM 的说明包括表格、围栏式代码块、自动识别 URL 等扩展。Original、CommonMark、Pandoc 也各有自己的处理边界。把它们统称为 Markdown,并不会让同一个竖线在每台机器上干同一件事。

给信封写上名字

RFC 7763 解决了第一层混乱。邮件附件或 HTTP 响应可以用 text/markdown 告诉对方,传来的东西属于 Markdown 文本。它的登记项目要求 charset,因为接收程序先要把字节解码成字符,才谈得上识别井号和竖线。该媒体类型没有预设字符集。

第二层问题是方言。RFC 增加了可选的 variant 参数。例如 Content-Type: text/markdown; charset=UTF-8; variant=Original,信封上既写了文件家族,也写了作者期望的语法。没有 variant 时,接收程序依上下文决定。即使写了,规范也把它称为提示:接收端可以采用,规范没有替它安装一个支持该语法的解析器。

这里的权力划分很直白。作者能声明“请按这种写法读”,读者软件掌握“我会怎样读”。如果目标程序根本不认识某种表格扩展,头部多写一个名字无法让表格出现。RFC 因此建议,想保住作者原意,发送方应选接收方真正了解的变体。兼容性不是登记成功的一枚印章,而是两端程序跑出来的结果。

更麻烦的是信封容易丢。RFC 7764 讨论了 Markdown 离开能携带媒体类型参数的协议后,如何留住这些上下文。一个 .md 文件可以把正文完整保存下来,却不一定保存当初随 HTTP 或邮件传来的 variant。RFC 7763 要求实施者重视把变体及相关参数随内容记录。源文件独自活下来,读法未必跟着活下来。

两本登记簿,几套机器

IANA 将 text/markdown 列在文本媒体类型中,又以单独的Markdown 变体登记表收录 Original、GFM、CommonMark、Pandoc 等名称。后一本采用先到先得的登记程序。登记让不同系统有共同的指称,方便说清“我用哪种写法”。它不会自动更新每家公司的解析器。

这也是为什么“都支持 Markdown”常常是一句缺了后半截的话。应该追问支持哪种变体、哪个版本、哪些结构。某个平台接受文件上传,只说明它收下了字节。它能否正确显示代码、表格和链接,得看它实际运行的解析器。最省事的验证方式是拿同一份真实稿件在两端各渲染一次,而不是盯着扩展名猜。

这四份官方原始记录记载的是命名和规则。若要判断哪家产品在何时发送过 variant、又有哪家按它处理,需要带日期的产品手册、源码版本或响应报文。已经可以确定的是:2016 年,Markdown 在网络上传输时终于有了正式身份;它的方言没有因此交出解释权。