# Chinese Markdown Format Spec

规范目标：统一中文 Markdown 文章中中英文混排的间距、标点符号与专有名词大小写。

---

## 1. 间距规则（Spacing Rules）

### 1.1 CJK 与 ASCII 之间必须有一个空格

**CJK** 指：Unicode 中文、日文、韩文字符（范围 `\u2e80-\u9fff`、`\uf900-\ufaff`、`\ufe30-\ufe4f` 等）。
**ASCII** 指：英文字母、数字（独立使用时）。

```
✗  的ABI
✓  的 ABI

✗  说的C++标准
✓  说的 C++ 标准

✗  8字节
✓  8 字节

✗  C++17是
✓  C++17 是
```

### 1.2 CJK 与 inline code 之间必须有一个空格

```
✗  调用`malloc`分配
✓  调用 `malloc` 分配

✗  通过`sizeof`获取
✓  通过 `sizeof` 获取
```

### 1.3 CJK 与链接之间必须有一个空格

链接语法 `[text](url)` 整体视为一个单元，检查其前后与 CJK 的间距。

```
✗  对[反射](https://example.com)的
✓  对 [反射](https://example.com) 的

✗  参考[文档](https://example.com)了解
✓  参考 [文档](https://example.com) 了解
```

图片语法 `![alt](url)` 同理（如果出现在行内）。

### 1.4 Bold/Italic 语法与 CJK 的间距

**排版原则：CJK 紧贴 `**`/`\*` 时不加空格。\*\*

中文排版中，字与字之间无论常体、粗体还是斜体，不存在物理空格。强行在 `**bold**` 前后加空格会在渲染结果中产生明显豁口，破坏阅读连贯性。现代 CommonMark 兼容解析器已支持 `**` 紧贴 CJK 字符的正确解析。

```
✗  中文 **加粗** 中文
✓  中文**加粗**中文
```

**例外：bold/italic 内容本身为英文时，遵循中英间距规则。**

空格的依据是 CJK↔ASCII 边界，而不是 Markdown 语法边界：

```
✓  中文 **bold text** 中文
✓  更多**详细信息**请参考
```

---

## 2. 括号规则（Bracket Rules）

### 2.1 括号内容全为 ASCII → 使用英文括号，与前方 CJK 保持一个空格

```
✗  中文（English）
✓  中文 (English)

✗  模式(Design Pattern)
✓  模式 (Design Pattern)
```

括号内部（紧贴括号）**不加空格**：

```
✗  模式 ( Design Pattern )
✓  模式 (Design Pattern)
```

### 2.2 括号内容含有 CJK（或 CJK+ASCII 混合）→ 使用全角括号，前后不加额外空格

```
✓  这种方式（适用于大多数场景）效率较高
✓  函数（function）是基本单元
✓  这个方法（parse_tree 解析）效率较高
```

> **注意**：括号内容混合 CJK+ASCII 时仍使用全角括号，归入此类。

**Fix 模式可自动修复括号类型。**

---

## 3. 标点符号规则（Punctuation Rules）

### 3.1 中文语境使用中文标点

中文语境下不混入 ASCII 标点（仅 lint，不 autofix，因为英文短语内的标点合法）：

```
✗  中文文本, 继续
✓  中文文本，继续

✗  句子结束.
✓  句子结束。
```

### 3.2 省略号必须使用 `……`（U+2026 × 2）

中文标准省略号占两个汉字宽度（六个点）。不应使用三个半角句点 `...`。

```
✗  继续等待...
✓  继续等待……
```

省略号前后与 CJK **不加额外空格**（全角符号自身已包含足够字距）。

### 3.3 破折号必须使用 `——`（U+2014 × 2）

中文破折号占两个汉字宽度。单连字符 `-` 仅用于英文连字或代码中，不作为中文破折号。

```
✗  这是一个问题-而且很难解决
✓  这是一个问题——而且很难解决
```

