内联代码(Inline Code)
用单个反引号 ` 包裹的内容显示为等宽字体(Monospace),对应 HTML 的 <code> 标签。它的内部不会解析 Markdown 语法。
运行 `npm install` 安装依赖。 变量 `userName` 不要写成 `user_name`。 配置文件在 `~/.config/app.json`。 函数签名:`getUserById(id: string)`
运行 npm install 安装依赖。
变量 userName 不要写成 user_name。
配置文件在 ~/.config/app.json。
函数签名:getUserById(id: string)
内联代码中包含反引号
如果内联代码本身需要包含反引号字符,用多个反引号作为包裹符:
# 双反引号包裹,内部可含单反引号 `` 使用 ` 在 shell 中执行命令 `` ``var x = `template ${str}` `` # 三反引号包裹,内部可含双反引号 ``` 包含 `` 双反引号 `` 的内容 ```
使用 ` 在 shell 中执行命令
var x = `template ${str}`
` code ` 等价于 `code`),这是为了方便写 `` ` `` 单个反引号(在两端各加一个空格)。
围栏代码块(Fenced Code Blocks)
多行代码使用"围栏"(Fence)包裹:三个及以上反引号(```)或三个及以上波浪线(~~~)。
基本语法
```python
def greet(name: str) -> str:
"""返回问候语"""
return f"Hello, {name}!"
print(greet("World")) # Hello, World!
```
def greet(name: str) -> str:
"""返回问候语"""
return f"Hello, {name}!"
print(greet("World")) # Hello, World!
波浪线风格(~~~)
波浪线和反引号在功能上完全等价,区别是:
- 波浪线代码块内部可以包含三个反引号(不需要转义)
- 反引号代码块内部可以包含三个波浪线
- 实践中推荐统一使用反引号风格(更常见,大多数工具优先支持)
~~~yaml
# docker-compose.yml
services:
web:
image: nginx:alpine
ports:
- "80:80"
~~~
围栏起始行可附加信息(Info String)
开始围栏行(```)后面除了语言标识符,还可以加其他信息,部分工具会利用这些信息:
# 某些平台支持显示文件名 ```python title="hello.py" print("Hello") ``` # 某些平台支持高亮特定行 ```javascript {2,4-6} function sum(a, b) { return a + b; // 第2行高亮 } const result = sum( 1, // 第4-6行高亮 2 ); ``` # Docusaurus 支持显示行号 ```python showLineNumbers def hello(): print("Hello, World!") ```
title、行号、行高亮)是特定平台的扩展功能。GitHub 只识别语言标识符,会忽略其他信息。Docusaurus、VitePress、Notion 等平台各有自己的扩展语法。
语法高亮(Syntax Highlighting)
在开始围栏后指定语言名称,渲染器会对代码进行语法高亮。语法高亮是由前端库(如 Prism.js、highlight.js)或服务端处理器实现的,不是 Markdown 本身的功能。
常用语言标识符
| 语言 | 标识符(常用) | 备注 |
|---|---|---|
| Python | python / py | 不区分大小写 |
| JavaScript | javascript / js | |
| TypeScript | typescript / ts | |
| Shell/Bash | bash / sh / shell / zsh | |
| SQL | sql | |
| JSON | json | |
| YAML | yaml / yml | |
| HTML | html | |
| CSS | css / scss / sass / less | |
| Go | go / golang | |
| Rust | rust / rs | |
| Java | java | |
| C | c | |
| C++ | cpp / c++ | |
| C# | csharp / cs | |
| Swift | swift | |
| Kotlin | kotlin / kt | |
| Ruby | ruby / rb | |
| PHP | php | |
| Dockerfile | dockerfile | |
| Markdown | markdown / md | 在 Markdown 中显示 Markdown 源码 |
| 纯文本(不高亮) | text / plaintext | 或不指定语言 |
| 终端输出 | console / terminal | GitHub 特殊样式 |
语法高亮的工作原理
了解语法高亮的原理,有助于理解为什么有时渲染结果不符合预期:
因此,语法高亮的质量取决于:
- Lexer 对该语言的理解深度(规则是否完整)
- CSS 主题的设计(颜色搭配)
- 指定的语言标识符是否正确
diff 代码块
用 diff 作为语言标识符,配合 +(新增行)和 -(删除行)前缀,展示代码变更:
```diff
function greet(name) {
- console.log("Hello " + name);
+ console.log(`Hello, ${name}!`);
}
+function farewell(name) {
+ console.log(`Goodbye, ${name}!`);
+}
```
diff 块的规则
| 前缀 | 含义 | 颜色 |
|---|---|---|
+ 开头 | 新增的行 | 绿色背景 |
- 开头 | 删除的行 | 红色背景 |
开头(空格)或无前缀 | 上下文行(未变更) | 正常颜色 |
@@ ... @@ | 块头(Hunk Header),标注文件行号 | 蓝色/青色 |
缩进代码块(旧式语法)
CommonMark 规范也支持用 4 个空格(或 1 个制表符)缩进来创建代码块,这是最早的 Markdown 代码块语法:
def hello():
print("Hello, World!")
hello()
def hello():
print("Hello, World!")
hello()
代码块内的特殊处理
HTML 特殊字符的转义
在围栏代码块中,HTML 特殊字符(如 <、>、&)会被自动转义为 HTML 实体,所以可以直接写原始代码不用担心 HTML 冲突:
```html
<!-- 模板变量不会被 HTML 解析器处理 -->
<div class="container">
<p>{{ user.name }}</p>
</div>
```
代码块内不处理 Markdown 语法
围栏代码块内部的任何 Markdown 语法都会被当作字面量显示:
``` **这不会变成加粗** # 这不会变成标题 [这不会变成链接](url) - 这不会变成列表 ```
展示 Markdown 语法本身
如果需要在文档中展示 Markdown 语法(比如写 Markdown 教程),把 Markdown 代码放在代码块内:
```markdown # 这是一个标题示例 - 列表项1 - 列表项2 **加粗**和*斜体* ```
特殊语言标识符
console / terminal
用于展示终端命令和输出,GitHub 会给命令行添加特殊样式:
```console $ npm install npm warn deprecated package@1.0.0 added 245 packages in 3s $ npm run build > my-app@1.0.0 build > vite build ✓ built in 1.23s ```
math(GitHub LaTeX 代码块)
GitHub 支持用 math 标识符的代码块来渲染 LaTeX 数学公式:
```math
E = mc^2
```
```math
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
```
mermaid
GitHub 原生支持 Mermaid 图表(详见第8章):
```mermaid
flowchart TD
A[开始] --> B{条件}
B -->|是| C[执行]
B -->|否| D[跳过]
```
代码块与可访问性
在技术文档中,代码块的可访问性也值得关注:
- 始终指定语言:屏幕阅读器和辅助技术会利用语言信息
- 复杂代码加注释:不要假设读者能完全理解代码,重要逻辑加行内注释
- 代码前后加说明:代码块通常需要前后的文字解释其用途和上下文
代码块排版最佳实践
1. 正确指定语言
# ❌ 不好:没有语言标识符,无法高亮 ``` function hello() { console.log("Hello") } ``` # ✅ 好:有语言标识符 ```javascript function hello() { console.log("Hello") } ```
2. 代码必须可运行
# ❌ 不好:缺少 import,无法直接运行 ```python df = pd.read_csv('data.csv') ``` # ✅ 好:包含必要的 import ```python import pandas as pd df = pd.read_csv('data.csv') print(df.head()) ```
3. 长代码块用注释说明关键步骤
```python
# 步骤1:加载预训练模型
model = AutoModel.from_pretrained("bert-base-chinese")
# 步骤2:准备输入数据
tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")
inputs = tokenizer("这是测试句子", return_tensors="pt")
# 步骤3:获取嵌入向量
with torch.no_grad():
outputs = model(**inputs)
# outputs.last_hidden_state 包含每个 token 的上下文向量
embeddings = outputs.last_hidden_state
print(f"输出形状: {embeddings.shape}") # [batch, seq_len, 768]
```
小结
- 内联代码:
`code`,内部 Markdown 不解析;包含反引号时用多个反引号包裹 - 围栏代码块:三个及以上反引号
```language,始终指定语言以启用语法高亮 - 语法高亮原理:词法分析生成 Token,各 Token 用
<span class>包裹,CSS 控制颜色 - diff 块:语言标识符
diff,+前缀(绿色)、-前缀(红色)表示增删 - 缩进代码块(4 个空格)是旧式语法,强烈不推荐使用
- 代码块内 HTML 特殊字符自动转义,Markdown 语法不解析
- 代码示例应可运行,包含 import,关键步骤用注释说明