草稿
本文档为草稿。
请勿在移除此通知前分享或链接到此 URL
我的书后记
2014 年 3 月 14 日
我已经写过不少书了,偶尔会有人问我用什么工具写书。多年来,我开发了一套相当不错的工具链——至少对我来说是如此——所以这里是我的想法,说明它是如何组合在一起的。
当我开始写作时,我使用的是文字处理或出版工具。我尝试过微软 Word 一段时间,但不太喜欢它。我的早期书籍(《分析模式》、《UML精粹》、《极限编程规划》和《重构》)都是用 Framemaker 写的——这是一个用于大型文档的复杂工具。如果你喜欢 WYSIWYG 编辑环境,它相当不错(虽然我从 2000 年左右就没有再用它了)。
在《企业应用架构模式》这本书中,我做了重大转变,转向了基于文本的系统。我的意思是将书籍的源文件保存在开放的文本格式中。这对我很有效。毕竟我是一个极客,用文本文件编写工具对我来说很容易。我还可以用标准的版本控制系统来管理书籍——这在独自工作时很有用,对于其他人来说,在协作工作时至关重要。
这种机制对于许多人来说有其缺点。我不能再使用 WYSIWYG 了——相反,我在文本编辑器中撰写文章,然后运行脚本生成可读的输出。这对我很有效,但想象一下,非极客会觉得它很原始。
对于像我这样的技术作家来说,这种方案的一个特别优势是处理软件代码。在我使用文本之前的日子里,我需要编写程序,让它们运行并经过测试,然后将它们复制粘贴到 Framemaker 中。最后一步是问题所在,我经常需要更改程序,然后必须更新书中的代码。手动复制粘贴很容易出错。
现在,在我的当前方案中,所有代码都作为构建过程的一部分自动导入到书中。因此,如果我更新代码,书就会自动更新。我再也不想回到手动复制粘贴了。
我全文本方法的唯一例外是图表。我使用过各种图表绘制工具,这些工具大多是 WYSIWYG 类型的工具。这不是理想的,但我还没有找到一个能够更好地与直接文本编辑配合使用的解决方案。
源文本格式
我的方法的关键点是使用开放的文本格式。在我的情况下,我使用的是自己开发的 XML 词汇。它与 HTML 大致相同,但添加了一些对我书籍有意义的额外标签。我一直是语义标记的粉丝——根据文本的含义而不是其输出格式对其进行标记。例如,我偶尔会对定义的短语使用粗体,就像我在上面所做的那样。我喜欢这样做,因为如果读者正在寻找某个术语的定义,他们可以通过扫描页面快速找到它。
但是,当我进行标记时,我不使用<b>
或<bold>
之类的标签,而是使用语义标签<term>
。然后,我在转换代码中决定将术语转换为粗体文本。
我更喜欢这样做,因为它迫使我专注于语义而不是格式。它还在转换过程中为我提供了其他有用的功能。当我转换术语时,不仅可以将它们设置为粗体,还可以将索引标记插入输出中。
我认识的许多人喜欢文本文档的想法,但不喜欢 XML。有些人发现 XML 难以输入,或者标签会妨碍阅读。这里一个流行的替代选择是 Markdown,它故意易于阅读和编写,以纯文本形式呈现。我更喜欢 XML,因为它在标记方面给了我更大的灵活性——我可以引入任何我喜欢的标签,包括专门用于这本书的标签——并将它们顺利地融入到流程中。
我遇到的另一个源格式是使用 Docbook XML 词汇。Docbook 是一个用于文档(尤其是长文档)的标准 XML 词汇。它有一些有用的优势,但我发现它的标签过于冗长且侵入性。此外,采用 Docbook 会阻止我使用自己的语义标签。
另一个具有悠久历史的文本选择是 LaTeX——但我从未尝试过。
转换目标
为了将我的源文档转换为输出,我使用了一个转换工具链,我将在稍后讨论。该工具链的直接目标是 Docbook。虽然我不喜欢 Docbook 作为源文档格式,但它作为转换目标非常出色。一旦将文本转换为 Docbook,就会有一系列 OSS 工具可以将 Docbook 转换为多种格式:HTML、PDF、ePub 等。我可以轻松地将这些工具整合到我的整体工具链中,因此只需一个命令,我就可以生成这些格式的任何组合。
在书籍的早期阶段,我通常使用 HTML 输出。如果我想与审阅者分享书籍,我可以根据他们的意愿生成 PDF 或 ePub。我的出版商(Pearson)会获取 Docbook 文件,并将它们输入到他们的出版流程中。
转换工具链
生成 Docbook 的工具链是我用 Ruby 自己编写的一系列脚本。它们会获取构成书籍文本的一系列 XML 文件,以及用于参考文献(如书目和实时代码目录)的参考文件,并生成 Docbook 输出。
它们被构建为转换规则,因此当转换器看到“term”标签时,它知道要输出相应的 Docbook 元素(以及索引信息)。如果我添加了新的标签,我只需要为它们添加新的处理程序方法,就可以快速在输出中看到它们。该工具链与我用于网站的工具链非常相似,主要区别在于网站工具链输出到 HTML 而不是 Docbook。
编辑
这种方法的好处在于,我可以使用任何文本编辑器进行写作。我最喜欢的文本编辑器是 Emacs,它有一个非常好的模式(NXML 模式)用于编辑 XML 文档,这一点特别有用。我见过的许多 XML 编辑器都是为了将 XML 作为分层数据结构的序列化而设计的,这并不适合标记文本。NXML 模式非常适合文本标记,因此对我来说很有效。除其他事项外,它可以与 RNC 模式文件一起设置,以便编辑器能够识别模式。
代码导入
自动代码导入是我工具链中非常重要的部分。我可以使用常规的程序代码,以任何我喜欢的格式进行组织。我需要做的就是将标记包含在注释中,以指示可能要提取到书中的代码片段区域。然后,我有一个 XML 元素,它命名了文件和代码片段,以及一个标签。当我运行工具链时,代码会从实时文件中提取到 Docbook 输出中。
图形
图形是我唯一不在文本编辑器中进行编辑的领域。目前,我沉迷于使用 OmniGraffle 绘制图表(仅限 Mac)。OmniGraffle 可以导出到书籍制作所需的各种格式(png、eps 等)。我的脚本工具链使用 Apple 的脚本功能自动重新导出文件,因此我不必记住在更改图表时导出。
版本控制
像任何程序员一样,我非常重视版本控制。当我开始使用 P of EAA 时,我们使用 CVS,从那时起,我使用过 SVN、Mercurial 和 git。版本控制系统在与他人协作时特别有用,因为我们可以使用与代码相同的方案来保持写作同步。
当书籍进入制作阶段时,我已经与我的出版商 Pearson 协商,使用熟悉在存储库中处理原始源文件的复制编辑、索引员和其他制作人员。
重大修订
2014 年 3 月 14 日