破折号前后与 CJK **不加额外空格**。

### 3.4 引号

- 中文句子用 `「」` 或弯引号 `""` `''`
- 代码或英文片段内部保持 ASCII 直引号

---

## 4. 专有名词表（Canonical Noun List）

以下名词在**正文**中出现时，须使用规范大小写形式。名词出现在代码块、inline code、URL 中时不做检查。

| 规范形式 | 常见错误写法                 |
| -------- | ---------------------------- |
| GCC      | gcc, Gcc                     |
| Clang    | clang, CLANG                 |
| MSVC     | msvc, Msvc                   |
| LLVM     | llvm, Llvm                   |
| CMake    | cmake, Cmake, CMAKE          |
| Python   | python, PYTHON               |
| Rust     | rust, RUST                   |
| C++      | c++, CPP, cpp                |
| CPU      | cpu, Cpu                     |
| GPU      | gpu, Gpu                     |
| ABI      | abi, Abi                     |
| API      | api, Api                     |
| ELF      | elf, Elf                     |
| POSIX    | posix, Posix                 |
| GitHub   | github, Github, GITHUB       |
| Linux    | linux, LINUX                 |
| Windows  | windows, WINDOWS             |
| macOS    | macos, MacOS, MACOS          |
| x86      | X86                          |
| x86-64   | X86-64（正文中；代码中不管） |
| ARM      | arm, Arm                     |

> 专有名词表作为正则驱动方案的补充例外表（Exception List），用于处理正则无法覆盖的边界情况。

---

## 5. 术语原子单元识别（Atomic Term Detection）

**采用正则驱动（词法分析）作为核心策略。**

将文本 tokenize，把「连续的字母+数字+特定连接符」视为一个原子 Token，内部不注入空格，只在该 Token 与前后 CJK 字符之间注入空格。

**原子 Token 的基本正则模式：**

```
[A-Za-z0-9]+(?:[+\-#.][A-Za-z0-9]+)*[+#]*
```

此模式自动将以下情形识别为单一原子单元：

| 示例         | 说明                     |
| ------------ | ------------------------ |
| `C++17`      | 语言名+版本号            |
| `C#`         | 语言名+符号              |
| `x86-64`     | 架构名+连字符+数字       |
| `Node.js`    | 名称+点+后缀             |
| `.NET`       | 点开头的框架名（需微调） |
| `ARMv8`      | 架构名+版本              |
| `Python3.12` | 语言名+版本号            |

**名词表仅作为例外补丁**，处理正则无法覆盖的奇葩专有名词（例如大小写规范化）。

---

## 6. 全角英数字转换（Full-width Alphanumeric Conversion）

中文输入法下误输入的全角英文字母和数字（`\uff10-\uff19`、`\uff21-\uff3a`、`\uff41-\uff5a`）必须转换为半角 ASCII。

```
✗  内存限制为 １６ ＧＢ
✓  内存限制为 16 GB

✗  调用 ＡＰＩ 接口
✓  调用 API 接口
```

**Fix 模式可自动修复**（Unicode 偏移量映射：`\uff10-\uff19` → `0-9`，`\uff21-\uff3a` → `A-Z`，`\uff41-\uff5a` → `a-z`）。

---

## 7. 数字与单位/符号的间距（Number-Unit Spacing）

### 7.1 数字与字母单位之间必须有一个空格

```
✗  支持 8GB 内存
✓  支持 8 GB 内存

✗  带宽 100Mbps
✓  带宽 100 Mbps

✗  延迟 50ms
✓  延迟 50 ms

✗  分辨率 1920x1080px
✓  分辨率 1920x1080 px
```

### 7.2 数字与百分号、度数符号之间不加空格

```
✗  性能提升了 20 %
✓  性能提升了 20%

✗  温度达到 80 °C
✓  温度达到 80°C
```

> `%`、`°`、`°C`、`°F` 紧贴数字，不加空格。

