關於降價的思考

已發表: 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 編輯器。 因為他們是錯的。 現代塊內容編輯器最好與指定格式進行互操作。 上述編輯器至少有一個合理的內部文檔模型,可以轉換成更便攜的東西。 If you look at the content management system landscape, you start to see various JSON-based block content formats emerge. Some of them are still tied to HTML assumptions or overly concerned with character positions. 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.