Asciidoctor EPUB3 文档

Asciidoctor EPUB3 是一组 Asciidoctor 扩展,用于将 AsciiDoc 文档直接转换为 EPUB3 电子书格式。

简介

Asciidoctor EPUB3 不仅仅是一个从 AsciiDoc 到 EPUB3 的转换器。相反,它是一个用于创建高度美观、专业、易于阅读的电子书的工具。让我们面对现实吧,市面上很多技术类电子书——尤其是那些从软件文档生成的——都非常丑陋。Asciidoctor EPUB3 的使命是颠覆现状。

text
图 1. Asciidoctor EPUB3 生成的电子书片段,显示在日间、夜间和棕褐色模式下。

项目使命

Asciidoctor EPUB3 项目旨在生成符合以下目标的 EPUB3 文档:

完全语义化

生成高度语义化的 XHTML5 文档,包括使用推荐的 epub:type 属性。

卓越的可读性

读者应该被吸引到文本中,以便他们能够阅读并吸收它。通过精心设计的、专注于以下几点的样式来最大化文本的可读性:

  • 自定义、可读的字体,具有强大的 UTF-8 字符支持

  • 充足的行距和页边距

  • 模块化字体大小比例

  • 微妙、悦目的颜色,具有良好的对比度

  • 响应式设计,可从小型屏幕缩放到大型屏幕

  • 尽可能避免孤行和孤页内容

完整准确的元数据

使用 AsciiDoc 源文档中的信息完全填充 EPUB3 包元数据。

一致的渲染

在广泛的 EPUB3(以及部分 EPUB2+)电子阅读器上一致渲染,并响应任何尺寸的屏幕。

精益求精,再精益求精

为最终产品增添光彩,例如基于字体的图标和标注编号。

我们相信 Asciidoctor EPUB3 生成的电子书是当今数字出版中您能期望获得的最好的输出。当然,总有改进的空间,因此我们将继续与您合作以实现并保持这一目标。

Asciidoctor EPUB3 只生成可变布局(即,可重排)的 EPUB3 文档,因为这种布局最适合 AsciiDoc 通常编写的文档类型。如果将来有需要,我们可能会探索使用固定布局文档。

显著特点

  • 直接 AsciiDoc 转 EPUB3

  • 高度美观且易读的样式,具有优化的文本可读性

  • 尊重字体设置(如果电子阅读器支持),而不改变标题、代码或图标

  • EPUB3 元数据、清单和书脊(由 Gepub 组装)

  • 文档元数据(标题、作者、主题、关键词等)

  • 内部交叉引用链接

  • 使用 Rouge、CodeRay 或 Pygments 进行语法高亮

  • Unicode 标注编号

  • 块内容避免分页(只要电子阅读器支持)

  • 避免孤立的章节标题(只要电子阅读器支持)

  • 尊重表格边框设置

  • 支持 SVG 图像内容

  • 通过 AsciiMath 进行 Stem 块

组织您的稿件

EPUB3 档案由多个文件组成。每个“章节”的内容通常存储在一个单独的 XHTML 文件中。因此,Asciidoctor EPUB3 转换器会将 AsciiDoc 源文档“分块”,生成多个 XHTML 文件添加到 EPUB3 档案中。与其他转换器一样,Asciidoctor EPUB3 通过在预定义的标题级别自动分割 XHTML 输出,来处理这种分块任务。

doctype 属性设置为 book 时,每个顶层章节将成为一个单独的电子书“章节”文件。这包括前言、参考文献、附录等。此行为可以通过 epub-chapter-level 文档属性进行配置。

否则,整个文档将被转换为一个单独的电子书章节。

您可以通过为章节分配 ID 来指定自定义章节文件名