---

## 8. 中文语境下的句末标点（Trailing Punctuation in Chinese Context）

当中文句子以 ASCII 词或 inline code 结尾时，紧随其后的标点必须使用中文标点。

```
✗  该功能仅支持 Windows. 接下来……
✓  该功能仅支持 Windows。接下来……

✗  配置 `config.json`, 然后重启。
✓  配置 `config.json`，然后重启。
```

检测模式：`ASCII词/inline-code` 后紧跟 ASCII 标点 `.` `,` `!` `?` `:`，且该标点后接空格或行尾、且上下文为中文句子。

**仅 lint，不 autofix**（与规则 3.1 合并，同一类违规）。

---

## 9. 连续重复标点去重（Duplicate Punctuation）

仅压缩**停顿/结束类**标点的重复（逗号、句号、分号、冒号），**语气类**标点（感叹号、问号）允许重复用于强调。

```
✗  请注意，，，这里需要提权。
✓  请注意，这里需要提权。

✗  这个问题。。反复出现。
✓  这个问题。反复出现。

✓  这个 Bug 终于修复了！！   ← 允许，语气强调
✓  真的吗？？                ← 允许，语气强调
```

豁免：`……`（两个 U+2026）和 `——`（两个 U+2014）是规范写法，不压缩。

**Fix 模式可自动修复**停顿类标点（`，。；：` 及对应 ASCII `,.:;`）的重复，语气类不处理。

---

## 10. 引号与 UI 路径符号（Quotes & Symbols）

### 10.1 统一使用直角引号「」与『』

推荐使用直角引号代替弯引号，在等宽字体和中英混排下边界更清晰。

- 外层引号：`「」`（U+300C, U+300D）
- 内层嵌套：`『』`（U+300E, U+300F）

```
✗  他说："请注意这个'致命'错误。"
✓  他说：「请注意这个『致命』错误。」
```

**Fix 模式可自动替换**成对的 `""` 和 `''`，但需跳过 HTML 标签属性（`id="app"` 等）。

### 10.2 UI 路径层级分隔符

描述 UI 操作路径时，统一使用带前后空格的半角 `>` 作为分隔符，路径各节建议加粗。

```
✗  请依次点击 设置->系统->关于
✗  请依次点击 设置>系统>关于
✓  请依次点击 **设置** > **系统** > **关于**
```

**仅 lint**（路径格式与上下文强耦合，不 autofix）。

---

## 11. 常见技术中文术语纠错（Common Tech Typos）

建立中文易错词字典，进行整词匹配检查与替换。

| 错误写法 | 规范写法 | 说明                                 |
| -------- | -------- | ------------------------------------ |
| 登陆     | 登录     | Login 是「记录」之意                 |
| 帐号     | 账号     | 「贝」字旁的账与财务记录相关         |
| 联接     | 连接     | Connection 通常用「连接」            |
| 其它     | 其他     | 现代汉语规范，指代事物统一用「其他」 |
| 粘帖     | 粘贴     | 常见输入法手误                       |
| 搜寻     | 搜索     | zh-CN 技术文档语境更倾向「搜索」     |

**Fix 模式可自动修复**（整词匹配，不在 inline code / 代码块 / URL 中替换）。

---

## 12. Markdown 结构与空白规范（Markdown Structure）

### 12.1 标题 `#` 与文本之间必须有且仅有一个空格

```
✗  ##标题文本
✗  ##  标题文本
✓  ## 标题文本
```

**Fix 模式可自动修复**（`^(#{1,6})\s+` → `$1 `）。

### 12.2 列表标记符与文本之间必须有一个空格

```
✗  -列表项
✗  1.列表项
✓  - 列表项
✓  1. 列表项
```

**Fix 模式可自动修复**。

### 12.3 不允许连续两个以上空行

```
✗  段落一。
   （空行）
   （空行）
   段落二。

✓  段落一。
   （空行）
   段落二。
```

