使用 HTML5、CSS3 和 MathML 在 EPUB 3 中制作版式丰富的出版物

探索用于高级排版和印刷的新一代开放电子书标准

EPUB 3.0 是最新的行业标准 XML 电子书格式,它采用了 HTML5 和 CSS3,因而融入了现代 Web 技术。它重点关注 XML 驱动的工具包,要求 XHTML 序列化,还增加了补充性的 XML 词汇,例如 MathML 和 SVG。EPUB 3 提供了多种开发先进的原生数字出版物的选项。在这篇文章中,您将学习如何利用 EPUB 3 中的部分新特性来制作具有版式丰富的页面。

Liza Daly, 软件工程师和企业家, Safari Books Online

2012 年 6 月 04 日

  • 技术分享内容

简介

EPUB 是由 International Digital Publishing Forum (IDPF) 标准化的一种 XML 格式,用于可重排版电子书和出版物。截至 2009,EPUB 2 是大多数主流电子书零售商和阅读系统使用的事实上的标准格式。

EPUB ZIP 存档打包为定义良好的结构。每个组件都有自己的规范,根据按照通用 EPUB 标签进行统一:

容器规范
定义 EPUB 文档的打包方法。
EPUB 出版物
包含有关电子书内容的全部元数据,其中包括:包清单、基本标题、作者元数据,在 EPUB 3 中,还包括出版物预期支持的高级特性的定义,例如 JavaScript 或 MathML。这类出版物也称为开放容器格式文件
EPUB 内容文档
构成出版物内容的实际 XHTML 和 CSS 文件。内容文档还包括二进制资源,例如图像、多媒体,可能还包括外部定义的 XML 文档。

常用缩写

  • CSS:层叠式样式表
  • DTD:文档类型定义
  • HTML:超文本标记语言
  • JAR:Java 存档
  • OPF:开放打包格式
  • SVG:可缩放矢量图形
  • XHTML:可扩展超文本标记语言
  • XML:可扩展标记语言
  • XSLT:可扩展样式表语言转换

本文探讨了部分 EPUB 3 特性。您将学习有关验证 EPUB 3 文档、导航和层次结构、开发指南的内容。本文提供了一个示例,将指导您了解将儿童书籍中的一页调整为 EPUB 3 的过程。另外您还能了解到如何在出版物中包含 MathML。

下载 本文中使用的示例。

先决条件

本文中的样例代码和示例假设读者对 EPUB 2 规范和基于 XML 的出版物有基本认识。有关 EPUB 2 的具体信息,请参见 参考资料

 

EPUB 3 中的变更

EPUB 2 提供了 HTML4 和 CSS2 的所有格式化和排版功能,足以满足包含大量文本的出版物的要求。不过,出版商和作者可能会发现,EPUB 2 无法处理许多内容类型和用例,例如多媒体图书、采用复杂版式的图书、数学出版物和交互式文档。2011 年 10 月,IDPF 和电子书社区发布了 EPUB 3 规范。

EPUB 3 阅读系统

截至 2011 年 12 月,尚无正式支持 EPUB 3 的阅读系统。不过,许多使用支持 HTML5 的浏览器引擎编写的阅读系统(例如 WebKit)均支持大多数 EPUB 3 内容文档规范。建议您使用基于现代 HTML 呈现引擎的最新浏览器来测试和开发 EPUB 3 文档。

本文包含在不具备完整 EPUB 3 阅读系统的情况下,创建无害填充内容 (shim) 以生成兼容 EPUB 3 的输出的一些技巧。

