ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

告别Word排版:用Markdown+Git+Pandoc构建自动化文档工作流

2026/9/15 2:16:00 拓冰建站 浏览量
告别Word排版:用Markdown+Git+Pandoc构建自动化文档工作流 干技术传播这一行我打交道最多的就是Word。可恰恰是这个天天用的工具让我在工作流上吃了大亏。一个几十页的技术手册光排版就能耗掉两三天改了一版又一版文件名从“终版”变成“终版2”再到“打死不改版”好不容易写完同事要拆章节复制粘贴后格式全乱……这些场景你是不是也熟今天我想聊聊工程实践层面的一件事抵制Word排版不是矫情而是从改进工作流做起。关键字就三个工程实践、Word排版、工作流。它们串起来正好是技术传播领域这几年最值得推进的一件事——把文档当代码一样管理让排版自动化让协作可控让传播高效。这篇文章不打算空谈理念我会把踩过的坑、试过的方法、落地的工具链和可直接复制的脚本都写出来。无论你是技术文档工程师、研发团队里的文档兼职还是产品经理只要你还被Word排版折磨这篇应该能帮到你。1. 为什么我决定和Word排版说再见1.1 技术文档的“车祸现场”Word排版的四大原罪先说清楚我并不是全盘否定Word作为文字处理器的能力。写个一页纸的通知、填个表格、给领导出个汇报材料Word够用。但一旦落入技术文档领域它的短板就暴露得特别彻底。第一宗罪格式和内容强耦合。你在Word里敲下每个字它背后都挂着一整套样式字体、字号、行距、缩进、页边距、编号格式。表面上所见即所得实际上你同时在做两件事——写内容以及给内容化妆。而这两件事混在一起会带来一个致命问题改内容的时候格式会乱调格式的时候内容可能被误删。我在一份60页的架构设计文档里经历过一次灾难性操作只想把二级标题的字体从黑体改成微软雅黑结果样式更新没生效反而是正文里所有“注意”字样的行全部变成了标题格式整个文档的目录直接重构了。第二宗罪版本对比基本靠肉眼。Word自带的“修订”和“比较”功能在小文档上还能用文档一长、参与的人一多基本就废了。最常见的场景是A同事改了第3章B同事改了第7章两个人各自存了一份最后合并时你根本分不清谁先谁后、哪个改动被谁覆盖。加上.Word文件是二进制格式Git这类版本控制工具对它直接失效——你没办法像看代码diff一样看文档diff也没法在提交记录里定位某句话是哪一版引入的。第三宗罪协作效率极低。Word的多人协作要么轮流改要么用OneDrive等云端同步但即便是云端协作遇到表格跨页、图注编号、交叉引用照样卡壳。更不要说团队的文档往往要复用这个项目的手册要抽出几章变成另一个项目的附录在Word里你得手动复制、调整样式、修页码。这套流程重复几次人就成了流水线上的机械臂。第四宗罪自动化规则对Word失效。做技术传播的人最怕的就是文档要满足各种发布规范字号不能小于小五、代码块必须有等宽字体、表格不能跨页、图片必须有编号和标题。这些规则如果靠人工去盯每小时最多审几十页还容易漏。但对于结构化文本比如Markdown这些规则可以被脚本和数据校验工具自动检查。Word做不到或者说做到的成本极高。1.2 技术传播的隐性成本Word让团队付出了什么如果说上面的四大原罪是表面的“不好用”那么它对技术传播的隐性成本杀伤力更大。第一个成本是时间成本。不夸张地说一个中等规模的产品文档200页左右Word手工排版的时间大约是内容撰写时间的1.5倍。因为你写完初稿之后还要统一术语、统一样式、调目录、修页码、改页眉页脚、处理图表编号。这些操作和内容创作毫无关系纯粹是“体力活”但它就是会吃掉你大量时间。第二个成本是人力门槛。Word排版熟练度是玄学有人能在十分钟内搞定页眉页脚有人研究了半天还是搞不定“上一节和下一节之间的分节符”。于是团队里经常出现“Word大神”这种角色所有文档都堆给他处理。表面上是个人能力问题实际上是把团队的工程能力寄托在一个人身上一旦这个大神休假或离职文档工作流直接停摆。第三个成本是内容复用成本。技术传播的核心价值之一是让文档能够在不同场景被复用用户手册可以拆出API参考白皮书可以变成市场宣传材料内部培训文档可以脱敏后发给客户。但这件事在Word里难度极高因为内容被锁死在排版格式里。你从Word复制一段到另一个Word里带过来的全是本地格式接下来又要花时间重新刷一遍样式。第四个成本是质量成本。Word下做文档审校人工看的是“版式对不对、字有没有错别字”但真正的技术文档审校应该关注“逻辑是否一致、接口是否遗漏、术语是否统一”。人工盯排版必然会减少对内容的关注最终文档的bug没错文档是有bug的流入市场轻则用户困惑重则产品事故。所以我说抵制Word排版不是为了追求工具上的“高级感”而是为了把技术传播从“手工作坊”变成“工程化流水线”。而工程化的第一步就是重构工作流。2. 抵制不是目的改进工作流才是2.1 核心思路把“排版”从内容创作中剥离想明白了上面的问题解决方案其实就一句话让内容和格式解耦。内容交给纯文本格式去承载格式交给模板和自动化脚本去生成中间用统一的工作流串联。类比一下软件开发程序员写代码用的是纯文本代码提交到Git仓库通过CI/CD流水线自动构建、自动部署。文档为什么不能这样技术文档本质上也是“源代码”——它的产物是PDF、Word、HTML、在线帮助中心但它的源头应该是可维护、可追踪、可diff的源文件。一旦你接受这个思路很多问题就迎刃而解内容创作者只用关心结构、逻辑、措辞在一个轻量级的编辑环境里自由书写排版规则交给模板设计师去维护同一套内容可以一键生成多种格式版本管理交给Git每一次改动都能追溯每一次review都像review代码一样有据可查。这套思路在技术圈有个专门的名字Docs as Code文档即代码。它不是一个新概念但直到Markdown语法普及、静态网站生成器和Pandoc这类工具成熟之后才真正具备了工程落地的条件。2.2 工作流选型为什么我选了Markdown Git Pandoc方案确定了接下来是选型。市面上的写作工具有很多Word、Google Docs、Notion、Confluence、飞书文档、Markdown编辑器、AsciiDoc、reStructuredText……我这里只说我在实际工程实践中跑通且稳定使用的组合Markdown Git Pandoc辅助工具是VS Code Typora作为编辑器加上一个自定义的Python脚本做构建和校验。为什么是Markdown第一它是纯文本任何编辑器都能打开任何进制工具都能处理diff第二语法足够简单标题、列表、表格、代码块、引用、链接都有唯一的表达方式学起来半小时就能上手第三生态成熟几乎所有文档工具链都对Markdown提供了原生支持。为什么是Git技术文档需要多人协作、需要版本追溯、需要分支和合并这和代码的需求完全一致。Git天然支持这些。有人可能会说团队成员不会Git怎么办我的回答是可以学而且学起来比重学一遍Word样式快得多。你只需要给他们几个基础命令clone、add、commit、push、pull剩下的都通过可视化客户端比如VS Code自带的Git面板完成。为什么是PandocPandoc是文档转换领域的“瑞士军刀”它能把Markdown转换成几乎一切格式Word、PDF、HTML、EPUB、LaTeX、reveal.js幻灯片。最关键的一点是Pandoc支持模板定制你可以通过修改模板引擎来精确控制Word输出风格这在其他转换工具里很难做到。2.3 技术传播的范式转移从“写文档”到“管理文档”选型定了但这里我要特别强调一个容易被忽视的点工作流升级不是简单的“换个编辑器”它是技术传播角色的重新定义。以前我们写文档精力分配大概是内容占40%排版占40%沟通审校占20%。工作流改完之后精力分配变成了内容占70%结构设计占20%自动化规则维护占10%。你不再是一个“Word排版工”而是一个“文档产品经理”加“文档工程师”。你要考虑的是这篇文档的读者是谁它的信息架构是否合理它的复用价值在哪里如何通过校验脚本保证术语一致这个转变才是“抵制Word排版”的最大收益。当你不再被排版琐事缠身你才有精力去想技术传播真正重要的事情——如何让信息准确、高效、友好地触达用户。3. 工程实践从零搭建一套Markdown转Word的自动化工作流3.1 环境准备与工具链理论说了一堆接下来进入正题。以下内容基于我在自己团队里落地的完整方案你按照步骤操作大概率能直接复现。你需要准备的工具工具用途安装方式VS Code主力编辑器内置Git支持、Markdown预览、各种插件官网下载安装包Typora可选沉浸式写作体验适合不擅长看代码的同事官网下载安装包Git版本控制官网或brew/apt安装Pandoc文档格式转换核心工具官网安装或brew install pandocPython 3运行构建脚本和校验脚本官网或包管理器安装pandoc-reference.docx自定义Word样式参考文档后续步骤中生成安装完Pandoc后终端里执行pandoc --version确认安装成功。如果你的机器上还没有Git建议同时把Git配置好并关联你的远程仓库GitLab/GitHub均可。3.2 项目结构设计工作流落地的第一步是设计一个清晰的项目目录结构。我推荐这种docs-project/ ├── docs/ # 存放所有Markdown源文件 │ ├── chapter-01.md │ ├── chapter-02.md │ └── ... ├── templates/ # Pandoc自定义模板 │ ├── reference.docx │ └── cover.tex ├── images/ # 文档中引用的图片 │ └── architecture.png ├── scripts/ # 构建脚本与校验脚本 │ ├── build.py │ ├── check.py │ └── publish.py ├── output/ # 生成的最终产物(.docx/.pdf/.html) ├── README.md # 项目说明与写作约定 ├── book.toml # 可选mdBook配置 └── requirements.txt这里有一个容易被忽略的设计理念每个章节是一个独立的markdown文件最后通过构建脚本按需合并。这样做的优势在于多人可以并行维护不同章节Git的分支冲突面更小单个文件体积小编辑器打开、渲染都流畅章节级别的复用变得异常简单——你想把“安装指南”抽出来变成另一个文档只需要在构建脚本里调整文件列表即可。3.3 编写构建脚本Markdown一键合并并转成Word构建脚本是整个工作流的心脏。我先给一个简单但可用的版本它完成这几件事按指定顺序合并多个Markdown章节将合并结果交给Pandoc生成一份Word文档通过--reference-doc参数指定自定义样式使输出格式统一#!/usr/bin/env python3 # scripts/build.py import subprocess import os from pathlib import Path ROOT Path(__file__).resolve().parent.parent DOCS_DIR ROOT / docs OUTPUT_DIR ROOT / output TEMPLATE ROOT / templates / reference.docx # 章节顺序在这里定义新增章节时只需修改这个列表 CHAPTERS [ cover.md, chapter-01.md, chapter-02.md, chapter-03.md, chapter-04.md, appendix.md, ] def build_docx(): OUTPUT_DIR.mkdir(exist_okTrue) # 1. 合并所有章节内容章节之间加页分隔 combined for name in CHAPTERS: md_path DOCS_DIR / name if not md_path.exists(): print(f[WARN] 章节文件不存在已跳过: {md_path}) continue combined f\\n\\n---\\n\\n combined md_path.read_text(encodingutf-8) merged_md ROOT / output / _merged.md merged_md.write_text(combined, encodingutf-8) # 2. 调用 pandoc 生成 docx out_file OUTPUT_DIR / 产品技术手册.docx cmd [ pandoc, str(merged_md), -o, str(out_file), f--reference-doc{TEMPLATE}, --toc, --toc-depth2, -M title产品技术手册, -M date subprocess.getoutput(date %Y-%m-%d), ] print(运行命令:, .join(cmd)) result subprocess.run(cmd, capture_outputTrue, textTrue) if result.returncode ! 0: print([ERROR] Pandoc 转换失败) print(result.stderr) return False print(f[OK] 已生成: {out_file}) return True if __name__ __main__: build_docx()这个脚本有几个细节值得说一下。先说--reference-doc。它接受一个docx文件作为样式参考Pandoc生成的Word文档会自动继承该docx里的样式定义。这是整个自定义排版的核心机制。要生成这个参考模板只需要在任意位置执行一次pandoc -o custom-reference.docx --print-default-data-file reference.docx再用Word打开它改一遍样式字体、字号、行距、标题颜色等保存即可。再说--toc和--toc-depth2。Pandoc会自动生成目录并支持多级标题。实测下来这个目录可以被Word识别为“目录域”插到文档开头后用户按F9即可刷新。这意味着你完全不需要在Word里手工维护目录。最后说章节合并时的---分隔。我在这里加了一个水平线配合参考模板中的分页设置可以实现每个章节从新的一页开始。如果你希望章节连续排布不换页删掉这个分隔即可。3.4 接入Git钩子与CI让构建自动化脚本能跑了但每次都手动执行python scripts/build.py还是太原始。工程化的下一步是让构建自动化。最简单的方式是给Git加上pre-commit钩子在代码提交前自动做文档语法校验再加上一个post-commit钩子提交后自动构建产物。这里我分享一个比较实用的做法用Git hooks让“提交即构建”同时用CI比如GitLab CI或GitHub Actions在推送到主干分支后自动发布。先看一个简单的pre-commit钩子用于检查Markdown里是否有明显错误#!/bin/sh # .git/hooks/pre-commit echo Running markdown lint checks... npx markdownlint-cli docs/*.md || exit 1 echo Check passed.这个钩子假设你安装了markdownlint它专门检查标题层级是否跳级、列表符号是否统一、行尾空格等规范问题。如果校验不通过提交会被拒绝这能强制团队成员遵循统一的写作规范。如果你用GitLab CI可以在仓库根目录放一个.gitlab-ci.ymlimage: pandoc/core:latest stages: - build - publish build: stage: build script: - python scripts/build.py artifacts: paths: - output/这样每次推送代码到远端CI就会自动跑一次构建生成最新的docx并作为构建产物保存下来。发布环节还可以再接一步上传到公司内部的文档平台或者转成PDF后发送到客户资料库。整个过程中人只需要做一件事——改Markdown剩下的交给流水线。4. 实操过程与核心细节让生成的Word文档更好用4.1 写作规范约定一个小团队如何统一风格工作流跑起来后最大的挑战不是技术而是团队习惯。我强烈建议在项目README里写一份“写作规范”哪怕只有几页也能避免大量无效沟通。我的规范文档里包括以下规则标题层级一级标题#只用于页面主标题二级标题##作为章节标题三级###及以下用于小节。交叉引用不使用Word的“插入-引用”而是通过Pandoc的[引用]或锚点链接。在Markdown里给需要被引用的地方加锚点{#sec:install}文中写[安装步骤](#sec:install)Pandoc会自动把链接转成Word内部的交叉引用且支持跳转。术语大小写产品名、API名一律按官方大小写书写例如“Kubernetes”不是“kubernetes”“API”不是“api”。代码块所有命令行代码块标注语言例如bashPandoc输出到Word时它会自动给代码块套上等宽字体样式。图片统一放在images目录命名用英文小写加连字符例如architecture-diagram.png。这些规则听起来琐碎但真的能救命。有一次我接手同事的文档发现他所有标题都是用加粗的正文冒充的结果Pandoc生成的目录完全为空。有了规范校验钩子之后这类问题在提交阶段就被拦住了。4.2 用模板定制Type让Word输出带“品牌感”很多团队抵制Markdown转Word理由是“转出来的Word太素了没有企业风格”。这个问题其实是最好解决的。Pandoc的reference.docx模板几乎控制了一切。你首先生成一个默认参考文档然后打开它逐项修改Normal样式统一全文正文的字体中文一般为等线或微软雅黑西文为Calibri或Arial和字号小四或五号。Heading 1 / Heading 2 / Heading 3设置标题字体颜色、字号、段前段后距甚至可以加下边框线模拟企业文档风格。Code Block样式设置背景色和边框线左侧竖线让代码块在Word里也清晰可辨。Table样式设置表格边框、表头底纹、单元格内边距。维护好这个模板文件放入templates目录并纳入Git管理团队所有人都用同一个模板生成的Word格式天然统一。后续改版也只改这个模板文件不用再人工刷样式。这里有个我踩过的坑pandoc的输出样式和Word的样式名存在一个“样式映射”关系如果多人各自改了Normal样式命名不一致比如有人自定义为“正文1”有人自定义为“Normal”转换结果就会乱。所以团队里必须约定修改样式名字幕保持Pandoc预设只改字体、字号、颜色、段落属性别动样式名。4.3 图片、表格与代码块的处理技巧技术文档离不开图片、表格和代码块这三样恰恰是Word自动化转换的痛点。我逐个说说实操经验。图片这块Pandoc的Markdown语法很好用![图注文字](images/xxx.png){#fig:arch width80%}。在图片语法后面用大括号扩展属性可以精确控制输出到Word中的宽度比例。注意如果你希望图片居中需要调整reference.docx里“Image Caption”样式给段落设置居中对齐。还有一个反直觉的小坑Pandoc默认会把图片按照Markdown中的相对路径输出如果你的图片路径里有中文名生成的Word里可能出现路径丢失。建议图片文件一律英文小写命名。表格的处理要谨慎。Markdown表格语法简单适合结构性强的数据表但遇到大段文字嵌套、多行合并单元格Markdown就力不从心了。我的建议是分场景简单表格少于10列单行表头直接用Markdown语法复杂表格需要纵向合并单元格用grid table语法或者先写在Excel里再用脚本转成JSON最后通过Pandoc的filters机制插入到文档中。代码块的问题不在转换而在排版。默认生成的Word代码块经常换行乱掉、字体不统一。我的做法是在reference.docx里给Code block样式设置一个偏小的等宽字体Consolas、九号或十号并开启“允许跨页断行”。另外如果代码行特别长建议在Markdown里手动断行或者在模板里设置一个半页宽的代码块区域否则输出后阅读体验很差。4.4 多产出格式一份源文档同时编译Word、PDF和HTML前面用的都是Word接收方但实际技术传播场景里客户可能往三种地方要文档印刷版要PDF、online help要HTML、日常传阅要Word。如果你还在用Word手工排版这三个版本就等于三份重复劳动。但用了Pandoc这只是一个命令的问题。同一份合并后的Markdown我通常这样处理# 转换Word pandoc output/_merged.md -o output/产品技术手册.docx --reference-doctemplates/reference.docx --toc # 转换PDF中文需要xelatex pandoc output/_merged.md -o output/产品技术手册.pdf --pdf-enginexelatex -V CJKmainfontNoto Sans CJK SC # 转换HTML pandoc output/_merged.md -o output/产品技术手册.html -s --embed-resources --toc三行命令产出三种格式样式各有适配。这才是“改进工作流”的终极意义你写好一次自动分发到所有渠道而不是逐个渠道手动适配。HTML这步尤其有意思配合--embed-resources参数图片会被转成base64嵌入HTML一个文件就能发给用户省去图片丢失的麻烦。5. 常见问题与排查技巧实录5.1 转换中文乱码或中文显示为方框这是我最早遇到也是最多人问的问题。核心原因一句话Pandoc生成PDF时用的是LaTeX引擎而中文需要设置CJK字体生成Word时如果模板里中文字体缺失也会出现类似问题。排查路径如下确认系统有中文字体Linux服务器上尤其容易缺。装fonts-noto-cjk包基本能解决。用PDF引擎时必须显式指定-V CJKmainfont我实测最稳定的是“Noto Sans CJK SC”和“Source Han Sans SC”。如果只是转Word大概率是reference.docx里Normal样式的中文部分没有正确设置字体。打开模板把Normal样式里的“中文字体”也改成目标字体不要只改西文字体。5.2 表格太宽超出页面边界Word生成后表格列宽自适应但对长英文串处理不好容易把页面撑开。两种解法第一种在Markdown表格里控制列数和内容宽度每列内容控制在20个字符以内复杂内容拆行。第二种修改reference.docx中Table样式的列宽策略选中表格后设置“根据窗口调整表格”并给表格开启“自动换行”选项。如果表格列数超过五列建议直接用gird table语法并手动指定列宽百分比。5.3 多人协作时Git冲突怎么处理Markdown是纯文本Git冲突不可避免但比Word时代温和太多了。实际遇到冲突时我的经验是别怕冲突只影响你正在改的那个章节而且大多数冲突可以借助VS Code的界面可视化合并解决。但如果团队协作频繁冲突正确解法不是写更多规范而是调整构建脚本——把章节拆得更细减少多人同时碰同一文件的可能性。比如原来一个chapter-01.md有30页拆成chapter-01-overview.md、chapter-01-config.md、chapter-01-install.md三个文件每个文件一个负责人冲突自然减少。构建脚本里的列表稍微调整即可。5.4 “最终版到底在哪”的版本确认问题这是Word时代最无解的问题工作流改完后就变成了一个小case。因为Git里的每一次提交都记录了时间、作者和改动内容我们约定发布的正式版本都打上Tag比如v1.0.0、v1.1.0。客户要什么版本直接git checkout v1.0.0 python scripts/build.py就能重现当时发布的文档。这个能力是Word根本无法提供的也是工程化工作流的最大价值点之一。5.5 团队成员不熟悉Git命令怎么办我见过不少团队在推进Docs as Code时被这个问题卡住。我的态度是不要求所有人会完整Git命令只要求会用VS Code的Git面板就够了。日常写作只需三步打开文件、编辑、提交推送在界面上填写commit message点击同步按钮。这套操作培训半小时能学会。如果连这个都嫌重可以考虑用一个轻量级的线上编辑器比如GitHub改文件、或者集成在文档平台的Web编辑入口但底层还是Git仓库。关键是让团队尝到甜头提交历史可追溯、远程自动备份、一键发布这些东西比“多学一个工具”的短期成本更有价值。写在最后根据我的实际使用体会从Word排版切换到Markdown Git Pandoc这套工作流不是一蹴而就的团队大概经历了两三周的适应期。第一周最痛苦因为要一边写内容一边学新语法第二周开始好转因为发现不再需要手动维护目录和页码了第三周之后就再也不愿意回头碰Word排版了。哪怕只写一篇五页的小文档我也是在Markdown里写完用脚本转成Word再交付。习惯之后你会觉得以前那个反复调整样式、反复刷格式的自己真的很浪费时间。最后再分享一个小技巧不要一次性把整个团队的老旧Word文档全部迁移过来那样工程量太大会引发强烈反弹。挑一个正在撰写的、还未定稿的新文档用它作为试点跑通工作流成功后再逐步迁移存量文档。这既是技术传播工程实践里的落地策略其实也是任何工作流改革通用的打法——先上一条支线验证成功后再全面铺开。