技術書をMarkdownで書いていて、同じ原稿をKindle(KDP)にも出すことにしました。変換ツールは使わず、Node.jsで、EPUBを自作しました。作り方と、途中で引っかかった点、KDPの登録画面で迷った点をまとめます。
先に書いておくと、この記事は作り方の記録です。売れ行きや、収益の話は、まだ書けません(発売して、まだ日が浅いためです)。
材料
-
marked: MarkdownをHTMLに変換する -
jszip: EPUB(中身はzip)を作る
EPUBは、決まった構造のzipファイルです。自作する場合に必要なファイルは、次のとおりです。
| ファイル | 役割 |
|---|---|
mimetype |
中身はapplication/epub+zipだけ。zipの先頭に、無圧縮で入れる
|
META-INF/container.xml |
本体(content.opf)の場所を指す |
OEBPS/content.opf |
書名、著者、章の一覧(spine)、表紙の指定 |
OEBPS/nav.xhtml と toc.ncx
|
目次(新しい形式と、古い形式の両方) |
OEBPS/c001.xhtml … |
章ごとの本文 |
OEBPS/style.css、cover.jpg
|
見た目と、表紙 |
zipの作り方で、守ること
const zip = new JSZip();
zip.file('mimetype', 'application/epub+zip', { compression: 'STORE' });
zip.file('META-INF/container.xml', containerXml);
zip.file('OEBPS/content.opf', opf);
// ... 本文、CSS、表紙
const buf = await zip.generateAsync({
type: 'nodebuffer',
compression: 'DEFLATE',
mimeType: 'application/epub+zip',
});
-
mimetypeは、最初のエントリにして、圧縮しない(STORE)。EPUBの決まりです - 私の環境では、書き込んだあとに、zipの先頭のエントリが
mimetypeになっていることを、確認しています
引っかかった点: チェックリストが、XHTMLとして不正になる
本文のMarkdownには、- [ ] ...というチェックリストがありました。markedは、これを<input type="checkbox" disabled="">に変換します。ところが、EPUBの本文はXHTMLです。XMLとして正しくなければいけません。閉じタグのない<input>は、そのままでは不正です。
const html = marked.parse(md, { gfm: true })
.replace(/<br>/g, '<br/>')
.replace(/<hr>/g, '<hr/>')
.replace(/<input([^>]*?)\s*\/?>/g, '<input$1/>');
<br>や<hr>も、同じ理由で自己終了の形(<br/>)にしています。
XMLとして正しいか、機械で確かめる
KDPにアップロードする前に、すべての.xhtmlを、XMLパーサで読み込んで、エラーが出ないか確認しました。私は、@xmldom/xmldomを使いました。
const { DOMParser } = require('@xmldom/xmldom');
// zipの中の .xhtml / .opf / .ncx を1つずつ読み込む
new DOMParser({ onError: (lvl, msg) => { if (lvl !== 'warning') errors.push(msg); } })
.parseFromString(xml, 'application/xhtml+xml');
最初の実行では、上のチェックリストの<input>で、1つ目のエラーが出ました。直したあとは、30ファイル、異常0になりました。
コードが多い本の注意: 折り返し
私の本は、コードの全文が多く載っています。Kindleの画面は幅が狭いので、preの中を折り返す設定を入れました。
pre {
font-family: monospace;
font-size: 0.72em;
line-height: 1.5;
white-space: pre-wrap;
word-wrap: break-word;
background: #f4f4f4;
padding: 0.6em;
}
折り返さないと、長い行がはみ出して、読めなくなります。
表紙
KDPは、表紙を、縦横比1:1.6(推奨)の画像で受け付けます。私は、1600×2560のJPEGを作りました。AIモデルによる画像生成ではなく、プログラムで描画した図形と文字だけです(あとで、登録画面の「AI生成画像」の質問に答えるときに、その事実を使いました)。
KDPの登録画面で、迷った点
- KDPセレクト: 同じ内容を、ほかの場所でも売っている場合は、登録しない。セレクトは、90日間、Amazonだけで売ることが条件です(日本のヘルプで、最終確認してください)
- AI生成コンテンツ: 登録時に、AIで生成した内容かを、申告する画面があります。文章を、AIを使って書いて、人が確認した場合は、「AI生成テキストを含む」と申告しました。本の中にも、その旨を書いています
-
アクセシビリティ: 「情報を提供する画像に代替テキストがあるか」を聞かれます。私の本は、本文に画像がなく、表紙だけでした。表紙には、EPUBの中で、代替テキスト(
alt="表紙")を付けています。事実に合う選択肢を、選びました - カテゴリー: 最初に、「Kindle本」を選び、そのあと、サブカテゴリー(コンピュータ・ITなど)の順に、絞っていく画面でした
- 価格: ロイヤリティが70%になる価格帯は、250〜1,250円です(日本のストア)
まとめ
- EPUBは、
mimetype(先頭・無圧縮)、container.xml、content.opf、目次、本文のXHTMLがあれば、自作できる -
markedの出力は、そのままではXHTMLにならないことがある。自己終了の形に直す - 提出前に、XMLパーサで全ファイルを機械的に確かめる
- コードが多い本は、
preを折り返す - 同じ内容をほかでも売るなら、KDPセレクトには入れない。AIの利用は、正直に申告する
この記事はZennにも投稿しています。