关于降价的思考

已发表: 2022-03-10
快速总结↬ Markdown 的所有风格、解释和分叉都不会消失。 但是,重要的是要关注试图满足现代需求的新兴内容格式。 在这篇文章中,Knut 通过回顾最初引入 Markdown 的原因,并回顾了 Web 内容的一些主要发展,分享了他反对 Markdown 的建议。

降价是我们许多人的第二天性。 回想起来,我记得在 John Gruber 与 Aaron Swartz 合作开发语言后不久,他在 2004 年发布了他的第一个基于 Perl 的解析器后不久就开始输入 Markdown。

Markdown 的语法有一个目的:用作网络写作的一种格式。

— 约翰·格鲁伯

那是差不多 20 年前的事了——哎呀! 最初作为对编写者和读者更友好的 HTML 语法已经成为如何为程序员和精通技术的人编写和存储技术散文的宠儿。

Markdown 是开发人员和文本修改者文化的标志。 但自推出以来,数字内容的世界也发生了变化。 虽然 Markdown 在某些方面仍然很好,但我认为它不再应该成为内容的首选。

这有两个主要原因:

  1. Markdown 的设计初衷不是为了满足当今的内容需求。
  2. Markdown 保留了编辑经验。

当然,这种立场受到为结构化内容平台工作的影响。 在 Sanity.io,我们大部分时间都在思考内容作为数据如何释放大量价值,我们花费大量时间深入思考编辑体验,以及如何节省人们的时间,让使用数字内容变得愉快. 所以,游戏中有皮肤,但我希望我能够描绘出这一点,尽管我会反对 Markdown 作为内容的首选格式,但我仍然对它的重要性、应用程序和遗产深表赞赏。

在我目前的演出之前,我曾在一家机构担任技术顾问,在那里我们不得不通过将客户的内容嵌入到演示文稿和复杂数据模型(是的,甚至是开源模型)中来真正与锁定客户内容的 CMS 作斗争。 我观察到人们在使用 Markdown 语法时遇到了困难,并且在他们作为编辑和内容创建者的工作中失去了动力。 我们花了几个小时(和客户的钱)来构建从未使用过的自定义标签渲染器,因为人们没有时间或动机来使用语法。 即使是我,在积极性高的时候,也放弃了为开源文档做贡献,因为基于组件的 Markdown 实现引入了太多的摩擦。

但我也看到了硬币的另一面。 Markdown 具有令人印象深刻的生态系统,从开发人员的角度来看,对于习惯阅读代码的人来说,纯文本文件具有优雅的简洁性和易于解析的语法。 我曾经花了几天时间在 Sublime Text 中为我的学术写作构建了一个令人印象深刻的MultiMarkdown -> LaTeX -> real-time-PDF-preview-pipelineREADME.md文件可以在代码编辑器中打开和编辑,并在 GitHub 上很好地呈现,这很有意义。 毫无疑问,Markdown 在某些用例中为开发人员带来了便利。

这也是为什么我想通过回顾一下最初引入 Markdown 的原因,并通过浏览网络内容的一些主要发展来构建我的反对 Markdown 的建议。 对于我们中的许多人来说,我怀疑 Markdown 是我们认为理所当然的“存在的东西”。 但所有技术都有历史,都是人类互动的产物。 当您作为读者开发供他人使用的技术时,记住这一点很重要。

口味和规格

Markdown 旨在让网络作家在网络出版需要编写 HTML 的时代更容易处理文章。 因此,其目的是让与 HTML 中的文本格式交互变得更简单。 这不是地球上第一个简化的语法,但它是多年来获得最大关注的语法。 今天,Markdown 的使用已经远远超出了它的设计意图,成为一种更简单的 HTML 读写方式,成为一种在许多不同上下文中标记纯文本的方法。 当然,技术和想法可以超越它们的意图发展,但是今天使用 Markdown 的紧张可以追溯到这个起源和对其设计的限制。

对于不熟悉语法的人,请使用以下 HTML 内容:

 <p>The <a href=”https://daringfireball.net/projects/markdown/syntax#philosophy”>Markdown syntax</a> is designed to be <em>easy-to-read</em> and <em>easy-to.write</em>.</p>

