KindleGen與Markdown轉換為Mobi的Kindle電子書工具:m2m.exe

自從使用Kindle當做閱讀網路小說的主要工具後,經常都要使用Calibre來將HTML檔轉換成Kindle支援的Mobi檔(參考:使用Calibre轉換TXT電子書(含目錄)並傳送至Kindle Paperwhite操作全攻略),但Calibre在轉換較大檔案時(其實也不過10多MB而已)卻要花費許多時間,少則半小時,多則40、50分鐘以上,通常就中斷轉換,直接使用文字格式了,缺點當然就是沒有目錄,降低了閱讀品質。最終搜尋到了亞馬遜用來編寫Kindle標準文件的工具:KindleGen,藉由KindleGen我們就能更方便的來控制要產生的電子書了。m2m.exe則是我寫來簡化製作Kindle電子書的小工具。

console

KindleGen需要的檔案

KindleGen是一個命令行指令,執行時會讀取下列檔案,依.opf檔的控制來產生Mobi檔:

檔案 檔案範例 說明
書籍內容的HTML檔 mybook.html HTML是書籍本文的內容。一本書可以使用多個HTML檔,但為方便我只使用一個HTML檔
HTML使用的樣式表 style.css HTML檔若有使用CSS樣式就需要本檔
目錄的HTML檔 toc.html 形成目錄(Table of Contents, toc)的網頁內容
目錄的索引檔 toc.ncx Kindle 「前往」出現的選單(ncx是Navigation Control file for XML applications)
封面圖片 mybook.jpg 封面圖片可不使用,但缺少時KindleGen較不穩定
控制組合的OPF檔 mybook.opf OPF是Open Packaging Format,負責將上述檔案組合起來以形成最終的Mobi檔

KindleGen參數

在命令提示字元視窗執行kindlegen.exe就能開始編寫書籍:

cd \util\kindlegen
kindlegen.exe  mybook.opf

執行過程會顯示在DOS視窗裡,若有錯誤訊息而中斷執行,則再去修改相關檔案後再次執行即可。執行時有下列參數可用:

To convert an EPUB or HTML book to the Kindle Format 8, use KindleGen version 2 or higher as 
described below:

kindlegen filename.opf/.htm/.html/.epub [-c0 or -c1 or c2] [-verbose] [-western] [-o 
<file name>]

Note:
zip formats are supported for XMDF and FB2 sources
directory formats are supported for XMDF sources
Options:
-c0: no compression
-c1: standard DOC compression
-c2: Kindle huffdic compression (recommended for large, text-heavy files)
-o <file name>: Specifies the output file name. Output file will be created in the 
same directory as that of input file. <file name> should not contain directory path.
-verbose: provides more information during ebook conversion
-western: force build of Windows-1252 book
-releasenotes: display release notes
-gif: images are converted to GIF format (no JPEG in the book)
-locale 執行時顯示訊息的語系,如en或zh (只有簡體中文)

由以上說明可知,kindlegen.exe不只接受 .opf檔,也能使用.htm、.html或.epub,但本文只使用了.opf檔。詳細的參數說明請參考 Amazon Kindle Publishing Guidelines --- How to make books available for the Kindle platform 第十頁。

NCX檔與OPF檔

上述原始檔案比較特別的是.ncx與.opf檔,二者皆為XML格式,簡述如下。

.ncx用來產生Kindle裡的目錄的樹狀控制,沒有這個控制就不像在看電子書。重要的標籤範例如下,範例裡建了三個導航點:目錄、第一卷與第一章,目錄與第一卷在第一層,第一章在第二層。每個導航點都有依序排列的playOrder與點擊後的錨點位置:

<navMap>
  <navPoint class="toc" id="toc" playOrder="0">
    <navLabel>
      <text>目錄</text>
    </navLabel>
    <content src="toc.html"/>
  </navPoint>

  <navPoint class="welcome" id="welcome" playOrder="1">
    <navLabel>
    <text>第一卷 第一卷標題</text>
    </navLabel>
    <content src="mybook.html#SECTION_1"/>
    <navPoint class="welcome" id="welcome" playOrder="2">
      <navLabel>
      <text>第一章 第一章標題</text>
      </navLabel>
      <content src="mybook.html#SECTION_2"/>
    </navPoint>

.opf主要由4大部份組成:

標籤 說明
metadata 定義書名、作者、ISBN號碼等
manifest 書籍使用到的原始檔案,mybook.html、toc.ncx等
spine 書籍本文裡要使用的內容,一般是toc.html與mybook.html,若不想把目錄也產生在文本裡則可以toc.html刪掉
guide 點擊目錄會跳到toc.html在書籍裡的位置,點擊本文會跳到mybook.html開始處

mybook.opf範例:

