行內程式碼:一對反引號
- 一對反引號包住句子裡的一個詞組;三個反引號各自獨立成行則包住一整段程式碼。
- 圍欄之間的內容原封不動保留,縮排與所有原本會被解讀成語法的字元都算在內。
- 開頭圍欄後面接語言名稱就會啟動語法標示,寫錯也只是沒有顏色,不會出錯。
- 開了圍欄卻忘了收尾,會把後面整份文件吃掉 - 這是 Markdown 裡破壞力最強的錯誤。
用一對反引號把內容包起來,它就會以等寬字體顯示,而且裡面所有 Markdown 語法一律失效:
請先執行 `npm install`,再編輯 `config/*.json`。
在這裡面寫 `**粗體**` 會原封不動顯示出來。
第二行就是重點所在。在反引號裡面,**粗體** 會顯示成四個星號而不會變粗;my_var_name 中間的底線不會把字變斜體;<div> 會以文字形式顯示,不會被當成 HTML。行內程式碼就是所有語法字元的逃生門。
內容本身含有反引號怎麼辦
外層的反引號比內層多就好,兩個、三個,需要幾個就用幾個:
``用 ` 這個字元可以開始一段行內程式碼``
``` 內容含有 ``兩個`` 的情況就需要三個 ```
如果內容的開頭或結尾就是反引號,請在分隔符內側各補一個空格。渲染器只會剝掉一個開頭與一個結尾空格,所以 `` ` `` 得到的就是一個孤零零的反引號。第一次看到確實會覺得荒謬,但所有 Markdown 教學都是這樣寫的。
行內程式碼不該拿來做什麼
它不是螢光筆。拿反引號來讓產品名稱「看起來醒目」,會給螢幕閱讀器錯誤的訊號,也會讓文章看起來像一份設定檔。請保留給讀者真的可能照打或複製的東西:指令、檔名、函式名、鍵、HTML 標籤。想強調語氣請改用粗體或斜體,想指向文件請用正規的連結。
圍欄式程式碼區塊
只要內容超過一個詞組,就用三個反引號各自獨立成行,把程式碼包在中間:
```
def greet(name):
return f"Hello, {name}"
```
圍欄之間的一切都會被完整保留:縮排、空行、標點,以及所有原本會被當成 Markdown 語法的字元。圍欄式寫法源自 GitHub 風格 Markdown,現在幾乎所有值得一用的渲染器都支援。
波浪號圍欄
三個波浪號的效果一模一樣:
~~~
console.log("結果相同");
~~~
波浪號只在一種情況下真正有用:當你要展示的內容本身含有反引號圍欄。用 ~~~ 包住一段內含 ``` 的 Markdown,兩者就不會打架。除此之外反引號才是慣例。兩種符號不能混用,用反引號開頭就必須用反引號收尾。
圍欄長度與空行
區塊能不能乾淨收尾,由兩條規則決定:
- 結尾圍欄的長度不能短於開頭圍欄,用四個反引號開的區塊要用四個以上收尾。
- 開頭圍欄之前、結尾圍欄之後都要留一行空行。
少了那一行空行,有些解析器會把整個區塊黏進上下段落。這是五秒鐘就能修好、卻讓人卡二十分鐘的問題。
四個空格的縮排寫法,以及圍欄為何勝出
2004 年的原始 Markdown 沒有圍欄。只要連續幾行縮排四個空格(或一個 Tab),那就是程式碼區塊:
範例如下:
$ git status
On branch main
回到一般段落。
這種寫法至今在所有渲染器裡仍然有效,老舊的 README 或十年前的 Stack Overflow 答案裡都會遇到。但還是請一律改用圍欄,理由有四個:
- 沒地方寫語言。縮排區塊無法做語法標示,因為根本沒有位置可以宣告語言。
- 縮排本身就是資料。Python、YAML、Makefile 都在意行首空白。每行多加四個空格、閱讀時再心算扣掉,是自找麻煩。
- 複製貼上就毀了。貼進來的程式碼沒有縮排,每次修改都得手動一行一行補。
- 會和清單打架。在清單項目裡,四個空格本來就代表「這一項的延續內容」,兩套規則直接衝突。
請把四個空格的寫法當成「要看得懂」的語法,而不是「要拿來寫」的語法。
小提醒:轉換舊檔案其實是純機械工作。選取整塊、每行去掉四個空格、包上圍欄,再補一個語言名稱即可。多數編輯器按一次 Shift+Tab 就能完成去縮排。
語言識別字與語法標示
把語言名稱緊接在開頭圍欄後面,中間不要空格:
```python
def greet(name):
return f"Hello, {name}"
```
那個字叫做 info string。渲染器會把它交給 Prism、highlight.js 或 Chroma 之類的標示器,替關鍵字、字串和註解上色。識別字不分大小寫,寫錯也不會出事,只會得到沒有顏色的區塊。既然猜錯零成本,就每個區塊都標上語言。
值得記住的識別字
| 識別字 | 常見別名 | 典型用途 |
|---|---|---|
javascript | js、node | 瀏覽器與 Node.js 程式碼 |
typescript | ts、tsx | 有型別的 JavaScript、React 元件 |
python | py、python3 | 腳本、資料處理、教學範例 |
bash | sh、shell、zsh | Shell 指令與腳本 |
console | shell-session | 含提示符號與輸出的終端機畫面 |
json | jsonc | 設定檔、API 回應 |
yaml | yml | CI 流程、Kubernetes、front matter |
html | xml、svg | 標記語言與模板 |
css | scss、less | 樣式表 |
sql | postgresql、mysql | 查詢語句與資料表結構 |
go | golang | Go 原始碼 |
rust | rs | Rust 原始碼 |
java | - | Java 原始碼 |
c / cpp | c++、cc、h | C 與 C++ 原始碼及標頭檔 |
php | - | PHP 原始碼與模板 |
markdown | md | 當作範例展示的 Markdown 原始碼 |
diff | patch | 變更內容,加減號會分別上色 |
text | plaintext、txt、none | 刻意關閉語法標示 |
diff 區塊
diff 這個識別字會依每行的第一個字元上色:+ 是綠色,- 是紅色。不需要任何額外工具,就能把程式碼區塊變成前後對照:
```diff
function total(items) {
- return items.length
+ return items.reduce((sum, i) => sum + i.price, 0)
}
```
注意未變更的行前面有一個空格,正是它告訴標示器這行維持原色;忘了加就會出現半邊上色的怪 diff。
刻意關閉語法標示
當顏色會誤導讀者時,就把區塊標成 text:日誌輸出、ASCII 示意圖、目錄樹、錯誤訊息都屬於這類。把堆疊追蹤丟給標示器,它會把一堆隨機單字當成關鍵字上色,結果反而更難讀。選 text 是真正的決定,不是退而求其次。
清單裡的程式碼區塊,以及圍欄裡的圍欄
放進清單項目裡
清單裡的圍欄必須縮排到和該項目的文字對齊,否則清單會被它從中間切成兩段。無序清單通常是兩到三個空格,有序清單則是三到四個:
1. 安裝相依套件:
```bash
npm install
```
2. 啟動開發伺服器:
```bash
npm run dev
```
規則和 Markdown 清單裡所有延續內容相同,三點就講完了:
- 縮排要對齊項目文字的第一個字,不是對齊項目符號。
- 開頭與結尾圍欄的縮排必須一致。
- 圍欄前留一行空行,嚴格的解析器才不會抱怨。
注意:縮排寫錯的典型症狀是:區塊後面的編號會重新從 1 開始。看到重新編號,就代表清單在圍欄那裡結束了,而不是延續下去。
在圍欄裡展示圍欄
想展示一段本身含有程式碼區塊的 Markdown,就讓外層圍欄比內層更長。外面四個反引號,裡面三個:
````markdown
程式碼區塊的寫法如下:
```js
alert("hi");
```
````
所有教 Markdown 的教學都靠這個機制運作,包括這一頁。內層若已用四個反引號,外層就用五個;另一個選擇是外層改用 ~~~,它和反引號永遠不會撞在一起。
語法標示到底在哪裡才會生效
圍欄本身幾乎到處都支援,但顏色不是,因為語法標示是另一套獨立的函式庫,平台有沒有內建全看它自己。
| 平台 | 圍欄式區塊 | 語法標示 |
|---|---|---|
| 本站的線上編輯器 | 支援 | 支援,只要圍欄有標語言代碼 |
| GitHub、GitLab | 支援 | 支援,數百種語言,在伺服器端處理 |
| VS Code 預覽 | 支援 | 支援,直接沿用編輯器本身的語法定義 |
| Hugo、Jekyll、Astro、Docusaurus | 支援 | 支援,但要在設定檔裡啟用標示器 |
| Obsidian、Notion | 支援 | 支援,並提供語言選單 |
| Discord、Slack | 支援 | Discord 有,Slack 沒有 |
純 marked 或 markdown-it 輸出 | 支援 | 不支援,除非自己接上 Prism 或 highlight.js |
| 電子郵件、多數 CMS 留言框 | 不一定 | 不支援 |
本站的預覽也照這張表的規則走:有標語言代碼的圍欄會交給 highlight.js 上色,沒標的則維持素色,不去猜語言。
實務上的結論:不要讓顏色承載意義。讀者非注意某一行不可時,就在區塊上方的文字裡講明,或在程式碼裡用註解標出來。一個在別處會變成灰色的高亮關鍵字,等於什麼都沒說。各家聊天與筆記軟體怎麼處理圍欄,Discord 指南與 Notion 指南有實測。
行長與水平捲動
多數渲染器不會替程式碼區塊自動換行。一行 200 個字元就會生出水平捲軸,手機讀者只看得到前三分之一。範例每一行請盡量壓在 80 個字元以內,四個習慣就夠了:
- 長的 shell 指令用行尾反斜線斷行。
- 長的函式呼叫拆成多行。
- 把佔位用的變數名稱改短、改直白。
- 範例網址只留有意義的那一段。
真的無法縮短時,就在文字裡把重點講完,讓沒人需要靠捲動才能理解。這裡也是很多人會想改用原生 HTML 寫個會換行的 <pre> 的地方;改貼截圖更糟,因為程式碼的圖片不能複製、不能搜尋,也無法被唸出來。
常見錯誤與修法
沒有收尾的圍欄
這是頭號災難,而且發作起來非常壯觀:
錯誤:
```js
const a = 1;
從這裡開始的所有內容都變成程式碼了。
標題、清單、連結,全部被吞掉。
開了圍欄卻沒有收尾,它會把文件剩下的全部吃光。症狀非常好認:從某個位置開始,整頁變成一大塊等寬字體。往上捲到排版死掉的那一點,補上漏掉的 ``` 即可。收尾圍欄必須自己獨佔一行,寫成 const a = 1;``` 不算。
小提醒:有即時預覽的話,圍欄一少收尾就會當場現形。這也是「先在編輯器裡打草稿,再貼進 pull request 說明欄」最實際的理由。
被換成彎引號
錯誤: const greeting = “hello”;
修正: const greeting = "hello";
彎引號和直引號是不同的字元,沒有編譯器吃得下。程式碼區塊裡 Markdown 渲染器不會替你轉換,但文字很可能在送進來之前就被轉過了:文書軟體、通訊軟體、CMS 編輯器,或 macOS 的系統層級自動替換。-- 被換成長橫線也是同一類問題。貼進來的程式碼若爆出莫名其妙的語法錯誤,先看引號。
從文書軟體貼過來
從 Word、Google 文件或電子郵件裡複製程式碼,會一併帶進幾種看不見的東西:
- 和一般空格長得一模一樣的不斷行空格。
- 被轉成不定寬縮排的 Tab。
- 完全沒有外觀的零寬字元。
- 上面提過的彎引號與長橫線。
結果就是看起來完全正確,就是跑不動。請先經過一道純文字關卡再貼:文字編輯器、終端機,或本站編輯器的左側面板,在送出之前先看清楚原始字元。
圍欄縮排太多
錯誤:
```js
const a = 1;
```
行首縮排四個空格本來就代表縮排式程式碼區塊,於是圍欄符號被當成純文字顯示出來。除非區塊放在清單項目裡,否則圍欄請貼齊左邊界。
語言名稱拼錯
寫成 ```JavaScipt 的代價只是沒有顏色,不會有錯誤訊息,所以表面上一切正常。該上色的區塊沒上色時,先對照上表檢查 info string 的拼字,再去怪平台。其餘部分請見完整 Markdown 指南、快速參考表或常見問題。
相容性資料驗證日期
常見問題
Markdown 的程式碼區塊怎麼寫?
先單獨一行打三個反引號,下面接程式碼,最後再單獨一行打三個反引號。想要語法標示,就在開頭圍欄後面緊接語言名稱,例如 ```python。如果只是句子中間的一個詞或一行指令,改用一對反引號即可。
為什麼我文件後面全部變成程式碼了?
上面某處有一個開了卻沒收尾的圍欄,把後面的內容全部吞掉了。往上捲到排版開始失效的位置,補上單獨一行的 ``` 就好。有即時預覽的話,這種錯誤打字當下就會被抓到。
有哪些語言識別字可以用?
取決於渲染器用的標示器認得哪些,GitHub 支援的是數百個名稱再加上別名。日常會用到的大致是 js、ts、python、bash、json、yaml、html、css、sql 和 diff。不認得的識別字只會變成沒有顏色的區塊,所以猜錯不會有代價。
行內程式碼裡面要顯示反引號怎麼辦?
外層的反引號比內層多就行,如果內容的開頭或結尾就是反引號,再各補一個空格。兩個外層反引號可以包住含有一個反引號的內容,三個可以包住含有兩個的,以此類推。
表格裡可以放程式碼區塊嗎?
只有行內程式碼可以。圍欄式區塊屬於區塊級元素,無法放進表格儲存格,因為換行就代表這一列結束了。儲存格裡放一對反引號的行內程式碼,多行的範例則移到表格下方用圍欄式區塊呈現。
.markdown 檔要用什麼開啟?
任何文字編輯器都行。.markdown 檔和 .md 檔是同一種東西,只是副檔名用了比較長的寫法,底層都是純文字。記事本、TextEdit、VS Code、Obsidian、手機的備忘錄全都打得開,不用轉檔也不用安裝任何東西。想看排版後的樣子而不是原始碼,可以丟進我們的 Markdown 檢視器,或把副檔名改成 .md,讓更多軟體一眼認出它。
延伸閱讀
立即使用編輯器
立即使用編輯器