使用 Markdown,您可以表达相同的格式:

 The [Markdown syntax](https://daringfireball.net/projects/markdown/syntax#philosophy) is designed to be _easy-to-read_ and _easy-to-write_.

就像自然法则一样,技术采用伴随着发展和添加功能的压力。 Markdown 越来越受欢迎意味着人们希望根据他们的用例对其进行调整。 他们想要更多功能,例如支持脚注和表格。 最初的实现带有一个固执己见的立场,这在当时是合理的设计意图是:

对于 Markdown 语法未涵盖的任何标记,您只需使用 HTML 本身。 无需为它加上前缀或定界以表明您正在从 Markdown 切换到 HTML; 您只需使用标签。

— 约翰·格鲁伯

换句话说,如果你想要一个表格,那么使用<table></table> 。 您会发现原始实现仍然是这种情况。 Markdown 的精神继承者之一,MDX,采用了相同的原则,但将其扩展到 JSX,一种基于 JS 的模板语言。

从降价到降价?

看起来 Markdown 对许多人的吸引力与其说是与 HTML 的结合,不如说是纯文本的人体工程学和简单的格式化语法。 一些内容创建者希望将 Markdown 用于其他用例,而不是网络上的简单文章。 MultiMarkdown 等实现为想要使用纯文本文件但需要更多功能的学术作者引入了可供性。 很快,您就会拥有一系列接受 Markdown 语法的编写应用程序,而不必将其转换为 HTML 甚至使用 markdown 语法作为存储格式。

在许多应用程序中,您会发现为您提供一组有限格式选项的编辑器,其中一些更受原始语法的“启发”。 事实上,我在这篇文章的草稿中得到的反馈之一是,到目前为止,“Markdown”应该是小写的,因为它已经变得如此普遍,并使其与最初的实现区分开来。 因为我们认为降价的东西也变得非常多样化。

CommonMark:驯服 Markdown 的尝试

像冰淇淋一样,Markdown 有很多口味,有些比其他的更受欢迎。 当人们开始分叉原始实现并向其添加功能时,发生了两件事:

  1. 作为一个作家,你可以用 Markdown 做什么和不能做什么变得更加不可预测。
  2. 软件开发人员必须决定为他们的软件采用何种实现方式。 最初的实现还包含一些不一致的地方,这给想要以编程方式使用它的人增加了摩擦。

这开始了关于将 Markdown 正式化为规范的讨论。 有趣的是,Gruber 拒绝并且仍然拒绝的东西,因为他认识到人们想要将 Markdown 用于不同的目的,并且“没有一种语法可以让所有人都满意。” 考虑到 Markdown 转换为 HTML,这是一个有趣的立场,HTML 是一种不断发展以适应不同需求的规范。

尽管 Markdown 的原始实现包含在“类似 BSD”的许可证中,但它也显示“未经事先明确的书面许可,不得使用 Markdown 名称或其贡献者的姓名来认可或推广源自该软件的产品。 ” 我们可以有把握地假设,大多数在营销材料中使用“降价”的产品都没有获得此书面许可。

将 Markdown 引入共享规范的最成功尝试是今天的 CommonMark。 它由 Jeff Atwood(以共同创立 Stack Overflow 和 Discourse 而闻名)和 John McFarlane(伯克利哲学教授,Babelmark 和 pandoc 的幕后推手)领导。 他们最初将其作为“标准降价”推出,但在受到 Gruber 的批评后将其改为“CommonMark”。 Markdown 的立场是一致的,其目的是成为一种简单的创作语法,可以转换为 HTML:

我认为这也标志着 Markdown 进入公共领域。 尽管 CommonMark 没有被标记为“Markdown”,(根据许可)该规范被认可并称为“markdown”。 今天,您会发现 CommonMark 作为 Discourse、GitHub、GitLab、Reddit、Qt、Stack Overflow 和 Swift 等软件的底层实现。 像unified.js这样的项目通过将语法转换为抽象语法树来桥接语法,也依赖于 CommonMark 的降价支持。

CommonMark 带来了很多关于如何实现 markdown 的统一,并且在很多方面让程序员在软件中集成 markdown 支持变得更加简单。 但它并没有为 Markdown 的编写和使用方式带来相同的统一。 以 GitHub 风格的 Markdown (GFM) 为例。 它基于 CommonMark,但扩展了更多功能(如表格、任务列表和删除线)。 Reddit 将其“Reddit Flavored Markdown”描述为“GFM 的变体”,并引入了诸如标记剧透的语法等功能。 我认为我们可以有把握地得出结论,CommonMark 和 Gruber 背后的团队都是正确的:它当然有助于共享规范,但是是的,人们希望将 Markdown 用于不同的特定事物。

Markdown 作为格式化快捷方式

Gruber 拒绝将 Markdown 形式化为共享规范,因为他认为这会使它不再是作家的工具,而更像是程序员的工具。 我们已经看到,即使规范被广泛采用,我们也不会自动获得一种在不同上下文中可预测地工作相同的语法。 像 CommonMark 这样流行的规范也取得了有限的成功。 一个明显的例子是 Slack 的 markdown 实现(称为mrkdown ),它将*this*转换为强/粗体,而不是强调/斜体,并且不支持[link](https://slack.com)语法,但使用<link|https://slack.com>代替。

您还会发现,您可以使用类似 Markdown 的语法在 Notion、Dropbox Paper、Craft 等软件中的富文本编辑器中初始化格式,在某种程度上,Google Docs(例如,新行上的asterisk + space将转换为项目符号列表)。 什么是支持的,什么是不同的。 因此,您不一定能在这些应用程序中随身携带肌肉记忆。 对于某些人来说,这很好,他们可以适应。 对于其他人来说,这是一张剪纸,它使他们无法使用这些功能。 哪个提出了一个问题,Markdown 是为谁设计的,现在它的用户是谁?

跳跃后更多! 继续往下看↓

Markdown 的用户应该是谁?

我们已经看到降价存在于不同用例、受众和用户的概念之间的紧张关系。 最初是专门为精通 HTML 的 Web 编写者提供的标记语言,后来成为开发人员类型的宠儿。

2014 年,Web 编写者开始不再通过 Perl 和 FTP 中的解析器来移动文件。 WordPress、Drupal 和 Moveable Type(我相信 Gruber 仍在使用)等内容管理系统 (CMS) 已稳步发展成为网络发布的首选工具。 他们提供了诸如富文本编辑器之类的功能,网络作家可以在他们的浏览器中使用。

这些富文本编辑器仍然假定 HTML 和 Markdown 作为底层的富文本语法,但他们通过添加按钮以在编辑器中插入此语法,从而消除了一些认知开销。 越来越多的作家不必也不必精通 HTML。 我敢打赌,如果您在 2010 年代使用 CMS 进行 Web 开发,您可能不得不处理当人们直接从 Word 粘贴时通过这些编辑器出现的“垃圾 HT​​ML”。

今天,我将论证 Markdown 的主要用户是开发人员和对代码感兴趣的人。 一旦 Slack 的软件被技术部门以外的更多人使用,Slack 将WYSIWYG默认输入模式并非巧合。 事实上,这是一个有争议的决定,以至于他们不得不将其作为一个选项带回来,这表明开发者社区对降价的热爱有多深。 没有太多庆祝 Slack 试图让每个人都更容易和更容易使用它。 而这正是问题的症结所在。

带有降价的 Slack 评论部分。
(大预览)

Markdown 的意识形态

Markdown 已成为通用语言的写作风格,以及大多数网站框架所迎合的事实,这也是我对发布此内容感到有些不安的主要原因。 它经常被谈论为一种与生俱来的、不可否认的好处。 Markdown 已成为对开发人员友好的标志。 聪明和熟练的人在各种情况下都投入了大量的集体时间来启用降价。 所以,挑战它的霸权肯定会惹恼一些人。 但希望它可以就一件通常被认为理所当然的事情引发一些富有成果的讨论。

我的印象是,人们对 Markdown 的友好程度主要与 3 个因素有关:

  1. 纯文本文件的舒适抽象。
  2. 有一个工具生态系统。
  3. 您可以使您的内容接近您的开发工作流程。

我并不是说这些立场是错误的,但我会建议它们伴随着权衡和一些不合理的假设。

纯文本文件的简单心理模型

数据库是惊人的东西。 但它们也因前端开发人员难以访问而享有盛誉。 我认识很多优秀的开发人员,他们回避后端代码和数据库,因为它们代表了他们不想花时间在上面的复杂性。 即使使用 WordPress,它做了很多开箱即用的工作,让您不必在设置后处理其数据库,启动和运行也是开销。

然而,纯文本文件更加有形,而且推理起来相当简单(只要您习惯于文件管理)。 特别是与将您的内容分解为具有某些专有结构的关系数据库中的多个表的系统相比。 对于有限的用例,例如带有图像和链接的简单富文本的博客文章,markdown 将完成工作。 您可以复制文件并将其粘贴到文件夹中或将其签入 git。 由于文件的有形性,内容感觉是的。 即使它们托管在 GitHub 上,GitHub 是 Microsoft 拥有的营利性软件即服务,因此受其服务条款的保护。

在您实际上必须启动本地数据库以进行本地开发并处理与远程同步的时代,纯文本文件的吸引力是可以理解的。 但是随着后端即服务的出现,那个时代几乎已经一去不复返了。 Fauna、Firestore、Hasura、Prisma、PlanetScale 和 Sanity 的 Content Lake 等服务和工具在开发人员体验方面投入了大量资金。 与仅 10 年前相比,即使是运营有关当地发展的传统数据库也变得不那么麻烦了。

如果您考虑一下,如果内容托管在数据库中,您是否拥有更少的内容? 随着 SaaS 工具的出现,开发人员处理数据库的体验是否变得更加简单? 可以公平地说,专有数据库技术会影响您内容的可移植性吗? 今天,您无需系统管理员技能即可启动本质上是 Postgres 数据库,制作表和列,将内容放入其中,并随时将其导出为.sql转储。

首先,内容的可移植性与您如何构建内容有关。 以 WordPress 为例,它是完全开源的,您可以托管自己的数据库。 它甚至具有标准化的 XML 导出格式。 但是任何试图退出成熟的 WordPress 安装的人都知道,如果您试图摆脱 WordPress,这将有多大帮助。

庞大的生态系统……对于开发人员

我们已经触及了庞大的降价生态系统。 如果您查看当代网站框架,它们中的大多数都认为降价是主要的内容格式,其中一些是唯一的格式。 例如,Smashing Magazine 使用的静态站点生成器 Hugo,仍然需要 markdown 文件进行分页发布。 这意味着如果 Smashing Magazine 想要使用 CMS 来存储文章,它必须与 markdown 文件交互,或者将所有内容转换为 markdown 文件。 如果您查看 Next.js、Nuxt.js、VuePress、Gatsby.js 等的文档,markdown 将占据显着位置。 它也是 GitHub 上README文件的默认语法,它也使用它来格式化拉取请求注释和评论。

有一些荣誉提到了将降价的人体工程学带给大众的举措。 Netlify CMS 和 TinaCMS(Forestry 的精神后裔)将为您提供用户界面,其中 Markdown 语法大部分是为编辑器抽象出来的。 您通常会发现 CMS 中基于 Markdown 的编辑器为您提供格式的预览功能。 一些编辑器,比如 Notion 的,会让你粘贴 markdown 语法,他们会将它翻译成他们的原生格式。 但我认为可以肯定地说,为降价而创新的精力并没有偏爱那些不喜欢编写其语法的人。 它并没有像以前那样从堆栈中溢出。

内容工作流程还是开发人员工作流程?

对于制作博客的开发人员来说,使用 markdown 文件可以减少启动和运行它的一些开销,因为框架通常带有内置解析或通常将其作为启动代码的一部分提供。 没有什么额外的注册。 您可以使用 git 将这些文件与您的代码一起提交。 如果您对 git diffs 感到满意,您甚至可以像在编程中习惯的那样进行修订控制。 换句话说,由于降价文件是纯文本的,它们可以与您的开发人员工作流程集成。

但除此之外,开发人员的体验很快就会变得更加复杂。 您最终会损害您团队作为内容创建者的用户体验,而我们自己的开发人员体验则被 Markdown 所困扰,以解决超出其设计意图的问题。

是的,如果你让你的内容团队使用 git 并检查他们的更改可能会很酷,但与此同时,这是对他们时间的最佳利用吗? 您是否真的希望您的编辑器遇到合并冲突或如何重新设置分支? Git 对于每天都在使用它的开发者来说已经够难了。 对于主要处理内容的人来说,这种设置真的代表了最佳工作流程吗? 这难道不是开发人员体验胜过编辑体验的情况吗?难道不是成本、时间和精力可以用来为用户做出更好的东西吗?

因为来自内容和编辑环境的期望和需求已经发生了变化,我认为降价不会为我们做这件事。 我看不出某些开发人员的人体工程学最终会如何偏向非开发人员,而且我认为即使对于开发人员来说,降价也会阻碍我们自己的内容创建和需求。 因为自 2000 年代初以来,网络上的内容发生了显着变化。

从段落到块

如果你想要更复杂的东西,Markdown 总是可以选择退出 HTML。 当作者也是网站管理员或至少知道 HTML 时,这很有效。 它也运行良好,因为网站通常主要是 HTML 和 CSS。 您设计网站的方式主要是通过创建整个页面布局。 您可以将 Markdown 转换为 HTML 标记并将其放在您的style.css文件旁边。 当然,我们在 2000 年代也有 CMS 和静态站点生成器,但它们的工作原理大致相同,通过在模板中插入 HTML 内容而不在组件之间传递任何“道具”。

但我们大多数人不再像过去那样真正编写 HTML。 Web 上的内容已经从主要是具有简单富文本格式的文章演变为通常具有用户交互性的组合多媒体和专用组件(这是一种奇特的说法,即“新闻通讯注册号召性用语”)。

从文章到应用

在 2010 年代初期,Web 2.0 处于鼎盛时期,软件即服务公司开始将 Web 用于数据密集型应用程序。 HTML、CSS 和 JavaScript 越来越多地用于驱动交互式 UI。 Twitter 开源 Bootstrap,这是他们构建更一致和更有弹性的用户界面的框架。 这推动了我们所谓的网页设计“组件化”。 它从根本上改变了我们为 Web 构建的方式。

在这个时代出现的各种 CSS 框架(例如 Bootstrap 和 Foundation)倾向于使用标准化的类名并假设特定的 HTML 结构,以降低制作弹性和响应式用户界面的难度。 随着原子设计的网页设计理念和像块元素修改器(BEM)这样的类名约定,默认值从首先考虑页面布局转变为将页面视为可重复和兼容的设计元素的集合。

无论您在降价中拥有的任何内容都与此不兼容。 除非您陷入插入降价解析器的兔子洞,并对其进行调整以输出您想要的语法(稍后会详细介绍)。 难怪,Markdown 被设计为包含原生 HTML 元素的简单富文本文章,您可以使用样式表作为目标。

对于使用 Markdown 为其网站驱动内容的人来说,这仍然是一个问题。

可嵌入网络

但是我们的内容也发生了一些事情。 我们不仅可以开始在语义<article> HTML 标签之外找到它,而且它开始包含更多……东西。 我们的很多内容从我们的 LiveJournals 和博客转移到社交媒体:Facebook、Twitter、tumblr、YouTube。 为了让内容片段回到我们的文章中,我们需要能够嵌入它们。 HTML 约定开始使用<iframe>标记从 YouTube 引导视频播放器,甚至在文本段落之间插入推文框。 一些系统开始将其抽象为“短代码”,通常是包含一些关键字的括号,以识别它应该代表什么内容块,以及一些键值属性。 例如,dev.to 允许将模板语言液体中的语法插入到他们的 Markdown 编辑器中:

 {% youtube dQw4w9WgXcQ %}

当然,这需要您使用自定义的 Markdown 解析器,并具有特殊的逻辑来确保在将语法转换为 HTML 时插入正确的 HTML。 您的内容创建者必须记住这些代码(除非有某种工具栏可以自动插入它们)。 如果一个括号被删除或弄乱了,那可能会破坏网站。

但是MDX呢?

解决块内容需求的一种尝试是 MDX,其标语为“组件时代的 Markdown”。 MDX 允许您使用 JSX 模板语言,以及 JavaScript,在 markdown 语法中交错。 围绕 MDX 的社区中有很多令人印象深刻的工程,包括Unified.js ,它专门将各种语法解析为抽象语法树 (AST),以便更易于以编程方式使用它们。 请注意,markdown 的标准化将使Unified.js及其用户的工作更简单,因为需要满足的边缘情况更少。

MDX 无疑为将组件集成到 Markdown 中的开发人员带来了更好的体验。 但它并没有带来更好的编辑体验,因为它给内容制作和编辑增加了很多认知开销:

 import {Chart} from './snowfall.js' export const year = 2018 # Last year's snowfall In {year}, the snowfall was above average. It was followed by a warm spring which caused flood conditions in many of the nearby rivers. <Chart year={year} color="#fcb32c" />

对于这个简单的例子,假设的知识量是巨大的。 你需要了解 ES6 模块、JavaScript 变量、JSX 模板语法,以及如何使用 props、十六进制代码和数据类型,你需要熟悉可以使用哪些组件,以及如何使用它们。 你需要在一个能给你某种反馈的环境中正确地输入它。 我毫不怀疑,在 MDX 之上会有更多可访问的创作工具,感觉就像解决一些原本不需要成为问题的事情。

除非您非常勤奋地编写和命名 MDX 组件,否则它还会将您的内容与特定的演示文稿联系起来。 就拿上面从 MDX 头版带来的例子来说吧。 您会找到图表的硬编码颜色十六进制。 当您重新设计网站时,该颜色可能与您的新设计系统不兼容。 当然,没有什么能阻止你抽象它并使用 prop color=”primary” ,但工具中也没有任何东西可以推动你做出这样的明智决定。

在您的内容中嵌入特定的表示关注点已越来越成为一种责任,并且会妨碍您的内容适应、迭代和快速移动。 它以比在数据库中包含内容更微妙的方式锁定它。 您可能最终与使用插件退出成熟的 WordPress 安装在同一个地方。 分解结构和表示是很麻烦的。

对结构化内容的需求

随着更复杂的网站和用户旅程,我们还看到需要在整个网站中呈现相同的内容。 如果您正在运营一个电子商务网站,您希望在单个产品页面之外的许多地方嵌入产品信息。 如果您运行一个现代营销网站,您希望能够在多个个性化视图中共享相同的副本。

为了有效和可靠地做到这一点,您需要调整结构化内容。 这意味着您的内容需要嵌入元数据并以能够解析意图的方式进行分块。 如果开发人员只看到带有“内容”的“页面”,那么很难在正确的位置包含正确的内容。 如果他们可以通过 API 或查询获得所有“产品描述”,那一切都会变得更容易。

使用降价,您只能将分类法和结构化内容表达为某种文件夹组织(使得很难将相同的内容放在多个分类法中),或者您需要用其他东西来扩充语法。

Jekyll 是一个为 Markdown 文件构建的早期静态站点生成器 (SSG),它引入了“Front Matter”作为使用 YAML(一种使用空格来创建范围的简单键值格式)在顶部的三个破折号之间添加元数据的方法的文件。 所以,现在您将有两种语法需要处理。 YAML 也以恶作剧而闻名(尤其是如果您来自挪威)。 尽管如此,其他 SSG 以及使用 markdown 作为其内容格式的基于 git 的 CMS 都采用了此约定。

当您必须在纯文件中添加额外的语法以获得结构化内容的某些功能时,您可能会开始怀疑它是否真的值得。 以及格式适用于谁以及排除谁。

如果你想一想,我们在网络上所做的很多事情不仅是消费内容,我们还在创造它! 我目前正在浏览器的高级文字处理器中编写这篇冗长的文章。

人们越来越期望您还应该能够在现代内容应用程序中创作阻止内容。 人们已经开始习惯于令人愉悦的用户体验,这些体验可以工作且看起来不错,而且您不必学习专门的语法。 Medium 普及了您可以在网络上创建令人愉悦且直观的内容的概念。 说到“概念”,流行的笔记应用程序已经全力以赴阻止内容,并允许用户从各种不同类型中混合最大。 这些块中的大多数都超出了降价和 HTML 的原生元素。

关于概念的块内容示例。
(大预览)

值得注意的是,Notion 描述了他们通过备受期待的 API 使他们的内容可访问的过程,并强调了选择他们的内容格式,即:

来自一个 Markdown 编辑器的文档通常会在另一个应用程序中以不同方式解析和呈现。 对于简单的文档,这种不一致往往是可以管理的,但对于 Notion 丰富的块库和内联格式化选项来说,这是一个大问题,其中许多在任何广泛使用的 Markdown 实现中根本不支持。

Notion 采用基于 JSON 的格式,可以让它们表达为结构化数据。 他们的论点是,对于想要构建自己的来自 Notion API 的块内容表示的开发人员来说,它使交互变得更容易和更可预测。

如果不是 Markdown,那又如何?

我怀疑 Markdown 的重要性阻碍了数字内容的创新和进步。 因此,当我认为我们应该停止选择它作为存储内容的主要方式时,很难直接回答应该用什么来代替它。 然而,我们所知道的是我们应该从现代内容格式和创作工具中得到什么。

让我们投资于无障碍创作体验

使用 markdown 需要您学习语法,并且通常需要学习多种语法和定制标签才能符合现代期望。 今天,对于大多数人来说,这感觉完全是不必要的期望。 我希望我们能够将更多的精力投入到制作可访问且令人愉悦的编辑体验中,从而产生现代便携式内容格式。

尽管众所周知很难构建出色的块内容编辑器,但仍有一些可行的选项可以针对您的用例进行扩展和定制(例如 Slate.js、Quill.js 或 Prosemirror)。 再说一次,围绕这些工具投资社区也可能有助于他们的进一步发展。

人们越来越希望创作工具具有可访问性、实时性和协作性。 为什么必须在 2021 年在网络上按下保存按钮? 为什么不能在不冒竞争条件的情况下更改文档,因为您的同事碰巧在选项卡中打开了文档? 我们是否应该期望作者必须处理合并冲突? 难道我们不应该让内容创建者更容易地使用有意义的视觉启示来处理结构化内容吗?

有点争议:过去十年在响应式 JavaScript 框架和 UI 组件方面的创新非常适合创建出色的创作工具。 而不是使用它们将 Markdown 转换为 HTML 并转换为抽象语法树,然后将其集成到输出 HTML 的 JavaScript 模板语言中。

块内容应遵循规范

我没有提到 HTML 的 WYSIWYG 编辑器。 因为他们是错的。 现代块内容编辑器最好与指定格式进行互操作。 上述编辑器至少有一个合理的内部文档模型,可以转换成更便携的东西。 如果您查看内容管理系统环境,您会开始看到各种基于 JSON 的块内容格式出现。 其中一些仍然依赖于 HTML 假设或过度关注字符位置。 And none of them aren't really offered as a generic specification.

At Sanity.io, we decided early that the block content format should never assume HTML as neither input nor output, and that we could use algorithms to synchronize text strings. More importantly, was it that block content and rich text should be deeply typed and queryable. The result was the open specification Portable Text. Its structure not only makes it flexible enough to accommodate custom data structures as blocks and inline spans; it's also fully queryable with open-source query languages like GROQ.

Portable Text isn't design to be written or be easily readable in its raw form; it's designed to be produced by an user interface, manipulated by code, and to be serialized and rendered where ever it needs to go. For example, you can use it to express content for voice assistants.

 { "style": "normal", "_type": "block", "children": [ { "_type": "span", "marks": ["a-key", "emphasis"], "text": "some text" } ], "markDefs": [ { "_key": "a-key", "_type": "markType", "extraData": "some data" } ] }

An interesting side-effect of turning block content into structured data is exactly that: It becomes data! And data can be queried and processed. That can be highly useful and practical, and it lets you ask your content repository questions that would be otherwise harder and more errorprone in formats like Markdown.

For example, if I for some reason wanted to know what programming languages we've covered in examples on Sanity's blog, that's within reach with a short query. You can imagine how trivial it is to build specialized tools and views on top of this that can be helpful for content editors:

 distinct( *["code" in body[]._type] .body[_type == "code"] .language ) // output [ "text", "javascript", "json", "html", "markdown", "sh", "groq", "jsx", "bash", "css", "typescript", "tsx", "scss" ]

Example: Get a distinct list of all programming languages that you have code blocks of.

Portable Text is also serializable, meaning that you can recursively loop through it, and make an API that exposes its nodes in callback functions mapped to block types, marked-up spans, and so on. We have spent the last years learning a lot about how it works and how it can be improved, and plan to take it to 1.0 in the near future. The next step is to offer an editor experience outside of Sanity Studio. As we have learned from Markdown, the design intent is important.

Of course, whatever the alternative to markdown is, it doesn't need to be Portable Text, but it needs to be portable text. And it needs to share a lot of its characteristics. There have been a couple of other JSON-based block content format popping up the last few years, but a lot of them seem to bring with them a lot of “HTMLism.” The convenience is understandable, since a lot of content still ends up on the web serialized into HTML, but the convenience limits the portability and the potential for reuse.

You can disregard my short pitch for something we made at Sanity, as long as you embrace the idea of structured content and formats that let you move between systems in a fundamental manner. For example, a goal for Portable Text will be improved compatibility with Unified.js, so it's easier to travel between formats.

Embracing The Legacy Of Markdown

Markdown 的所有风格、解释和分叉都不会消失。 I suspect that plain text files will always have a place in developers' note apps, blogs, docs, and digital gardens. As a writer who has used markdown for almost two decades, I've become accustomed to “markdown shortcuts” that are available in many rich text editors and am frequently stumped from Google Docs' lack of markdownisms. But I'm not sure if the next generation of content creators and even developers will be as bought in on markdown, and nor should they have to be.

I also think that markdown captured a culture of savvy tinkerers who love text, markup, and automation. I'd love to see that creative energy expand and move into collectively figuring out how we can make better and more accessible block content editors, and building out an ecosystem around specifications that can express block content that's agnostic to HTML. Structured data formats for block content might not have the same plain text ergonomics, but they are highly “tinkerable” and open for a lot of creativity of expression and authoring.

If you are a developer, product owner, or a decision-maker, I really want you to be circumspect of how you want to store and format your content going forward. If you're going for markdown, at least consider the following trade-offs:

Markdown is not great for the developer experience in modern stacks :

  • It can be a hassle to parse and validate, even with great tooling.
  • Even if you adopt CommonMark, you aren't guaranteed compatibility with tooling or people's expectations.
  • It's not great for structured content, YAML frontmatter only takes you so far.

Markdown is not great for editorial experience :

  • Most content creators don't want to learn syntax, their time is better spent on other things.
  • Most markdown systems are brittle, especially when people get syntax wrong (which they will).
  • It's hard to accommodate great collaborative user experiences for block content on top of markdown.

Markdown is not great in block content age , and shouldn't be forced into it. Block content needs to:

  • Be untangled from HTMLisms and presentation agnostic.
  • Accommodate structured content, so it can be easily used wherever it needs to be used.
  • Have stable specification(s), so it's possible to build on.
  • Support real-time collaborative systems.

What's common for people like me who challenge the prevalence of markdown, and those who are really into the simple way of expressing text formating is an appreciation of how we transcribe intent into code. That's where I think we can all meet. But I do think it's time to look at the landscape and the emerging content formats that try to encompass modern needs, and ask how we can make sure that we build something that truly caters to editorial experience, and that can speak to developer experience as well.

I want to express my gratitude to Titus Wormer (@wooorm) for his insightful feedback on my first draft of this post, and for the great work he and the Unified.js team have done for the web community.