我的自述文件第一次跨越一千行時,我做了每個人都會做的事情:我滾動。然後我又滾動了一些。在第四遍的某個地方尋找 "部署&引用;部分,我放棄了,開始在文件頂部手寫目錄。這一直有效,直到我重新命名標題,忘記更新鏈接,並發貨了一個自述文件,其中 "配置&引用;什麼都不指。您自己的文件中的頁面內損壞連結是一件小事,但它是一種告訴讀者沒有人關心商店的小事。
我建立了 [toolz。dev](/,一系列基於瀏覽器的開發人員實用程序,並且我維護了許多 Markdown:工具指南、自述文件、內部規範和您現在正在閱讀的文檔。目錄我必須手動維護的是最終會說謊的內容表。所以我建立了 Markdown TOC 產生器 每次正確完成鑽孔部分,本指南是我在建造錨鏈時了解到的有關錨鏈的所有內容。
TL;DR: Markdown 目錄是跳到同一頁標題的連結的嵌套清單。這些連結之所以有效,是因為每個標題都有一個自動錨點 id,而 GitHub 分配的 slug 遵循特定規則:將文字小寫,刪除連字符以外的標點符號,並將空格轉換為連字符。將 Markdown 貼到生成器中,選擇要包含的標題級別,然後複製該清單。該工具計算精確的 slugs GitHub 渲染,包括
-1重複標題的後綴,因此當您將其貼回時,不會有任何損壞。
什麼是 Markdown 目錄?
Markdown 中的目錄不是特殊語法。 通用標記 沒有定義這樣的構造,github Flavored Markdown 也沒有定義。它是一個普通列表,其中每個項目都是一個鏈接,並且每個鏈接都指向同一文檔內的錨點。當像 GitHub 這樣的 Markdown 渲染器將標題轉換為 HTML 時,它也會為該標題提供 a id 屬性。寫為的標題 ## Getting Started 變得粗略 <h2 id="getting-started">Getting Started</h2>。 一旦該 id 存在,連結就會寫為 [Getting Started](#getting-started) 將頁面捲動到它。
因此,目錄只是這些連結的集合,縮排以反映標題層次結構:
- [Getting Started](#getting-started)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
整個技巧都存在於該範例中的一個單字中:錨點。錨點出錯,連結默默地失敗,無處滾動。把它做好,內容區塊可以在 GitHub 上、大多數靜態站點生成器以及遵循相同約定的文件平台內運行。困難的部分不是寫列表。困難的部分是預測每個渲染器將分配的確切 ID,這就是為什麼在任何更改的文件上手動執行它都是一個失敗的遊戲。
航向錨實際上是如何產生的?
GitHub' sslug 演算法是確定性的,值得記住,因為一旦您知道它,您就可以預測頁面上的每個錨點。步驟依序為:將標題文字轉換為小寫,刪除任何不是字母、數字、空格或連字符的字符,然後用連字符替換每個空格。這就是整個規則。
後果是人們旅行的地方。考慮一個類似的標題 ## Set Up & Config. 下殼給出 set up & config. 刪除&號(但留下其周圍的空格)給出 set up config 有兩個空間 & 曾經是。將空間變成連字符會產生 set-up--config,帶有雙連字符。這個雙連字符看起來像是錯誤,但它正是 GitHub 所呈現的,所以這正是您的連結所需要的。一個工具,"清理並引用;雙連字符將產生一個無法解析的連結。
重標點符號的標題崩潰得比你預期的還要嚴重。 ## C++ Guide 成為 c-guide,因為兩個加號都被剝離,剩下的空格變成一個連字符。 ## What's New? 成為 whats-new,因為撇號和問號消失了。表情符號和大多數符號完全消失。這 Markdown TOC 產生器 將此規則字元套用為字符,以便 slug 顯示您是 GitHub 將建立的 ID,不涉及猜測。
當兩個標題相同時會發生什麼事?
文件重複標題。變更日誌可能包含三個部分,全部標題為 ### Fixed. 如果他們每個人都產生了slug fixed,只有第一個連結可以工作。 GitHub 透過對重複項進行編號來解決這個問題:第一個 Fixed 得到 fixed,第二個得到 fixed-1,第三個得到 fixed-2,依此類推,依文件順序排列。後綴附加在基數slug之後,並帶有連字符。
這是手寫目錄不同步的最常見原因之一。您新增第二個部分,其中包含您已使用的名稱,錨點將悄悄變為 -1,您的舊連結現在指向錯誤的位置或根本沒有指向。生成器追蹤它發出的每個 slug 並應用相同的數字後綴,因此重複的標題連結到正確的出現。
該工具讀取哪些類型的標題?
Markdown 有兩種標題樣式,完整的生成器必須讀取這兩種樣式。常見的是 ATX,其中一行以 1 到 6 開頭 # 字元後面跟著標題文字。哈希數就是水平,所以 # 是H1和 ###### 是 H6。第二種樣式是 Setext,其中下一行文字加下劃線,H1 的符號相等,H2 的連字符:
Document Title
==============
A Section
---------
兩種樣式都會產生帶有錨 id 的標題,因此都屬於目錄。 Setext 的棘手部分是除了水平規則之外還告訴一個真正的下劃線標題,因為一行連字符可以表示其中之一。生成器使用的規則是,連字符下劃線僅在其正上方的行是普通段落文本時才算標題,而不是空白行、列表項、塊引用或其他塊結構。 A --- 單獨坐著,周圍有空白行是一個主題休息,它被正確地忽略了。
還有一個類別需要處理,它悄悄地破壞了樸素的工具:程式碼中的標題。如果您的文件包含一個顯示 shell 命令的圍欄程式碼區塊,其中一些行將以 開頭 # 作為評論。這些不是標題,它們絕不能出現在內容中。生成器追蹤圍欄代碼塊(由三重反向勾選或三重波形符界定的代碼塊)並跳過任何代碼塊 # 它們裡面有線。貝殼評論喜歡 # install dependencies 在範例中,它停留在它所屬的位置。
如何控制目錄的深度?
列出每個標題到 H6 的目錄不是目錄,而是文件的第二份副本。當內容僅涵蓋 H2 和 H3 時,大多數自述文件閱讀效果最佳,為讀者提供主要部分及其直接子部分,而不會詳細淹沒它們。生成器可讓您設定最小和最大級別,並且僅包含屬於該範圍的標題。
這裡的微妙行為是縮排。如果您包含 H2 到 H4,則您保留的最淺航向是 H2,並且它應該與左邊緣齊平,而不是像看不見的 H1 位於其上方一樣縮進。生成器測量相對於其實際包含的最淺航向的嵌套深度,因此從 H2 開始的內容區塊開始時沒有縮排。這是看起來有意的清單和看起來失去第一列的清單之間的差異。
您也可以選擇列表標記。無序清單對每個條目使用一個項目符號,這是自述文件的傳統外觀。有序清單對條目進行編號,生成器重新啟動每個巢狀層級內的計數,以便編號的輪廓正確讀取,而不是直接從 1 到 50 進行計數。縮排可以是兩個空格、四個空格或一個選項卡,具體取決於文件的其餘部分使用什麼。
重音和非拉丁標題怎麼樣?
並非每個標題都是簡單的英文,slug 規則必須處理。 GitHub 保留其他字母表中的字母而不是剝離它們,因此標題類似 ## Configuración 保留其重音字元並成為 configuración,西里爾字母或希臘語的標題也保留了這些字母。被刪除的是標點符號和符號,而不是字母,無論腳本如何。生成器遵循相同的原則,將任何 Unicode 字母或數字視為有效的 slug 字符,因此多語言文檔會產生與 GitHub 渲染的匹配的錨點,而不是一排空連結。
這比它最初看起來更重要。用西班牙語、德語或日語編寫文件的團隊經常發現樸素的 slug 工具將其標題損壞為無法使用的錨點,因為這些工具採用 ASCII。如果您的連結從未在翻譯的自述文件中指向任何內容,那麼默默丟棄非 ASCII 字母的 slug 幾乎肯定是原因。使用 Unicode 感知工具產生內容區塊會刪除整個類別的損壞鏈接,並且這意味著同一文檔可以保存多種語言的標題,而不會失去任何一個錨點。
我什麼時候應該使用產生的 TOC 與自動的 TOC?
有些平台會為您建立目錄。 GitLab 支援 [[_TOC_]] 令牌上,某些 wiki 會自動注入內容框,而 Docusaurus 等文件框架會從標題中呈現頁面大綱,而無需您編寫任何內容。當您在其中一個系統內工作時,請使用內建功能。它以零努力保持最新狀態,因為平台在每次渲染時都會重新生成它。
生成器在其他地方都佔有一席之地,並且 "在其他地方&引用;是一個大地方。 GitHub 自述文件不會自動產生內容區塊,因此儲存庫登陸頁面需要將真實的 Markdown 清單提交到文件中。被轉換為其他內容、透過電子郵件發送、貼上到問題中或由最小檢視器呈現的 Markdown 需要靜態內容區塊,因為沒有引擎可以即時建立內容區塊。下表列出了每種方法的適合位置。
| 情況 | 最佳方法 | 為什麼 |
|---|---|---|
| GitHub 自述文件 | 產生的靜態清單 | GitHub 渲染標題 id,但不會自動插入 TOC |
| GitLab wiki 或文件 | [[_TOC_]] 代幣 |
原生,始終當前 |
| Docusaurus/MkDocs 頁面 | 內建輪廓 | 框架從標題渲染它 |
| 用於匯出的普通 Markdown 檔案 | 產生的靜態清單 | 沒有渲染器可以在查看時建立一個渲染器 |
| 發出或拉取請求描述 | 產生的靜態清單 | 錨點可以工作,但沒有任何東西可以自動產生該清單 |
經驗法則:如果顯示 Markdown 的東西可以自行建立內容,那就讓它吧。如果您的 Markdown 可能在無法讀取的地方讀取,則產生清單並提交它。當您在格式之間進行轉換時, 標記為 HTML 轉換器 和 HTML 到 Markdown 轉換器 自然地與生成的內容塊配對,因為錨在往返中倖存下來。
這如何適應 Markdown 工作流程的其餘部分?
目錄是保持長文檔可讀性的一部分,它與一些習慣一起效果最好。一旦您發布了標題的鏈接,請保持標題文本穩定,因為重命名標題會更改其slug 並破壞指向它的每個鏈接。當您重新命名時,請重新生成內容而不是編輯您記住的一個鏈接,因為重命名通常會將重複後綴編號移至文件下方。
結構化內容受益於同一系列中的其他工具。當文件依賴表格資料時, 降價表 建立正確對齊的管道表,而手動輸入的表幾乎永遠不會正確。當您繼承需要成為乾淨 Markdown 的混亂 HTML 或需要成為 HTML 的乾淨 Markdown 時,轉換器會在保留標題結構的同時處理翻譯。如果您正在審核文件的長度或關鍵字平衡,則 字計數器 給你數字,而不將草稿貼到任何基於雲端的東西上。
一切都在瀏覽器中運行,這比聽起來更重要。自述文件通常包含未發布的功能名稱、內部 URL 或客戶端詳細信息,並且不應僅為了建立連結清單而將這些內容上傳到第三方伺服器。生成器使用客戶端 JavaScript 解析您的 Markdown,因此文件永遠不會離開您的電腦。如果您考慮開發人員工具中的隱私問題,請進行撰寫 資料隱私和線上工具 涵蓋為什麼本地處理是正確的預設值,以及 web 開發人員工具包 匯總我每天訪問的其餘實用程式。
一個快速工作的例子
假設您有此文件:
# Payment Service
## Getting Started
### Requirements
### Local Setup
## API Reference
### Authentication
### Errors
## Deployment
將範圍設定為 H2 到 H3,選擇項目符號列表,然後留下錨鏈接。產生器產生:
- [Getting Started](#getting-started)
- [Requirements](#requirements)
- [Local Setup](#local-setup)
- [API Reference](#api-reference)
- [Authentication](#authentication)
- [Errors](#errors)
- [Deployment](#deployment)
H1 標題被排除在外,因為它位於範圍之上,H2 部分向左齊平,並且它們的 H3 子部分縮排一級。在自述文件中貼上標題下方的區塊,每個條目都會跳到 GitHub 上的其部分。這就是整個工作,在閱讀這句話的時間內完成,並且它保持正確,因為機器計算的是 slugs 而不是您。
常見問題
Markdown 目錄如何運作?
Markdown 目錄是指向同一頁面內標題錨點的連結清單。 Markdown 文件中的每個標題都有一個自動 ID 和一個寫為 的連結 節 跳到它。此工具讀取您的標題,建立匹配的錨點,並為您組裝嵌套清單。
錨鏈接是如何產生的?
錨點遵循 GitHub slug 規則:標題文字小寫,刪除連字符以外的標點符號,空格變為連字符。 &引用;設定&放大;配置&引用;成為 id 設定-配置-配置。當兩個標題產生相同的slug 時,第二個標題會得到-1 後綴,第三個標題會得到-2 後綴,依此類推,與GitHub 呈現它們的方式相符。
它可以與 GitHub 自述文件搭配使用嗎?
是的。 slug 演算法反映了 GitHub 用於渲染標題 ids 的演算法,因此目錄連結在 github。com 上的自述文件中正確解析。貼上您的自述文件,選擇您的標題級別,然後將產生的清單丟棄在標題下方。
我可以選擇出現哪些標題等級嗎?
是的。設定最小和最大級別,例如 H2 到 H4,並且僅包含該範圍內的標題。嵌套深度是相對於最淺的包含標題來測量的,因此輪廓永遠不會以大的空縮排開始。
代碼塊內包含標題嗎?
否。 以圍欄代碼塊內的# 開頭的行(由三重反引號或三重波形符分隔)被視為代碼,而不是標題,因此示例片段和 shell 註釋永遠不會出現在目錄中。
有序和無序 TOC 有什麼區別?
無序目錄對每個條目使用連字符等項目符號標記,而有序目錄則使用在每個嵌套層級內遞增的數字。當讀者從編號大綱中受益時選擇有序的內容,對於更輕、更傳統的內容區塊則選擇無序的內容。
該工具支援 Setext 標題嗎?
是的。它讀取以 # 開頭的 ATX 標題和 Setext 標題,其中一行文字以 H1 的等號或 H2 的連字符下劃線。兩種樣式都以相同的方式轉換為錨鏈接。
Markdown TOC 產生器是免費且私有的嗎?
是的。它是完全免費的,沒有註冊,也沒有限制。所有解析都在您的瀏覽器中使用客戶端 JavaScript 進行,因此您貼上的大幅下注永遠不會離開您的設備,並且一旦頁面加載,該工具就會保持離線工作。



