# 文档标记语言：Markdown、AsciiDoc 与 DITA 的能力与取舍

Source: https://flowingdocs.com/docs/markup/

## 格式特性与实践定位

选择格式时，可以先看文档需要怎样排版、复用和发布：

- **Markdown**：语法简洁，常用于 README、博客和 API 说明。标准语法没有合并单元格、变量和内容复用机制；需要这些能力时，通常借助 HTML、扩展或构建工具。
- **AsciiDoc**：支持表格跨行跨列、文档属性和 `include`。多处使用相同参数或说明片段、需要组合多份文件时，这些功能便于集中维护内容。
- **DITA**：用 XML 按主题组织内容，通过 Topic 和 Map 组合文档，并用 `conref` 等机制复用内容。适合需要结构校验、内容复用和多种输出格式的文档；同时需要维护对应的编辑与发布工具链。可参考 [OASIS DITA 概述](https://docs.oasis-open.org/dita/dita/v1.3/os/part0-overview/dita-v1.3-os-part0-overview.html)。

工作台上方提供两条演练路径：“**基础撰写**”用于实时对照 Markdown 与 AsciiDoc 的排版差异；“**DITA · 组织多份说明**”用于体验如何通过 Topic 与 Map 编排交付整套产品手册。

关于表格排版：Markdown 的管道表格遵循 [GFM 扩展规范](https://github.github.com/gfm/#tables-extension-)，无合并语法；练习中采用内嵌 HTML 的 `rowspan` 与 `colspan` 实现，需注意目标渲染平台是否开启 HTML 过滤。AsciiDoc 则[原生支持跨行跨列语法](https://docs.asciidoctor.org/asciidoc/latest/tables/span-cells/)。

## 把练习用于自己的文档 {#database-docs}

工作台借用 **MySQL 8.0 场景**比较文档结构。这些片段用于写作练习，不是完整的生产运维流程。你可以把其中的结构用于自己的说明：

- **参数字典与存储引擎对照** → 数据库关键参数或 API 规约清单（数据类型、默认值、生效作用域）。
- **初始化与启停 Runbook** → 服务集群部署、证书轮换或故障恢复流程（强调前置依赖、执行动作与验证回执）。
- **控制台报错与原样输出** → CLI 控制台日志、连接状态码与排错指引。

无论选用哪种标记语言，工具能校验的只是语法有效性。技术文档的完整性仍取决于是否清晰交代了前置条件、执行结果与异常退路。

## 按需求深入查阅 {#format-resources}

根据实际遇到的文档工程问题，推荐继续探索对应方向：

| 遇到场景                   | 推荐技术路径与资料                                                                                                                                                                                            |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 编写开源项目 README、团队协作笔记   | 参考 [CommonMark](https://commonmark.org/help/) 与 [GFM 规范](https://github.github.com/gfm/)，确认团队渲染引擎支持的扩展列表。                                                                                            |
| 多处跨文档引用相同产品名称、版本号或警告片段 | 参见工作台左侧“内容复用”示例，深入查阅 [AsciiDoc 属性系统](https://docs.asciidoctor.org/asciidoc/latest/attributes/document-attributes/) 与 [include 指令](https://docs.asciidoctor.org/asciidoc/latest/directives/include/)。 |
| 在文档正文中嵌入交互式 React 组件   | 学习 [MDX 规范](https://mdxjs.com/docs/what-is-mdx/)，需要配合现代静态站点生成器（如 Docusaurus、Next.js）进行构建支持。                                                                                                          |
| 企业级产品线需要模块化组装多套交付手册    | 进入工作台“DITA 路径”熟悉 Topic 与 Map 架构，导出项目后可直接在专业编写工具（如 Oxygen XML Editor）中深入实践。                                                                                                                           |

### 离线练习包与工程迁移

你可以通过顶部的下载操作导出当前编辑状态：

- **只下载源文件**：保留编辑草稿，使用站点全局资源路径。
- **下载练习包（含资源）**：将配套矢量图一并打包为相对路径，解压后可直接放入本地静态构建环境中验证。

在选型后续的发布工具时，推荐阅读[静态站点生成器选型指南](https://flowingdocs.com/docs/publishing/)；若关注文本结构背后的信息传达效率，可参考[信息表达实践](https://flowingdocs.com/docs/information-design/)。

以下参考答案与互动练习使用同一份示例数据。可以直接阅读、复制，也可以下载 Markdown 版。

MySQL 片段用于比较文档写法，不是完整的生产运维流程。内容复用示例使用虚构产品；正式使用前应在所选工具链中验证。

## 标题与段落

给手册加上一级标题，把“服务简介”设为小节标题，段落之间留空行。

### Markdown

文档标题写作 \# 标题，小节写作 \#\# 标题。\# 后留一个空格。

\# 后留空格；段落之间留一个空行。

```markdown
# MySQL 数据库服务

## 服务简介

MySQL 是广泛应用的开源关系型数据库管理系统。支持高并发连接、ACID 事务与多存储引擎，是现代 Web 架构与企业核心系统的基础数据存储设施。
```

### AsciiDoc

文档标题写作 = 标题，小节写作 == 标题。标题后留空行，再开始正文。

等号后留空格，标题与正文之间空一行。

```asciidoc
= MySQL 数据库服务

== 服务简介

MySQL 是广泛应用的开源关系型数据库管理系统。支持高并发连接、ACID 事务与多存储引擎，是现代 Web 架构与企业核心系统的基础数据存储设施。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 无序列表

把三项准备事项改成无序列表。它们不需要编号。

### Markdown

每行前加 \- 和一个空格。\* 或 \+ 也可以。

\- 后留空格，列表前与正文空一行。

```markdown
## 启动前检查

- 确认系统 3306 端口未被占用。
- 验证当前用户具备数据目录读写权限。
- 准备有效的配置文件 my.cnf。
```

### AsciiDoc

每行前加 \* 和一个空格。

星号后需要空格；列表前与正文空一行。

```asciidoc
== 启动前检查

* 确认系统 3306 端口未被占用。
* 验证当前用户具备数据目录读写权限。
* 准备有效的配置文件 my.cnf。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 有序列表

把三项操作改成从 1 开始的有序列表。

### Markdown

用 1\.、2\.、3\. 加空格。每行都写 1\. 也可以自动编号。

英文句点后需要空格，否则可能仍是普通段落。

```markdown
## 初始化实例

1. 执行初始化命令生成系统表与数据目录。
2. 启动 mysqld 服务进程。
3. 运行安全脚本配置管理员初始密码。
```

### AsciiDoc

每行以一个英文句点和空格开头：\. 操作。编号由处理器生成。

使用英文句点加空格，不需要手动写 1、2、3。

```asciidoc
== 初始化实例

. 执行初始化命令生成系统表与数据目录。
. 启动 mysqld 服务进程。
. 运行安全脚本配置管理员初始密码。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 加粗与斜体

把“systemctl start mysqld”加粗，把“停止服务前，应先确认业务连接可以中断”设为斜体。

### Markdown

\*\*文字\*\* 加粗，\*文字\* 斜体。中文说明通常优先用加粗，斜体这里只用来认识语法。

标记贴着文字写，不要写成 \*\* 文字 \*\*。

```markdown
## 服务启停与重载

需要启动服务时，执行 **systemctl start mysqld**。停止服务使用 systemctl stop mysqld。

*停止服务前，应先确认业务连接可以中断*。
```

### AsciiDoc

\*文字\* 加粗，\_文字\_ 斜体。示例在标记两侧留空格，避免与前后文字粘连。

标记要成对。本课示例在整组标记两侧留空格，避免与相邻文字粘连。

```asciidoc
== 服务启停与重载

需要启动服务时，执行 *systemctl start mysqld*。停止服务使用 systemctl stop mysqld。

_停止服务前，应先确认业务连接可以中断_。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 嵌套列表

把实例规划分成生产集群和测试环境两组，每组下面放一项说明。

### Markdown

子列表缩进两个空格。列表内另起段落也要保持缩进，否则会跳出列表。

本例子项前有两个空格；与父项顶格对齐会变成同一层。

```markdown
## 按环境规划实例

- 生产集群
  - 主节点写入，只读副本同步。
- 测试环境
  - 单元测试库与数据沙箱。
```

### AsciiDoc

第一层用 \*，第二层用 \*\*。这里的双星号是列表层级，不是加粗标记。

第二层用两个星号；这里的 \*\* 不是加粗。

```asciidoc
== 按环境规划实例

* 生产集群
** 主节点写入，只读副本同步。
* 测试环境
** 单元测试库与数据沙箱。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 图片与链接

插入架构图，写上替代文字，再加一个“查看架构大图”链接。

### Markdown

\!\[替代文字\]\(图片路径\) 插入图片，\[链接文字\]\(地址\) 插入链接。替代文字要说明图里有什么。

图片比链接多一个 \!；练习中请使用素材提供的图片路径。

```markdown
## 架构拓扑与参考资料

![MySQL 架构拓扑：连接池、查询优化器与 InnoDB 存储引擎](/img/markup/mysql-architecture.svg)

[查看架构大图](/img/markup/mysql-architecture.svg)
```

### AsciiDoc

image::路径\[替代文字\] 插入块级图片，link:地址\[链接文字\] 插入链接。

块级图片用两个冒号 image::，并独占一行。

```asciidoc
== 架构拓扑与参考资料

image::/img/markup/mysql-architecture.svg[MySQL 架构拓扑：连接池、查询优化器与 InnoDB 存储引擎]

link:/img/markup/mysql-architecture.svg[查看架构大图]
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 普通表格

把引擎、事务支持和适用场景整理成三列表格，保留两行引擎数据。

### Markdown

GFM 表格需要表头和分隔行。:\-\-\- 左对齐，:\-\-\-: 居中，\-\-\-: 右对齐。表格是 GFM 扩展。

分隔行不能省略。这是 GFM 扩展，管道表格不能合并单元格。

```markdown
## 存储引擎对照

| 引擎 | 事务支持 | 适用场景 |
| :--- | :--- | :--- |
| InnoDB | 支持 (ACID) | 高并发事务与核心业务 |
| MyISAM | 不支持 | 历史只读数据归档 |
```

### AsciiDoc

用两行 \|=== 包住表格；表头后空一行，每个单元格用 \| 开头。\[cols="1,2,2",options="header"\] 设置列和表头。

表头与数据之间空一行；结尾不要漏掉 \|===。

```asciidoc
== 存储引擎对照

[cols="1,2,2",options="header"]
|===
|引擎 |事务支持 |适用场景

|InnoDB |支持 (ACID) |高并发事务与核心业务
|MyISAM |不支持 |历史只读数据归档
|===
```

[Markdown](https://github.github.com/gfm/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 合并单元格

Markdown 的管道表格没有原生合并能力。这里使用 HTML 的 rowspan 和 colspan，需要发布平台允许内嵌 HTML。AsciiDoc 原生支持跨行和跨列。

### Markdown \+ HTML

这是内嵌 HTML，不是 Markdown 原生合并语法；合并后必须删掉被占用的单元格。

```markdown
## 备份与维护安排

<table>
  <thead><tr><th>备份类型</th><th>方式</th><th>说明</th></tr></thead>
  <tbody>
    <tr><td rowspan="2">物理备份</td><td>全量冷备</td><td>停机直接拷贝数据文件</td></tr>
    <tr><td>增量热备</td><td>基于 Redo Log 持续追加</td></tr>
    <tr><td>通用规范</td><td colspan="2">备份文件必须离线归档，定期演练恢复。</td></tr>
  </tbody>
</table>
```

### AsciiDoc

句点代表跨行（\.2\+\|），无句点代表跨列（2\+\|）。合并标记直接替代竖线，不要写成 \| \.2\+\|；并务必删掉被跨越覆盖的单元格。

```asciidoc
== 备份与维护安排

[cols="1,1,2",options="header"]
|===
|备份类型 |方式 |说明

.2+|物理备份 |全量冷备 |停机直接拷贝数据文件
|增量热备 |基于 Redo Log 持续追加

|通用规范 2+|备份文件必须离线归档，定期演练恢复。
|===
```

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/tables/span-cells/)

## 代码与原样文本

把 1045 标为行内等宽文字，把两行状态放进原样文本块。

### Markdown

行内文字用反引号包住，多行文字用三个反引号围起来。后面的 text 表示普通文本。

使用英文反引号 \`，不是单引号；围栏各占一行。

````markdown
## 终端回显与状态码

认证失败时客户端将回显 `1045` 错误码。

```text
状态：运行中
活跃连接：18
```
````

### AsciiDoc

行内文字用反引号包住。用两行 \.\.\.\. 围住多行文字，保留换行和空格。

上下两行都是四个英文句点，不是省略号。

```asciidoc
== 终端回显与状态码

认证失败时客户端将回显 `1045` 错误码。

....
状态：运行中
活跃连接：18
....
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 页内链接

把“实例维护”变成指向对应小节的链接，并在预览中点击试试。

### Markdown

写成 \[实例维护\]\(\#实例维护\)。本练习按标题生成锚点，不同站点的规则可能不同。

锚点必须存在。不同平台生成标题锚点的规则可能不同。

```markdown
## 故障排查

排查权限与连接故障见[实例维护](#实例维护)。
```

### AsciiDoc

写成 \<\<maintenance,实例维护\>\>。目标小节上方已放了 \[\[maintenance\]\]，作为固定锚点。

两处的锚点名称必须相同；引用显示文字可以不同。

```asciidoc
== 故障排查

排查权限与连接故障见 <<maintenance,实例维护>>。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 提示说明

把全量备份提醒单独放在 mysqldump 导出动作前面。

### Markdown

\> \*\*提醒\*\*：文字 可以单独显示提醒。引用块本身没有“警告”等级，标题是你写的。

\> 放在行首；这是引用块，提醒标题和颜色不代表通用的警告等级。

```markdown
## 实例维护

> **提醒**：执行结构变更前，先对数据进行全量备份。

使用 mysqldump 导出 SQL 脚本。
```

### AsciiDoc

NOTE: 文字 创建提示块。AsciiDoc 有专门的提示类型，与 Markdown 引用块的语义不同。

NOTE 大写，使用英文冒号并留空格；提示前后空一行。

```asciidoc
[[maintenance]]
== 实例维护

NOTE: 执行结构变更前，先对数据进行全量备份。

使用 mysqldump 导出 SQL 脚本。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 任务清单

把两项内容改成任务清单，一项已完成，一项未完成。

### Markdown

\- \[x\] 表示已完成，\- \[ \] 表示未完成。本课通过编辑标记改变状态，预览里的框只负责显示。

方括号内外的空格要保留；这是 GFM 扩展。

```markdown
## 上线检查清单

- [x] 慢查询日志已开启。
- [ ] 备份脚本已加入定时任务。
```

### AsciiDoc

\* \[x\] 表示已完成，\* \[ \] 表示未完成。本课预览使用静态复选框。

保留方括号内外的空格；本课在源码中修改勾选状态。

```asciidoc
== 上线检查清单

* [x] 慢查询日志已开启。
* [ ] 备份脚本已加入定时任务。
```

[Markdown](https://github.github.com/gfm/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## 字符转义

让“\*\.\*”连同两个星号原样显示，不被当作强调标记。

### Markdown

在星号前加反斜杠：\\\*\.\\\*。表格里的竖线也需要转义，才能留在同一个单元格。

反斜杠紧挨需要转义的标点，预览中不显示反斜杠。

```markdown
## 授权语句记录

授权全局库表时写作 \*.\*。
```

### AsciiDoc

用反斜杠阻止标记生效：\\\*\.\*。预览中应看到两个星号。

本例在开头标记前加反斜杠；AsciiDoc 与 Markdown 的转义细节不同。

```asciidoc
== 授权语句记录

授权全局库表时写作 \*.*。
```

[Markdown](https://commonmark.org/help/)

[AsciiDoc](https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/)

## Markdown：复用方式取决于工具

Markdown 本身没有变量和文件包含。下面是 Docusaurus 的 MDX 示例，需要 MDX 和 JavaScript 环境；普通 Markdown 编辑器不能直接执行。

手册 B 可以导入相同片段，也可以直接写自己的提醒。VitePress 则有另一套文件包含写法，不能与这里的 MDX 代码混用。

### shared\.js

```javascript
export const productName = "PolarisDB 分布式数据库";
export const clusterPort = "5432";
```

### snippets/SafetyNotice\.mdx

```markdown
> **提醒**
>
> 变更前确认适用版本、验证方法和恢复方案。具体要求以相应操作说明为准。
```

### guide\-production\.mdx

```markdown
---
title: 运维说明
---

import SafetyNotice from './snippets/SafetyNotice.mdx';
import { productName, clusterPort } from './shared.js';

# {productName}

服务端口：{clusterPort}

<SafetyNotice />
```

[Docusaurus MDX 说明](https://docusaurus.io/docs/3.9.2/markdown-features/react)

[VitePress 文件包含说明](https://vitepress.dev/guide/markdown#markdown-file-inclusion)

## AsciiDoc：属性、包含文件和条件

下面四个文件放在同一个项目中。两份手册读取共享属性；手册 B 用条件选择自己的提醒。

### shared\-attributes\.adoc

```asciidoc
:product-name: PolarisDB 分布式数据库
:cluster-port: 5432
```

### snippets/dr\-safety\-notice\.adoc

```asciidoc
[NOTE]
====
变更前确认适用版本、验证方法和恢复方案。具体要求以相应操作说明为准。
====
```

### guide\-production\.adoc

```asciidoc
= {product-name} 运维说明
include::shared-attributes.adoc[]

服务端口：{cluster-port}

include::snippets/dr-safety-notice.adoc[]
```

### guide\-staging\.adoc

```asciidoc
= {product-name} 演练说明
include::shared-attributes.adoc[]

ifdef::env-staging[]
[NOTE]
====
本手册适用于演练环境。使用测试数据，结束后恢复初始配置。
====
endif::[]
ifndef::env-staging[]
include::snippets/dr-safety-notice.adoc[]
endif::[]
```

[AsciiDoc 文件包含说明](https://docs.asciidoctor.org/asciidoc/latest/directives/include/)

## DITA：键引用与内容引用

键定义放在 map 中，正文通过 keyref 引用产品名；note 通过 conref 引用另一份文件中的提醒。下面是结构片段，需放入完整项目并用 DITA 工具校验。

若某份手册需要独立提醒，可以引用另一片段；更复杂的条件发布需要配置过滤属性和 DITAVAL。本页不会执行这些处理。

### root\.ditamap

```xml
<map>
  <title>示例手册</title>
  <keydef keys="product_name">
    <topicmeta><keywords><keyword>PolarisDB 分布式数据库</keyword></keywords></topicmeta>
  </keydef>
  <topicref href="guide-production.dita"/>
</map>
```

### shared\-topics\.dita

```xml
<topic id="safety-defs">
  <title>共享提醒</title>
  <body>
    <note id="dr-warning">变更前确认适用版本、验证方法和恢复方案。具体要求以相应操作说明为准。</note>
  </body>
</topic>
```

### guide\-production\.dita

```xml
<concept id="prod-guide">
  <title>运维说明</title>
  <conbody>
    <p>产品：<ph keyref="product_name"/></p>
    <note conref="shared-topics.dita#safety-defs/dr-warning"/>
  </conbody>
</concept>
```

## DITA：主题与 map

concept 解释概念，task 组织步骤，reference 提供查阅信息。两份 map 引用同一份主题文件，修改主题后重新发布，各手册就能使用更新后的内容。

### engines\.dita

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="engines" xml:lang="zh-CN">
  <title>存储引擎有什么区别</title>
  <conbody>
    <p>InnoDB 支持事务与行级锁定，适用于核心高并发业务；MyISAM 仅支持表锁，适合离线只读报表。</p>
    <p>这是一个用于写作练习的示例数据库指南。生产环境配置请参考 MySQL 官方参考手册。</p>
  </conbody>
</concept>

```

### start\-service\.dita

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">
<task id="start-service" xml:lang="zh-CN">
  <title>初始化并启动服务</title>
  <taskbody>
    <steps>
      <step><cmd>执行初始化命令生成系统表与数据目录。</cmd></step>
      <step><cmd>配置 my.cnf 并启动 mysqld 服务进程。</cmd></step>
      <step><cmd>运行安全脚本配置管理员初始密码。</cmd></step>
    </steps>
  </taskbody>
</task>

```

### parameters\.dita

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE reference PUBLIC "-//OASIS//DTD DITA Reference//EN" "reference.dtd">
<reference id="parameters" xml:lang="zh-CN">
  <title>核心参数对照表</title>
  <refbody>
    <simpletable>
      <sthead><stentry>参数</stentry><stentry>说明</stentry><stentry>建议配置</stentry></sthead>
      <strow><stentry>max_connections</stentry><stentry>最大连接数</stentry><stentry>依据并发需求调整</stentry></strow>
      <strow><stentry>innodb_buffer_pool_size</stentry><stentry>缓冲池大小</stentry><stentry>建议设为物理内存的 50% 至 70%</stentry></strow>
    </simpletable>
  </refbody>
</reference>

```

### quickstart\.ditamap

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
<map xml:lang="zh-CN">
  <title>快速上手</title>
  <topicref href="engines.dita"/>
  <topicref href="start-service.dita"/>
</map>

```

### guide\.ditamap

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">
<map xml:lang="zh-CN">
  <title>完整运维手册</title>
  <topicref href="engines.dita"/>
  <topicref href="start-service.dita"/>
  <topicref href="parameters.dita"/>
</map>

```

[OASIS DITA 1.3](https://docs.oasis-open.org/dita/dita/v1.3/os/part0-overview/dita-v1.3-os-part0-overview.html)

## 在 Oxygen 中继续

下载互动练习中的 DITA 项目，解压后在 Oxygen 的 DITA Maps Manager 中打开 guide\.ditamap；在 Author 视图中编辑主题，校验后通过转换场景发布。

浏览器预览通过不代表完整 DITA 校验通过；在 Oxygen 中校验后再发布。

[Oxygen DITA Maps Manager](https://www.oxygenxml.com/doc/versions/27.1/ug-editor/topics/dita-maps-manager.html)
