# 钉钉文档排版规范

本文规定 DWS 创建或编辑钉钉文档时的排版判断方法。核心流程：**确定文档类型 → 选骨架 → 按读者任务选元素 → 按视觉语义统一表达 → 软约束自检**。

> 写入流程见 [doc-create-workflow.md](./doc-create-workflow.md)。改写老文档见 [doc-update-workflow.md](./doc-update-workflow.md)。callout / 分栏等块的字段以 [doc.md](../../doc.md) 与 [doc-jsonml-schema.md](../format/doc-jsonml-schema.md) 为准。

## 快速入口

按任务定位章节，不必通读全文：

| 任务 | 必读章节 |
|------|---------|
| 起稿前必读 | §2.0 + §2.0.1 + §3.0 |
| 不确定文档类型 | §2.0 类型判断决策表 |
| 写决策型（日报/汇报/方案选型） | §2.1 + §3 + §5 + §7 |
| 写执行型（SOP/Runbook/接入指南） | §2.2 + §3 + §4.4 + §5 + §7 |
| 写说明型（接口文档/能力清单） | §2.3 + §3 + §4.3/§4.4 + §7 |
| 写知识沉淀（调研/技术方案/复盘） | §2.4 + §3 + §4.6 |
| 颜色 / emoji 选择 | §5 |
| 何时插图 | §6 |
| 改写老文档 | 直接看 [doc-update-workflow.md](./doc-update-workflow.md) |
| 写完自检 | §8 判定表 |

---

## 一、硬规则

1. **`--name` 是 H1**：正文从 `##` 开始；正文内不写 `#`（除非确需正文内再造一级 H1 并说明动机）
2. **同类信息同表达**：风险、状态、行动项、证据，每类只用一种元素 + 一种视觉语义（见 §5）
3. **Markdown 草稿阶段只用稳定元素**：标题、段落、列表、checklist、表格、代码块；callout / 分栏 / 附件 / 复杂嵌套留到创建后用 `doc block insert` / `doc media insert` 精修
4. **引用块只用于原文**：用户原话、会议摘录、外部材料原文；不许包装作者自己的结论
5. **不编造 URL**：图片、链接、文档 ID 不确定时留 TODO 占位，向用户求证
6. **写入后必须回读**：见 [doc-create-workflow.md «回读验收»](./doc-create-workflow.md) 与 [doc-update-workflow.md §6](./doc-update-workflow.md)

---

## 二、按文档类型选骨架

### 2.0 类型判断决策表

按读者**第一个动作**选类型。若同时符合多类，按表中第一行优先：