EPUB 2 过渡到 EPUB 3 之后的主要变化包括:

  • EPUB 3 内容文档必需的架构从 XHTML 1.1 变为 HTML5 的 XHTML 序列化。为了包含 HTML5 中的多媒体元素(<video><audio> 和 <canvas>),这是必不可少的。
  • EPUB 3 中的 CSS 容许使用范围从 CSS2.1 的子集扩展到 CSS3 中与文档创作相关的一组成熟模块。
  • MathML 已经作为一级内容类型添加到 XHTML5 和 SVG 之中。
  • 拥有 CSS 窗口 (viewport) 的阅读系统现在必须支持内嵌字体。Web 开放字体格式现已添加为可接受的字体格式。
  • 显式支持非西欧手写模式和字体,包括日语和其他亚洲语言的竖行版式。
  • 可选择使用自定义安全模型,支持以 JavaScript 作为中介的互操作性。
  • 出版文档中允许使用的元数据已经得到扩展,包括对属性方面的资源描述框架 (RDFa) 的部分支持。
  • EPUB 2 Navigational Center eXtended (NCX) 目录 (TOC) 文档已经弃用,改为基于 XHTML5 的 TOC。(为了支持向后兼容性,仍然允许使用 NCX。)
 

验证 EPUB 3 文档

对于大多数内容类型而言,EPUB 3 依赖于 XML 序列化,因此支持自动验证。EpubCheck 工具是测试 EPUB 文档的有效性和一致性的规范方法。EpubCheck 是一种开源的(Berkeley Software 发放许可)Java™ 库。有一个开发人员预览版可以与 EPUB 3 一起使用,本文中使用的也是这个版本。请参阅 参考资料 部分,获得最新版本的链接。

强烈建议您为所有 EPUB 内容文档使用 .xhtml 扩展名。如果未使用该扩展名,浏览器无法将 HTML 内容解释为 application/xhtml+xml。在使用本文演示的 CSS 名称空间等众多特性时,必须使用 XML 处理模式。

典型情况下,您需要通过命令行与 EpubCheck 进行交互,如下所示。

$ java -jar epubcheck-3.0b3.jar sample.epub

Epubcheck Version 3.0b3

No errors or warnings detected.

如果您得到了 java.lang.NoClassDefFoundError: com/thaiopensource/validate/SchemaReader 错误响应,请确保 EpubCheck 发布版附带的库/目录与 EpubCheck JAR 文件处于同一个目录之中。

EpubCheck 3 可以单独验证 EPUB 包的一个子组件,如 清单 1 所示。本文示例中使用的这种极为有用的特性可以:

  • 帮助隔离问题。
  • 减少仅仅为了验证而将 EPUB 重新打包为新 ZIP 的繁琐工作。
  • 整合到单元测试框架之中,提供输出单独一种文件类型的工具链。
清单 1. 对单一文件类型运行 EpubCheck 3。
$ java -jar ~/src/epubcheck-3.0b3.jar sample-toc.xhtml -mode nav 
Epubcheck Version 3.0b3

WARNING: sample-toc.xhtml: File is validated as a single file of type nav and version 3! 
         Only a subset of the available tests is run!

No errors or warnings detected.
 

EPUB 3 文档的导航和层次结构

尽管 EPUB 2 中的 NCX TOC 文件支持许多层次导航和页面地图标记,但它派生自 Digital Accessible Information System (DAISY) Digital Talking Book(一种制作能够访问禁止打印内容的电子书)。依靠定义良好的 DAISY 格式,开发人员可以更加轻松地开发支持丰富可访问性的电子书阅读器。从这种意义上来讲,NCX 表现非常出色。然而,NCX DTD 较大,包含与 EPUB 2 不相关的特性。人们对 EPUB 必须使用 NCX 的哪些部分众说纷纭,因而造成某些电子书零售商和阅读系统供应商各自为政,提供了一些支离破碎的、专有的扩展。

