写作语法
这一页是给要改文档的人看的。
你可以在改文档的时候随手查,也可以通读一遍。通读大概十分钟,比每次改的时候现搜省时间。
先记住一件事:GitBook 用的不是标准 Markdown,而是一个叫 kramed 的实现。大部分语法跟你在别处写的一样,但有几处不一样。下面用提示框标出来的,都是实际会踩的坑。
标题
# 到 ######,六级。
# 一级标题
## 二级标题
### 三级标题
几条硬规矩:
- 一页只写一个
#。 不是因为规定,是因为它决定这条在目录里的位置。你一页里塞两个#,读者会以为这是两页,翻半天才发现内容连着。 - h2 切大块,h3 切小块。
- h4 以下不要用。 右侧「本页目录」的 selector 只到 h3,你写 h4 等于白写,读者看不见。
强调
**粗体** *斜体* ~~删除线~~ ***粗斜***
删除线是支持的,这点跟 GitHub 一样。
别用下划线强调
__文字__ 在 kramed 里也是粗体,不是下划线。想强调就用 **,别自创语法。
代码
行内代码
键位、变量名、文件名用反引号包起来:
按 `Ctrl+S` 保存,改 `book.json` 里的 `plugins` 字段。
按 Ctrl+S 保存,改 book.json 里的 plugins 字段。
代码块
三个反引号加语言名:
```cpp
int main() { return 0; }
```
int main() { return 0; }
语言名必须写对
写 c++ 不会报错,只是没有高亮。没有高亮比报错更难发现,因为你以为成功了。
正确的是 cpp。其他常用:c、python、bash、json、diff、markdown、text。
diff 高亮
讲"改了什么"的时候特别有用:
```diff
- ios::sync_with_stdio(false);
+ ios::sync_with_stdio(true);
```
- ios::sync_with_stdio(false);
+ ios::sync_with_stdio(true);
代码里嵌套反引号
代码块内容本身含三个反引号时,外层用四个:
````markdown
```cpp
int x;
```
## 列表
```markdown
- 无序项
- 另一项
- 嵌套项(缩进 4 个空格)
1. 有序项
2. 第二项
```
- 无序项
- 另一项
- 嵌套项
1. 有序项
2. 第二项
> #### Danger:: 任务列表不支持
>
> `- [ ]` 和 `- [x]` 这种复选框写法,kramed 不认。它会原样输出成 `[ ] 文字`,看起来像作者忘了改。
>
> 要列待办就直接写字,或者在「更新记录」里用普通列表。**别指望它变成复选框。**
## 表格
```markdown
| 状态 | 含义 | 该做什么 |
| --- | --- | --- |
| AC | 通过 | 下一题 |
| WA | 答案错 | 比对输出 |
```
| 状态 | 含义 | 该做什么 |
| --- | --- | --- |
| AC | 通过 | 下一题 |
| WA | 答案错 | 比对输出 |
### 对齐
冒号的位置决定对齐:
```markdown
| 左对齐 | 居中 | 右对齐 |
|:---|:---:|---:|
| a | b | c |
```
| 左对齐 | 居中 | 右对齐 |
|:---|:---:|---:|
| a | b | c |
> #### Warning:: 表格里不要放代码块
>
> 单元格里只能放行内代码(`` `x` ``)。放三反引号代码块会把表格撑坏,整张表变成一堆竖线。要展示大段代码,写表格下面。
## 链接
### 站内链接
**写 `.md`,不要写 `.html`。** 构建时 GitBook 自动转换成 `.html`,你写死了反而容易错。
```markdown
[快速开始](guide/getting-started.md)
[上一级](../README.md)
```
### 站外链接
必须带协议头,`https://` 不能省:
```markdown
[评测系统](https://oj.hanzel.top/)
```
裸地址想直接显示,用尖括号:
```markdown
<https://oj.hanzel.top/>
```
<https://oj.hanzel.top/>
### 跳到页内某节
```markdown
[看评测状态](#评测状态)
```
锚点就是标题文字,**去掉标点、空格换成连字符**。中文标题也能用,GitBook 会做 URL 编码,不用你操心。
> #### Warning:: 别手写编码后的锚点
>
> 别自己把中文标题转成 `%E8%AF%84%E6%B5%8B`。写原始中文,浏览器和 GitBook 都会处理。手写编码的结果是一改标题就失效。
## 图片
```markdown

```
图片放 `images/` 目录,用相对路径。
> #### Info:: 图片不会自动压缩
>
> 传一张 5MB 的 PNG,读者就要下载 5MB。截图先用工具压一下,或者存成 JPG。控制台截图这种文字多的图,PNG 反而更小。
## 引用块
普通引用用 `>`:
```markdown
> 这是一段引用。
```
> 这是一段引用。
引用块适合放:别人的话、需要停顿一下的重话、注意事项。**不要用它做排版缩进**,缩进用列表。
## 分割线
```markdown
---
```
三个减号,前后各空一行。只写 `---` 紧跟在文字下面,会被当成标题的下划线(把上一行变成 h2)。
## 提示框
四种,由 `callouts` 插件提供。
**它不是 hints 插件的语法。** 那个插件的写法是用大括号加百分号把 hint 包起来,我们没装它,照抄会直接构建失败。
### 写法
提示框就是**带 h4 标题的引用块**:
````markdown
> #### Info::可选的标题
>
> 正文第一行
> 正文第二行
可选的标题
正文第一行 正文第二行
四种类型
> #### Info::信息
>
> 补充说明,读者不看也不影响操作。
> #### Success::成功
>
> 做对了的现象,或者推荐做法。
> #### Warning::注意
>
> 容易出错但不会造成严重后果的地方。
> #### Danger::警告
>
> 会丢数据、会构建失败、会让人白干一天的坑。
信息
补充说明,读者不看也不影响操作。
Success::成功
做对了的现象,或者推荐做法。
Warning::注意
容易出错但不会造成严重后果的地方。
Danger::警告
会丢数据、会构建失败、会让人白干一天的坑。
类型不区分大小写,info 和 Info 都行。标题可以留空,直接写 > #### Info::。
怎么选类型
| 类型 | 什么时候用 |
|---|---|
| Info | 补充信息,跳过也能干活 |
| Success | 推荐做法、正确姿势 |
| Warning | 容易踩、但后果可控 |
| Danger | 会毁东西、会白干、会构建失败 |
每行都要有 >
这是最容易写错的地方。提示框内部的每一行都要以 > 开头,块内的空行要写成单独一个 >。
漏一行,提示框就从那里断成两半,后半段变成普通正文,而且不报错。
数学公式
支持,靠 katex 插件。
这条跟你在别处写的不一样:行内公式也要用两对美元符号。
很多地方的行内公式用一对,这个插件不认。写一对的话它不会渲染,会原样输出成带美元符号的文本,看起来像你忘了加格式。
区别只在位置上:
- 行内 —— 两对美元符号夹着公式,跟正文同行
- 块级 —— 同样两对,但两块定界符各自单独占一行
行内
正文里直接写,不换行:
时间复杂度 ,空间 。
上面这行有两处公式。写法就是在正文中插两对美元符号夹住内容,前后不用加空格,也不用缩进。
块级
想让公式独占一块、居中显示,把两对定界符各自单独占一行:
定界符不能和公式写在同一行,那样会被当成行内。
别在代码块里示范公式写法
这个插件对美元符号的匹配发生在 markdown 解析之前,它不认代码块。你在代码块里写公式示例,它照样渲染,把整个代码块撑成一堆乱码。
要告诉别人怎么写,就照这一页的做法:用文字描述,再给真实渲染出来的结果。
常用写法
| 想要 | 写法 |
|---|---|
| 下标 | a_i → |
| 上标 | a^2 → |
| 分数 | \frac{a}{b} → |
| 根号 | \sqrt{n} → |
| 求和 | \sum_{i=1}^{n} → |
| 小于等于 | \le → |
| 不等于 | \neq → |
| 无穷 | \infty → |
| 大 O | O(n^2) → |
公式里不要用中文
KaTeX 的字体里没有汉字,写进去要么不显示,要么整段错位。要中文说明,写在公式外面的正文里。
另外,行内公式不能跨段落。定界符开了没在同一段里闭合,会把它后面的所有内容都吞进去,然后整个构建失败。
脚注
支持:
这句话有个出处[^1]。
[^1]: 出处写在这里。
这句话有个出处1。
1. 出处写在这里。 ↩
脚注会渲染到页面底部,带一个返跳链接。编号必须成对,定义漏了会在正文留下一个空的 [^1]。
不支持的语法
这些写了不会有预期效果,别浪费时间:
| 语法 | 结果 |
|---|---|
- [ ] 任务列表 |
原样输出 [ ] |
[TOC] 自动目录 |
原样输出 [TOC] |
| 表格内代码块 | 表格结构破坏 |
目录不用手写。GitBook 的左侧栏和右侧「本页目录」都是自动生成的,你只要把标题写好。
SUMMARY.md 怎么写
这是全站最重要的一个文件。 它决定左侧目录长什么样,也决定哪些页面能被访问到。
基本结构
# Summary
# 入门
* [前言](README.md)
* [快速开始](guide/getting-started.md)
# 训练
* [题单与训练](guide/training.md)
# 分节名生成目录里的分节标题* [显示名](文件路径.md)生成一个目录项- 缩进 4 个空格生成子项
三条规矩
- 新页面必须在这里加一行。 不加,文件在磁盘上存在,但没人能点进去,等于没写。
- 路径相对于
SUMMARY.md所在目录,guide/xxx.md不是./guide/xxx.md。 - 顺序就是目录顺序,不是按文件名排。
删页面要先删这里
直接删 .md 文件但 SUMMARY.md 里还留着那一行,构建会报 ENOENT,整个站点构建失败。先删 SUMMARY 里的引用,再删文件。
book.json 能配什么
改完要跑 ./build.sh 才生效。
| 字段 | 作用 |
|---|---|
title |
书名,显示在浏览器标签和左侧栏顶部 |
description |
站点描述,给搜索引擎看 |
author |
作者 |
language |
语言,影响界面文字(zh-hans) |
links |
左侧栏底部的链接 |
plugins |
启用的插件,加一个就要重新 gitbook install |
styles |
自定义 CSS 路径 |
build.sh 会自动装插件
你改了 plugins 字段后直接跑 ./build.sh,它会发现 book.json 比 node_modules 新,自动执行一次 gitbook install。不用手动装。
写之前先看这段
语法只是工具。一页文档写得好不好,跟你会不会写表格没关系。
判断标准只有一条:读者看完能不能自己把事做成。
写之前先问自己:读者是谁?他读之前知道什么?读完之后要能做什么?
- 写给新人的,就假设他什么都不知道,每个名词第一次出现时解释一句。
- 写给老手的,别铺垫,直接给结论和边界情况。
别写"我们建议您可以根据实际情况进行相应的配置"。
写"把
timeout改成 5"。含糊的句子不是在留余地,是在把决策推回给读者。
1. 这一条是脚注的实际效果演示。 ↩