| 读者第一个动作 | 类型 | 推荐格式 | 视觉锚点 | 跳转 |
|----|----|----|----|----|
| 按步骤操作（升级、部署、接入、上手） | 执行型 | markdown 起稿 + JSONML 精修（callout 标高风险） | 有序列表 / 代码块 / ⚠️ 高风险 callout | §2.2 |
| 拿结论做选择 / 决策 / 汇报判断 | 决策型 | **直接 JSONML 起稿**（不走 markdown → 精修；见 [doc-create-workflow.md §JSONML 起稿](./doc-create-workflow.md#jsonml-起稿判定)） | ✅ 推荐 callout / 对比表 / 数据加粗 | §2.1 |
| 查参数 / 能力 / 限制 / 错误码 | 说明型 | markdown（表格密集、callout 偶尔） | 参数表 / 错误码表 | §2.3 |
| 看推理链路 / 分析 / 调研过程 | 知识沉淀型 | 含对比/数据可视化时**直接 JSONML 起稿**；纯叙事时 markdown + 精修（见 [doc-create-workflow.md §JSONML 起稿](./doc-create-workflow.md#jsonml-起稿判定)） | ℹ️ 信息 callout / 引用块（原话）/ 流程图 | §2.4 |
| 以上都不像 | 兜底走知识沉淀型 §2.4 | — | — | — |

> **推荐格式列**：起稿统一用 markdown，富结构（callout/分栏/带颜色的对比/sectPr）一律走精修阶段的 JSONML；JSONML 形态优先级与命令见 [doc-update-workflow.md §1.3](./doc-update-workflow.md)。决策型默认进 JSONML 优先，因为汇报/方案的视觉锚点（callout + 彩色表头）markdown 表达不出来。

### 2.0.1 写前三问（草稿前 30 秒自答）

下笔前先答三句话；答不出第二、三句说明信息不足，回 [doc-create-workflow.md «创建前检查»](./doc-create-workflow.md) 补齐：

1. **读者**：谁打开这篇文档？读完要做什么动作（操作 / 选择 / 查参数 / 看推理）？
2. **唯一记忆点**：读者关掉文档后，最想让他记住的一句话是什么？这句话决定开头摘要 / callout 该写什么。
3. **形态**：按 §2.0 推荐格式列 + [doc-create-workflow.md §JSONML 起稿判定](./doc-create-workflow.md#jsonml-起稿判定) 决定路径。命中判定条件（决策型 / 含对比的知识沉淀型 / 用户意图关键词）→ **直接 JSONML 起稿**（但必须先完成 [doc-create-workflow.md §设计规划](./doc-create-workflow.md#设计规划jsonml-起稿前必做) 的 4 步规划）；未命中 → markdown 起稿 + 创建后精修。

写完自检时回看这三个答案：开头有没有兑现「记忆点」、形态有没有兑现「推荐格式」。两条任一不兑现，按 §8 自检表对应行动。

### 2.1 决策型（日报、月报、复盘、方案选型、汇报）

**适用**：读者读完要拿到判断或做选择。

| 段位 | 内容 | 推荐元素 |
|------|------|----------|
| 开头 | 结论、推荐方案、关键数据 | 2-4 条 bullet 摘要 |
| 主体 | 选项 / 维度 / 风险 / 数据 | 对比表、风险表、关键指标 |
| 收尾 | 下一步、需用户决策事项 | callout（仅决策有时限或重大风险）|

**反推荐**：长背景铺垫、连续叙事、结论藏在文末。

样板：

~~~~markdown
## 摘要
- 推荐方案 A：上线快、依赖已有流程
- 主要风险：权限配置需补
- 决策时限：本周五前

## 方案对比
| 维度 | 方案 A | 方案 B | 建议 |
|------|--------|--------|------|
| ... | ... | ... | ... |

## 下一步
- [ ] @负责人 完成权限配置
~~~~

### 2.2 执行型（SOP、TODO、行动方案、接入指南、Runbook）

**适用**：读者读完要按步骤操作。

| 段位 | 内容 | 推荐元素 |
|------|------|----------|
| 开头 | 目标、范围、前置条件 | 短段落 + checklist（前置条件）|
| 主体 | 顺序步骤、操作命令、校验方法 | 有序列表、代码块、流程截图 |
| 收尾 | 异常处理、回滚方法 | 表格（错误码 → 处理）或 callout（高风险动作）|

**反推荐**：多动作压成一段、缺负责人、缺校验方法。

样板：

~~~~markdown
## 目标
将服务 X 从 v1 升级到 v2，零宕机切换。

## 前置条件
- [ ] 备份当前配置
- [ ] 通知下游

## 操作步骤
1. 拉取最新镜像：`docker pull x:v2`
2. 灰度切流：5% → 50% → 100%
3. 每步校验：观察 dashboard，错误率 < 0.1%

## 异常处理
| 错误码 | 含义 | 处理 |
|--------|------|------|
| ... | ... | ... |
~~~~

### 2.3 说明型(产品说明、新人手册、接口文档、能力清单)

**适用**：读者按需查阅，不一定从头读到尾。

| 段位 | 内容 | 推荐元素 |
|------|------|----------|
| 开头 | 适用对象、能力概要 | 短段落或 bullet |
| 主体 | 功能矩阵、参数表、使用示例 | 表格、代码块（带语言标识）|
| 收尾 | 限制、注意事项、变更记录 | callout（限制）、表格（变更记录）|

**反推荐**：长结论、未分类的功能混排、缺示例。

样板（其中"调用示例"位置应放一个 `bash` 语言标识的代码块演示 dws 命令）：

~~~~markdown
## 适用对象
本接口供 DWS 内部模块调用，不暴露给外部租户。

## 能力清单
| 能力 | 说明 | 必要参数 |
|------|------|----------|
| ... | ... | ... |

## 调用示例
（此处放一个 bash 代码块演示 dws 命令）

## 限制
> ⚠️ 单次返回最多 1000 个 block，超出请分页。
~~~~

### 2.4 知识沉淀型（调研报告、技术方案、项目复盘、学习笔记）

**适用**：读者要看到推理链路，理解为什么是这个结论。

| 段位 | 内容 | 推荐元素 |
|------|------|----------|
| 开头 | 背景、问题、目标 | 短段落 |
| 主体 | 分析过程、对比、推理 | 小标题分层、表格、引用块（外部原文）|
| 收尾 | 结论、证据链、附件 | 附件（原始材料）|

**反推荐**：结论先行但缺证据链、引用块包装作者自己的判断。

---

## 三、按读者任务选元素（五列表）

### 3.0 AI 文档常见反模式

下笔前快速扫一遍，命中任何一条立刻按右列改：

| 反模式 | 信号 | 改法 |
|------|------|------|
| 万篇一律的「摘要-细节-总结」三段式 | 每篇文档第一节都是「## 摘要」+ 三条 bullet | 按 §2.0 选骨架；执行型不要写摘要，开门见山列前置条件 |
| 全篇 H2 平铺 | 标题层级单一、没有 H3 收纳同主题 block | 按 §7 量化标尺拆 §N.N 子标题 |
| 全列表无表无 callout | 风险、对比、数据全部塞进 bullet | 对比改表（§4.2）、风险改 callout（§4.7）、数据加粗（§5）|
| 结论藏文末 | 关键判断在最后一段才出现 | 按 §2.1 决策型骨架，结论 / 推荐方案前置到摘要 bullet |
| markdown 包不住富结构却硬包 | 草稿里出现 `> ⚠️ ...`、`【callout】`、表格里塞颜色 hex | 按 §2.0 推荐格式切到 JSONML 精修阶段；草稿留占位 |
| 同一语义两种视觉表达 | 风险既用 ⚠️ 又用红色文字也加 callout | §5 收敛到一组（emoji + 颜色 + 元素都按表对齐）|
| 装饰性 emoji 满天飞 | 段落、列表项、普通段每行都带 emoji | §5 规则：emoji 只在 callout / 状态标记 / `H2/H3` 标题前 |
| 编造 URL / 文档 ID / 图片地址 | 出现 `https://example.com/...`、`docs.dingtalk.com/xxx` 占位形 | §4.5 / §6 留 TODO 占位，向用户求证 |

### 3.1 读者任务对照

骨架定好后按读者要完成的具体动作选元素。扫"常见误用"列，命中则按"修复"列调整。

| 读者任务 | 推荐版式 | 避免 | 常见误用 | 修复方法 |
|----------|----------|------|----------|----------|
| 快速了解重点 | 开头 2-4 条 bullet 摘要；重大风险用 callout | 长背景；引用块包装摘要 | 三段式硬套，背景写了 5 段才到结论 | 结论提前到第一条 bullet，背景挪到末尾或删 |
| 做选择 | 多维比较用表格；轻量两项可分栏（精修阶段）| 只两个对象做大宽表 | 两个方案做 6 列对比表，每列一句话 | 改为两段并列短文，或保留 3 维核心对比 |
| 看状态 | 状态表（事项/状态/阻塞/下一步）或 checklist | 长段落描述多个状态 | "A 在做、B 卡住、C 完成…" 写一段 | 转为状态表，每行一个事项 |
| 执行动作 | 有序列表；待办用 checklist；分支用条件表 | 一段话写多个动作 | "先备份再升级然后切流" 写一段 | 拆为有序列表，每步独立 |
| 理解关系 | 小标题分层；复杂关系用图示或附件 | 把复杂关系压成连续段落 | 系统依赖关系写了三段叙事 | 建议用户上传架构图（§6）|
| 查证事实 | 引用块保留原文；真实文件用附件 | 引用块包装改写后的总结 | 作者自己的结论加 `>` 装成引用 | 改为普通段落或加粗 |
| 阅读背景 | 小标题 + 短段落；过长时拆列表 | 为结构化把叙事硬塞表格 | 把"项目历史"硬做时间表 | 用小标题分段叙事 |

**推荐表头**：

- 风险表：`风险 / 影响 / 缓解 / 负责人`
- 状态表：`事项 / 状态 / 阻塞点 / 下一步`
- 对比表：`维度 / 方案 A / 方案 B / 建议`

---

## 四、元素边界规范

### 4.1 标题与段落

- 正文从 `##` 开始（H1 已被 `--name` 占用）
- 标题层级 ≤ 4 层（§7）
- 单段过长先拆段，再考虑换元素

### 4.2 列表与 checklist

- 普通列表：并列要点
- 有序列表：顺序步骤
- checklist：待办状态（含 `- [ ]` / `- [x]`）

列表项里开始出现"负责人 / 截止时间 / 状态"这类字段时，改用表格。

### 4.3 表格

表格用于字段稳定的信息。

- 单元格写短句；解释超过两行放表格下方段落
- 列数 ≤ 6，行数 ≤ 20（§7 给具体拆法）

### 4.4 代码块

必须带语言标识（`bash` / `python` / `json` / `go` 等）；无对应语言时用 `text`。

形如（用 \`\`\` 三反引号围栏 + 紧跟语言名 + 闭合 \`\`\`）：

~~~~markdown
```bash
dws doc read --node abc123
```
~~~~

约束：

- 单块 ≤ 80 行；超长时拆为多个语义独立的块，或作为附件上传
- 与正文有强关联时，在代码块前后用一句话说明用途
- **禁止**在代码块里写敏感信息（token、密码、内部 IP）

### 4.5 链接与卡片

| 场景 | 用法 | 典型例 |
|------|------|--------|
| 行内引用 | `[文字](url)` | PR/Issue/外部博客 |
| 强调外部资源 | 创建后 `doc block insert` 插入卡片 | 外部 PRD、Figma、Notion 主页 |
| 引用钉钉文档 | 直接粘贴 alidocs URL | @文档（DWS 自动渲染卡片）|

**禁止**：编造看似真实的 URL；不确定的链接留 TODO。

### 4.6 引用块

只用于需保留原貌的内容：用户原话、会议摘录、外部材料原文、API 错误信息原文。

**禁止**把作者自己的摘要、推荐结论或判断写成引用块。

### 4.7 Callout

每篇文档 0-2 个（§7）。

| 场景 | 处理 |
|------|------|
| 创建前必须确认的限制 | ✅ 用 callout |
| 会改变结论的风险 | ✅ 用 callout |
| 需要用户立即决策的分歧 | ✅ 用 callout |
| 普通章节说明 | ❌ 普通段落 |
| 装饰性章节开头提示 | ❌ 删除 |
| 可放进摘要 bullet 的一般结论 | ❌ 放摘要 |

callout 是块级元素，**Markdown 草稿阶段不支持**。创建后用 `doc block insert` 精修。

**形态优先级（按 [doc-update-workflow.md §1.3](./doc-update-workflow.md)）**：

1. **首选 JSONML**：`doc block insert --content-format jsonml --element '["container",{"uuid":"...","subType":"colorBlocks","metadata":{"bgcolor":"...","border":"..."}},["p",...]]'`，bgcolor/border 取本文 §5 颜色表
2. **次选 element JSON**：`doc block insert --element '{"blockType":"callout","callout":{...}}'`，字段以 [doc.md](../../doc.md) 为准；JSONML 节点完整结构见 [doc-jsonml-schema.md](../format/doc-jsonml-schema.md) 的 `container[subType="colorBlocks"]`，可复制范例见 [doc-jsonml-cookbook.md](../format/doc-jsonml-cookbook.md)

### 4.8 分栏（精修阶段）

分栏适合两个对象的轻量并置。**Markdown 草稿阶段无法直接写入**，必须创建后用 `doc block insert`。

**形态优先级（按 [doc-update-workflow.md §1.3](./doc-update-workflow.md)）**：

1. **首选 JSONML**（保真度最高、和现有 block 结构一致）：

```bash
dws doc block insert --node <nodeId> --content-format jsonml \
  --element '["container",{"uuid":"cols1","subType":"columns","metadata":{"size":"2"}},["container",{"uuid":"cols1c1","subType":"column"},["p",{"uuid":"cols1c1p"},["span",{"data-type":"text"},["span",{"data-type":"leaf"},"左栏"]]]],["container",{"uuid":"cols1c2","subType":"column"},["p",{"uuid":"cols1c2p"},["span",{"data-type":"text"},["span",{"data-type":"leaf"},"右栏"]]]]]'
```

2. **次选 element JSON**（老接口，仅当 JSONML 不便构造时）：

```bash
dws doc block insert --node <nodeId> --content-format element \
  --element '{"blockType":"columns","columns":{"size":2},"children":[{"blockType":"paragraph","paragraph":{"text":"左栏"}},{"blockType":"paragraph","paragraph":{"text":"右栏"}}]}'
```

每栏需要多个字段时**改用表格**。轻量两项对比优先并列短段落，分栏只在视觉强对照需要时使用。完整 JSONML 字段见 [doc-jsonml-schema.md](../format/doc-jsonml-schema.md) 的 `container[subType="columns"]`，可复制范例见 [doc-jsonml-cookbook.md](../format/doc-jsonml-cookbook.md)。

### 4.9 附件与图片

```bash
dws doc media insert --node <nodeId> --file ./diagram.png
```

- 插入后在前后用一句话说明它支持哪个结论
- 插入后用 `doc block list` 验证存在
- **禁止**在 Markdown 里编造无法访问的图片 URL
- **禁止**把 `alidocs.dingtalk.com/i/nodes/...`、`alidocs.dingtalk.com/i/document/...` 或任何文档/节点页面 URL 当作图片 src——这些是页面链接，不是图片资源，写入后无法渲染。图片必须先下载到本地，再通过 `dws doc media insert --node <docId> --file <本地路径>` 插入
- 何时主动建议用户提供图见 §6

---

## 五、颜色与视觉语义

**全篇必须保持语义一致**——同一语义只用同一组视觉表达。

| 语义 | emoji 前缀 | callout bgcolor (hex) | callout border (hex) | 文字加粗 | 典型用法 |
|------|----------|------------------------|----------------------|---------|----------|
| 信息说明 | ℹ️ | `#E8F2FE`（淡蓝）| `#B3D4FC` | — | 普通提示、说明性补充 |
| 推荐结论 | ✅ | `#E3F8E2`（淡绿）| `#B7E4B5` | 是 | 推荐方案、已确认结论 |
| 风险/错误 | ⚠️ / ❌ | `#FDE2E0`（淡红）| `#F5C2C7` | 是 | 风险、错误码、不可逆操作 |
| 待确认 | ❗ | `#FFF6D9`（淡黄）| `#FFE69C` | — | 待用户决策、待补齐信息 |
| 中性辅助 | — | `#F4F5F7`（淡灰）| `#DEE2E6` | — | 非关键背景、变更记录 |

调用规则：

- callout 字段格式以 [doc.md](../../doc.md) / [doc-jsonml-schema.md](../format/doc-jsonml-schema.md) 为准
- 调 `doc block insert --element` 插入 callout 前若字段名不确定，先用 `doc block list --node <id> --block-type callout` 抓现有实例确认字段
- 颜色属性值只接受 hex；**禁止**把语义名（如 `light-blue`）当属性值
- 关键指标用加粗 + ↑↓ 或 +/- 同时标注方向（不仅依赖颜色，兼容色觉无障碍）
- emoji 只在 callout、状态标记、`H2/H3` 标题前使用，不在普通段落和列表项里滥用

---

## 六、何时使用图示

以下信息特征出现时，**主动建议用户提供截图或示意图**，不用纯文本承载：

| 内容特征 | 信号词 | 建议图示 |
|----------|--------|----------|
| 多步骤流程（≥4 步）| "先…然后…最后"、"步骤 1/2/3" | 流程图截图 |
| 系统/模块依赖 | "调用"、"依赖"、"上游/下游"、"请求→响应" | 架构图截图 |
| 时间线/里程碑 | "Q1/Q2"、"阶段一→阶段二"、日期序列 | 时间线图 |
| 数值趋势 | 带数字的时间序列、"增长/下降"、百分比变化 | 折线图/柱状图截图 |
| 占比分布 | "占比"、"份额"、百分比加总 ≈100% | 饼图/树状图截图 |
| 层级递进 | "基础→进阶→高级"、"L1/L2/L3"、"核心→外围" | 金字塔图 |
| 因果/根因 | "导致"、"根因"、"原因"、"影响因素" | 鱼骨图 |
| 闭环/飞轮 | "正循环"、"驱动"、"闭环"、"反馈" | 飞轮图 |

**规则**：

1. 关键流程/架构/趋势能图示就图示，不用纯文本承载
2. **禁止**在 Markdown 里编造图片 URL（如 `![](https://example.com/diagram.png)`）
3. 正文里留占位（如 `📌 待补充：架构图`），向用户主动询问能否提供截图
4. 用户提供后用 `dws doc media insert --node <id> --file ./xxx.png` 插入，并在图前后补一句说明

---

## 七、量化标尺（软约束）

超出时不一定要重写，但要按"超出处理"列采取具体动作：

| 维度 | 建议上限 | 超出处理（具体动作）|
|------|---------|---------------------|
| 单段行数 | ≤ 5 行 | 按句号拆段；或抽出并列要点转 bullet 列表 |
| 单章节 block 数 | ≤ 12 | 按子主题拆 `### N.N` 子标题；合并冗余 block |
| 标题层级 | ≤ 4 层 | 把最深层标题降级为加粗段落或列表 |
| 表格列数 | ≤ 6 | 按"维度类别"拆为多个子表，前 2 列保留作锚 |
| 表格行数 | ≤ 20 | 拆表（按类别）；或转附件 `doc media insert --file table.xlsx` |
| callout 数量 | ≤ 2 / 篇 | 同语义 callout 合并；非关键 callout 降级为加粗或行内 emoji |
| 代码块行数 | ≤ 80 | 按"功能段"拆为多个独立块；超长输出转附件 |
| 连续纯文本段 | ≤ 3 段 | 中间穿插 `##/###` 标题、bullet、或表格分组 |

---

## 八、自检判定表

写完后逐条扫描，命中"判定"列的情况按"动作"列处理：

| 判定 | 动作 |
|------|------|
| 命中 §3.0 任一反模式 | 按 §3.0 对应行改 |
| 文档类型不属于 §2 四类之一 | 回 §2.0 决策表归类；仍归不出走 §2.4 兜底 |
| `--name` 之外正文里还有 `#` 一级标题 | 改为 `##`，除非确需且已说明动机（§4.1）|
| callout 数 > 2 | 按 §4.7 合并同语义；非关键 callout 降级 |
| 单段 > 5 行 | 按 §7 拆段或转列表 |
| 单章节 block 数 > 12 | 按 §7 拆 `### N.N` 子标题 |
| 表格列 > 6 或行 > 20 | 按 §7 拆表或转附件 |
| 代码块缺语言标识 | 补语言标识；无对应语言用 `text`（§4.4）|
| 代码块 > 80 行 | 按功能段拆，或转附件（§7）|
| 同一语义出现 ≥2 种视觉表达 | 按 §5 收敛到同一组 |
| 引用块里写的是作者自己的结论 | 改为加粗段落或普通段落（§4.6）|
| Markdown 草稿里写了 callout / 分栏 | 删掉，转到精修阶段用 `doc block insert`（§4.7 / §4.8）|
| 内容含 "先…然后…"、"调用/依赖"、"Q1/Q2"、"导致/根因" 等信号词但写成纯文本 | 按 §6 询问用户能否补图 |
| 出现编造的图片 URL / 文档 URL | 删除或改为 TODO 占位（§4.5 / §6）|
| 写入完成但未回读 | 按 [doc-create-workflow.md «回读验收»](./doc-create-workflow.md) 或 [doc-update-workflow.md §6](./doc-update-workflow.md) 回读 |