[#custom-chapter-id]
= Chapter

以下是展示书籍结构的示例:

= Book Title
Author Name
:doctype: book
:imagesdir: images
//...and so on

== Chapter One

Some interesting text here.

== Chapter Two

Even more exciting stuff.

在旧版本的 Asciidoctor EPUB3 中,文档组织有严格的规则:一个带有章节包含的“书脊”主文档。现在不再是这样了。如果您遵循了旧规则,很可能您的文档经过少量调整或甚至不经调整即可在新版 Asciidoctor EPUB3 中正常工作。

先决条件

使用 Asciidoctor EPUB3 所需的只有 Ruby 2.7 或更高版本以及一些 Ruby gem,我们将在下一节中解释如何安装它们。

要检查您是否安装了 Ruby,请使用 ruby 命令查询已安装的版本

$ ruby --version

入门

您可以通过安装发布的 gem 来获取 Asciidoctor EPUB3。

安装已发布的 gem

Asciidoctor EPUB3 发布在 RubyGems.org 上。您可以使用以下命令安装已发布的 gem:

$ NOKOGIRI_USE_SYSTEM_LIBRARIES=1 gem install asciidoctor-epub3

这个可选的环境变量告诉 gem 安装程序使用系统上的 C 库进行链接(如果可用),而不是从头开始编译库。这大大加快了 Nokogiri 的安装速度。

如果您想对源代码列表进行语法高亮,您还需要安装 Rouge、CodeRay 或 Pygments。选择一个(或多个)以下选项:

Rouge
$ gem install rouge
CodeRay
$ gem install coderay
Pygments
$ gem install pygments.rb

然后,您可以通过将 source-highlighter 属性添加到文档头来为特定文档激活语法高亮(此处为 Rouge 示例)

:source-highlighter: rouge
如果未指定样式,则使用黑白主题(即 bw)。此默认设置是为了确保无论阅读器选择哪种阅读模式(白色、黑色、棕褐色等),语法高亮都清晰可辨。要覆盖此默认设置,您必须将 <highlighter>-style 文档头属性设置为有效的荧光笔样式名称(例如,:rouge-style: pastie)。

假设所有必需的 gem 都已成功安装,请验证您是否可以运行 asciidoctor-epub3 脚本:

$ asciidoctor-epub3 -v

如果您看到 Asciidoctor EPUB3 的版本信息打印出来,则表示您已准备好使用 Asciidoctor EPUB3。现在,让我们准备一个 AsciiDoc 文档以转换为 EPUB3。

生成的 EPUB3 文件中的元数据是从 AsciiDoc 文档中的属性填充的。属性的名称及其映射到的元数据元素在本节中进行说明。

表 1 中的“包元数据”一词指的是 EPUB3 包文档(例如,package.opf)中的 <metadata> 元素dc 命名空间前缀指的是 Dublin Core 元数据元素集

控制 EPUB3 元数据(即 package.opf)的 AsciiDoc 属性
名称 描述

uuid

填充包元数据中必需的唯一标识符(<dc:identifier>)。如果未指定,将从 doctitle 自动生成一个 ID。推荐的做法是通过符合正式识别系统的字符串或数字来标识文档。

lang

填充包元数据中的内容语言/区域设置(<dc:language>)。

scripts

根据指定的脚本(例如,字母表)控制所选的字体子集。(值:latin、latin-ext、latin-cyrillic 或 multilingual)

revdate

填充包元数据中的发布日期(<dc:date>)。日期应以可解析的格式指定,例如 2014-01-01

doctitle

填充包元数据中的标题(<dc:title>)。标题以纯文本格式添加到元数据中。

author

填充包元数据中的贡献者(<dc:contributor>)。每个章节文档中的作者将与主文件中的作者一起汇总。

username

用于解析作者的头像,该头像在章节标题下方显示,当 doctype 设置为非 book 的值时。头像图片应位于路径 {imagesdir}/avatars/{username}.jpg,其中 {username} 是此属性的值。

producer

填充包元数据中的发布者(<dc:publisher>)。

creator

填充包元数据中的创建者(<dc:creator>)。如果未指定创建者,则将 Asciidoctor 设置为创建者,角色为“mfr”(制造商的缩写)。

description

填充包元数据中的描述(<dc:description>)。

keywords

填充包元数据中的主题(即 <dc:subject>)。关键词应表示为逗号分隔值(CSV)。

front-cover-image

填充包元数据中的封面图片和封面页(仅限 EPUB3)上的图片。图片也会被添加到电子书档案中。该值可以指定为路径或内联图像宏。首选使用内联图像宏,因为它允许指定高度和宽度。

copyright

填充包元数据中的权利声明(<dc:rights>)。

source

填充包元数据中的源引用(<dc:source>)。推荐的做法是通过符合正式识别系统的字符串或数字来标识引用的资源。

epub-properties

此文档在清单中条目的属性的可选覆盖。仅适用于章节文档。

epub-chapter-level

指定将 EPUB 分割成单独“章节”文件的节级别。此属性仅影响具有 :doctype: book 的文档。默认情况下,在 1 级章节分割。此属性仅影响 EPUB 的内部构成,而不影响向用户显示章节的方式。如果章节文件过大,某些阅读器可能会变慢,因此对于包含少量 1 级标题的大型文档,可以考虑使用 2 级或 3 级章节。

series-name, series-volume, series-id

填充包元数据中的系列声明(belongs-to-collection)。Volume 是一个数字,ID 可能是对系列中所有 Volume 都相同的 UUID。

epub3-frontmatterdir

包含前言文件的目录路径。文件名必须匹配 front-matter*.html,并将按字母顺序包含。文件预计为有效的 EPUB HTML 文件。如果只需要一个前言页面,可以使用默认的 'front-matter.html' 文件代替。

epub3-stylesdir

包含备用的 epub3.css 和 epub3-css3-only.css 文件的目录路径,用于自定义外观和感觉。

doctype

用于控制在生成的 HTML 中包含特殊内容。如果设置为 book 以外的值,则会在章节标题下方包含署名信息(作者和头像),并在最后一个段落末尾添加一个排版结束标记。建议值包括:book(默认)、article。

toc

在书籍开头添加目录。深度由 :toclevels: 属性控制。

outlinelevels

设置目录元数据的深度。如果未设置,则默认为 :toclevels:

以上准备工作就绪,现在可以开始将 AsciiDoc 文档直接转换为 EPUB3 了。

执行转换

您可以使用 Asciidoctor EPUB3 项目随附的 asciidoctor-epub3 脚本从命令行将 AsciiDoc 文档转换为 EPUB3。

将 AsciiDoc 转换为 EPUB3

将 AsciiDoc 文档转换为 EPUB3 就像将文档传递给 asciidoctor-epub3 命令一样简单。如果您安装了 asciidoctor-epub3 gem,则此命令应在您的 PATH 中可用。否则,您可以在项目中的 bin 文件夹中找到该命令。我们还建议使用 -D 选项标志指定输出目录。

$ asciidoctor-epub3 -D output samples/sample-book.adoc

当脚本完成时,您将在 output 目录中看到 sample-book.epub 文件。使用 EPUB 阅读器(又称电子阅读器)打开该文件以查看结果。

以下是此示例书籍在 Android 手机上显示效果的几张截图。

chapter title
图 2. 日间和夜间模式下并排显示的章节标题和摘要示例
section title paragraph
图 3. 章节标题后跟着段落文本,由字面块分隔的示例
figure admonition
图 4. 图形和警告的示例
sidebar
图 5. 侧边栏示例
table
图 6. 表格示例
asciidoctor-epub3 命令是调用 Asciidoctor EPUB3 转换器的临时解决方案。一旦我们完成了与 asciidoctor 命令的正确集成,我们就计划删除此脚本。
作为另一个示例,将 asciidoctor-epub3 指向我们已移植到 AsciiDoc 的GitHub Guides,然后将输出与真实的GitHub Guides进行比较。

验证 EPUB3 档案

接下来,让我们验证 EPUB3 档案,以确保其已正确构建。

带验证的 EPUB3
$ asciidoctor-epub3 -D output -a ebook-validate samples/sample-book.adoc
验证成功
Validating using EPUB version 3.0.1 rules.
No errors or warnings detected.
Messages: 0 fatal / 0 errors / 0 warnings / 0 info
EPUBCheck completed

如果 EPUB3 档案包含任何错误,它们将在您的终端中输出。

EPUB 标准与验证器

电子出版(EPUB)标准由国际数字出版论坛(IDPF)制定。EPUB 3.1 于 2017 年 1 月发布,是该标准的最新版本。

EPUB3 档案包含:

  • 一个包文档(元数据、文件清单、书脊)

  • 一个导航文档(目录)

  • 一个或多个内容文档

  • 资产(图像、字体、样式表等)

IDPF 还支持EPUBCheck。EPUBCheck 会解析文件并根据 EPUB 模式进行验证。

如果您想浏览生成的 EPUB3 文件内容,或在常规浏览器中预览 XHTML 文件,请将 -a ebook-extract 标志添加到 asciidoctor-epub3 命令。EPUB3 文件将提取到生成文件旁边的目录中,但没有文件扩展名。

$ asciidoctor-epub3 -D output -a ebook-extract samples/sample-book.adoc

在此示例中,EPUB3 的内容将提取到 output/sample-book 目录中。

调整列表标题

与内置转换器不同,EPUB3 转换器配置为在所有具有标题的列表和源代码块的标题开头添加一个标识符(例如,Listing)。此行为被触发是因为 listing-caption 属性默认已设置。

如果您不希望在列表和源代码块的标题开头包含标识符,只需在调用 Asciidoctor EPUB3 时取消设置 listing-caption 即可。

$ asciidoctor-epub3 -a listing-caption! book.adoc

现在,行为将与内置转换器匹配。有关此属性和其他相关属性的更多信息,请参阅国际化和编号

命令参数

-h, --help

显示用法消息

-D, --destination-dir

将文件写入指定目录(默认为当前目录)

-a ebook-epubcheck-path=<path>

指定与 -a ebook-validate 一起使用的 EPUBCheck 可执行文件的路径。此属性优先于 EPUBCHECK 环境变量。

-a ebook-extract

在文件生成后,将 EPUB3 提取到目标目录中的一个文件夹

-a ebook-validate

运行EPUBCheck 以根据 EPUB3 规范验证输出文件

-v, --version

显示程序版本

环境变量

EPUBCHECK

指定与 -a ebook-validate 一起使用的 EPUBCheck 可执行文件的路径。此变量的效果可以通过 -a ebook-epubcheck-path 属性覆盖。

EPUB3 档案结构

以下是 Asciidoctor EPUB3 生成的 EPUB3 文档中文件的示例清单。

META-INF/
  container.xml
EPUB/
  fonts/
    awesome/
      fa-solid-900.ttf
    font-icons.ttf
    mplus-1mn-latin-bold.ttf
    mplus-1mn-latin-light.ttf
    mplus-1mn-latin-medium.ttf
    mplus-1mn-latin-regular.ttf
    mplus-1p-latin-bold.ttf
    mplus-1p-latin-light.ttf
    mplus-1p-latin-regular.ttf
    noto-serif-bold-italic.ttf
    noto-serif-bold.ttf
    noto-serif-italic.ttf
    noto-serif-regular.ttf
  images/
    avatars/
      default.png
    figure-01.png
    figure-02.png
  styles/
    epub3-css3-only.css
    epub3.css
  chapter-01.xhtml
  chapter-02.xhtml
  ...
  cover.xhtml
  nav.xhtml
  package.opf
  toc.ncx
mimetype

使用图像

您的 AsciiDoc 文档中引用的图像必须存储在图像目录中。图像目录由 imagesdir 属性定义。如果设置了此属性,则该属性的值将相对于文档解析,并且必须位于该文档的目录中或其子目录下(即,在其内部)。(换句话说,它不能指向文档目录外部的位置)。如果未设置此属性,则图像目录默认为文档的目录。Asciidoctor EPUB3 将发现所有本地图像引用,并将这些图像以相同的相对路径插入到 EPUB3 档案中。

默认图像

示例书中包含一个作者头像的占位符图像。

添加封面图片

电子阅读器在书籍封面方面对图像分辨率和文件大小有限制。Kindle 封面通常为 1050x1600(16:9 宽高比)。为确保您的封面正确显示,您需要查阅您目标电子阅读平台(如 Kindle)的文档或发布指南。

我们发现,如果书的封面任何一边超过 1600 像素,Aldiko 将无法渲染它,甚至可能崩溃。

您可以随意使用data/images 文件夹中的示例封面的 SVG 作为创建自己封面的模板。一旦您的图片准备就绪,您可以通过在主文档的头部定义 front-cover-image 属性来设置封面图片。

:front-cover-image: image:cover.png[Front Cover,1050,1600]

图像相对于 imagesdir 属性指定的目录解析,该目录默认为文档的目录。图像可以是任何格式,尽管我们建议使用 PNG、JPG 或 SVG,因为它们是最便携的格式。

您应始终指定封面图片的尺寸。这样可以确保查看器在需要缩放以适应屏幕时保留宽高比。如果您不指定宽度和高度,则假定尺寸为 1050x1600。

如何按章节组织图像

您可以通过章节设置 imagesdir 属性(只要该属性未被 API 覆盖)。为此,请使用属性条目在包含指令之上的一行上为章节设置 imagesdir 属性的值。

:imagesdir: chapter-one/images
include::chapter-one.adoc[]

:imagesdir: chapter-two/images
include::chapter-two.adoc[]

使用 Docinfo 添加补充内容

可以使用docinfo 文件将补充内容注入到输出文档中。

目前,EPUB3 文档中有三个 docinfo 内容的插入位置:

head

内容插入到 <head> 元素的最后一个子节点之后。文件名:docinfo-epub.html

header

内容插入到 <body> 元素的第一个子节点。文件名:docinfo-header-epub.html

footer

内容插入到 <body> 元素的最后一个子节点。文件名:docinfo-footer-epub.html

为了启用 docinfo 文件包含,您需要定义 :docinfo: 属性。例如,:docinfo: shared。有关可能的值及其含义,请参阅docinfo 文件文档。

关于主题

EPUB3 文件使用 CSS3 进行样式设置。但是,每个电子阅读平台都支持有限的 CSS3 样式集,而且它们允许的样式以及它们的实现方式很少有文档记录。我们唯一能说的是,感谢 CSS 技巧、媒体查询和多年的 CSS 经验!

Asciidoctor EPUB3 提供的样式表经过精心设计,可在最常见的 EPUB3 平台之间尽可能一致地显示 EPUB3 文件,并在部分 EPUB2 平台上优雅降级。该样式表无论阅读模式(即日间、夜间或棕褐色)如何,或显示设备的像素密度和屏幕分辨率如何,都能保持可读性。

样式表的 CSS 文件位于 data/style 目录中。

Asciidoctor EPUB3 只提供一个主题,并且目前您无法使用 stylesheet 属性将其替换为自定义主题。但是,您可以通过使用 epub3-stylesdir 属性指定您的自定义 epub3.cssepub3-css3-only.css 文件的位置来使用它们。

设备特定样式

对于支持 JavaScript 的阅读器,Asciidoctor EPUB3 会向每个章节的 body 元素添加一个 CSS 类,该类对应于 epubReadingSystem JavaScript 对象报告的阅读器名称。此增强功能允许您使用专门针对该阅读器的样式。

您可以在下面找到已知支持此功能且添加到 body 元素的 CSS 类名称的阅读器。

阅读器 HTML 元素 CSS 类名

Gitden

body

gitden-reader

Namo PubTreeViewer

body

namo-epub-library

Readium

body

readium-js-viewer

iBooks

body

ibooks

Adobe RMSDK >= 11

body

rmsdk

Google Books

div

gb-reader-container

Kobo 不支持 epubReadingSystem JavaScript 对象,尽管它确实支持 JavaScript。

推送到 Android

虽然在您的台式机/笔记本电脑上查看 EPUB3 当然是可能的,但您可能希望在最可能被阅读的地方进行测试——例如在智能手机或平板电脑等阅读设备上。假设您有 Android 设备可用,在完成一些设置后,通过 USB 连接将 EPUB3 传输到设备非常容易。

您可以使用 Android SDK Tools 中的一个名为 adb 的命令,通过 USB 连接将文件从计算机传输到 Android 手机。请按照以下步骤进行设置:

  1. 从“获取 Android SDK”页面上标记为仅 SDK 工具的表格中下载 Android SDK Tools zip 文件

  2. 解压缩存档

  3. 找到 adb 命令的路径(提示:查看 platform-tools 文件夹)

  4. 设置名为 ADB 的环境变量为 adb 命令的路径

    $ export ADB=~/apps/android-sdk/platform-tools/adb

现在您可以使用 adb push 将 EPUB3 文件推送到您的 Android 设备。

将 EPUB3 文件推送到 Android 设备
$ adb push output/sample-book.epub /sdcard

您需要手动将 EPUB3 导入到您选择的电子阅读器中。

电子书阅读器推荐和注意事项

EPUB3 电子阅读器在查看 Asciidoctor EPUB3 生成的书籍时将提供最佳阅读体验。以下是我们知道具有良好 EPUB3 支持的一些电子阅读器及其运行的系统列表:

要获得完整的体验,请确保电子阅读器设置为使用出版商的样式。不同的电子阅读器对此设置的表述方式不同。查找允许您设置字体和字体颜色的选项屏幕,并将其启用。启用出版商样式后,您仍然可以调整字体和页边距的相对大小,并在日间、夜间和棕褐色模式之间切换。

当书籍在 EPUB2 电子阅读器和已达到生命周期结束(EOL)的 Kindle 应用/设备上查看时,电子书将依赖于 HTML 的强大语义和一些备用样式来正确渲染。EPUB2 电子阅读器(如 Aldiko)不理解 CSS3 样式,因此会错过一些格式的细微之处。

主题部分所述,样式表试图在常见的 EPUB3 电子阅读器中提供尽可能一致的阅读体验,尽管每个电子书应用程序都有不同的 CSS 实现规则和限制。我们已经解决了其中大多数障碍,使用了媒体查询或显式类。有些我们尚未克服。但最终会。

Kindle 注意事项列表》展示了我们遇到的一些限制。要查看所有解决方法以及我们为何选择特定样式选项,请查看 epub3.cssepub3-css-only.css 文件中的代码和注释。

Kindle 注意事项
  • 像中世纪暴君一样覆盖边距和行高

  • font-family 不能在 <body> 上设置

  • 需要 !important 来设置 text-decoration

  • 不允许 position: relative

  • 删除(或解包)<header> 标签

  • 不支持 @page

  • 不支持 page-break: avoid

  • page-break-* 不能使用复合或嵌套 CSS 选择器应用;必须是简单的 ID 或类

  • 不支持 max-width

  • widows 被遗忘

  • 没有显式类将不会为页脚设置样式

  • -webkit-hyphens: auto 会导致 Kindle for Mac(以及其他一些)崩溃

  • text-rendering: optimizeLegibility 会导致文件被 KFP 拒绝(并在某些预览器中导致文本消失)

  • Kindle Direct Publishing (KDP) 在某些情况下会删除选定的字体相关 CSS 规则(例如 font-family)(原因几乎无法逆向工程);已知的解决方法是通过使用 @import 来隐藏 CSS 文件,从而在脚本中添加一个间接层