**Fix 模式可自动修复**（将 `\n{3,}` 压缩为 `\n\n`）。

---

## 13. 代码块规范（Code Block Rules）

### 13.1 代码块必须声明语言

使用反引号包裹的代码块，第一行必须显式指定语言标识；纯文本使用 `text` 或 `plain`。

````
✗  ```
   const a = 1;
   ```

✓  ```javascript
   const a = 1;
   ```
````

**仅 lint，不 autofix**（无法准确推断语言类型）。

### 13.2 文件末尾保留一个换行符

遵循 POSIX 规范，文件最后一行以 `\n` 结束。

**Fix 模式可自动修复**（文件末尾补充 `\n`）。

---

## 14. 检查范围（Scope）

### 目标文件

默认检查 `website/content/zh-cn/articles/*/index.md`，也支持传入任意 `.md` 文件路径。英文文章（`en/`）暂不纳入。

### 检查的内容

- 正文段落
- 标题（`#`、`##` 等）
- 链接 alt text（`[alt text](url)` 中的 `alt text`）
- 图片 alt text（`![alt text](url)` 中的 `alt text`）
- 列表项
- Blockquote 内容

### 跳过的内容

- YAML frontmatter（文件开头 `---` 到 `---` 之间）
- 代码块（` ``` ` 包裹的内容，含语言标注）
- Inline code（反引号包裹的内容本身不检查；但其前后与 CJK 的间距仍检查）
- 链接 URL 部分（`[text](URL)` 中的 `URL`）
- HTML 标签

---

## 15. 运行模式（Modes）

### Lint 模式

输出所有违规位置，不修改文件：

```
file.md:42: [spacing] 缺少空格：「的ABI」→「的 ABI」
file.md:87: [noun]    大小写错误：「gcc」→「GCC」
file.md:103:[bracket] 应使用英文括号：「（English）」→「(English)」
file.md:115:[punct]   应使用中文省略号：「...」→「……」
```

### Fix 模式

自动修复所有可安全修复的违规，输出修改摘要：

```
file.md: fixed 3 spacing, 1 noun, 1 bracket, 0 punct issues
```

**可自动修复：**

- CJK 与 ASCII / inline code / link 之间插入空格
- 专有名词大小写替换（整词匹配，不在 inline code / URL 中替换）
- 括号类型切换（全角↔半角，依据内容判断）
- `...` → `……`，`--` → `——`（仅在中文语境中）
- 全角英数字 → 半角（Unicode 偏移量映射）
- 数字与字母单位之间插入空格（`8GB` → `8 GB`）
- 数字与 `%` `°` 之间去除多余空格
- 停顿类重复标点压缩（`，。；：` 重复）
- 弯引号 `""` `''` → 直角引号 `「」` `『』`
- 常见技术术语纠错（`登陆` → `登录` 等）
- 标题 `#` 后空格规范化
- 列表标记符后空格规范化
- 连续空行压缩为单空行
- 文件末尾补充换行符

**仅 lint 不 autofix：**

- ASCII 标点 → 中文标点（`,` `.` 等），可能出现在合法英文短语中
- 代码块无语言声明（无法推断语言）
- UI 路径格式（与上下文强耦合）

---

## 16. 示例（Examples）

### 完整段落对比

**修复前：**

```
GCC和Clang是两种常见的C++编译器。使用`-O2`选项可以开启优化。
参考[文档](https://example.com)了解更多关于ABI兼容性(Application Binary Interface)的内容。
这个函数**非常重要**，它实现了x86-64架构下的内存对齐...
```

**修复后：**

```
GCC 和 Clang 是两种常见的 C++ 编译器。使用 `-O2` 选项可以开启优化。
参考 [文档](https://example.com) 了解更多关于 ABI 兼容性 (Application Binary Interface) 的内容。
这个函数**非常重要**，它实现了 x86-64 架构下的内存对齐……
```
