kramdown 完整语法中文指南

kramdown 完整语法中文指南

本文根据 kramdown 官方 Syntax 2.5.2 文档整理。
原文地址:https://kramdown.gettalong.org/syntax.html

本文不是机械逐句翻译,而是在不遗漏主要语法项目的前提下,用更容易理解的中文重新说明,并保留、改写或补充了示例。

目录


1. kramdown 语法概述

kramdown 是 Markdown 的一个超集。它保留了 Markdown 的常用写法,同时吸收了 PHP Markdown Extra、Maruku 和 Pandoc 等实现中的一些功能,例如:

  • 定义列表;
  • 表格;
  • 脚注;
  • 属性列表;
  • 数学公式;
  • 缩写;
  • 扩展语法;
  • 更明确的列表和块边界规则。

kramdown 的目标不是百分之百复刻原始 Markdown,而是提供一套更严格、更明确、解析结果更可预测的语法。

大多数普通 Markdown 文件都可以直接由 kramdown 处理,但在以下细节上可能不同:

  • 标题前是否必须有空行;
  • 列表缩进;
  • 代码块连续时如何合并;
  • HTML 内是否继续解析 Markdown;
  • 表格、脚注、属性列表等扩展语法;
  • 同一段文本在边界情况下如何归类。

2. 源文本的基本规则

2.1 块级元素和行内元素

kramdown 文档包含两大类元素。

块级元素

块级元素负责文档的整体结构,例如:

  • 段落;
  • 标题;
  • 列表;
  • 引用;
  • 代码块;
  • 表格;
  • 数学公式块;
  • HTML 块。

示例:

# 标题

这是一个段落。

- 列表项一
- 列表项二

行内元素

行内元素只标记一小段文字,例如:

  • 强调;
  • 链接;
  • 图片;
  • 行内代码;
  • 脚注引用;
  • 行内 HTML。

示例:

