精讀《對 Markdown 的思考》

黃子毅發表於2022-02-21

Markdown 即便在 2022 年也非常常用,比如這篇文章依然採用 Markdown 編寫。

但 Markdown 是否應該成為文字編輯領域的預設技術選型呢?答案是否定的。我找到了一篇批判無腦使用 Markdown 作為技術選型的好文 Thoughts On Markdown,它提到 Markdown 在標準化、結構化、元件化都存在硬傷,如果你真的想做一個現代化的文字結構編輯器,不要採用 Markdown。

概述

Markdown 流傳甚廣,甚至已成為我們的第二語言。Markdown 最早的解析器由 John Gruber 在 2004 年基於 Perl 編寫釋出,那時候 Markdown 只有一個目的,即為了方便網路寫作。

網路寫作必須基於 HTML 規範,而 HTML 規範對大部分人上手成本太高,因此 Markdown 就是基於文字建立的更易理解,或者說上手成本更低,甚至傻瓜化的一種語法,而要解析這個語法需要配套一個解析器,將這種語法文字最終轉化為 HTML。

而數字化發展到今天,Markdown 已不再適合當下的寫作場景了,主要原因有二:

  1. Markdown 不再適合當下富互動、內容形態的編寫。
  2. Markdown 純文字的開發體驗不再滿足當代開發者日益提高的體驗需求。

首先還是從 Markdown 思想開始介紹。

Markdown 的核心思想

Markdown 最大優勢就是好上手,不需要接觸 HTML 這種複雜的巢狀語句(雖然對程式設計師來說 HTML 也簡單到處於鄙視鏈底端)。原文抽象了三個優勢:

  1. 基於文字的合適抽象。雖然 HTML 甚至程式碼都是文字,但 “合適” 這個詞很重要,即任何文字都可以是 Markdown,只要加一點點小標記就能描述專業結構,學習成本極低。
  2. 有大量生態工具。比如語法解析器、高亮、格式轉換、格式化、渲染等工具完備。
  3. 編輯內容便於維護。比如 Markdown 很方便作為原始碼儲存,而其他格式的富文字可能並不方便在原始碼裡維護。

如果把 Markdown 與資料庫表結構做比較,那資料庫的理解成本真是太高了。

但是在如今後端即服務的時代,資料庫訪問越來越輕鬆,甚至出現大量如 AirTable 等 SAAS 產品將結構化資料快速轉化為應用,其實接觸了這些後才真正發現,結構化資料對開發者有多重要。Markdown 用來寫寫文章還是不錯的,但用來表達邏輯結構最後一定會引發災難後果,原文作者的團隊就深受 Markdown 技術選型的困擾,被迫解決大量遠超預期的難題。

如果真的要在 Markdown 的坑越走越深,就必須使用語法擴充來滿足自定義訴求。

Markdown 語法擴充

最初 Markdown 語法是不支援表格的,如果想用 Markdown 繪製一張表格,只能使用原生 HTML 標籤:<tabke></table>,當然,這也說明了 Markdown 本質就是給 HTML 加強了便捷的語法,我們完全可以將其當 HTML 使用。

然而並不是所有創作平臺都支援 <table></table> 語法的,筆者自己就經常受到困擾,比如有些平臺會遮蔽原生 HTML 語法,已保障所謂的 “安全性” 或者內容體驗的 “一致性”,而這些平臺為了彌補缺失的繪製表格能力,往往會支援一些自定義語法,更糟糕的是不支援,這就說到了 Markdown 的語法擴充。

Markdown 有哪些擴充呢?比如:multiMarkdowncommonMarkGithub Flavored Markdown 等等。

這裡隨便舉個例子,比如標準 MD 格式,其實第一行最後要加兩個空格才能換行,但 GFM 取消了這個限制。這雖然更方便了,但暴露出平臺間規範的不一致性,導致 Markdown 跨平臺基本一定被坑。

而各平臺擴充的語法,我們是否有足夠的精力學習和記憶呢?先不說能不能記得下來,首先值不值得學習就是個問題,為什麼一個網路寫作平臺需要佔用寫手學習與認知成本,而不是想辦法去簡化寫作流程呢?所以語法擴充看似很美好,但放在寫手角度,或者整個網際網路各平臺林立的角度來看,這種非標準的做法一定不靠譜,沒有使用者覺得你的平臺有資格 “教他語法”,除非你是微信,釘釘或者飛書。