<?xml version="1.0"?>
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">

  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
    <dc:title>我的電子書</dc:title>
    <dc:language>zh-TW</dc:language>
    <dc:identifier id="BookId" opf:scheme="ISBN">123456789Y</dc:identifier>
    <dc:creator opf:file-as="(未知)" opf:role="aut">(未知)</dc:creator>
    <dc:publisher>Jerry</dc:publisher>
    <dc:subject>我的電子書</dc:subject>
    <dc:date>2015-08-29</dc:date>
    <dc:description>我的電子書</dc:description>
    <meta name="cover" content="my-cover-image" />
  </metadata>
 
  <manifest>
    <item id="tc" properties="nav" href="toc.html" media-type="application/xhtml+xml"/>
    <item id="book" href="mybook.html" media-type="application/xhtml+xml"/>
    <item id="stylesheet" href="style.css" media-type="text/css"/>
    <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/>
    <item id="my-cover-image" href="mybook.jpg" media-type="image/jpeg" />
  </manifest>
 
  <!-- Each itemref references the id of a document designated in the manifest. The order of the itemref elements organizes the associated content files into the linear reading order of the publication.  -->
  <spine toc="ncx">
    <itemref idref="tc" />
    <itemref idref="book" />
  </spine>
 
  <!-- The Kindle reading system supports two special guide items which are both mandatory.
  type="toc" [mandatory]: a link to the HTML table of contents
  type="text" [mandatory]: a link to where the content of the book starts (typically after the front matter) -->
  <guide>
    <reference type="toc" title="Table of Contents" href="toc.html"/>
    <reference type="text" title="Beginning" href="mybook.html"></reference>
  </guide> 
</package>

M2M:將Markdown轉換為Mobi的工具

為了方便產生KindleGen需要的檔案,我花了一兩天閑暇時間以Lazarus寫了一個小工具m2m:Markdown to Mobi,只要指定好要使用的文字檔(Markdown格式)後就能產生所有需要的檔案並叫用KindleGen產生.Mobi檔:

m2m main form

m2m.exe的使用方法很簡單,指定好文字檔後再依1、2、3的順序點擊按鈕就可以了。檢視Mobi檔可以下載Kindle Previewer,再把.mobi的預設應用程式設定為Kindle Previewer。

Markdown檔製作要點

Markdown文字檔編碼必須是UTF-8不帶BOM,通常只要再加上章節開頭的標題符號,第一層標題用一個半形井字號,第二層標題用兩個半形井字號,如果全文只有一層就用兩個半形井字號,如:

原始章節標題 加入標題符號
第一卷 京華煙雲 # 第一卷 京華煙雲
第二十八章 最長的一天(上) ## 第二十八章 最長的一天(上)

文字檔裡的空行不用處理,轉出HTML檔時會全部被濾掉,每個段落在HTML裡會被夾在<p>...</p>裡。因受限於Kindle,目錄階層最多兩層。

M2M操作要點

  1. m2m.exe依template.ncx、template.opf等樣板檔來產生原始檔,有特殊需求時可自行修改樣板檔,讓系統產生出不同內容的檔案。
  2. 【第二層最多項目數】用在文本只有一層標題的狀況,系統自動依此數目插入第一層標題,例如全文有1000章, 系統會產生成 第1部份 (第二層是第1章到第20章)、第2部份 (第二層是第21章到第40章),方便章節切換。
  3. 〔2.產生設定檔案〕執行後最好檢視一下toc.html,以確認自已製作的Markdown章節有正確的產生出來,若看到錯誤,則可以按書籍檔名右方的編輯按鈕進入編輯,書籍檔修改後必須再按〔1.讀檔〕重新讀入新的內容
  4. 〔3.產生Mobi檔〕若彈出的kindlegen.exe有錯誤訊息,依訊息修改相關檔案。例如出現toc.html不為UTF-8編碼訊息,則打開toc.html找看看錯誤並修正。
  5. 〔3.產生Mobi檔〕進行到產生最後卻出現無法產生Mobi檔:同樣的原始檔有時kindlegen無法產生檔案,請再重覆執行幾次看看,或直接在DOS視窗執行mybook.bat。
  6. KindleGen使用 -c2 壓縮選項時失敗率較高,但能產生較小檔案。
  7. 修改mybook.opf將封面圖片設定刪掉可讓Kindle產生預設的封面。
  8. 最後以Kindow Previewer查看Mobi檔的內容是否一切正確。先看本文、封面,再看目錄內容和NCX。

previewer text cover

toc html ncx

相關連結

##

您可能也會有興趣的類似文章

簡睿

服務於軟體業的資訊老兵。興趣廣泛,學習力佳,樂於分享所知所學。

您可能也會喜歡…

2 個回應

  1. Jonathan表示:

    執行 m2m 時會出現 connot found OpenSSL Library 的錯誤訊息,以致不能執行!

    請問如何解決?或是要另外安裝什麼?

    謝謝!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *