狼愛上貍

          我胡漢三又回來了

          使用 EPUB 制作數(shù)字圖書 基于 XML 的開放式 eBook 格式

          /////////////////////////////////////////////////////////////////////////////////////////////Page1

          簡介:  是否需要分發(fā)文檔、創(chuàng)建電子圖書或者把喜歡的博客文章存檔?EPUB 是一種開放式的數(shù)字圖書規(guī)范,以常用的技術(shù)如 XML、CSS 和 XHTML 為基礎(chǔ),EPUB 文件可在便攜式的 e-ink 設(shè)備、移動電話和桌面計算機上閱讀。本教程詳細闡述了 EPUB 格式,首先用 Java™ 技術(shù)示范了 EPUB 驗證,然后詳細說明如何使用 DocBook 和 Python 自動創(chuàng)建 EPUB。

          開始之前

          本教程講述如何創(chuàng)建 EPUB 格式的電子圖書。EPUB 是一種基于 XML 的、對開發(fā)者友好的格式,正逐漸成為數(shù)字圖書的事實標準。但 EPUB 不僅可用于圖書,還包括:

          • 對文檔打包以便離線閱讀或者分發(fā)
          • 打包博客文章或者其他 Web 內(nèi)容
          • 使用常見的開放源代碼工具創(chuàng)建、搜索和整理

          關(guān)于本教程

          常用的縮寫詞

          • API:應(yīng)用程序編程接口(application programming interface)
          • CSS:級聯(lián)樣式表(Cascading stylesheet)
          • DOM:文檔對象模型(Document Object Model)
          • DTD:文檔類型定義(Document type definition)
          • GUI:圖形用戶界面(Graphical user interface)
          • HTML:超文本標記語言(Hypertext Markup Language)
          • SAX:XML 簡易 API(Simple API For XML)
          • W3C:萬維網(wǎng)聯(lián)盟(World Wide Web Consortium)
          • XHTML:可擴展的 HTML(Extensible HTML)
          • XML:可擴展標記語言

          本教程首先手工創(chuàng)建一個 EPUB 圖書,幫助您了解其構(gòu)成和需要的文件。然后說明如何捆綁完成的數(shù)字圖書,按照規(guī)范進行驗證以及在不同的閱讀系統(tǒng)上測試。

          然后討論如何從 DocBook XML 生成 EPUB — 最常用的技術(shù)文檔標準之一 — 以及如何使用 Python 實現(xiàn)從 DocBook 到 EPUB 的自動創(chuàng)建。

          目標

          通過本教程可以學(xué)習(xí)如下內(nèi)容:

          • 了解 EPUB 是什么,誰支持它,誰采用它
          • 了解 EPUB 包的結(jié)構(gòu),包括需要的文件及其模式
          • 如何從頭創(chuàng)建一個內(nèi)容簡單而有效的 EPUB 文件
          • 使用開放源代碼工具從 DocBook 生成 EPUB 文件,DocBook 是一種常見的技術(shù)文檔和圖書模式
          • 使用 Python 和 DocBook 自動轉(zhuǎn)換成 EPUB

          先決條件

          本教程對操作系統(tǒng)沒有特殊要求,但是應(yīng)該熟悉創(chuàng)建文件和目錄的機制。建議使用 XML 編輯器或者集成開發(fā)環(huán)境(IDE)。

          對于本教程后半部分的 EPUB 創(chuàng)建自動化內(nèi)容,需要讀者了解基本的 XML 處理技巧 — XSLT、 DOM 或者基于 SAX 的解析 — 并熟悉使用 XML 原生 API 構(gòu)造 XML 文檔。

          閱讀本教程不需要熟悉 EPUB 文件格式。

          系統(tǒng)需求

          嘗試本教程中的例子,需要一個 Java 解釋器(1.5 或更高版本)和 Python 解釋器(2.4 或更高版本)以及相應(yīng)的 XML 庫。不過,有經(jīng)驗的 XML 開發(fā)人員很容易將這些例子修改為適合任何編程語言和 XML 庫。

           

           /////////////////////////////////////////////////////////////////////////////////////////////Page2

          關(guān)于 EPUB 格式

          了解 EPUB 的背景,EPUB 最適合做什么,以及 EPUB 和便攜式文檔格式(PDF)的區(qū)別。

          什么是 EPUB?

          EPUB 是可逆的數(shù)字圖書和出版物 XML 格式,數(shù)字出版業(yè)商業(yè)和標準協(xié)會 International Digital Publishing Forum (IDPF) 制定的標準。IDPF 于 2007 年 10 月正式采用 EPUB,隨后被主流出版商迅速采用。可以使用各種開放源代碼或者商業(yè)軟件在所有主流操作系統(tǒng)、Sony PRS 之類的 e-ink 設(shè)備或者 Apple iPhone 之類的小型設(shè)備上閱讀 EPUB 格式。

          誰在使用 EPUB?只能用于圖書嗎?

          雖然最早采用 EPUB 的是傳統(tǒng)的印刷品出版商,但是這并不妨礙它在電子圖書中的應(yīng)用。利用免費的軟件工具,可以將網(wǎng)頁捆綁成 EPUB,轉(zhuǎn)化成文本文件或者將原有的 DocBook XML 文檔轉(zhuǎn)化成結(jié)構(gòu)良好的、有效的 EPUB(后一點將在 從 DocBook 到 EPUB 一節(jié)討論)。

          EPUB 與 PDF 有什么不同?

          PDF 仍然是世界上應(yīng)用最廣泛的電子文檔格式。從圖書出版商的角度來看,PDF 的優(yōu)點包括:

          • PDF 文件允許對頁面布局進行像素級的控制,包括復(fù)雜的打印格式,如多欄格式和奇偶頁相間的格式。
          • 有多種不同的 GUI 文檔工具可生成 PDF,如 Microsoft® Office Word 和 Adobe® InDesign®。
          • PDF 閱讀器非常普及,現(xiàn)在大多數(shù)計算機上都有安裝。
          • PDF 可以嵌入特殊的字體,精確控制最終的輸出結(jié)果。

          三合一的標準

          EPUB 包括三個單獨的 IDPF 規(guī)范,雖然實際上將其統(tǒng)稱為 EPUB 更保險:

          • Open eBook Publication Structure Container Format (OCF):定義了 EPUB 檔案的目錄樹結(jié)構(gòu)和文件結(jié)構(gòu)(ZIP)。
          • Open Publication Structure (OPS):定義了電子圖書的公共詞匯表,特別是可作為圖書內(nèi)容的格式(比如 XHTML 和 CSS)。
          • Open Packaging Format (OPF):描述了 EPUB 必須的和可選的元數(shù)據(jù)、閱讀順序和目錄。

          此外,對于檔案中的特定類型的內(nèi)容,EPUB 還重用了其他一些標準,如 XHTML 1.0 和 Digital Accessible Information SYstem (DAISY)。

          從軟件開發(fā)人員的角度來看,PDF 還遠遠不夠理想:

          • 這不是一種簡單易學(xué)的標準,因此編寫自己的 PDF 生成代碼非常困難。
          • 雖然 PDF 現(xiàn)在是一種 International Organization for Standardization(ISO)標準(ISO 32000-1:2008),但過去一直受一家公司的控制:Adobe Systems。
          • 盡管多數(shù)編程語言都提供了 PDF 庫,但很多是商業(yè)產(chǎn)品或者嵌入到 GUI 應(yīng)用程序中,外部進程不容易控制。并非所有的免費庫都得到積極的維護。
          • PDF 原生文本可以通過程序提取出來并進行搜索,但很少可以對 PDF 進行標記以便簡單可靠地轉(zhuǎn)化成 Web 友好的格式。
          • PDF 文檔不容易流動,就是說很難適應(yīng)小屏幕或者對布局進行明顯的改變。

          為何說 EPUB 對開發(fā)人員是友好的

          EPUB 解決了 PDF 和開發(fā)人員友好性有關(guān)的所有瑕疵。一個 EPUB 就是一個簡單 ZIP 格式文件(使用 .epub 擴展名),其中包括按照預(yù)先定義的方式排列的文件。如何制作 ZIP 文檔有一些技巧,稍后將在 將 EPUB 文件捆綁為 ZIP 文檔 一節(jié)介紹。除此以外,EPUB 非常簡單:

          • EPUB 中的所有內(nèi)容基本上都是 XML。EPUB 文件可使用標準 XML 工具創(chuàng)建,不需要任何專門或者私有的軟件。
          • EPUB 內(nèi)容(eBook 的具體內(nèi)容)基本上都是 XHTML 1.1(另一種格式是 DTBook,為視力受限者編碼書籍的一種標準。關(guān)于 DTBook 的更多信息請參閱參考資料,本教程中不涉及這部分)。
          • 大多數(shù) EPUB XML 模式都來自現(xiàn)成的、可免費獲得的、已發(fā)布的規(guī)范。

          最關(guān)鍵的在于 EPUB 元數(shù)據(jù)是 XMLEPUB 內(nèi)容是 XHTML。如果您的文檔構(gòu)建系統(tǒng)產(chǎn)生的結(jié)果用于 Web 和/或基于 XML,那么也可用于生成 EPUB。

           

           /////////////////////////////////////////////////////////////////////////////////////////////Page3

          創(chuàng)建第一個 EPUB

          最小的 EPUB 包至少要包含幾個文件。規(guī)范對于 EPUB 包中這些文件的格式、內(nèi)容和位置要求可能很嚴格。這一節(jié)討論使用 EPUB 標準必須 了解的基礎(chǔ)知識。

          解剖 EPUB 包

          小型 EPUB 文件的基本結(jié)構(gòu)遵循 清單 1 所示的樣式。準備好分發(fā)之前,整個目錄結(jié)構(gòu)被壓縮到一個 ZIP 格式文件中,幾點特殊要求將在 用 ZIP 打包 EPUB 文件 一節(jié)討論。

          清單 1. 簡單 EPUB 檔案的目錄和文件結(jié)構(gòu)

          					 mimetype META-INF/    container.xml OEBPS/   content.opf   title.html   content.html   stylesheet.css   toc.ncx   images/      cover.png 

          提示:可 下載 符合該結(jié)構(gòu)的一個電子圖書,但建議按照本教程的說明自己創(chuàng)建一個。

          編寫 EPUB 圖書之前首先創(chuàng)建 EPUB 項目的目錄。打開文本編輯器或者 Eclipse 之類的 IDE。建議采用支持 XML 的編輯器 — 具體而言就是能夠根據(jù) 參考資料 給出的 Relax NG 模式進行驗證。


           

          mimetype 文件

          這個文件非常簡單,必須命名為 mimetype,文件內(nèi)容如下:

          application/epub+zip 

          要注意,mimetype 文件不能包含新行或者回車。

          此外,mimetype 文件必須作為 ZIP 檔案中的第一個文件,而且自身不能壓縮。用 ZIP 打包 EPUB 文件 一節(jié)將介紹如何使用一般的 ZIP 參數(shù)將其包含進來。現(xiàn)在創(chuàng)建該文件并保存,并確保它在 EPUB 項目的根目錄中。

          META-INF/container.xml

          EPUB 根目錄下必須包含 META-INF 目錄,而且其中要有一個文件 container.xml。EPUB 閱讀系統(tǒng)首先查看該文件,它指向數(shù)字圖書元數(shù)據(jù)的位置。

          創(chuàng)建目錄 META-INF。在其中創(chuàng)建一個新文件 container.xml。container 文件非常小,但是對結(jié)構(gòu)要求很嚴格。將 清單 2 中的代碼粘貼到 META-INF/container.xml 中。

          清單 2. container.xml 文件

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

          full-path(粗體)的值僅僅是該文件的一部分,不同的文件可能相差甚大。目錄路徑必須相對于 EPUB 文件根目錄本身,而不是 META-INF 目錄。

          關(guān)于 META-INF

          META-INF 目錄還可以包含其他幾個文件。這些文件使 EPUB 支持數(shù)字簽名、加密和數(shù)字版權(quán)管理(DRM)。本教程不討論這些主題。更多信息請參閱 OCF 規(guī)范。

          mimetype 和 container 是 EPUB 檔案中僅有的兩個需要嚴格限制位置的文件。建議(盡管不是必須的)將其他文件保存到 EPUB 的子目錄下(按照慣例,通常被稱為OEBPS,即 Open eBook Publication Structure,但不是必須的)。

          接下來在 EPUB 項目中創(chuàng)建目錄 OEBPS。本教程下一節(jié)將介紹 OEBPS 中的文件 — 數(shù)字圖書的核心:元數(shù)據(jù)和頁面。


          打開 Packaging Format 元數(shù)據(jù)文件

          盡管該文件名沒有特殊要求,但通常被稱為 content.opf。它指定了圖書中所有 內(nèi)容的位置,如文本和圖像等其他媒體。它還給出了另一個元數(shù)據(jù)文件,內(nèi)容的 Navigation Center eXtended (NCX) 表。

          該 OPF 文件是 EPUB 規(guī)范中最復(fù)雜的元數(shù)據(jù)。創(chuàng)建 OEBPS/content.opf 并粘貼 清單 3 所示的內(nèi)容。

          清單 3. 包含示例元數(shù)據(jù)的 OPF content 文件

          					 <?xml version='1.0' encoding='utf-8'?> <package xmlns="http://www.idpf.org/2007/opf"              xmlns:dc="http://purl.org/dc/elements/1.1/"              unique-identifier="bookid" version="2.0">   <metadata>     <dc:title>Hello World: My First EPUB</dc:title>     <dc:creator>My Name</dc:creator>     <dc:identifier id="bookid">urn:uuid:12345</dc:identifier>     <meta name="cover" content="cover-image" />   </metadata>   <manifest>     <item id="ncx" href="toc.ncx" media-type="text/xml"/>     <item id="cover" href="title.html" media-type="application/xhtml+xml"/>     <item id="content" href="content.html" media-type="application/xhtml+xml"/>     <item id="cover-image" href="images/cover.png" media-type="image/png"/>     <item id="css" href="stylesheet.css" media-type="text/css"/>   </manifest>   <spine toc="ncx">     <itemref idref="cover" linear="no"/>     <itemref idref="content"/>   </spine>   <guide>     <reference href="cover.html" type="cover" title="Cover"/>   </guide> </package> 

          OPF 模式與名稱空間

          OPF 文檔本身必須使用名稱空間 http://www.idpf.org/2007/opf,元數(shù)據(jù)則使用 Dublin Core Metadata Initiative (DCMI) 名稱空間http://purl.org/dc/elements/1.1/

          最好現(xiàn)在將 OPF 和 DCMI 模式添加到 XML 編輯器中。EPUB 用到的所有模式都可以 下載。

          元數(shù)據(jù)

          Dublin Core 定義了一組常用的元數(shù)據(jù),可用于描述各種不同的數(shù)字資料,它不是 EPUB 規(guī)范的一部分。所有這些術(shù)語都可以出現(xiàn)在 OPF 元數(shù)據(jù)部分。編寫要分發(fā)的 EPUB 時,這里可以放很多內(nèi)容,目前來說 清單 4 的內(nèi)容就足夠了。

          清單 4. OPF 元數(shù)據(jù)摘要

          					 ... <metadata>   <dc:title>Hello World: My First EPUB</dc:title>   <dc:creator>My Name</dc:creator>   <dc:identifier id="bookid">urn:uuid:12345</dc:identifier>   <meta name="cover" content="cover-image" /> </metadata> ...

          有兩個術(shù)語是必須的,即 title 和 identifier。按照 EPUB 規(guī)范,標識符必須 是惟一的,但是這個惟一的值要靠數(shù)字圖書的創(chuàng)建者來定義。對于圖書出版商來說,這個字段一般包含 ISBN 或者 Library of Congress 編號。對于其他 EPUB 創(chuàng)建者,可以考慮使用 URL 或者很大的隨機生成的惟一用戶 ID(UUID)。要注意,屬性 unique-identifier 的值必須和 dc:identifier 元素的 ID 屬性匹配。

          其他和內(nèi)容相關(guān)的可以考慮添加的元數(shù)據(jù)包括:

          • 語言(如 dc:language)。
          • 出版日期(如 dc:date)。
          • 出版商(如 dc:publisher)。(可以是公司或個人的名稱)。
          • 版權(quán)信息(如 dc:rights)。(如果采用 Creative Commons 許可證,可以將許可證的 URL 放在這里)。

          關(guān)于 DCMI 的更多信息請參閱 參考資料

          EPUB 規(guī)范沒有要求包含 name 屬性值為 cover 的 meta 元素,但為了增加封面和圖像的可移植性,建議這樣做。一些 EPUB 呈現(xiàn)程序喜歡使用圖像文件作為封面,另一些則愿意使用包含內(nèi)聯(lián)封面圖像的 XHTML 文件。該例子顯示了這兩種情況。meta 元素的 content 屬性的值應(yīng)該是圖書封面圖像在 manifest 中的 ID 號,manifest 是 OPF 文件的一部分。

          Manifest

          OPF manifest 列出了 EPUB 內(nèi)容(不包括元數(shù)據(jù))中的所有資源。就是說,通常是組成電子圖書文本的一組 XHTML 文件再加上一些相關(guān)的媒體如圖像。EPUB 鼓勵使用 CSS 設(shè)定圖書內(nèi)容的樣式,因此 manifest 中也包含 CSS。進入數(shù)字圖書的所有文件都必須在 manifest 中列出。

          清單 5 顯示了 manifest 的一部分。

          清單 5. OPF manifest 的一部分

          					 ... <manifest>   <item id="ncx" href="toc.ncx" media-type="text/xml"/>   <item id="cover" href="title.html" media-type="application/xhtml+xml"/>   <item id="content" href="content.html" media-type="application/xhtml+xml"/>   <item id="cover-image" href="images/cover.png" media-type="image/png"/>   <item id="css" href="stylesheet.css" media-type="text/css"/> </manifest> ... 

          高級 OPF manifest

          更高級的 manifest 文件可能包含多個 XHTML 文件以及圖像和 CSS。可 下載 一個完整的包含各種常見類型的 EPUB 例子。

          第一項 toc.ncx(參見 下一節(jié))是必須的。所有的項都有相應(yīng)的 media-type 值,XHTML 內(nèi)容的媒體類型為 application/xhtml+xml。媒體類型必須正確,不能 是 text/html或者其他類型。

          EPUB 支持四種核心 圖像文件類型:Joint Photographic Experts Group (JPEG)、Portable Network Graphics (PNG)、Graphics Interchange Format (GIF) 和 Scalable Vector Graphics (SVG)。如果能夠提供對核心類型的后退轉(zhuǎn)換(fall-back),也可包含不支持的文件類型。關(guān)于后退轉(zhuǎn)換內(nèi)容的更多信息請參閱 OPF 規(guī)范。

          href 屬性的值應(yīng)該是一個相對于該 OPF 文件 的統(tǒng)一資源標識符(URI)。(很容易和 container.xml 中對 OPF 文件的引用混淆,其中的引用是相對于 EPUB 的整體引用)。這里的 OPF 文件位于和內(nèi)容相同的 OEBPS 目錄中,因此不需要路徑信息。

          Spine

          manifest 告訴 EPUB 閱讀器哪些文件屬于檔案,spine 則指定這些文件出現(xiàn)的順序或 — 按照 EPUB 的說法 — 數(shù)字圖書的線性閱讀順序。可以將 OPF spine 看作是書中 “頁面” 的順序。按照文檔順序從上到下依次讀取 spine。清單 6 顯示了 OPF 文件的一個片段。

          清單 6. OPF spine 的一部分

          					 ... <spine toc="ncx">   <itemref idref="cover" linear="no"/>   <itemref idref="content"/> </spine> ... 

          每個 itemref 元素都需要有一個 idref 屬性,并且和 manifest 中的某個 ID 匹配。toc 屬性也是必需的。它引用 manifest 中表示內(nèi)容 NCX 表文件名的 ID。

          spine 中的 linear 屬性表明該項是作為線性閱讀順序中的一項,還是和先后次序無關(guān)。建議將封面定義為 linear=no。符合 EPUB 規(guī)范的閱讀系統(tǒng)將首先打開 spine 中沒有設(shè)置為 linear=no 中的第一項。

          Guide

          OPF 內(nèi)容文件的最后一部分是 guide。這一節(jié)是可選的,但最好保留。清單 7 顯示了 guide 文件的部分內(nèi)容。

          清單 7. OPF guide 的一部分

          					 ... <guide>   <reference href="cover.html" type="cover" title="Cover"/> </guide> ... 

          guide 可以為 EPUB 閱讀系統(tǒng)提供語義信息。manifest 定義了 EPUB 中的物理資源,spine 提供了這些資源的順序信息,guide 負責解釋這些部分的含義。下面是可以出現(xiàn)在 OPF guide 中的部分值:

          • cover圖書封面
          • title-page包含作者和出版商信息的頁面
          • toc目錄

          完整的列表請參閱 OPF 2.0 規(guī)范(參見 參考資料)。


           

          內(nèi)容的 NCX 表

          NCX 和 OPF 元數(shù)據(jù)的交叉

          由于 NCX 源自其他標準,使用 NCX 編碼的信息和 OPF 內(nèi)容之間存在重復(fù)。如果通過程序生成 EPUB,這算不上什么問題,因為同樣的代碼可輸出到兩個文件中。兩個位置的信息要一致,不同的 EPUB 讀者可能使用不同位置的值。

          盡管 OCF 文件是作為 EPUB 本身的一部分定義的,但最后一個主要的元數(shù)據(jù)文件參照了不同的數(shù)字圖書標準。DAISY 是一個專門為不能使用傳統(tǒng)書籍的讀者設(shè)計數(shù)據(jù)格式的組織,通常是因為視力受損或者不便于使用印刷的書籍。EPUB 借用了 DAISY 的 NCX DTD。NCX 定義了數(shù)字圖書的目錄表。復(fù)雜的圖書中,目錄表通常采用層次結(jié)構(gòu),包括嵌套的內(nèi)容、章和節(jié)。

          使用 XML 編輯器創(chuàng)建 OEBPS/toc.ncx 并粘貼 清單 8 所示的代碼。

          清單 8. 簡單的 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">   <head>     <meta name="dtb:uid" content="urn:uuid:12345"/>     <meta name="dtb:depth" content="1"/>     <meta name="dtb:totalPageCount" content="0"/>     <meta name="dtb:maxPageNumber" content="0"/>   </head>   <docTitle>     <text>Hello World: My First EPUB</text>   </docTitle>   <navMap>     <navPoint id="navpoint-1" playOrder="1">       <navLabel>         <text>Book cover</text>       </navLabel>       <content src="title.html"/>     </navPoint>     <navPoint id="navpoint-2" playOrder="2">       <navLabel>         <text>Contents</text>       </navLabel>       <content src="content.html"/>     </navPoint>   </navMap> </ncx> 

          NCX 元數(shù)據(jù)

          DTD 要求 NCX <head> 標記中包含四個 meta 元素:

          • uid 數(shù)字圖書的惟一 ID。該元素應(yīng)該和 OPF 文件中的 dc:identifier對應(yīng)。
          • depth反映目錄表中層次的深度。該例只有一層,因此是 1
          • totalPageCount 和 maxPageNumber僅用于紙質(zhì)圖書,保留 0 即可。

          docTitle/text 的內(nèi)容是圖書的標題,和 OPF 中的 dc:title 匹配。

          NCX navMap

          NCX 和 OPF spine 有什么不同?

          兩者很容易混淆,因為兩個文件都描述了文檔的順序和內(nèi)容。要說明兩者的區(qū)別,最簡單的辦法就是拿印刷書來打比方:OPF spine 描述了書中的各個章節(jié)是如何實際連接起來的,比方說翻過第一章的最后一頁就看到第二章的第一頁。NCX 在圖書的一開始描述了目錄。目錄肯定會包含書中主要的章節(jié),但是還可能包含沒有單獨分頁的小節(jié)。

          一條法則是 NCX 包含的 navPoint 元素通常比 OPF spine 中的 itemref 元素多。實際上,spine 中的所有項都會出現(xiàn)在 NCX 中,但 NCX 可能更詳細。

          navMap 是 NCX 文件中最重要的部分,定義了圖書的目錄。navMap 包含一個或多個 navPoint 元素。每個 navPoint 都要包含下列元素:

          • playOrder 屬性,說明文檔的閱讀順序。和 OPF spine 中 itemref元素的順序相同。
          • navLabel/text元素,給出該章節(jié)的標題。通常是章的標題或者數(shù)字,如 “第一章”,或者 — 像這個例子一樣 — “封面”。
          • content 元素,它的 src 屬性指向包含這些內(nèi)容的物理資源。就是 OPF manifest 中聲明的文件(也可使用片段標識符引用 XHTML 內(nèi)容中的錨元素 — 比如content.html#footnote1)。
          • 還可以有一個或多個 navPoint 元素。NCX 使用嵌套的導(dǎo)航點表示層次結(jié)構(gòu)的文檔。

          該文檔的結(jié)構(gòu)非常簡單:只有兩頁,不存在嵌套關(guān)系。就是說有兩個 navPoint 元素,它們的 playOrder 值按升序排列,從 1 開始。在 NCX 中可以命名這些章節(jié),以便讀者跳到電子圖書不同的部分。


           

          添加最后的內(nèi)容

          現(xiàn)在知道了 EPUB 需要的所有元數(shù)據(jù),可以加入真正的圖書內(nèi)容了。可以使用 下載 的內(nèi)容,也可以自己寫,只要文件名和元數(shù)據(jù)匹配即可。

          然后創(chuàng)建下列文件和文件夾:

          • title.html:圖書的標題頁。創(chuàng)建該文件并在其中包含引用封面圖片的 img 元素,src 的屬性值為 images/cover.png
          • images:在 OEBPS 下創(chuàng)建該文件夾,然后復(fù)制給定的示例圖片(或者創(chuàng)建自己的圖片)并命名為 cover.png
          • content.html:圖書的實際文字內(nèi)容。
          • stylesheet.css:將該文件放在和 XHTML 文件相同的 OEBPS 目錄中。該文件可以包含任意 CSS 聲明,比如設(shè)置字體或者文字顏色。清單 10 給出了一個 CSS 文件的例子。

          EPUB 圖書中的 XHTML 和 CSS

          清單 9 包含了一個有效的 EPUB 內(nèi)容頁。將其作為標題頁(title.html),用一個類似的頁面作為主要內(nèi)容頁(content.html)。

          清單 9. 示例 title 頁面(title.html)

          					 <html xmlns="http://www.w3.org/1999/xhtml">   <head>     <title>Hello World: My First EPUB</title>     <link type="text/css" rel="stylesheet" href="stylesheet.css" />   </head>   <body>     <h1>Hello World: My First EPUB</h1>     <div><img src="images/cover.png" alt="Title page"/></div>   </body> </html> 

          EPUB 的 XHTML 需要符合幾條要求,和一般的 Web 開發(fā)不同:

          • 內(nèi)容必須是有效的 XHTML 1.1:XHTML 1.0 Strict 和 XHTML 1.1 的主要區(qū)別是去掉了 name屬性(使用 ID 引用錨元素)。
          • img 元素只能引用電子圖書的本地圖片:該元素不能引用 Web 上的圖片。
          • 避免使用 script:EPUB 閱讀器不一定支持 JavaScript 代碼。

          EPUB 支持 CSS 的方式有一些細微的差別,但是不會影響樣式表的一般用法(詳情參閱 OPS 規(guī)范)。清單 10 中的簡單 CSS 文件可以設(shè)置基本的字體,并把標題設(shè)為紅色。

          清單 10. 電子圖書的示例樣式表(stylesheet.css)

          					 body {   font-family: sans-serif;      } h1,h2,h3,h4 {   font-family: serif;        color: red; }

          有趣的是,EPUB 非常支持 CSS 2 @font-face 規(guī)則,允許內(nèi)嵌字體。如果創(chuàng)建技術(shù)文檔,這點可能無關(guān)緊要,但是如果用多種語言或針對特定領(lǐng)域編寫 EPUB,能夠指定具體的字體數(shù)據(jù)就很有必要了。

          現(xiàn)在已經(jīng)準備好了創(chuàng)建 EPUB 圖書所需的所有內(nèi)容。下一節(jié)將按照 OCF 規(guī)范將圖書裝訂起來,并看看如何進行驗證。

           

           /////////////////////////////////////////////////////////////////////////////////////////////Page4

          打包和檢查 EPUB

          現(xiàn)在,應(yīng)當可以對 EPUB 包進行打包。這個包可以是您自己創(chuàng)建的一本新書,也可使用從本文 下載 部分獲得的原始文件。

          用 ZIP 打包 EPUB 文件

          EPUB 規(guī)范的 OEBPS Container Format 討論了 EPUB 和 ZIP,最重要的幾點是:

          • 檔案中的第一個文件必須是 mimetype 文件(參見本教程 Mimetype一節(jié))。mimetype 文件不能被壓縮。這樣非 ZIP 工具就能從 EPUB 包的第 30 個字節(jié)開始讀取原始字節(jié),從而發(fā)現(xiàn) mimetype。
          • ZIP 檔案不能加密。EPUB 支持加密,但不是在 ZIP 文件這一層上。

          在類 UNIX® 操作系統(tǒng)上,使用 ZIP 2.3 可通過兩個命令來創(chuàng)建 EPUB ZIP 文件,如 清單 11 所示(這些命令假設(shè)當前工作目錄為 EPUB 項目。)

          清單 11. 將 EPUB 打包成有效的 epub+zip 文件

          					 $ zip -0Xq  my-book.epub mimetype $ zip -Xr9Dq my-book.epub * 

          第一個命令創(chuàng)建了一個新的 ZIP 檔案,并添加了沒有進行壓縮的 mimetype 文件。第二個命令添加其他內(nèi)容。選項 -X 和 -D 最大限度地減少 .zip 文件中無關(guān)緊要的信息;-r遞歸地包含 META-INF 和 OEBPS 目錄的內(nèi)容。


           

          EPUB 驗證

          雖然 EPUB 標準并不很難,但其 XML 文件必須符合特定的模式。如果使用模式感知的 XML 編輯器生成元數(shù)據(jù)和 XHTML,就能事半功倍。對 EpubCheck 包進行最后檢查(參見 參考資料)。

          Adobe 負責維護 EpubCheck 包,它是采用 Berkeley Software Distribution (BSD) 許可證的開源項目。它是一個可以作為獨立工具、Web 應(yīng)用程序運行的 Java 程序,或者可以將它集成到在 Java Runtime Environment (JRE) 1.5 或更高版本下運行的應(yīng)用程序中。

          在命令行中運行非常簡單。清單 12 給出了一個例子。

          清單 12. 運行 EpubCheck 工具程序

          					 $ java -jar /path/to/epubcheck.jar my-book.epub 

          如果沒有創(chuàng)建輔助文件或者元數(shù)據(jù)文件出錯,可能會看到 清單 13 所示的錯誤消息。

          清單 13. EpubCheck 錯誤

          					 my-book.epub: image file OEBPS/images/cover.png is missing my-book.epub: resource OEBPS/stylesheet.css is missing my-book.epub/OEBPS/title.html(7): 'OEBPS/images/cover.png':       referenced resource missing in the package  Check finished with warnings or errors! 

          這時候可能需要設(shè)置 CLASSPATH 使它指向 EpubCheck 的安裝位置,因為確實需要導(dǎo)入幾個外部庫。如果得到這樣的消息則需要設(shè)置 CLASSPATH:

          org.xml.sax.SAXParseException: no implementation available for schema language     with namespace URI "http://www.ascc.net/xml/schematron" 

          如果驗證成功,就會看到 “No errors or warnings detected(沒有檢測到錯誤或警告)”。祝賀您完成了第一個 EPUB!


          查看 EPUB

          測試不僅僅是驗證,還要保證書的外觀看起來不錯。樣式表能正確工作嗎?章節(jié)的邏輯順序是否正確?書中是否包含了所有需要的內(nèi)容?

          有多重 EPUB 閱讀器可供選擇。圖 1 顯示了 Adobe Digital Editions (ADE) 的屏幕截圖,這是最常用的 EPUB 閱讀器。

          圖 1. ADE 中顯示的 EPUB

           

          字體顏色和圖像都顯示出來了,不錯。ADE 未能用 sans-serif 字體正確地顯示標題,不過這可能是 CSS 的問題。這時候最好換一個閱讀器試試。圖 2 是用我自己編寫的、開放源代碼的、基于 Web 的 EPUB 閱讀器 Bookworm 顯示的同一本書。

          圖 2. 在 Bookworm 中顯示 EPUB

          這里的問題在于 ADE 不支持這種特殊聲明。如果數(shù)字圖書的格式非常重要,那么就必須了解不同閱讀軟件的特點。

          前面我們費了很大力氣手工創(chuàng)建了一個簡單的 EPUB,現(xiàn)在看看如何將一種常見的 XML 文檔 DocBook 轉(zhuǎn)換成 EPUB。

           

          /////////////////////////////////////////////////////////////////////////////////////////////Page5

          從 DocBook 到 EPUB

          DocBook 是需要維護大型技術(shù)文檔的開發(fā)人員常用的選擇。與傳統(tǒng)字處理程序生成的文件不同,可以使用基于文本的版本控制系統(tǒng)管理 DocBook 輸出。由于 DocBook 是 XML,很容易將其轉(zhuǎn)換成不同輸出格式。2008 年夏天出現(xiàn)了正式的 DocBook XSL 項目,將 EPUB 作為一種輸出格式。

          使用 XSLT 運行 DocBook-to-EPUB 管道

          從一個簡單 DocBook 文檔開始,如 清單 14 所示。該文檔的類型為 book,包括前言、兩個章節(jié)以及標題頁面中內(nèi)聯(lián)顯示的圖像。圖像和 DocBook 源文件的目錄相同。可以自己創(chuàng)建該文件和標題頁,也可 下載 本文提供的例子。

          清單 14. 簡單的 DocBook 圖書

          					 <?xml version="1.0" encoding="utf-8"?`>   <book>   <bookinfo>     <title>My EPUB book</title>     <author><firstname>Liza</firstname>             <surname>Daly</surname></author>     <volumenum>1234</volumenum>   </bookinfo>   <preface id="preface">       <title>Title page</title>     <figure id="cover-image">       <title>Our EPUB cover image icon</title>       <graphic fileref="cover.png"/>     </figure>   </preface>   <chapter id="chapter1">      <title>This is a pretty simple DocBook example</title>     <para>       Not much to see here.      </para>   </chapter>   <chapter id="end-notes">      <title>End notes</title>     <para>       This space intentionally left blank.     </para>   </chapter> </book> 

          然后從 參考資料 下載最新版本的 DocBook XSL 樣式表,并安裝 xsltproc 或 Saxon 之類的 XSLT 處理程序。本文使用 xsltproc,大多數(shù)類 UNIX 系統(tǒng)上都能找到。轉(zhuǎn)換 DocBook 文件,只需要用 DocBook XSL 中包含的 EPUB 模塊運行該文件即可,如 清單 15 所示。

          清單 15. 將 DocBook 轉(zhuǎn)化成 EPUB

          					 $ xsltproc /path/to/docbook-xsl-1.74.0/epub/docbook.xsl docbook.xml Writing OEBPS/bk01-toc.html for book Writing OEBPS/pr01.html for preface(preface) Writing OEBPS/ch01.html for chapter(chapter1) Writing OEBPS/ch02.html for chapter(end-notes) Writing OEBPS/index.html for book Writing OEBPS/toc.ncx Writing OEBPS/content.opf Writing META-INF/container.xml 

          定制 DocBook XSL

          DocBook-to-EPUB 轉(zhuǎn)換管道仍然比較新,可能需要定制 XSLT 以得到需要的結(jié)果。

          然后添加 mimetype 文件并建立 epub+zip 檔案。清單 16 顯示了這三個命令和通過 EpubCheck 驗證程序的結(jié)果。

          清單 16. 從 DocBook 創(chuàng)建 EPUB 檔案

          					 $ echo "application/epub+zip" > mimetype $ zip -0Xq  my-book.epub mimetype $ zip -Xr9D my-book.epub * $ java -jar epubcheck.jar my-book.epub  No errors or warnings detected 

          太簡單了!圖 3 顯示了 ADE 中的結(jié)果。

          圖 3. ADE 顯示了從 DocBook 轉(zhuǎn)化得到的 EPUB

           


          利用 Python 和 lxml 實現(xiàn) DocBook-to-EPUB 轉(zhuǎn)換自動化

          DocBook XSL 大大降低了生成 EPUB 的復(fù)雜性,但是在 XSLT 之外還有幾個步驟要執(zhí)行。最后一節(jié)給出的 Python 示例程序能夠生成有效的 EPUB 包。本教程顯示了不同的方法,可 下載 完整的 docbook2epub.py 程序。

          可使用不同的 Python XSLT 庫,我喜歡 lxml。它不但提供了 XSLT 1.0 必要的功能,而且解析效率高,完全支持 XPath 1.0,提供了專門處理 HTML 的擴展。如果喜歡不同的庫或者使用 Python 以外的編程語言,修改這些例子也很簡單。

          用 lxml 調(diào)用 DocBook XSL

          使用 lxml 調(diào)用 XSLT 的最有效辦法是事先解析 XSLT,然后創(chuàng)建反復(fù)使用的轉(zhuǎn)換器。這樣很方便,因為我的 DocBook-to-EPUB 需要轉(zhuǎn)換多個 DocBook 文件。如 清單 17所示。

          清單 17. 使用 lxml 運行 DocBook XSL

          					 import os.path from lxml import etree  def convert_docbook(docbook_file):     docbook_xsl = os.path.abspath('docbook-xsl/epub/docbook.xsl')     # Give the XSLT processor the ability to create new directories     xslt_ac = etree.XSLTAccessControl(read_file=True,                                        write_file=True,                                        create_dir=True,                                        read_network=True,                                        write_network=False)     transform = etree.XSLT(etree.parse(docbook_xsl), access_control=xslt_ac)     transform(etree.parse(docbook_file)) 

          DocBook XSL 中的 EPUB 模塊創(chuàng)建輸出文件本身,因此轉(zhuǎn)換過程什么也不返回。相反,DocBook 在當前工作目錄中創(chuàng)建了兩個文件夾(META-INF 和 OEBPS),包含轉(zhuǎn)換的結(jié)果。

          將圖片和其他資源復(fù)制到檔案中

          DocBook XSL 不會對文檔中使用的任何圖片執(zhí)行操作,僅僅創(chuàng)建元數(shù)據(jù)文件和要呈現(xiàn)的 XHTML。由于 EPUB 規(guī)范要求 content.opf manifest 列出所有資源,可以預(yù)料到 manifest 將尋找原始 DocBook 文件引用的任何圖片。清單 18 顯示了這種技術(shù),其中假定 path 變量包含 DocBook XSLT 生成的、當前所處理的 EPUB 的路徑。

          清單 18. 解析 OPF 內(nèi)容文件以尋找缺失的資源

          					 import os.path, shutil from lxml import etree  def find_resources(path='/path/to/our/epub/directory'):     opf = etree.parse(os.path.join(path, 'OEBPS', 'content.opf'))      # All the opf:item elements are resources     for item in opf.xpath('//opf:item',                            namespaces= { 'opf': 'http://www.idpf.org/2007/opf' }):          # If the resource was not already created by DocBook XSL itself,          # copy it into the OEBPS folder         href = item.attrib['href']         referenced_file = os.path.join(path, 'OEBPS', href):         if not os.path.exists(referenced_file):             shutil.copy(href, os.path.join(path, 'OEBPS')) 

          自動創(chuàng)建 mimetype

          DocBook XSL 不會創(chuàng)建 mimetype 文件,不過 清單 19 中所示的代碼可以完成這項任務(wù)。

          清單 19. 創(chuàng)建 mimetype 文件

          					 def create_mimetype(path='/path/to/our/epub/directory'):     f = '%s/%s' % (path, 'mimetype')     f = open(f, 'w')     # Be careful not to add a newline here     f.write('application/epub+zip')     f.close() 

          用 Python 創(chuàng)建 EPUB 包

          現(xiàn)在只需要將文件打包成有效的 EPUB ZIP 包。需要分兩步:將未經(jīng)壓縮的 mimetype 文件作為第一個文件加進去,然后添加其他目錄。如 清單 20 所示。

          清單 20. 使用 Python zipfile 模塊創(chuàng)建 EPUB 包

          					 import zipfile, os  def create_archive(path='/path/to/our/epub/directory'):     '''Create the ZIP archive.  The mimetype must be the first file in the archive      and it must not be compressed.'''      epub_name = '%s.epub' % os.path.basename(path)      # The EPUB must contain the META-INF and mimetype files at the root, so      # we'll create the archive in the working directory first and move it later     os.chdir(path)          # Open a new zipfile for writing     epub = zipfile.ZipFile(epub_name, 'w')      # Add the mimetype file first and set it to be uncompressed     epub.write(MIMETYPE, compress_type=zipfile.ZIP_STORED)          # For the remaining paths in the EPUB, add all of their files     # using normal ZIP compression     for p in os.listdir('.'):         for f in os.listdir(p):             epub.write(os.path.join(p, f)), compress_type=zipfile.ZIP_DEFLATED)     epub.close() 

          好了!切記要進行驗證。

           

          /////////////////////////////////////////////////////////////////////////////////////////////Page6

          結(jié)束語

          上一節(jié) 中的 Python 腳本僅僅是充分實現(xiàn) EPUB 轉(zhuǎn)換自動化的第一步。為了簡化起見,沒有涉及一些常見的情況,比如任意嵌套的路徑、樣式表或者內(nèi)嵌字體。Ruby 愛好者可以看看 DocBook XSL 分發(fā)包中所含的 dbtoepub,方法與此類似。

          因為 EPUB 還是一種比較年輕的格式,很多有效的轉(zhuǎn)換方法還等待人們?nèi)?chuàng)造。所幸的是,多數(shù)結(jié)構(gòu)化標記,如 reStructuredText 或 Markdown 都已經(jīng)存在生成 HTML 或者 XHTML 的渠道了;稍加修改來生成 EPUB 應(yīng)該非常容易,尤其是有了本文所示的 DocBook-to-EPUB Python 或 Ruby 腳本這些例子以后。

          因為 EPUB 基本上就是 ZIP 和 XHTML,與其使用 .zip 文件,沒有理由不使用 EPUB 來分發(fā)文檔。擁有 EPUB 閱讀器的讀者可從傳統(tǒng)元數(shù)據(jù)和自動目錄表收益,沒有閱讀器的讀者也可將其作為一般 ZIP 文件并在瀏覽器中查看 XHTML 內(nèi)容。考慮將 EPUB 生成的代碼添加到各類文檔系統(tǒng)中,如 Javadoc 或 Perldoc。EPUB 是為具有圖書長度的文檔設(shè)計的,因此非常適合越來越多的在線或者漸進式編程圖書。

          來自:http://www.cnblogs.com/linlf03/archive/2011/12/15/2285953.html

          posted on 2011-12-28 10:57 狼愛上貍 閱讀(779) 評論(0)  編輯  收藏 所屬分類: EPUB

          主站蜘蛛池模板: 偏关县| 宾阳县| 韩城市| 大英县| 武穴市| 乐陵市| 金阳县| 清流县| 得荣县| 灯塔市| 竹溪县| 修文县| 巴楚县| 交城县| 隆化县| 邹平县| 芜湖县| 慈利县| 祁东县| 南漳县| 连云港市| 无锡市| 邢台市| 昭苏县| 城步| 永宁县| 平武县| 成武县| 西盟| 五华县| 古交市| 汶上县| 新竹县| 武鸣县| 大庆市| 余江县| 吉首市| 河池市| 桐梓县| 贡嘎县| 广河县|