原文提到的觀點是:

  1. 作為寫手,你不知道 Markdown 哪些語法可用,哪些語法不可用。
  2. 標準規範存在一些 模糊地帶 導致開發者實現時也會遇到各種糾結。

原文還提到一個語法擴充導致理解成本增高的例子:slack 平臺自定義的 mrkdown 就不支援 [link](https://slack.com) 方式描述連結,而使用了 <link|https://slack.com> 語法。

總結來說,Markdown 語法擴充本應該是件好事,但實際無標準導致了標準的百花齊放,使 Markdown 成為了實際上沒有標準的狀態,整體來看弊端更多。

Markdown 面向的使用者群

Markdown 的對自己的定位其實很不清晰,這也導致了一直不想確定標準化語法。

最初 Markdown 是服務給熟悉 HTML 的人提供的標記語言,而後來面向使用者群實質上轉向了開發者,因為開發者才會想到擴充語法以滿足更復雜的使用場景,Markdown 原生語法無法適應越來越複雜的視覺展示形態。

如今 Markdown 的主要使用者已經是開發人員與對程式碼感興趣的人了,這倒不是說開發者有多喜歡它,而是在說 Markdown 的受眾變窄了。如今任何一款面向非開發者群體的文件編輯器都不會採用 Markdown 了,而是所見即所得的 WYSIWYG(what you see is what you want)模式。

這個轉變的過程是痛苦的,但現在來看,富文字編輯器不應用用 Markdown 語法,而是 WYSIWYG 模式已經是共識了。

從段落到區塊、從文章到應用

簡單來說,即 Markdown 已經不適應當前 HTML 豐富的生態了,能輕鬆描述段落的標記語言,遇到富有互動的元件區塊時,不得不引入例如 MDX 等方案,但這樣的方案根本只適合程式設計師群體,完全無法移植。

網路瀏覽形態也從簡單的文章發展到具有整體性的應用,這些應用擁有複雜的佈局、樣式與互動,如果你嘗試基於 Markdown 擴充語法來支援,最後可能發現還不如直接用原生 HTML。

對結構化內容的訴求

從程式設計角度理解就是 “元件複用”。Markdown 原生語法無法實現內容的複用,如果必須要複用內容,只能將其重複寫在每一處,勢必造成巨大同步成本。

比如 Jekyll 就提出了 FrontMatter 概念用來建立複用的變數:

---
food: Pizza
---

<h1>{{ page.food }}</h1>

WYSIWYG 編輯器不應將 HTML 作為底層資料結構

雖然瀏覽器真正將 HTML 作為底層資料結構,但這並不代表所見即所得的編輯器也可以如此,這也是為什麼瀏覽器只能提供從原始碼到 UI 的輸出,而不能提供從 UI 編輯到原始碼的反向輸入。

因為使用者的輸入與 HTML 並不是一一對應關係,其中存在大量模糊地帶,比如當前游標處在粗體與細體文字中間,那下一個輸入到底算加粗還是不加粗呢?從 UI 上看不到加粗標籤。再有,如果 HTML 存在冗餘,其實當前游標所在位置已經被加粗標籤包裹了好幾層,但因為游標所在區域又被另一個樣式標籤覆蓋成非加粗模式,當再次輸入時可能就跳出了覆蓋範圍,重新變成了加粗,這個過程符合使用者預期嗎?從技術上,這種複雜標籤結構也幾乎無法被處理,因為組合花樣實在太多。

現代大多數編輯器都以 JSON 格式儲存資料結構,就因為其結構化且易於檢索。

結構化最重要的體現是,其生成的 HTML 結構可以是穩定的,即對於一個既加粗又標紅的文字,一定包裹在一個 <strong style="color: red"> 標籤裡,而不是 <strong><div style="color: red">,也就是這種模式根本沒把 HTML 作為結構化資料去看待,自然就不會出現歧義。

Markdown 也是一樣,其本身也會出現類似 HTML 標籤的二義性,不適合作為底層資料結構儲存。

精讀

批判 Markdown 的文章不多見,筆者也是看了之後才恍然發現 Markdown 竟然有這麼多缺點。筆者結合自己的經驗談談 Markdown 的缺點吧。

不支援富互動的無奈

Markdown 僅能支援簡單的 HTML 結構,而無法描述邏輯區塊。Github 上大部分 Readme 都採用圖片來實現這些功能,包括狀態卡片、構建結果、個人資訊名片等,可惜互動能力還是太弱,我覺得有朝一日 Github 應該會推出比如 Block 小區塊的概念,讓這些區塊可以直接插入 Markdown 成為一個可互動的元素。

MDX 解決了 Markdown 的痛點嗎?

看似完美相容 JSX 與 Markdown 的 MDX 曾經也是筆者寫作的救命稻草,但該方案移植性是一大痛點,元件只能在自己部署的網站用,如果你想把文章釋出到另一個平臺,完全不可能。

這還僅是筆者的視角,如果從 Markdown 生態來看,MDX 面向使用者僅是程式設計師群體,根本沒有解決其使命 “方便網路寫作”,而程式設計師最終也會拋棄 MDX 而轉向開發所見即所得編輯器解決問題。

Markdown 到 HTML 的轉換存在邏輯問題

Markdown 本質上還是一種脫離 HTML 的文字表示結構,看上去解耦很優雅,實際上會遇到不少不一致的問題。

比如說連續敲擊多個空格會出現什麼情況呢?在 Markdown 會變成一個引用區塊,那如何才能展示多個空格呢?誰也不知道,可能需要查閱具體平臺提供的額外語法才可以做到。

這種大體上用起來方便,但細節無法定製,甚至使用者無法控制的情況會大大傷害已經深度使用 Markdown 的使用者,此時使用者要麼硬著頭皮發明新語法解決這些漏洞,要麼就完全放棄 Markdown 了。

結構化能力不足

看上去 Markdown 的語法挺具有結構化的,但實際上 Markdown 的結構化不具有強約束力。

拿 JSON 作對比,比如我們可以用 JSON 擴充出 https://json-schema.org/ 結構,這個結構甚至可以反推出一個完整的表單應用,其原因是 JSON 可以針對每一個 Key、層級下定義,首先有結構,其次才有內容。

而 Markdown 正好反過來,是先有內容,再有結構。比如我們可以在 Markdown 任何地方寫任何 HTML 標籤,或者任意段落的問題,這些內容是無法被序列化的,即便我們按照瀏覽器解析 HTML 的規則解析成 JSON,也無法從中方便的提取資訊。

背後的根本原因是,Markdown 本身定位就是 “近乎於 UI 渲染結果” 的,而實際上瀏覽器渲染 UI 背後是需要一套嚴謹的 HTML 語法,因為 UI 與背後語法並不能一一建立對映,一個穩定的渲染邏輯只能是從原始碼推導到渲染,而不能從渲染反推出原始碼。Markdown 本身定位就近乎於渲染結果,所以結構化能力不足是天然的問題。

總結

記得語雀早期內部試用時,編輯態還是採用 Markdown 的,但後來很快就把 Markdown 的編輯入口下掉了,這件事還引發了不少開發者的不滿,甚至還有一些 Markdown 編輯的外掛被開發出來,一度很受歡迎。但漸漸的我們都習慣用所見即所得方式編輯了,Markdown 唯一留給我們的印象就是快捷鍵,比如 ### 後敲入空格可以生成 h3 標題段落,而語雀編輯器也在富互動元件區塊上越走越遠,要是當年被 Markdown 鎖定住了技術,也不可能有今天這麼高階的編輯體驗。

所以技術前瞻性真的很重要,Markdown 所有程式設計師都愛,但提前看到它在當前網際網路發展階段的侷限性,並設計一套結構化資料代替 Markdown 結構不是所有人都能想到的,我們需要以動態的眼光看待技術,也要放下技術人的偏見,把偏愛讓位於產品定位。

討論地址是:精讀《對 Markdown 的思考》· Issue #397 · dt-fe/weekly

如果你想參與討論,請 點選這裡,每週都有新的主題,週末或週一釋出。前端精讀 - 幫你篩選靠譜的內容。

關注 前端精讀微信公眾號

<img width=200 src="https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg">

版權宣告:自由轉載-非商用-非衍生-保持署名(創意共享 3.0 許可證

相關文章