EPUB 3 弃用了 NCX,使用 EPUB 导航文档 (END) 取而代之。清单 2 给出了一个示例。END 使用了 XHTML5,而非自定义 DTD,从而减少了需要实现和验证的 XML 格式数量。自定义 EPUB 属性使用 EPUB 名称空间提供 (http://www.idpf.org/2007/ops)。

清单 2. 最简单的 END
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:epub="http://www.idpf.org/2007/ops">
  <head>
    <title>Example</title>
  </head>
  <body>
    <section epub:type="frontmatter toc">
      <header>
        <h1>Contents</h1>
      </header>
      <nav epub:type="toc" id="toc">
        <ol>
          <li id="chapter_001">
            <a href="chapter_001.html">Chapter 1</a>
          </li>
        </ol>
      </nav>
    </section>
  </body>
</html>

HTML5 <nav> 元素是必不可少的(epub:type 值 toc 也是如此)。

声明 END

要在出版物中包含 END,只需在清单中声明 item,并使用 nav 的 properties 值即可,如 清单 3 所示。

清单 3. 在 EPUB 打包文档 (OPF) 中包含 END
  <manifest>

    <item id="toc" 
    properties="nav"
    href="toc.html" 
    media-type="application/xhtml+xml"/>

    <item id="chapter_001" 
    href="chapter_001.html" 
    media-type="application/xhtml+xml"/>
    ...
  </manifest>

EPUB 3 要求必须包含 END 文件。为了实现向后兼容性,您还可以包含一个 NCX 文件,但 EPUB 3 处理器必须 忽略 NCX,而支持 END。

END 的可视化表示

与 NCX 不同的是,您可以在图书内容流中包含 END。在 EPUB 2 中,如果您希望为用户展示自定义的 TOC(而不是依赖电子阅读器的内置 TOC 支持),则必须制作相同的两份副本:一个使用 NCX,另一个作为 HTML 内容文档。END 消除了这种重复劳动,支持灵活地在内容流中显示部分或全部 TOC。

要向内容流添加 END,只需在 OPF spine 中包含 END 即可,如 清单 4 所示。

清单 4. 在阅读流中包含 END
 <![CDATA[
  <spine>
    <itemref idref="toc" />
    <itemref idref="chapter_001" />
    ...
  </spine>

在包含较深层次结构的文档中,例如技术文档,您可能希望在一个纯功能性 TOC 中包含所有章节,同时在内容流中为用户仅显示一级或者二级章节。只需为不想显示给用户的所有元素使用 HTML5 hidden 属性即可实现此目的,如 清单 5 所示。

清单 5. 从 TOC 的可视化显示中删除小节
...
<nav xmlns:epub="http://www.idpf.org/2007/ops" epub:type="toc" id="toc">
  <ol>
    <li id="chapter_001">
      <a href="chapter_001.html">Chapter 1</a>
      <ol hidden="hidden">
        <li>
          <a href="chapter_001.html#id1">Chapter 1 subsection</a>
          <ol>
            <li>
              <a href="chapter_001.html#id1.1">Chapter 1 subsection 1</a>
            ...

您可能会感到疑惑,为什么不能使用 CSS display: none 属性来实现此目标。因为 EPUB 得到了多种阅读系统的采用,包括非可视屏幕阅读器或 Braille 设备,而并非所有阅读器都支持 CSS。大多数现代 Web 浏览器都为 hidden 提供了原生支持。最好包含 CSS 来显式设置这些元素的显示属性,如 清单 6 所示。由于 END 文件仅仅是另一个 HTML 文件,因此您可以在 HTML head 中添加 CSS,就像其他任何样式表中一样。

清单 6. 设置显示属性
/* Never display elements with the hidden attribute */
*[hidden] {
  display: none;
}

在不兼容的阅读系统或浏览器中,如果未提供 hidden 属性的样式,则会导致显示所有小节,如 图 1 所示。

图 1. 无隐藏属性或 CSS 的 END TOC
技术分享

在支持 hidden 的浏览器中,或者在您应用了 shim CSS 之后,输出将发生转变,如 图 2 所示。

图 2. 应用了隐藏的 END TOC
技术分享

默认情况下,有序列表 HTML 将生成一组编号列表。但是,END 规范表明:“.. . 列表项的默认显示样式必须与 CSS list-style: none 相同。”为了达到这样的显示效果,可以为 EPUB 3 CSS 填充内容添加另一条规则,如 清单 7 所示。

清单 7. 设置列表项的样式
 /* In a declared TOC list, never show list numbering */
nav#toc ol {
  list-style-type: none;
}

通过 XSLT 从 NCX 迁移到 END

尽管 EPUB 3 END 提供了更多的版式和控制选项,但如果您正在从 EPUB 2 迁移到 EPUB 3 工作流,那么应该考虑首先转换现有 NCX 文档。由于输入和输出文档均为 XML,因此最理想的方法是应用 XSLT。

清单 8 提供了生成 HTML 文档并填充 TOC 的基本框架。

清单 8. 为 NCX 和 END 声明必要的名称空间
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" 
                exclude-result-prefixes="ncx xsl"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ncx="http://www.daisy.org/z3986/2005/ncx/"
                xmlns:epub="http://www.idpf.org/2007/ops"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="ncx:ncx">
    <html>
      <head>
        <title><xsl:apply-templates select="/ncx:ncx/ncx:docTitle/ncx:text"/></title>
      </head>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

请注意,http://www.idpf.org/2007/ops 名称空间是强制包含的,其前缀通常是 epub。包含此名称空间的主要目的是支持 EPUB 语义拐点(有关 EPUB 内容文档中一个元素的特定目的的附加含义)。如果使用 EPUB 3,则建议您使用结构化语义词汇表中可用的表达能力,为可访问性软件和机器处理提供上下文。有关该词汇表中所含值的更多信息,请参阅 参考资料 部分。

如欲获得其他页面地图类型的完整转换示例,请参阅 参考资料 部分中包含的开源 nend 应用程序。

有了基本的大纲之后,即可开始处理 NCX 中的层次化 TOC 和输出对应的 XHTML 元素。尽管 NCX 支持多种不同类型的页面列表,但 EPUB 图书通常仅包含 ncx:navMap清单 9 中的模板摘要展示了如何输出 ncx:navMap 中的一组节点。

清单 9. 输出 navMap
...
  <!-- Generate a complete nav element and sub-list out of the navMap, 
       then recurse through the nodes -->
  <xsl:template match="ncx:navMap">
      <nav id="toc" epub:type="toc">
        <xsl:copy-of select="@class"/>
        <xsl:choose>
          <xsl:when test="ncx:navLabel">
            <xsl:apply-templates select="ncx:navLabel" mode="heading"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:if test="self::ncx:navMap">
              <h1>Table of Contents</h1>
            </xsl:if>
          </xsl:otherwise>
        </xsl:choose>
        <ol>
          <xsl:apply-templates select="ncx:navPoint|ncx:navLabel"/>
        </ol>
      </nav>
  </xsl:template>

  <xsl:template match="ncx:navPoint">
    <xsl:text>
</xsl:text>
    <li>
      <xsl:copy-of select="@id|@class"/>

      <!-- Every navPoint must have a navLabel and content -->
      <a href="{ncx:content[1]/@src}">
        <xsl:apply-templates select="ncx:navLabel"/>
      </a>

      <!-- Does this element have a sub-nav? -->
      <xsl:if test="ncx:navPoint">
        <ol>
          <xsl:apply-templates select="ncx:navPoint"/>
        </ol>
      </xsl:if>
    </li>
  </xsl:template>

  <!-- These nodes only contain text -->
  <xsl:template match="ncx:navLabel|ncx:text">
    <xsl:apply-templates/>
  </xsl:template>
...

清单 10 提供了层次化 NCX 的一个示例。

清单 10. 使用分层组织的 NCX 的样例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ncx PUBLIC "-//NISO//DTD ncx 2005-1//EN" 
  "http://www.daisy.org/z3986/2005/ncx-2005-1.dtd">

<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="en">

  <head>
    <meta name="dtb:uid" content="d989d60c-2302-40d1-9c85-1c028414342a" />
    <meta name="dtb:depth"          content="-1" />
    <meta name="dtb:totalPageCount" content="-1" />
    <meta name="dtb:maxPageNumber"  content="-1" />
  </head>

  <docTitle>
    <text>Middlemarch</text>
  </docTitle>

  <navMap>
    <navPoint id="np1" playOrder="1">
      <navLabel>
        <text>Prelude</text>
      </navLabel>
      <content src="prelude.html"/>
    </navPoint>

    <navPoint id="np2" playOrder="2">
      <navLabel>
        <text>I: Miss Brooke</text>
      </navLabel>
      <content src="book1.html" />

      <navPoint id="np3" playOrder="3">
        <navLabel>
          <text>Chapter 1</text>
        </navLabel>
        <content src="chapter1.html" />
      </navPoint>
      <navPoint id="np4" playOrder="4">
        <navLabel>
          <text>Chapter 2</text>
        </navLabel>
        <content src="chapter2.html" />
      </navPoint>
   ...

使用 XSLT 改变 清单 10 中的文件将获得下面的 清单 11 所示的输出。您可以 下载 示例文件。

清单 11. 从 NCX 转变为 END 的输出结果
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
  <head>
    <title>Middlemarch</title>
  </head>
  <body>
    <nav id="toc" epub:type="toc">
      <h1>Table of Contents</h1>
      <ol>
        <li id="np1">
          <a href="prelude.html">Prelude</a>
        </li>
        <li id="np2">
          <a href="book1.html">I: Miss Brooke</a>
          <ol>
            <li id="np3">
              <a href="chapter1.html">Chapter 1</a>
            </li>
            <li id="np4">
              <a href="chapter2.html">Chapter 2</a>
            </li>
...

由于原始文件中的 @id 值得到了保留,因此您应能够编写验证工具,确保捕捉了所有原始节点。用于进一步转换的其他选项包括:

  • 根据 Publications 3.0 规范的定义,将旧 Dublin Core 模式中 OPF 文件的元数据更新为元 @property 模式(请参见 参考资料)。
  • 将弃用的 OPF guide 内容迁移为 END 中的 landmarks 特性。
  • 删除 OPF spine 中对 NCX 文件的引用(除非您正在制作向后兼容的文档)。

通常情况下,不必修改 XHTML 1.1 内容即可生成兼容 EPUB 3 的内容文档。在语义信息可用时,例如从内容管理系统或者其他文档存储库中获取信息,应考虑对输出应用语义拐点 (semantic inflection)。EPUB 3 规范提供了有关语义拐点的更多信息(请参阅 参考资料)。

 

EPUB 3 开发指南

在 EPUB 3 阅读系统可用之前,推荐具体最佳实践的时机尚未成熟。不过,EPUB 3 是以迅速发展成熟的 Web 技术为基础的,已经有充分的信息可以用来提供有关建议,比如如何使用基本技术,以及何时使用最佳实践来生成可靠的、语义性的、可访问的标记等。

何时生成 EPUB 3

您目前应该对制作的电子书使用 EPUB 2 还是 EPUB 3?幸运的是,EPUB 3 的设计目标之一就是向后兼容性。您应受益于 EPUB 3 中的语义增强和更丰富的元数据,同时仍然能够制作在旧电子阅读器中可以阅读的文档。在实践中,有可能在某些电子书市场中无法销售此类内容,出于业务规则方面的原因,他们可能并不接受 EPUB 3。然而,“侧面分载 (sideloading)” 此类内容在大多数一致的 EPUB 2 阅读系统中都是有效的。EPUB 3 在设计时也考虑到了阅读系统支持的向后兼容性,EPUB 3 阅读系统必须 支持有效的 EPUB 2 文档。

许多阅读系统都支持某种 “EPUB 2.5”,允许使用 HTML5 标记(特别是在与 videoaudio 和 canvas 元素相关的某些方面)。使用 Web 浏览器引擎的电子阅读平台(例如 Apple iBooks)能够成功地呈现 EPUB 3 内容文档中支持的许多元素。对于前沿 Web 内容,则应在发布之前在尽可能多的阅读器内测试您的内容。

响应式电子书设计

CSS3 媒体查询模块是 EPUB 3 中一个振奋人心的新组件。媒体查询允许作者指定一组仅应用于特定查看条件的规则和属性,通常以窗口的大小为依据。您还可以使用媒体查询来定位特定的纵横比,例如纵向和横向模式。

许多网站已经在利用这些特性提供更好的移动设备用户体验。将这些原则整合在一起,便形成了响应式 Web 设计。这些技术已经在 Web 中进行了有效的证明,而且从某种意义上来说,它们甚至更加适合图书设计者。图书设计者经过数十年的研究和实验确定了如何在各种尺寸和方向中有效地展示可视信息。(有关响应式 Web 设计的更多信息,请参阅 参考资料 部分。)

大多数电子书都是纯文本或者以文本为主的。然而,出于市场营销方面的原因,或者由于内容本身的特质,许多类型的出版物需要更加丰富的版式。人们通常认为版式复杂的图书不适合转换为电子书,但 EPUB 3 及其对 HTML5 和 CSS3 的使用为高级设计提供了支持。更强大的力量带来了更出色的响应能力。希望轻松阅读版式出色的内容的移动设备用户群是不容忽视的。此时,结合使用 CSS3 版式和响应式电子书设计技术会带来良好的成效。

 

EPUB 3 中的高级、响应式版式

图鉴、烹饪书籍、教科书和诗集难以转换为可重排版的内容。在这一节中,您将看到如何调整一本儿童诗集中的页面(如 图 3 所示),使其适应 EPUB 3。我们这里之所以使用调整,而不是转换,是因为这个过程更加倾向于艺术角度,而非技术方法。

图 3. 摘自 Thomas Crane 创作的 Abroad 的一个页面(来自互联网存档的公开图片)
技术分享

我们的方法是将文本捕捉为 XHTML,随后提取部分图像来展现(并非复制)原始版式。EPUB 3 假设使用 XHTML5/CSS3 处理上下文,因此您可以使用极少的语义标记,而不必像在开放 Web 中那样适应大量遗留浏览器。清单 12 展示了内容的 XHTML 标记。

清单 12. 诗歌标记
 <?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
  <head>
    <title>Example of Media Query in EPUB 3</title>
    <link rel="stylesheet" type="text/css" href="childrens-book-style.css" />
  </head>
  <body>
    <div epub:type="chapter">
      <h1>The Swans.</h1>
      <p>
        <span>"Ho! pretty swans,</span>
        <span>Do you know, in our Zoo‘</span>
        <span>The swans of old England</span>
        <span>Are just like you?"</span>
      </p>
      <p>
        <span>"Don‘t tell me!"</span>
        <span>Said a cross old bird;</span>
        <span>"I know better,</span>
        <span>The thing‘s quite absurd.</span>
      </p>
      <p>
        <span>Their figures, I‘m sure,</span>
        <span>Are not worth a glance:</span>
        <span>If you want to see style,</span>
        <span>You <em>must</em> come to France."</span>
      </p>
      <p>
        <span>With a scornful whisk</span>
        <span>The swan turned tail,</span>
        <span>Spread its wings to the breeze</span>
        <span>And was off full-sail.</span>
      </p>
      <p>
        <span>"Ho! pretty swan,</span>
        <span>Do you know, in our Zoo‘</span>
        <span>The swans are not half</span>
        <span>So conceited as you?"</span>
      </p>
    </div>
  </body>
</html>

这里未指定任何图像。为了简化响应式设计,会在 CSS 中提供图像。许多响应式 Web 开发均倡导 “移动优先” 的战略,但首先使用桌面或者平板电脑的屏幕尺寸应该更容易调整印刷内容。就本例而言,我们假设默认视图是大尺寸屏幕。清单 13 展示了 CSS,图 4 展示了制作完成的电子书在 Apple iPad 的 iBooks 中的显示效果。

清单 13. 用于平板电脑屏幕版式的 CSS
 @namespace epub "http://www.idpf.org/2007/ops";

body {
    font-family: Georgia, serif;
    margin: 0;
    padding: 0;
}

/* Select the entire <div epub:type> and apply the background 
   images at various positions relative to the text. */

div[epub|type="chapter"] {
    background-image: url(‘childrens-book-swans.jpg‘),
                      url(‘childrens-book-flowers.jpg‘);
    background-position: 100% 50%, bottom center;
    background-size: 50% auto, auto auto;
    background-repeat: no-repeat, repeat-x;
    background-color: #fdefc2;

    padding: 2em;
}

p {
    font-size: .75em;
    text-align: left;
}

p:last-child {
    padding-bottom: 2em;
}

h1 {
    margin-top: 0;
    text-transform: uppercase;
    font-weight: 200;
}

p > span {
    display: block;
}

/* Use the CSS Selector module to apply rule-based formatting to the 
   poetry content, generating alternating rows of indented text. */

p > span:nth-child(even) {
    text-indent: 1em;
}

示例使用了 CSS 名称空间模块中的 @namespace 语法。CSS 名称空间允许样式化以名称空间为前缀的元素和属性。尽管在 EPUB 3 中不必使用 CSS 名称空间,但应用 EPUB 语义拐点来为这些元素附加样式(@epub:type 属性)更加便捷,不必仅为样式创建独立的类。HTML 文档必须 使用 .xhtml 扩展名,只有这样大多数浏览器才能正确处理 CSS 名称空间。

图 4. Abroad 一书中的页面,在平板电脑屏幕上的显示效果
技术分享

图 4 的版式使用正确对齐的图像和宽大的装饰边框,很好地展现了原始页面。然而,这种排版并不适合纵向移动设备,因为这种设备的屏幕宽度不足以显示图像和文本。移动设备的典型宽度是 480 像素左右,您可以覆盖某些元素,如 清单 14 所示。利用 清单 14 中的 CSS:

  • 天鹅的图像将缩小,改为居中,并在文本之前显示。页面底部的装饰图像也将缩小,以免抢占了诗歌内容的空间。
  • 标题会缩小并居中对齐。
  • 诗歌文本会更加居中,而非靠左对齐。
清单 14. 适用于纵向手机屏幕版式的 CSS
 @media screen and (max-width:480px) { 

    div[epub|type="chapter"] {
        background-position: top center, bottom center;
        background-size: 30% auto, 50% auto;

        padding: 1em;
        margin: auto;
        text-align: center;
    }

    h1 {
        margin: 50% auto 0 0;
        font-size: 1em;
        text-align: center;
    }

    p {
        margin-left: 25%;
    }
}

上面的指令与之前的 CSS 一致,仅需覆盖新版式中值发生了变化的属性。图 5 展示了输出结果,内容分布到了两个页面中。

图 5. Abroad 一书中的页面在手机屏幕上的显示效果
技术分享

窄型显示在纵向版式中效果良好,但这样一首短诗可以更轻松地在横向页面中展示。您可以添加一个最终媒体查询,允许横向设备以多列形式显示这首诗。这项特性是 CSS 文本模块的一部分,也是 EPUB 3 CSS 支持的核心组成部分。横向手机屏幕版式的 CSS 如 清单 15 所示。

清单 15. 适用于横向手机屏幕版式的 CSS
@media screen and (orientation:landscape and max-width:480px) { 
    div[epub|type="chapter"] {
        background-position: 97% 40%, bottom center;
        background-size: 20% auto, 50% auto;

        /* For now we are required to use the vendor-prefixed versions in most browsers */
        -webkit-column-count: 2;
        -moz-column-count: 2;
        column-count: 2;

        -webkit-column-gap: 0;
        -moz-column-count: 0;
        column-gap: 0;

        padding: 2em 4em 5em 4em;
    }
}

图 6 展示了所呈现的输出结果。

图 6. Abroad 一书中的页面在横向手机屏幕上的显示效果
技术分享
 

在出版物中包含 MathML

在 EPUB 2 中,出版物可能包含采用光栅图像或 SVG 格式的数学内容。尽管 SVG 数学内容能生成极富吸引力的输出结果,但对于屏幕阅读器来说,这些内容很难处理,编写也非常困难。光栅图的情况更糟,它们的可访问性更差,而且在不同的字体和屏幕尺寸间缩放的能力也更差。

EPUB 3 将 MathML 作为原生 EPUB 内容类型。可以在不转为另外一种类型的前提下提供 MathML 标记,例如光栅图像。EPUB 3 阅读器必须在大多数情况下支持 MathML 显示。

尽管 MathML 是一种核心内容类型,但您必须在 OPF 文件中声明哪些 XHTML 页面包含 MathML,如 清单 16 所示。

清单 16. 在 OPF 文件中声明 MathML 内容
   <manifest>
    <item href="mathml-style.css" id="css1" media-type="text/css"/>
    <item href="mathml.xhtml" properties="mathml" 
             id="page1" media-type="application/xhtml+xml"/>
    <item href="toc.ncx" id="ncx" media-type="application/x-dtbncx+xml"/>
    <item id="toc" properties="nav" 
             href="toc.xhtml" media-type="application/xhtml+xml"/>
  </manifest>

清单 17 展示了一个简单的等式。尽管某些 Web 浏览器现在支持 HTML5 上下文(无名称空间)中的 MathML,但 EPUB 3 要求在http://www.w3.org/1998/Math/MathML 的正确名称空间中声明 MathML 内容。

清单 17. EPUB 3 内容文档中的 MathML
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:epub="http://www.idpf.org/2007/ops" 
      xmlns:m="http://www.w3.org/1998/Math/MathML">
  <head>
    <title>Example of MathML in EPUB 3</title>
    <link rel="stylesheet" type="text/css" href="mathml-style.css" />
  </head>
  <body>

    <m:math display="block">
      <m:mrow>
        <m:mi>x</m:mi>
        <m:mo>=</m:mo>
        <m:mfrac>
          <m:mrow>
            <m:mo form="prefix">-</m:mo>
            <m:mi>b</m:mi>
            <m:mo>±</m:mo>
            <m:msqrt>
              <m:msup>
                <m:mi>b</m:mi>
                <m:mn>2</m:mn>
              </m:msup>
              <m:mo>-</m:mo>
              <m:mn>4</m:mn>
              <m:mo>?</m:mo>
              <m:mi>a</m:mi>
              <m:mo>?</m:mo>
              <m:mi>c</m:mi>
            </m:msqrt>
          </m:mrow>
          <m:mrow>
            <m:mn>2</m:mn>
            <m:mo>?</m:mo>
            <m:mi>a</m:mi>
          </m:mrow>
        </m:mfrac>
      </m:mrow>
    </m:math>              
  </body>
</html>

图 7 展示了 iBooks 中的输出结果。您可能需要嵌入一种包含恰当数学符号的字体,以便正确呈现所有等式类型。有关用于科学出版物的 STIX 字体的信息,请参阅 参考资料 部分。

图 7. EPUB 3 中呈现的简单数学等式
技术分享

许多输出 MathML 的系统都可以使用 MathML 1.0 DTD 中的命名实体,如 &PlusMinus;。您需要将这些实体转为数字实体,然后才能将其包含在 EPUB 3 出版物之中。由于它们属于外部 DTD(尽管是核心内容类型),因此不应包含在 EPUB 存档中。

 

进一步探索的主题

EPUB 3 提供了多种开发先进的原生数字出版物的选项。您可能还希望查看以下主题。

  • 对互动式图书使用与 JavaScript 搭配使用的 HTML5 canvas
  • 如果您对语义 Web 感兴趣,那么可以自行熟悉 EPUB 3 结构化语义词汇表中的语义拐点选项。
  • HTML5 语义和可访问的富 Internet 应用程序套件 (WAI-ARIA) 角色提供了一种极有吸引力的方法,允许您丰富内容,在辅助设备或机器学习算法时使用这些内容。

EPUB 3 仍在积极扩展。未来的修订版中很可能整合来自新 CSS 模块的特性,如 CSS 域。

 

下载

描述名字大小
用于 NCX 转换的 XSLT 和样例文件 ncx-to-end.zip 5KB
一个演示了高级 CSS3 布局的样例 EPUB 3 childrens-book-epub.zip 139KB
一个演示了 MathML 的样例 EPUB 3 mathml-epub.zip 3KB

参考资料

学习

获得产品和技术

  • EpubCheck:下载最新版本的验证工具,此工具可以与 EPUB 2 和 EPUB 3 文档一起使用。
  • nend:获得完整的 XSLT 和 Python 工具套件,以便将 NCX 文件转为 END。
  • STIX 字体:使用为科学和工程社区提供服务的完整字体集。
  • IBM 产品评估试用版软件:下载或 IBM SOA 人员沙箱,开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。

讨论

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。