这里有 **粗体**、*斜体*、[链接](https://example.com) 和 `代码`。

行内元素只能出现在块级元素内部,或者嵌套在其他行内元素中。

2.2 自动换行与懒惰写法

kramdown 允许某些块级元素跨多行书写。后续行即使没有重复首行的标记,也可能仍属于同一个元素。这种写法通常被称为“懒惰写法”。

例如:

> 这是引用的第一行
第二行虽然没有 `>`,仍可能属于引用。

虽然这种写法能够被解析,但不推荐使用,因为它会降低可读性。更清晰的写法是:

> 这是引用的第一行
> 第二行继续使用 `>`。

通常,支持跨行的块级元素在遇到以下内容时结束:

  • 空行;
  • 块结束标记 ^
  • 块级属性列表;
  • 文档结尾;
  • HTML 块。

以下元素不适合使用懒惰换行:

  • 标题;
  • 围栏代码块的边界行及其内容;
  • 定义列表中的术语;
  • 表格。

普通段落中的源代码换行

源文件中的普通换行通常不会直接生成 <br>

输入:

这是第一行,
这是第二行。

通常会输出为同一个段落,而不是两个视觉上的行。

需要明确换行时,可以在行末添加两个空格:

第一行··
第二行

上面的 ·· 表示两个普通空格。

kramdown 还支持在行末写两个反斜杠:

第一行\\
第二行

2.3 制表符 Tab

kramdown 按照每四列一个制表位处理 Tab。

这在列表和代码块缩进中很重要。建议:

  • 不要混用空格和 Tab;
  • 编辑器的 Tab 宽度设为 4;
  • 最好统一使用空格缩进;
  • Tab 只应出现在行首缩进位置;
  • 不要先写空格再写 Tab。

错误或不稳定的写法:

[空格][Tab]内容

推荐:

[四个空格]内容

2.4 自动转义与手动转义

输出 HTML 时,<>& 等字符会根据输出格式自动正确转义。

因此普通文字中可以直接写:

5 < 10,10 > 5,A & B。

如果某个字符本身是 kramdown 语法标记,但你只想显示这个字符,可以在前面添加反斜杠。

输入:

这段 \`文字\` 不是行内代码。

显示效果:

这段 `文字` 不是行内代码。

常见可转义字符包括:

\         反斜杠
.         句点
*         星号
_         下划线
+         加号
-         减号
=         等号
`         反引号
()[]{}<>  各类括号
#         井号
!         感叹号
<<  >>    尖引号
:         冒号
|         竖线
"         双引号
'         单引号
$         美元符号

例如,避免把年份开头的句子识别为有序列表:

1984\. It was a great year.

避免把减号识别为无序列表:

\- 这只是普通文本,不是列表。

2.5 块边界

有些块级元素必须从“块边界”开始,或者在“块边界”结束。

可以构成块边界的内容包括:

  • 空行;
  • 块结束标记 ^
  • 块级属性列表;
  • 文档开头或结尾。

例如,标题通常应和前面的段落用空行隔开:

这是上一段。

## 新标题

而不是:

这是上一段。
## 新标题

kramdown 对块边界的要求比部分 Markdown 实现更严格,这样可以减少歧义。


3. 结构性元素

3.1 空行

只包含空格或 Tab 的行也会被视为空行。

多个连续空行通常等价于一个空行:

第一段。



第二段。

空行主要用于分隔块级元素,但在以下场景中还可能影响语义:

  • 标题;
  • 代码块;
  • 列表;
  • 数学公式块;
  • 必须从块边界开始或结束的元素。

3.2 段落

一行或多行连续普通文本会组成一个段落。

这是第一行。
这是第二行,它仍然属于同一个段落。

段落首行最多可以缩进三个空格:

   这仍然是普通段落。

如果缩进四个空格,通常会被识别为代码块:

    这通常是代码块。

两个段落之间使用一个或多个空行:

这是第一段。

这是第二段。

段落开头和结尾的多余空白会被移除。

显式换行

使用行尾两个空格:

第一行··
第二行

或者行尾两个反斜杠:

第一行\\
第二行

段落最后一行上的换行标记会被忽略,因为段落本身已经结束。

3.3 标题

kramdown 支持 Setext 和 ATX 两种标题。

3.3.1 Setext 标题

一级标题使用等号:

一级标题
========

二级标题使用减号:

二级标题
--------

等号或减号的数量不重要,一个也能被识别,但多写一些更容易阅读:

一级标题
=

Setext 标题应从块边界开始,通常意味着标题前要有空行。

推荐:

这是上一段。

新的标题
--------

不推荐:

这是上一段。
新的标题
--------

在下面这个例子中,--- 会优先被解释为 Setext 二级标题下划线,而不是水平线:

header
---
para

解析结果相当于:

<h2>header</h2>
<p>para</p>

3.3.2 ATX 标题

使用一个到六个 #

# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题

# 前不能有空格。

行尾可以添加任意数量的 #

### 三级标题 ###

行尾的 # 只是装饰,不决定级别。

3.3.3 指定标题 ID

可在标题后明确指定 ID:

## 安装方法
{: #installation}

Setext 标题也可以:

安装方法
--------
{: #installation}

官方语法还支持把 ID 直接写在标题文字后:

## 安装方法 {#installation}

ATX 标题有行尾 # 时,ID 写在最后:

## 安装方法 ## {#installation}

生成 HTML:

<h2 id="installation">安装方法</h2>

这不是标准 Markdown,而是 kramdown 扩展。

3.4 引用

引用使用 >

> 这是一段引用。

> 后的空格可有可无,但建议保留:

> 推荐写法

引用可以有多个段落:

> 第一段。
>
> 第二段。

引用可以嵌套:

> 第一层引用
>
> > 第二层引用

引用中可以包含其他块级元素:

> ## 引用中的标题
>
> - 列表项一
> - 列表项二
>
>     引用中的代码块

由于 > 后面的第一个空格不计入内部缩进,引用中的缩进代码块通常需要这样写:

> 代码示例:
>
>     ruby -e 'puts :works'

不建议省略后续行的 >,即使解析器允许:

> 第一行
第二行

推荐:

> 第一行
> 第二行

3.5 代码块

代码块中的内容按原样处理,不解析 Markdown 语法。

3.5.1 缩进代码块

每行缩进四个空格或一个 Tab:

    def hello
      puts "Hello"
    end

显示为:

def hello
  puts "Hello"
end

连续两个缩进代码块如果只用空行分隔,可能会被合并为同一个代码块:

    第一段代码

    第二段代码

需要强制拆成两个代码块时,使用块结束标记:

    第一段代码
^
    第二段代码

3.5.2 围栏代码块

kramdown 官方语法使用三个或更多波浪线:

~~~
def hello
  puts "Hello"
end
~~~

起始围栏使用多少个 ~,结束围栏至少要使用相同数量:

~~~~~~~~
这里可以出现较短的 ~~~ 行。
~~~~~~~~

围栏代码块适合直接粘贴代码,因为不用给每一行增加缩进。

在 GitHub 页面中,也通常会使用反引号围栏:

```ruby
puts "Hello"
```

但需要注意:是否支持反引号围栏取决于所选输入解析器。使用 GFM 输入时通常支持。

3.5.3 指定代码语言

方法一:使用属性列表:

~~~
def answer
  42
end
~~~
{: .language-ruby}

方法二:直接写在起始围栏后:

~~~ ruby
def answer
  42
end
~~~

在 GitHub 风格文档中通常写成:

```ruby
def answer
  42
end
```

语言信息可供 Rouge 等高亮器使用。

3.6 列表

kramdown 支持:

  • 无序列表;
  • 有序列表;
  • 定义列表。

3.6.1 无序列表

可使用 *+-

* 第一项
+ 第二项
- 第三项

这些标记可以混用,但为了可读性,建议统一使用一种:

- 第一项
- 第二项
- 第三项

3.6.2 有序列表

1. 第一项
2. 第二项
3. 第三项

kramdown 通常不在意源文件中的实际数字,输出列表一般从 1 开始:

8. 第一项
3. 第二项
99. 第三项

为了阅读方便,仍建议按正常顺序编号。

3.6.3 列表类型不能混成一个列表

在 kramdown 中,下面会形成两个列表:

- 无序项目
1. 有序项目

不要依赖“第一个标记决定整个列表类型”的宽松行为。

3.6.4 列表缩进

列表标记后的第一个非空字符位置,决定后续内容所需的缩进。

推荐简单写法:

- 第一项内容很长,
  第二行与正文起始位置对齐。
- 第二项。

有序列表:

1. 第一项内容很长,
   第二行继续缩进。
2. 第二项。

两位数编号需要更多缩进:

10. 第一项内容很长,
    第二行继续缩进。

不要随意改变同级列表项的缩进:

- 第一项
   - 看起来可能像子列表

为了避免歧义,嵌套列表要保持稳定缩进。

3.6.5 嵌套列表

- 第一项
  - 子项一
  - 子项二
- 第二项

有序列表嵌套:

1. 第一项
   1. 子项一
   2. 子项二
2. 第二项

混合嵌套:

1. 安装依赖
   - Ruby
   - Bundler
2. 执行构建

3.6.6 紧凑列表和松散列表

紧凑列表:

- 第一项
- 第二项
- 第三项

生成的 <li> 内通常不会再包一层 <p>

松散列表:

- 第一项的第一段。

  第一项的第二段。

- 第二项。

有空行时,列表项内容通常会作为段落处理。

如果希望最后一个列表项也明确形成段落,可以在列表后加空行和块结束标记:

- 第一项

- 第二项

^

3.6.7 列表项中包含多个块

- 第一项

  第二个段落。

  - 嵌套列表

  > 嵌套引用

- 第二项

列表项中可以包含:

  • 多个段落;
  • 子列表;
  • 引用;
  • 标题;
  • 代码块;
  • 表格;
  • 其他块级元素。

3.6.8 列表后紧接代码块

当列表后立即跟缩进代码块时,容易被认为代码仍属于列表。可以用 ^ 分隔:

- 这是列表项。
^
    这是列表外的代码块。

3.6.9 列表项第一个元素就是代码块

可先写一个只有标记的列表项,再深度缩进代码:

- 
        puts "这是列表项中的代码块"

由于这种写法不直观,更推荐围栏代码块:

- 示例代码:

  ```ruby
  puts "Hello"
  ```

3.6.10 两个同类型列表相邻

两个无序列表直接相邻会合并。需要拆开时使用 ^

- 列表一
^
- 列表二

3.6.11 让类似列表标记的文字保持普通文本

1984\. 这不是有序列表。

\- 这也不是无序列表。

3.6.12 给列表项添加属性

- {:.important} 这个列表项具有 `important` 类。
- 普通列表项。

3.7 定义列表

定义列表不是原始 Markdown 的一部分。

基本写法:

术语
: 术语的定义。

多个定义:

术语
: 第一个定义。
: 第二个定义。

多个术语对应同一组定义:

术语一
术语二
: 共同定义。

定义内容可跨多行:

kramdown
: 一个 Ruby 编写的 Markdown 超集解析器,
  可以转换为 HTML 等格式。

定义中可包含多个块:

kramdown
: 第一段定义。

  第二段定义。

  - 特点一
  - 特点二

术语必须各自占一行,不适合懒惰换行。

3.8 表格

表格也是 kramdown 扩展语法。

3.8.1 基本表格

| 名称 | 数量 |
|------|------|
| 苹果 | 10   |
| 香蕉 | 20   |

3.8.2 对齐

| 左对齐 | 居中 | 右对齐 |
|:-------|:----:|-------:|
| A      | B    | C      |

规则:

  • :---:左对齐;
  • :---::居中;
  • ---::右对齐;
  • ---:使用默认对齐方式。

3.8.3 可省略两侧竖线

某些情况下可以写:

名称 | 数量
-----|-----
苹果 | 10
香蕉 | 20

为了兼容 GitHub 和减少歧义,建议保留首尾竖线:

| 名称 | 数量 |
|------|------|
| 苹果 | 10   |

3.8.4 表头、表体和表尾

kramdown 表格可以使用分隔行表示不同区域。普通使用中至少保留表头分隔行即可。

| 名称 | 数量 |
|------|------|
| 苹果 | 10   |
| 香蕉 | 20   |

3.8.5 单元格中的竖线

需要显示普通 | 时进行转义:

| 表达式 |
|--------|
| A \| B |

3.8.6 表格不能随意跨行

每一行代表一个表格行或分隔行,因此不要把一行表格强行拆成两行。

错误:

| 名称
| 数量 |

正确:

| 名称 | 数量 |

3.8.7 表格示例

| 选项 | 类型 | 默认值 | 说明 |
|:-----|:-----|:------:|:-----|
| `auto_ids` | Boolean | `true` | 自动生成标题 ID |
| `hard_wrap` | Boolean | `false` | 是否把普通换行转为 `<br>` |
| `input` | String | `kramdown` | 输入解析器 |

3.9 水平线

使用三个或更多星号、减号或下划线:

***
---
___

字符之间可以有空格:

* * *

不要混用不同字符:

*-*

注意下面的结构会优先被识别为 Setext 标题:

标题
---

需要明确水平线时,在前面加空行:

上一段。

---

下一段。

3.10 数学公式块

数学公式不是原始 Markdown 的一部分。

块级公式通常使用双美元符号:

$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$

行内公式:

勾股定理可以写为 $$a^2+b^2=c^2$$。

输出方式取决于配置的数学引擎,例如:

kramdown:
  math_engine: mathjax

或者:

kramdown:
  math_engine: katex

公式内部通常不会按普通 Markdown 解析。

如果公式中需要美元符号,应根据数学引擎规则转义。

3.11 HTML 块

kramdown 可以直接嵌入块级 HTML:

<div class="notice">
  这是一段 HTML 内容。
</div>

常见块级标签包括:

<div>
<section>
<article>
<table>
<blockquote>
<pre>

3.11.1 HTML 中解析 Markdown

可以使用 markdown 属性控制 HTML 标签内部是否解析 Markdown。

<div markdown="1">

这里的 **粗体** 会被解析。

</div>

常见值的含义取决于元素和解析器,但通常用于指定:

  • 内部按块级 Markdown 解析;
  • 内部按行内 Markdown 解析;
  • 不解析 Markdown。

3.11.2 HTML 和 Markdown 的混合

<section class="example" markdown="1">

## HTML 容器中的 Markdown 标题

- 项目一
- 项目二

</section>

3.11.3 安全提示

kramdown 只是解析器,不是安全过滤器。

对于不可信输入,以下内容可能有风险:

<script>alert("危险")</script>

还需专门处理:

  • <script>
  • 事件属性,如 onclick
  • javascript: URL;
  • 危险 SVG;
  • 表单;
  • 内联样式;
  • 嵌入对象。

4. 行内文本标记

4.1 链接与图片

4.1.1 自动链接

URL:

<https://example.com>

邮箱:

<user@example.com>

输出时邮箱地址可能会进行一定混淆处理,以降低简单爬虫直接收集地址的风险。

4.1.2 行内链接

[示例网站](https://example.com)

带标题:

[示例网站](https://example.com "打开示例网站")

相对链接:

[安装说明](installation.md)

页面内锚点:

[跳到标题部分](#33-标题)

URL 中包含括号等特殊字符时,建议转义或使用尖括号包裹目标地址:

[链接](<https://example.com/a_(b)>)

4.1.3 引用链接

访问 [kramdown 官网][kramdown]。

[kramdown]: https://kramdown.gettalong.org/ "kramdown"

引用标识可以使用数字:

访问 [kramdown 官网][1]。

[1]: https://kramdown.gettalong.org/

隐式引用:

访问 [kramdown][]。

[kramdown]: https://kramdown.gettalong.org/

4.1.4 链接定义

链接定义本身不会显示:

[docs]: https://kramdown.gettalong.org/documentation.html

可以在文档其他位置引用:

查看 [官方文档][docs]。

链接定义通常可以放在文档任意位置。

4.1.5 图片

行内图片:

![替代文字](images/logo.png)

带标题:

![替代文字](images/logo.png "图片标题")

引用式图片:

![kramdown 标志][logo]

[logo]: images/logo.png "kramdown"

生成 HTML:

<img src="images/logo.png" alt="kramdown 标志" title="kramdown">

替代文字非常重要,应该说明图片内容,不应只写“图片”。

4.2 强调

斜体:

*斜体*

或者:

_斜体_

粗体:

**粗体**

或者:

__粗体__

粗斜体:

***粗斜体***

嵌套:

**粗体中包含 *斜体***

单词内部的下划线

不同解析器对单词内部下划线的处理可能不同:

file_name

为了代码标识符显示稳定,建议使用行内代码:

`file_name`

强调标记旁的空白

下面通常不会形成强调:

* 内容 *

推荐:

*内容*

4.3 行内代码

使用反引号:

运行 `bundle exec jekyll build`。

代码内容中包含一个反引号时,外层使用两个反引号:

``这里包含 ` 一个反引号``

代码内容两侧有空格时,外层可留出额外空格:

`` `code` ``

行内代码中的 Markdown 标记不会被解析:

`**这不是粗体**`

显示为:

**这不是粗体**

4.4 行内 HTML

可直接使用行内 HTML:

这是 <span class="highlight">高亮文字</span>。

换行:

第一行<br>
第二行

上标和下标:

H<sub>2</sub>O

x<sup>2</sup>

是否解析 HTML 标签内部的 Markdown,取决于标签和相关配置。

例如:

<span markdown="span">这里有 **粗体**</span>

4.5 脚注

脚注不是原始 Markdown 的一部分。

正文引用:

这里有一个脚注[^note]。

脚注定义:

[^note]: 这是脚注内容。

完整示例:

kramdown 使用 Ruby 编写[^ruby]。

[^ruby]: Ruby 是一种动态编程语言。

多段脚注:

这里引用一个长脚注[^long]。

[^long]: 这是第一段。

    这是第二段。

    - 还可以包含列表
    - 以及其他块级元素

同一个脚注标识符可以被多次引用,但最终编号和返回链接的具体表现取决于转换器。

脚注标识符只是关联用,不一定直接显示给读者。

4.6 缩写

缩写定义不是原始 Markdown 的一部分。

HTML 和 CSS 是网页开发中的常见技术。

*[HTML]: HyperText Markup Language
*[CSS]: Cascading Style Sheets

输出 HTML 时,匹配到的缩写可能生成:

<abbr title="HyperText Markup Language">HTML</abbr>

缩写定义本身不会显示。

注意:

  • 匹配通常区分完整词;
  • 相同缩写重复定义时,后面的定义可能覆盖前面的定义;
  • 缩写定义可以放在文档其他位置。

4.7 排版符号

kramdown 可以根据配置转换某些排版符号,例如:

  • 直引号转换为弯引号;
  • 连续句点转换为省略号;
  • 连字符组合转换为短破折号或长破折号。

示例:

"双引号"
'单引号'
...
--
---

实际输出由以下配置决定:

kramdown:
  smart_quotes: ["lsquo", "rsquo", "ldquo", "rdquo"]
  typographic_symbols:
    hellip: "…"
    mdash: "—"
    ndash: "–"

如果不希望触发转换,可使用反斜杠或行内代码:

\...

`---`

5. 非内容元素

这些语法通常用于控制解析,不直接产生普通正文。

5.1 块结束标记

单独一行的 ^ 是块结束标记,也称 EOB Marker。

^

它主要用于消除歧义。

分隔两个代码块

    第一段代码
^
    第二段代码

分隔两个同类型列表

- 列表一
^
- 列表二

结束列表后再写代码块

- 列表项
^
    列表外的代码

块结束标记通常不会生成可见内容。

5.2 属性列表定义

属性列表可以给元素增加:

  • ID;
  • CSS 类;
  • 普通 HTML 属性。

直接写属性:

{: #intro .lead lang="zh-CN"}

含义:

#intro       设置 id="intro"
.lead        添加 class="lead"
lang="zh-CN" 设置 lang 属性

定义可复用属性列表

{:notice: .notice role="note"}

之后引用:

这是提示内容。
{:notice}

可复用定义本身不会生成可见正文。

5.3 行内属性列表

IAL 是 Inline Attribute List 的缩写。虽然名称中有“Inline”,但既可以作用于块级元素,也可以作用于行内元素。

5.3.1 块级属性列表

属性列表单独放在块级元素后:

这是一个段落。
{: #intro .lead}

生成:

<p id="intro" class="lead">这是一个段落。</p>

标题:

## 重要说明
{: #important .warning}

列表:

- 项目一
- 项目二
{: .task-list}

引用:

> 注意事项
{: .notice}

代码块:

```ruby
puts "Hello"
```
{: #hello-example .number-lines}

5.3.2 行内元素属性列表

紧跟在行内元素后面:

*重点*{: .important}

链接:

[打开网站](https://example.com){: target="_blank" rel="noopener"}

图片:

![说明](image.png){: width="320" height="180"}

5.3.3 属性合并

多个类可一起写:

这是正文。
{: .lead .large .muted}

也可以设置键值属性:

这是正文。
{: data-kind="example" aria-label="示例"}

5.3.4 ID 应保持唯一

不要给多个元素设置相同 ID:

第一段。
{: #same}

第二段。
{: #same}

HTML 中重复 ID 会影响锚点、JavaScript 和无障碍功能。

5.4 扩展语法

kramdown 扩展通常使用如下形式:

{::扩展名 选项 /}

或者包含内容:

{::扩展名}
内容
{:/扩展名}

5.4.1 注释扩展

{::comment}
这段内容只作为源文件注释,不会作为普通正文输出。
{:/comment}

适合写:

  • 编辑备注;
  • 待办说明;
  • 构建提示;
  • 不希望发布的内容。

5.4.2 名义空元素

某些扩展使用自闭合形式:

{::options key="value" /}

准确可用扩展和选项取决于 kramdown 版本及转换器。

5.4.3 原始内容或解析控制

部分扩展可用于改变某段内容的解析方式。由于不同版本支持情况不同,使用前应查看当前版本文档和源码。


6. 推荐写法

虽然 kramdown 支持很多宽松写法,但为了让文档同时适用于 GitHub、Jekyll 和其他 Markdown 工具,建议遵守以下规则。

6.1 标题前后留空行

推荐:

上一段。

## 新标题

下一段。

6.2 列表统一使用 -

- 第一项
- 第二项
- 第三项

6.3 嵌套内容统一缩进

- 父项
  - 子项
  - 子项

6.4 代码统一使用围栏

```ruby
puts "Hello"
```

6.5 明确标注代码语言

不要只写:

```
puts "Hello"
```

推荐:

```ruby
puts "Hello"
```

6.6 不使用懒惰引用

不推荐:

> 第一行
第二行

推荐:

> 第一行
> 第二行

6.7 不混用 Tab 和空格

统一使用空格,尤其是列表和代码块。

6.8 表格保留首尾竖线

| 名称 | 值 |
|------|----|
| A    | 1  |

6.9 程序标识符使用行内代码

将 `auto_ids` 设置为 `true`。

6.10 属性列表单独成行

推荐:

## 标题
{: #custom-id .title}

比将大量属性都挤在标题末尾更容易维护。


7. 完整示例

下面是一份同时使用标题、目录、段落、引用、列表、代码、表格、链接、图片、脚注、缩写、数学公式和属性列表的完整 kramdown 文档。

---
layout: default
title: kramdown 示例
lang: zh-CN
---

# kramdown 示例
{: #top}

* 目录
{:toc}

## 简介

kramdown 是一个使用 Ruby 编写的 Markdown 超集解析器[^kramdown]。

本文包含 **粗体**、*斜体*、`行内代码` 和
[官方网站](https://kramdown.gettalong.org/)。

*[HTML]: HyperText Markup Language

## 引用

> Markdown 的目标之一,是让源文件本身也容易阅读。
>
> > 这是嵌套引用。

## 列表

- 解析器
  - kramdown
  - GFM
  - HTML
- 转换器
  - HTML
  - LaTeX
  - kramdown

## 定义列表

解析器
: 把源文本转换为内部元素树。

转换器
: 把内部元素树转换为目标格式。

## 代码

```ruby
require "kramdown"

source = "# Hello"
puts Kramdown::Document.new(source).to_html
```

## 表格

| 选项 | 类型 | 默认值 |
|:-----|:-----|:------:|
| `auto_ids` | Boolean | `true` |
| `hard_wrap` | Boolean | `false` |
| `input` | String | `kramdown` |

## 数学公式

行内公式:$$a^2+b^2=c^2$$。

$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$

## HTML

<div class="notice" markdown="1">

这里位于 HTML 容器内,但 **Markdown 仍会被解析**。

</div>

## 图片

![kramdown 示例图片](images/example.png){: width="480"}

## 脚注

[^kramdown]: kramdown 项目主页:
    <https://kramdown.gettalong.org/>

---

返回[页面顶部](#top)。

8. Jekyll 配置示例

在 GitHub Pages 或 Jekyll 中,可在 _config.yml 中使用:

title: kramdown 中文文档
description: kramdown 语法中文指南
lang: zh-CN

theme: jekyll-theme-primer

markdown: kramdown

kramdown:
  input: GFM
  auto_ids: true
  hard_wrap: false
  syntax_highlighter: rouge

defaults:
  - scope:
      path: ""
    values:
      layout: default

如果你希望严格使用 kramdown 原生语法,而不是 GitHub Flavored Markdown,可改为:

kramdown:
  input: kramdown

需要 GFM 解析器时,通常需要安装:

gem install kramdown-parser-gfm

9. 语法选择建议

使用场景 推荐方案
普通 GitHub 仓库文档 GitHub Flavored Markdown
GitHub Pages + Jekyll kramdown + GFM
需要脚注、属性列表、定义列表 kramdown
需要严格模拟 GitHub input: GFM
需要数学公式 配置 MathJax 或 KaTeX
需要代码高亮 配置 Rouge
混合 HTML 与 Markdown 使用 kramdown,并明确控制 markdown 属性
不可信用户内容 kramdown 后再使用 HTML sanitizer

10. 原文与版本

本文依据以下页面整理:

https://kramdown.gettalong.org/syntax.html

官方页面标明的语法文档版本:

2.5.2

kramdown 的不同版本可能调整部分边界行为、配置项或扩展功能。实际项目中应同时确认:

kramdown --version

以及:

kramdown --help
目录
下一篇 kramdown详细用法