EPUB3 文件结构

我没有阅读 EPUB3 标准文档,所以这里的文字只是根据网上的文章总结的一个可行结构。

│  mimetype
├─EPUB
│  │  package.opf
│  ├─images
│  │      cover.png
│  ├─styles
│  │      main.css
│  └─text
│          cover.xhtml
│          nav.xhtml
│          简介.xhtml
└─META-INF
        container.xml

接下来根据文件结构解释文件作用和内容。

mimetype

这个文件位于根目录,指定文件格式,内容固定为:application/epub+zip

META-INF

这个文件夹是存放文件信息的,只有一个文件:container.xml:

<?xml version="1.0"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
    <rootfiles>
        <rootfile full-path="EPUB/package.opf"
            media-type="application/oebps-package+xml" />
    </rootfiles>
</container>

EPUB

书籍的内容都在这个文件夹里。

package.opf

书籍的元信息、文件清单、阅读顺序等都在 package.opf 文件里。这个文件名称和 container.xml 里的 rootfile 对应。当然,文件可以不叫这个名字,只要是 opf 文件就可以。

<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="uid" xml:lang="en-US" prefix="cc: http://creativecommons.org/ns#">
    <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
        <dc:identifier id="uid">5159da60</dc:identifier>
        <dc:title>文昌孝经</dc:title>
        <dc:creator>sharebook.top</dc:creator>
        <!-- <dc:language></dc:language> -->
        <dc:date>2023-09-28 21:31:23</dc:date>
        <meta property="dcterms:modified">2023-09-28 21:31:23</meta>
        <meta name="cover" content="cover" />
    </metadata>
    <manifest>
        <item id="简介" href="text/简介.xhtml" media-type="application/xhtml+xml" />
        <item id="cover-page" href="text/cover.xhtml" properties="nav" media-type="application/xhtml+xml" />
        <item id="nav" href="text/nav.xhtml" properties="nav" media-type="application/xhtml+xml" />
        <item id="cover" href="images/cover.png" media-type="image/png" properties="cover-image" />
        <item id="css" href="styles/main.css" media-type="text/css" />
    </manifest>
    <spine toc="ncx">
        <itemref idref="cover-page" />
        <itemref idref="nav" />
        <itemref idref="简介" />
    </spine>
    <guide>
        <reference type="toc" href="text/nav.xhtml" />
    </guide>
</package>

上面的代码就是 opf 文件里的大致内容。

metadata 标签里的内容就是元数据,唯一标识、标题、创建人、日期之类的。需要注意的是 name 为 cover 的这个标签,这个标签的作用是指明文件的封面,这样阅读器应用可以据此显示缩略图。标签的 content 对应的不是路径,而是 manifest 里文件的 id。

manifest 部分是书籍内容的文件清单,包括样式、图片、各个页面等。

spine 部分是书籍的阅读顺序,比如示例代码里面从封面开始,然后导航,接着是简介。

guide 指定文件的页面,和 spine 作用差不多,阅读器据此显示目录。

内容

书籍的内容文件是 xhtml,以 nav.xhtml 为例:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>

<html
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:epub="http://www.idpf.org/2007/ops"
>
  <head>
    <title>文昌孝经</title>
    <link
      rel="stylesheet"
      type="text/css"
      href="../styles/main.css"
    />
  </head>

  <body>
    <div>
      <div><h1>文昌孝经</h1></div>
    </div>

    <nav
      epub:type="toc"
      id="toc"
    >
      <ol>
        <li>
          <a href="简介.xhtml">简介</a>
        </li>
      </ol>
    </nav>
  </body>
</html>

其内容基本就是 HTML,只不过多了些属性。比如 nav 标签多了 epub:type=”toc”。

然后有一个需要注意的是文件的引用路径需要是相对路径。我试过绝对路径,无法正确解析。

其他

在前端实现的时候,我还发现一个 jszip 的注意事项——添加 base64 图片的时候,需要将前导标识去掉。比如 data:image/png;base64, ,这几个字符是浏览器 dataurl 标识,不是 base64 的内容。