嘿,朋友!我是 Agnes。今天咱们不聊那些枯燥的理论,我想跟你聊聊一个看似简单、实则坑很多的技能——在 Markdown 里写代码块。
你可能觉得:“这不就是几个反引号嘛?” 别急,等你真正在写博客、做文档或者给 GitHub 项目贡献代码时,你会发现,一个缩进搞不好,你的代码块就炸了;一个语言标记写错,高亮就失效了。
这篇文章,我会像老朋友聊天一样,带你从最基础的“缩进大法”一路聊到最优雅的“围栏代码块”,最后再帮你把那些让人抓狂的常见错误统统排查一遍。准备好了吗?我们开始。
一、 为什么我们关心代码块?
想象一下这个场景:你正在写一份技术文档,介绍 Python 的 for 循环。你写道:
你可以用这个语法:
for i in range(5): print(i)
如果只有一行,用行内代码(反引号)没问题。但如果我要展示一个完整的函数:
def greet(name):
"""向用户打招呼"""
print(f"Hello, {name}!")
greet("Agnes")
这时候,如果我把这段代码直接写在正文里,Markdown 渲染器可能会把它当成普通文本,甚至因为换行和空格搞得一团糟。
代码块的作用,就是让代码“隔离”出来,保持原样,并且最好还能有颜色高亮。 这正是我们今天要深入探讨的核心。
二、 第一种写法:缩进式代码块(Indented Code Blocks)
这是 Markdown 最原始的代码块写法,出现在最经典的 Markdown 规范里。它的规则很简单:在段落前缩进 4 个空格或 1 个制表符(Tab)。
2.1 怎么写?
看这个例子:
这是一个普通的段落。
def hello():
return "world"
print(hello())
注意看,代码的每一行前面都多了 4 个空格(或者一个 Tab)。
2.2 渲染效果
渲染出来的样子大致如下:
这是一个普通的段落。
> def hello(): > return "world" > > print(hello()) > ``` 代码会被包裹在一个没有背景色的框里(不同编辑器样式不同,有的有灰色背景,有的没有),**重点是:不会自动高亮语法**。 ### 2.3 为什么现在用得少了? 虽然缩进法简单,但它有几个致命缺点: 1. **容易误触**:如果你正在写一个无序列表(`-` 开头),下面紧接着想写代码,你得非常小心地加满 4 个空格,否则列表会中断,或者代码块会意外开始。 2. **嵌套困难**:在代码块里再写代码块?那将是噩梦。你需要缩进 4 个空格,再缩进 4 个空格……容易把自己绕晕。 3. **没有语言高亮**:这是最大的痛点。渲染出来的代码是纯黑白的,对于长代码来说,阅读体验很差。 4. **对排版敏感**:如果你用 Markdown 编辑器,它可能会自动帮你调整缩进,导致你看到的渲染效果和你预期的不一样。 ### 2.4 一个小技巧 如果你非得用缩进法,记得**代码块前后要有一个空行**,这样渲染器才能正确识别边界。 ```markdown 这是开头。 代码行1 代码行2 这是结尾。
三、 第二种写法:围栏代码块(Fenced Code Blocks)—— 主流推荐!
这是现在几乎所有 Markdown 编辑器(包括 GitHub、Typora、Obsidian、VS Code)都支持的标准写法,也是我最推荐你使用的方法。
3.1 基础语法:三个反引号
你只需要用三个反引号(`)把代码包起来,前后各一行。
def hello():
return "world"
渲染效果:
def hello():
return "world"
看,是不是简洁多了?而且,因为代码在围栏里,缩进问题基本消失,你不需要在每一行前加 4 个空格。
3.2 进阶用法:指定语言高亮
这是围栏代码块最强大的地方!你只需要在开头的三个反引号后面,写上语言名称,渲染器就会自动应用对应的语法高亮。
```python
def hello():
return "world"
渲染效果:
```python
def hello():
return "world"
是不是颜色一下子就跳出来了?这对阅读长代码帮助巨大。
3.3 常见语言标记速查表
你不需要记住所有语言,但常用的这些得熟:
| 语言 | 标记 | 示例 |
|---|---|---|
| Python | python |
”`python |
| JavaScript | javascript 或 js |
”`javascript |
| HTML | html |
”`html |
| CSS | css |
”`css |
| SQL | sql |
”`sql |
| Bash/Shell | bash 或 shell |
”`bash |
| JSON | json |
”`json |
| YAML | yaml 或 yml |
”`yaml |
| Markdown | markdown |
”`markdown |
小贴士:如果你不确定语言标记,可以留空,渲染器会尝试自动检测,或者只显示纯文本。
3.4 更高级:代码块参数(可选)
某些 Markdown 引擎(如 Mermaid、Vivus)支持在围栏代码块里添加额外参数。例如,Mermaid 流程图:
```mermaid
graph TD
A[开始] --> B{判断}
B -->|是| C[结果1]
B -->|否| D[结果2]
渲染出来就是一个流程图!不过这个属于进阶玩法,我们先不深入,知道有这个可能性就行。
---
## 四、 两种写法的对比与选择
为了让你更清楚怎么选,我给你画个对比图:
| 特性 | 缩进式代码块 | 围栏代码块 |
|------|--------------|------------|
| **语法复杂度** | 低(只需空格) | 低(只需反引号) |
| **语言高亮** | ❌ 不支持 | ✅ 支持 |
| **代码嵌套** | ❌ 困难,容易混乱 | ✅ 简单,清晰 |
| **兼容性** | 几乎所有 Markdown 支持 | 现代编辑器均支持 |
| **推荐程度** | ⭐ 不推荐 | ⭐⭐⭐⭐⭐ 强烈推荐 |
**结论**:除非你在使用一个非常古老的 Markdown 处理器,否则**请一律使用围栏代码块**。
---
## 五、 常见错误排查(新手必看!)
即使是最简单的围栏代码块,也会遇到各种坑。别急,我帮你把最常见的错误都列出来,并给出解决方案。
### 错误 1:代码块没有闭合
**现象**:代码块开始后,后面的所有内容都变成了代码,直到文档结束。
**原因**:你在开头写了三个反引号,但忘了在结尾再写三个反引号。
**示例**:
```markdown
```python
print("Hello")
// 忘记写结尾的 “` 了!
**解决**:确保每对代码块都有**开**和**关**两个反引号组。
```markdown
```python
print("Hello")
### 错误 2:反引号数量不匹配
**现象**:渲染异常,或者代码块提前结束。
**原因**:代码内部本身包含三个或更多连续的反引号,被误认为是代码块的结束符。
**示例**:
```markdown
这里有一个 是单个反引号。
这里有两个` 是两个反引号。
解决:如果代码里本身有反引号,你就用更多的反引号来包裹。比如,代码里有三个反引号,你就用四个、五个甚至六个来包裹。
````
这里有一个 ``` 是三个反引号。
””
错误 3:语言标记写错了,高亮失效
现象:代码块渲染出来了,但没有颜色,看起来像纯文本。
原因:你写的语言标记不存在,或者拼写错误。
示例:
```pythn
print("Hello")
注意,pythn 是错的,正确是 python。
解决:检查拼写。如果你不确定,可以去 GitHub 的 Language Graphs 查一下官方支持的语言列表。
错误 4:代码块前后没有空行
现象:代码块前面的段落和代码块混在一起,或者后面的段落和代码块混在一起,渲染效果混乱。
原因:Markdown 要求代码块前后必须有空行,否则可能无法正确识别边界。
示例:
这是前一段落。
```python
print("Hello")
这是后一段落。
**解决**:在代码块的前后都加上空行。
```markdown
这是前一段落。
```python
print("Hello")
这是后一段落。
### 错误 5:缩进问题(在围栏代码块里)
**现象**:代码被渲染成了嵌套的代码块,或者缩进全部丢失。
**原因**:在围栏代码块内部,某些 Markdown 解析器会对行首的空格有特殊处理。如果你希望在代码中保留缩进,确保不要混合使用“缩进式代码块”和“围栏代码块”的逻辑。
**示例**:
```markdown
```python
def hello(): # 注意这里多了一个缩进
return "world"
在某些严格模式下,这可能导致解析问题。
**解决**:在围栏代码块内,**不要**在行首额外添加缩进(除非你代码本身就需要缩进)。直接写代码即可。
### 错误 6:在代码块里写 Markdown 语法
**现象**:你以为代码块里的 `**bold**` 会变成粗体,但实际没有。
**原因**:代码块内的所有内容都是**纯文本**,Markdown 语法(如加粗、斜体、链接)在代码块内是无效的。
**解决**:如果你需要在代码块内强调某部分,只能靠颜色高亮或注释来说明,不要用 Markdown 语法。
---
## 六、 实战演练:一个完美的代码块示例
让我们把学到的东西组合起来,写一个既美观又规范的代码块。
**场景**:你正在写一篇关于 Python 爬虫的教程,要展示如何用 `requests` 库获取网页。
**你的 Markdown 源码**:
```markdown
首先,我们需要安装 `requests` 库:
```bash
pip install requests
然后,我们可以编写如下代码:
import requests
def get_webpage(url):
"""
发送 GET 请求并返回响应内容
:param url: 目标网址
:return: 响应文本
"""
try:
response = requests.get(url, timeout=10)
response.raise_for_status() # 如果状态码不是 200,抛出异常
return response.text
except requests.exceptions.RequestException as e:
print(f"请求失败: {e}")
return None
# 示例调用
if __name__ == "__main__":
url = "https://www.example.com"
content = get_webpage(url)
if content:
print(f"成功获取 {len(content)} 字节的数据")
这段代码演示了基本的错误处理和请求发送。 “`
渲染效果预览:
首先,我们需要安装
requests库:pip install requests然后,我们可以编写如下代码:
import requests def get_webpage(url): """ 发送 GET 请求并返回响应内容 :param url: 目标网址 :return: 响应文本 """ try: response = requests.get(url, timeout=10) response.raise_for_status() # 如果状态码不是 200,抛出异常 return response.text except requests.exceptions.RequestException as e: print(f"请求失败: {e}") return None # 示例调用 if __name__ == "__main__": url = "https://www.example.com" content = get_webpage(url) if content: print(f"成功获取 {len(content)} 字节的数据")这段代码演示了基本的错误处理和请求发送。
看到了吗?代码块有清晰的边界,Python 语法高亮让关键字、字符串、注释一目了然,而且前后都有空行,阅读体验极佳。
七、 一些额外的小贴士
- 使用代码编辑器的快捷键:大多数代码编辑器(如 VS Code、PyCharm、Sublime Text)都有快捷键可以快速插入代码块。比如 VS Code 里,选中代码后按
Ctrl+Shift+P,搜索“Insert Code Block”,就能自动生成。 - 复制粘贴时注意:从某些网站复制代码时,可能会带入隐藏的特殊字符(如不可见空格)。建议在粘贴到 Markdown 编辑器后,检查一下代码是否对齐。
- 测试你的 Markdown:在发布之前,先用支持 Markdown 预览的工具(如 Typora、VS Code 预览、GitHub 预览)看看效果,确保代码块渲染正确。
- 保持一致性:在一个文档里,选择一种风格(推荐围栏代码块)并坚持使用,不要混用缩进式和围栏式,以免给自己和读者带来困惑。
结语
好了,我们今天一起梳理了 Markdown 代码块的两种主要写法,重点推荐了围栏代码块,并排查了常见的错误。
记住,好的文档不仅内容要有价值,格式也要清晰易读。一个漂亮的代码块,能让读者更愿意阅读你的技术分享。
希望这篇文章能帮你搞定 Markdown 代码块的所有问题!如果还有疑问,欢迎随时来找我聊聊。祝你写作愉快!
—— Agnes
