review 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +1 -0
- data/ChangeLog +100 -0
- data/README.rdoc +11 -12
- data/Rakefile +6 -2
- data/bin/review-check +1 -1
- data/bin/review-compile +13 -4
- data/bin/review-epubmaker +172 -24
- data/bin/review-epubmaker-ng +8 -161
- data/bin/review-index +1 -1
- data/bin/review-init +17 -5
- data/bin/review-pdfmaker +40 -19
- data/bin/review-preproc +1 -1
- data/bin/review-validate +2 -2
- data/bin/review-vol +1 -1
- data/debian/control +2 -2
- data/doc/format.rdoc +23 -6
- data/doc/format_idg.rdoc +3 -3
- data/doc/libepubmaker/config.yaml +163 -0
- data/doc/quickstart.rdoc +27 -27
- data/doc/sample.yaml +10 -5
- data/lib/epubmaker.rb +2 -5
- data/lib/epubmaker/content.rb +9 -6
- data/lib/epubmaker/epubv2.rb +233 -109
- data/lib/epubmaker/epubv3.rb +83 -119
- data/lib/epubmaker/producer.rb +50 -20
- data/lib/epubmaker/resource.rb +22 -8
- data/lib/review/book/base.rb +1 -0
- data/lib/review/book/chapter.rb +2 -2
- data/lib/review/book/compilable.rb +1 -1
- data/lib/review/book/index.rb +33 -27
- data/lib/review/book/parameters.rb +3 -2
- data/lib/review/book/part.rb +1 -1
- data/lib/review/builder.rb +10 -42
- data/lib/review/compiler.rb +1 -1
- data/lib/review/configure.rb +3 -3
- data/lib/review/epubmaker.rb +428 -0
- data/lib/review/htmlbuilder.rb +45 -95
- data/lib/review/htmlutils.rb +2 -0
- data/lib/review/i18n.yaml +25 -0
- data/lib/review/idgxmlbuilder.rb +11 -9
- data/lib/review/inaobuilder.rb +1 -1
- data/lib/review/latexbuilder.rb +7 -6
- data/lib/review/latexutils.rb +6 -0
- data/lib/review/makerhelper.rb +4 -2
- data/lib/review/markdownbuilder.rb +8 -0
- data/lib/review/sec_counter.rb +71 -0
- data/lib/review/topbuilder.rb +0 -1
- data/lib/review/version.rb +2 -2
- data/review.gemspec +4 -4
- data/test/sample-book/README.md +2 -2
- data/test/sample-book/src/Rakefile +2 -2
- data/test/sample-book/src/config.yml +4 -4
- data/test/sample-book/src/images/cover.jpg +0 -0
- data/test/sample-book/src/sty/{samplemacro.sty → reviewmacro.sty} +1 -1
- data/test/test_book_parameter.rb +1 -1
- data/test/test_epubmaker.rb +77 -15
- data/test/test_epubmaker_cmd.rb +11 -7
- data/test/test_helper.rb +7 -0
- data/test/test_htmlbuilder.rb +39 -6
- data/test/test_idgxmlbuilder.rb +14 -2
- data/test/test_inaobuilder.rb +2 -1
- data/test/test_latexbuilder.rb +23 -2
- data/test/test_makerhelper.rb +19 -3
- data/test/test_markdownbuilder.rb +35 -0
- data/test/test_pdfmaker_cmd.rb +11 -7
- data/test/test_topbuilder.rb +36 -2
- metadata +18 -18
- data/VERSION +0 -1
- data/doc/libepubmaker/sample.yaml +0 -90
data/doc/format_idg.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
=
|
1
|
+
= Re:VIEW フォーマット InDesign XML 形式拡張
|
2
2
|
|
3
|
-
|
3
|
+
Re:VIEW フォーマットから、Adobe 社の DTP ソフトウェア「InDesign」
|
4
4
|
で読み込んで利用しやすい XML 形式に変換できます (通常の XML とほぼ同じ
|
5
5
|
ですが、文書構造ではなく見た目を指向した形態になっています)。
|
6
6
|
現時点では idgxmlbuilder.rb と topbuilder.rb のみが拡張に対応しています。
|
@@ -107,7 +107,7 @@ XMLとしては<label id='〜' />と<labelref idref='〜' />というタグに
|
|
107
107
|
という特別な書式を代わりに使います。
|
108
108
|
|
109
109
|
== ロー指定
|
110
|
-
現時点で
|
110
|
+
現時点で Re:VIEW はブロックの入れ子処理ができないため、ロー指定で XML
|
111
111
|
エレメントを指定しなければならないこともあります。
|
112
112
|
|
113
113
|
インラインの@<raw>{ 〜 }の他に、単一行の//raw[〜]、ブロック版の //rawblock{ 〜 //} でも、フォーマット処理をせずにそのままの文字列が出力できます。
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# review-epubmaker-ng向けYAMLファイルのサンプル
|
2
|
+
#
|
3
|
+
# このファイルはUTF-8エンコーディングで記述してください
|
4
|
+
# YAMLにおける空は、「nil」ではなく「null」であることに注意してください
|
5
|
+
|
6
|
+
# ブック名(ファイル名になるもの。ASCII範囲の文字を使用)
|
7
|
+
bookname: sample
|
8
|
+
# 記述言語
|
9
|
+
language: ja
|
10
|
+
# 書名
|
11
|
+
title: "Re:VIEW EPUBのサンプル"
|
12
|
+
|
13
|
+
# 固有IDに使用するドメイン。指定しない場合には、時刻に基づくランダムUUIDが入る
|
14
|
+
# urnid: urn:uid:http://example.com/some-book-title/1.0.2/
|
15
|
+
|
16
|
+
# ISBN。省略した場合はランダム生成したUUIDが入る
|
17
|
+
# isbn: null
|
18
|
+
|
19
|
+
# 著者名。「, 」で区切って複数指定できる
|
20
|
+
aut: ["Minero Aoki", "Kenshi Muto", "Masayoshi Takahashi", "Masanori Kado"]
|
21
|
+
|
22
|
+
# 以下はオプション(autと同じように配列書式で複数指定可能)。
|
23
|
+
# a-が付いているものはcreator側、
|
24
|
+
# 付いていないものはcontributor側(二次協力者)に入る
|
25
|
+
# a-adp, adp: 異なるメディア向けに作り直した者
|
26
|
+
# a-ann, ann: 注釈記述者
|
27
|
+
# a-arr, arr: アレンジした者
|
28
|
+
# a-art, art: グラフィックデザインおよび芸術家
|
29
|
+
# a-asn, asn: 関連・かつての所有者・関係者
|
30
|
+
# a-aqt, aqt: 大きく引用された人物
|
31
|
+
# a-aft, aft: 後書き・奥付の責任者
|
32
|
+
# a-aui, aui: 序論・序文・前書きの責任者
|
33
|
+
# a-ant, ant: 目録責任者
|
34
|
+
# a-bkp, bkp: メディア制作責任者
|
35
|
+
# a-clb, clb: 限定参加または補足者
|
36
|
+
# a-cmm, cmm: 解釈・分析・考察者
|
37
|
+
# a-dsr, dsr: デザイナ
|
38
|
+
# a-edt, edt: 編集者
|
39
|
+
# a-ill, ill: イラストレータ
|
40
|
+
# a-lyr, lyr: 歌詞作成者
|
41
|
+
# a-mdc, mdc: メタデータセットの一次的責任者
|
42
|
+
# a-mus, mus: 音楽家
|
43
|
+
# a-nrt, nrt: 語り手
|
44
|
+
# a-oth, oth: その他
|
45
|
+
# a-pht, pht: 撮影責任者
|
46
|
+
# a-prt, prt: 出版社
|
47
|
+
# a-red, red: 項目の枠組起草者
|
48
|
+
# a-rev, rev: 評論者
|
49
|
+
# a-spn, spn: 援助者
|
50
|
+
# a-ths, ths: 監督者
|
51
|
+
# a-trc, trc: 筆記・タイプ作業者
|
52
|
+
# a-trl, trl: 翻訳者
|
53
|
+
|
54
|
+
# rights: 権利表記(配列で複数指定可)
|
55
|
+
# date: 刊行日(省略した場合は実行時の日付)
|
56
|
+
# description: 説明
|
57
|
+
# subject: 短い説明用タグ(配列で複数指定可)
|
58
|
+
# type: 書籍のカテゴリーなど(配列で複数指定可)
|
59
|
+
# format: メディアタイプおよび特徴(配列で複数指定可)
|
60
|
+
# source: 出版物生成の重要なリソース情報(配列で複数指定可)
|
61
|
+
# relation: 補助的リソース(配列で複数指定可)
|
62
|
+
# coverage: 内容の範囲や領域(配列で複数指定可)
|
63
|
+
|
64
|
+
# htmlext: HTMLファイルの拡張子(省略した場合はhtml)
|
65
|
+
# cover: カバーページのファイル名(省略した場合はbookname.xhtmlになる)
|
66
|
+
#
|
67
|
+
# coverimage: カバー用画像
|
68
|
+
#
|
69
|
+
# CSSファイル(配列で複数指定可)
|
70
|
+
stylesheet: ["stylesheet.css"]
|
71
|
+
|
72
|
+
# ePUBのバージョン (2か3)
|
73
|
+
# epubversion: 2
|
74
|
+
# HTMLのバージョン (4か5。epubversionを3にしたときには5にする)
|
75
|
+
# htmlversion: 4
|
76
|
+
|
77
|
+
# 目次として抽出する見出しレベル
|
78
|
+
# toclevel: 2
|
79
|
+
# 目次を要素の階層表現にしない。省略した場合(null)は階層化する。
|
80
|
+
# 構成によっては、階層化目次ではepubcheckにパスしない目次ができるが、
|
81
|
+
# そのようなときにはこれをtrueにする
|
82
|
+
# flattoc: null
|
83
|
+
# 目次のインデントレベルをスペース文字で表現する(flattocがtrueのときのみ)
|
84
|
+
# flattocindent: true
|
85
|
+
# 本文でセクション番号を表示する見出しレベル
|
86
|
+
# secnolevel: 2
|
87
|
+
# 前付でセクション番号を表示する見出しレベル
|
88
|
+
# pre_secnolevel: 0
|
89
|
+
# 後付でセクション番号を表示する見出しレベル
|
90
|
+
# post_secnolevel: 0
|
91
|
+
# 部番号を表示する見出しレベル
|
92
|
+
# part_secnolevel: 1
|
93
|
+
|
94
|
+
# NCX目次の見出しレベルごとの飾り(配列で設定)
|
95
|
+
#ncxindent:
|
96
|
+
#-
|
97
|
+
#- -
|
98
|
+
|
99
|
+
# EPUB2標準の目次以外に物理目次ファイルを作成するか。省略した場合はnull (作成しない)
|
100
|
+
# ePUB3においてはこの設定によらず必ず作成する
|
101
|
+
# mytoc: true
|
102
|
+
|
103
|
+
# 表紙の後に権利表記ページを作成するか。デフォルトでは作成されない。ファイル名を指定するとそのファイルが使われる(data配列にも指定しておく必要がある)
|
104
|
+
# titlepage: title.xhtml
|
105
|
+
|
106
|
+
# 奥付を作成するか。デフォルトでは作成されない。trueを指定するとデフォルトの奥付、ファイル名を指定するとそれがcolophon.xhtmlとしてコピーされる(data配列にも指定しておく必要がある)
|
107
|
+
# colophon: true
|
108
|
+
# pubhistory: 奥付履歴
|
109
|
+
|
110
|
+
# プロフィールページファイル。ファイル名を指定すると著者紹介として入る
|
111
|
+
# profile: null
|
112
|
+
# プロフィールページの目次上の見出し
|
113
|
+
# profiletitle: 著者紹介
|
114
|
+
|
115
|
+
# フックは、各段階で介入したいときのプログラムを指定する。自動で適切な引数が渡される
|
116
|
+
# プログラムには実行権限が必要
|
117
|
+
|
118
|
+
# ファイル変換処理の前に実行するプログラム。スタイルシートのコンパイルをしたいときなどに利用する。
|
119
|
+
# 渡される引数1=作業用展開ディレクトリ
|
120
|
+
# hook_beforeprocess: null
|
121
|
+
|
122
|
+
# 前付の変換後に実行するプログラム。作業用展開ディレクトリにある目次ファイル(toc-html.txt)を操作したいときなどに利用する。
|
123
|
+
# 渡される引数1=作業用展開ディレクトリ
|
124
|
+
# hook_afterfrontmatter: null
|
125
|
+
|
126
|
+
# 本文の変換後に実行するプログラム。作業用展開ディレクトリにある目次ファイル(toc-html.txt)を操作したいときなどに利用する。
|
127
|
+
# 渡される引数1=作業用展開ディレクトリ
|
128
|
+
# hook_afterbody: null
|
129
|
+
|
130
|
+
# 後付の変換後に実行するプログラム。作業用展開ディレクトリにある目次ファイル(toc-html.txt)を操作したいときなどに利用する。
|
131
|
+
# 渡される引数1=作業用展開ディレクトリ
|
132
|
+
# hook_afterbackmatter: null
|
133
|
+
|
134
|
+
# 画像およびフォントをコピーした後に実行するプログラム。別の画像やフォントを追加したいときなどに利用する。
|
135
|
+
# 渡される引数1=作業用展開ディレクトリ
|
136
|
+
# hook_aftercopyimage: null
|
137
|
+
|
138
|
+
# ePUB zipアーカイブ直前に実行するプログラム。メタ情報などを加工したいときなどに利用する。
|
139
|
+
# 渡される引数1=ePUB準備ディレクトリ
|
140
|
+
# hook_prepack: null
|
141
|
+
|
142
|
+
# ハイライトを有効にするか。pygments.gemが必要
|
143
|
+
# pygments: null
|
144
|
+
|
145
|
+
# 取り込む画像が格納されているディレクトリ。省略した場合は以下
|
146
|
+
# imagedir: images
|
147
|
+
|
148
|
+
# 取り込むフォントが格納されているディレクトリ。省略した場合は以下
|
149
|
+
# fontdir: fonts
|
150
|
+
|
151
|
+
# imagedir内から取り込まれる対象となるファイル拡張子。省略した場合は以下
|
152
|
+
# image_ext: ["png", "gif", "jpg", "jpeg", "svg", "ttf", "woff", "otf"]
|
153
|
+
|
154
|
+
# fontdir内から取り込まれる対象となるファイル拡張子。省略した場合は以下
|
155
|
+
# font_ext: ["ttf", "woff", "otf"]
|
156
|
+
|
157
|
+
# Re:VIEWファイル名を使わず、前付にpre01,pre02...、本文にchap01,chap02l...、後付にpost01,post02...という名前付けルールにするか
|
158
|
+
# rename_for_legacy: null
|
159
|
+
|
160
|
+
# ePUBアーカイブの非圧縮実行
|
161
|
+
# zip_stage1: "zip -0Xq"
|
162
|
+
# ePUBアーカイブの圧縮実行
|
163
|
+
# zip_stage2: "zip -Xr9Dq"
|
data/doc/quickstart.rdoc
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
=
|
1
|
+
= Re:VIEWクイックスタートガイド
|
2
2
|
|
3
|
-
|
3
|
+
Re:VIEW は、EWB や RD あるいは Wiki に似た簡易フォーマットで記述したテキストファイルを、目的に応じて各種の形式に変換するツールセットです。
|
4
4
|
|
5
5
|
平易な文法ながらも、コンピュータ関係のドキュメント作成のための多くの機能を備えており、テキスト、LaTeX、HTML、XML といった形式に変換できます。独自のカスタマイズも簡単です。
|
6
6
|
|
7
|
-
|
7
|
+
Re:VIEW は GNU Lesser General Public License Version 2.1 に基づいて配布されており、自由に利用、改変、再配布できます。このライセンスは、Re:VIEW を使ってあなたが作成しようとする文書とは無関係であり、あなたの文書はこのライセンスに強制されることはありません。Re:VIEW のツールセットあるいは Re:VIEW を組み込んだシステムを配布あるいは販売しようとしているときには、ライセンスファイル COPYING をよく確認してください。
|
8
8
|
|
9
|
-
このドキュメントでは、
|
9
|
+
このドキュメントでは、Re:VIEW のセットアップから変換の例までを簡単に説明します。
|
10
10
|
|
11
11
|
== セットアップ
|
12
12
|
|
13
|
-
|
13
|
+
Re:VIEW は Ruby 言語で記述されており、Linux/Unix 互換システムで動作します。Mac OS X および Windows Cygwin でも動作可能です。Ruby gem、Git、Subversion のいずれかを使ってダウンロード・展開します。
|
14
14
|
|
15
|
-
なお、
|
15
|
+
なお、Re:VIEW フォーマット自体は文字で表現されたタグが付いている以外は単なるテキストファイルなので、エディタ、OS についてはまったく制限はありません。
|
16
16
|
|
17
17
|
=== Ruby gemを使う場合
|
18
18
|
|
19
|
-
機能セットがまとまった区切りごとに、
|
19
|
+
機能セットがまとまった区切りごとに、Re:VIEW の開発チームが Re:VIEW の gem を更新しています。
|
20
20
|
|
21
|
-
次のように
|
21
|
+
次のように Re:VIEW の gem をインストールします。
|
22
22
|
|
23
23
|
gem install review
|
24
24
|
|
@@ -30,7 +30,7 @@ Ruby gem の bin ディレクトリにパスを通すようにしておいてく
|
|
30
30
|
|
31
31
|
=== Gitを使う場合
|
32
32
|
|
33
|
-
|
33
|
+
Re:VIEW は GitHub で開発されており、バージョン管理ツールの Git を使って最新の Re:VIEW コードを入手できます。Git は分岐が容易なので、独自のカスタマイズを施すのにも向いています。
|
34
34
|
|
35
35
|
初めて取得するときには、次のようにします (コピーを作っています)。
|
36
36
|
|
@@ -56,19 +56,19 @@ review というディレクトリに展開されるので、review/bin にパ
|
|
56
56
|
|
57
57
|
svn up
|
58
58
|
|
59
|
-
=
|
59
|
+
= Re:VIEW テキストの作成と変換
|
60
60
|
|
61
|
-
セットアップを終えたら、
|
61
|
+
セットアップを終えたら、Re:VIEW フォーマットのテキストを作り、変換できるようになります。次に Re:VIEW フォーマットテキストの簡単な例を示します。これを sample.re といった名前で保存します (拡張子も自由ですが、.re 拡張子を推奨します)。
|
62
62
|
|
63
|
-
= はじめての
|
63
|
+
= はじめてのRe:VIEW
|
64
64
|
|
65
65
|
//lead{
|
66
|
-
「Hello,
|
66
|
+
「Hello, Re:VIEW.」
|
67
67
|
//}
|
68
68
|
|
69
|
-
==
|
69
|
+
== Re:VIEWとは
|
70
70
|
|
71
|
-
@<b>{
|
71
|
+
@<b>{Re:VIEW}は、EWBやRDあるいはWikiに似た簡易フォーマットで記述したテキストファイルを、目的に応じて各種の形式に変換するツールセットです。
|
72
72
|
|
73
73
|
平易な文法ながらも、コンピュータ関係のドキュメント作成のための多くの機能を備えており、次のような形式に変換できます。
|
74
74
|
|
@@ -85,13 +85,13 @@ review というディレクトリに展開されるので、review/bin にパ
|
|
85
85
|
|
86
86
|
ホームページは@<tt>{https://github.com/kmuto/review/wiki/}です。
|
87
87
|
|
88
|
-
テキストファイルの文字エンコーディングには、UTF-8 を使うことをお勧めします。
|
88
|
+
テキストファイルの文字エンコーディングには、UTF-8 を使うことをお勧めします。Re:VIEW は日本語文字エンコーディングとして UTF-8、EUC-JP、Shift-JIS、JIS を扱うことができ、入力ファイルについては自動判別、出力ファイルについても選択可能 (デフォルトは UTF-8) ですが、入力・出力のいずれにおいても、使用可能な文字についての制限が少ない UTF-8 が最適です。
|
89
89
|
|
90
|
-
次に、章構成ファイルの CHAPS ファイルを同じディレクトリに用意します。このファイルには、
|
90
|
+
次に、章構成ファイルの CHAPS ファイルを同じディレクトリに用意します。このファイルには、Re:VIEW フォーマットファイルの名前を格納します。
|
91
91
|
|
92
92
|
sample.re
|
93
93
|
|
94
|
-
CHAPS ファイルの1行目に書いたものが第1章、2行目に書いたものが第2章、……と構成されます (CHAPS に似たものとして、前付けを列挙する PREDEF ファイル、後付けを列挙する POSTDEF
|
94
|
+
CHAPS ファイルの1行目に書いたものが第1章、2行目に書いたものが第2章、……と構成されます (CHAPS に似たものとして、前付けを列挙する PREDEF ファイル、後付けを列挙する POSTDEF ファイルがあります。これらを「カタログファイル」と呼びます)。
|
95
95
|
|
96
96
|
sample.re から目的の形式に変換するには、review-compile コマンドを使います。
|
97
97
|
|
@@ -112,17 +112,17 @@ sample.re を HTML に変換すると、次のようになります。
|
|
112
112
|
<head>
|
113
113
|
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
|
114
114
|
<meta http-equiv="Content-Style-Type" content="text/css" />
|
115
|
-
<meta name="generator" content="
|
116
|
-
<title>はじめての
|
115
|
+
<meta name="generator" content="Re:VIEW" />
|
116
|
+
<title>はじめてのRe:VIEW</title>
|
117
117
|
</head>
|
118
118
|
<body>
|
119
|
-
<h1><a id="h1" />第1章 はじめての
|
119
|
+
<h1><a id="h1" />第1章 はじめてのRe:VIEW</h1>
|
120
120
|
<div class="lead">
|
121
|
-
<p>「Hello,
|
121
|
+
<p>「Hello, Re:VIEW.」</p>
|
122
122
|
</div>
|
123
123
|
|
124
|
-
<h2><a id="h1-1" />1.1
|
125
|
-
<p><b>
|
124
|
+
<h2><a id="h1-1" />1.1 Re:VIEWとは</h2>
|
125
|
+
<p><b>Re:VIEW</b>は、EWBやRDあるいはWikiに似た簡易フォーマットで記述したテキストファイルを、目的に応じて各種の形式に変換するツールセットです。</p>
|
126
126
|
<p>平易な文法ながらも、コンピュータ関係のドキュメント作成のための多くの機能を備えており、次のような形式に変換できます。</p>
|
127
127
|
<ul>
|
128
128
|
<li>テキスト(指示タグ付き)</li>
|
@@ -140,13 +140,13 @@ sample.re を HTML に変換すると、次のようになります。
|
|
140
140
|
</body>
|
141
141
|
</html>
|
142
142
|
|
143
|
-
|
143
|
+
Re:VIEW フォーマットについての詳細は、 {format.rdoc}[https://github.com/kmuto/review/blob/master/doc/format.rdoc] を参照してください。
|
144
144
|
|
145
145
|
review-compile を含め、ほとんどのコマンドは --help オプションを付けるとオプションについてのヘルプが表示されます。review-compile には多数のオプションがあるので確認してください。
|
146
146
|
|
147
147
|
なお、--target で毎回指定するのは面倒なので、review-compile に対するシンボリックリンクを作成しておくとよいでしょう。「review2...」のコマンド名で呼び出せるようになります。
|
148
148
|
|
149
|
-
cd
|
149
|
+
cd Re:VIEWのインストールされたパス/bin
|
150
150
|
ln -s review-compile review2text
|
151
151
|
ln -s review-compile review2html
|
152
152
|
ln -s review-compile review2latex
|
@@ -181,7 +181,7 @@ PDF を作成するには、pTeXLive2009 以上の環境が必要です。EPUB
|
|
181
181
|
|
182
182
|
== クレジット
|
183
183
|
|
184
|
-
|
184
|
+
Re:VIEW は、青木峰郎によって最初に作成されました。武藤健志がこの開発・保守を引き継ぎ、2014年3月時点では、武藤健志、高橋征義、角征典が開発・保守を継続しています。
|
185
185
|
|
186
186
|
バグ・パッチの報告、開発者用メーリングリストなどについての情報は、
|
187
187
|
https://github.com/kmuto/review/wiki
|
data/doc/sample.yaml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# review-epubmaker向けの設定ファイルの例。
|
2
|
-
# yamlファイルを
|
2
|
+
# yamlファイルをRe:VIEWファイルのある場所に置き、
|
3
3
|
# 「review-epubmaker yamlファイル」を実行すると、<bookname>.epubファイルが
|
4
4
|
# 生成されます。
|
5
5
|
# このファイルはUTF-8エンコーディングで記述してください。
|
@@ -7,14 +7,15 @@
|
|
7
7
|
# ブック名(ファイル名になるもの。ASCII範囲の文字を使用)
|
8
8
|
bookname: review-sample
|
9
9
|
# 書名
|
10
|
-
booktitle:
|
10
|
+
booktitle: Re:VIEW EPUBサンプル
|
11
11
|
# 著者
|
12
|
-
aut:
|
12
|
+
aut: 執筆者
|
13
13
|
# 以下はオプション
|
14
14
|
# prt: 出版社
|
15
15
|
# asn: Associated name
|
16
16
|
# ant: Bibliographic antecedent
|
17
17
|
# clb: 貢献者
|
18
|
+
# csl: 監修者
|
18
19
|
# edt: 編集者
|
19
20
|
# dsr: デザイナ
|
20
21
|
# ill: イラストレータ
|
@@ -30,12 +31,14 @@ aut: 吟遊詩人
|
|
30
31
|
#
|
31
32
|
# 固有IDに使用するドメイン。指定しない場合には、時刻に基づくランダムUUIDが入る
|
32
33
|
# urnid: urn:uid:http://example.com/some-book-title/1.0.2/
|
33
|
-
# CSSファイル (yamlファイルおよび
|
34
|
+
# CSSファイル (yamlファイルおよびRe:VIEWファイルを置いたディレクトリにあること)
|
34
35
|
stylesheet: stylesheet.css
|
35
36
|
# LaTeX用のスタイルファイル(styディレクトリ以下に置くこと)
|
36
37
|
# texstyle: samplemacro
|
37
38
|
# LaTeX用のdocumentclassを指定する
|
38
39
|
# texdocumentclass: ["jsarticle", "b5paper,oneside"]
|
40
|
+
# LaTeX用のコマンドを指定する(platex or lualatex)
|
41
|
+
# texcommand: "platex"
|
39
42
|
# 目次として抽出するレベル
|
40
43
|
toclevel: 3
|
41
44
|
# セクション番号を表示するレベル
|
@@ -52,11 +55,13 @@ toc: true
|
|
52
55
|
mytoc: null
|
53
56
|
# 奥付を作成するか。デフォルトでは作成されない。trueを指定するとデフォルトの奥付、ファイル名を指定するとそれがcolophon.htmlとしてコピーされる
|
54
57
|
colophon: null
|
55
|
-
# XHTML生成後に実行するプログラム。$1:HTMLの生成されたディレクトリ $2:
|
58
|
+
# XHTML生成後に実行するプログラム。$1:HTMLの生成されたディレクトリ $2:Re:VIEWファイルのあるディレクトリ $3:起動時指定のyamlファイル名
|
56
59
|
# posthook: hook.sh
|
57
60
|
# EPUBで表紙をコンテンツに含めるか。デフォルトでは作成されない。yesにするとiBooks等でも最初に表紙が表示されるようになる
|
58
61
|
cover_linear: null
|
59
62
|
# review-compileに渡すパラメータ
|
60
63
|
params: --stylesheet=sample.css
|
64
|
+
# Pygmentsカラーリングを利用する (pygments外部gemが必要)
|
65
|
+
# pygments: true
|
61
66
|
# デバッグフラグ。nullでないときには一時ファイルをカレントディレクトリに作成し、削除もしない
|
62
67
|
debug: null
|
data/lib/epubmaker.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# = epubmaker.rb -- EPUB production set.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2010-
|
4
|
+
# Copyright (c) 2010-2013 Kenshi Muto
|
5
5
|
#
|
6
6
|
# This program is free software.
|
7
7
|
# You can distribute or modify this program under the terms of
|
@@ -9,16 +9,13 @@
|
|
9
9
|
# For details of the GNU LGPL, see the file "COPYING".
|
10
10
|
#
|
11
11
|
# == Quick usage
|
12
|
-
# (If you put xhtml files on current directory and put figures in
|
13
|
-
# images subdirectory)
|
14
|
-
#
|
15
12
|
# require 'epubmaker'
|
16
13
|
# epub = EPUBMaker::Producer.new
|
17
14
|
# params = epub.load("config.yaml")
|
18
15
|
# epub.contents.push(EPUBMaker::Content.new({"file" => "ch01.xhtml"}))
|
19
16
|
# epub.contents.push(EPUBMaker::Content.new({"file" => "ch02.xhtml"}))
|
20
17
|
# ...
|
21
|
-
# epub.
|
18
|
+
# epub.import_imageinfo("images")
|
22
19
|
# epub.produce
|
23
20
|
|
24
21
|
require 'epubmaker/producer'
|
data/lib/epubmaker/content.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# = content.rb -- Content object for EPUBMaker.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2010 Kenshi Muto
|
4
|
+
# Copyright (c) 2010-2014 Kenshi Muto
|
5
5
|
#
|
6
6
|
# This program is free software.
|
7
7
|
# You can distribute or modify this program under the terms of
|
@@ -11,11 +11,12 @@
|
|
11
11
|
|
12
12
|
module EPUBMaker
|
13
13
|
|
14
|
-
# EPUBMaker::Content
|
14
|
+
# EPUBMaker::Content represents a content data for EPUBMaker.
|
15
|
+
# EPUBMaker#contents takes an array of Content.
|
15
16
|
class Content
|
16
17
|
# ID
|
17
18
|
attr_accessor :id
|
18
|
-
# File path (
|
19
|
+
# File path (will accept #<anchor> suffix also)
|
19
20
|
attr_accessor :file
|
20
21
|
# MIME type
|
21
22
|
attr_accessor :media
|
@@ -61,9 +62,10 @@ module EPUBMaker
|
|
61
62
|
|
62
63
|
private
|
63
64
|
|
64
|
-
# Complement other parameters
|
65
|
+
# Complement other parameters by using file parameter.
|
65
66
|
def complement
|
66
|
-
@id = @file.gsub(/[\\\/\.]/, '-') if @id.nil?
|
67
|
+
@id = @file.gsub(/[\\\/\. ]/, '-') if @id.nil?
|
68
|
+
@id = "rv-#{@id}" if @id =~ /\A[^a-z]/i
|
67
69
|
@media = @file.sub(/.+\./, '').downcase if !@file.nil? && @media.nil?
|
68
70
|
|
69
71
|
@media = "application/xhtml+xml" if @media == "xhtml" || @media == "xml" || @media == "html"
|
@@ -71,8 +73,9 @@ module EPUBMaker
|
|
71
73
|
@media = "image/jpeg" if @media == "jpg" || @media == "jpeg" || @media == "image/jpg"
|
72
74
|
@media = "image/png" if @media == "png"
|
73
75
|
@media = "image/gif" if @media == "gif"
|
74
|
-
@media = "image/svg" if @media == "svg"
|
75
76
|
@media = "image/svg+xml" if @media == "svg" || @media == "image/svg"
|
77
|
+
@media = "application/vnd.ms-opentype" if @media == "ttf" || @media == "otf"
|
78
|
+
@media = "application/font-woff" if @media == "woff"
|
76
79
|
|
77
80
|
if @id.nil? || @file.nil? || @media.nil?
|
78
81
|
raise "Type error: #{id}, #{file}, #{media}, #{title}, #{notoc}"
|
data/lib/epubmaker/epubv2.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
# = epubv2.rb -- EPUB version 2 producer.
|
3
3
|
#
|
4
|
-
# Copyright (c) 2010-
|
4
|
+
# Copyright (c) 2010-2013 Kenshi Muto and Masayoshi Takahashi
|
5
5
|
#
|
6
6
|
# This program is free software.
|
7
7
|
# You can distribute or modify this program under the terms of
|
@@ -13,19 +13,19 @@ require 'epubmaker/producer'
|
|
13
13
|
require 'cgi'
|
14
14
|
|
15
15
|
module EPUBMaker
|
16
|
-
|
16
|
+
|
17
17
|
# EPUBv2 is EPUB version 2 producer.
|
18
18
|
class EPUBv2
|
19
19
|
# Construct object with parameter hash +params+ and message resource hash +res+.
|
20
20
|
def initialize(producer)
|
21
21
|
@producer = producer
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# Return mimetype content.
|
25
25
|
def mimetype
|
26
|
-
|
26
|
+
"application/epub+zip"
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# Return opf file content.
|
30
30
|
def opf
|
31
31
|
s = <<EOT
|
@@ -33,6 +33,23 @@ module EPUBMaker
|
|
33
33
|
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
|
34
34
|
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
35
35
|
EOT
|
36
|
+
|
37
|
+
s << opf_metainfo
|
38
|
+
s << opf_coverimage
|
39
|
+
|
40
|
+
s << %Q[ </metadata>\n]
|
41
|
+
|
42
|
+
s << opf_manifest
|
43
|
+
s << opf_tocx
|
44
|
+
s << opf_guide
|
45
|
+
|
46
|
+
s << %Q[</package>\n]
|
47
|
+
|
48
|
+
s
|
49
|
+
end
|
50
|
+
|
51
|
+
def opf_metainfo
|
52
|
+
s = ""
|
36
53
|
%w[title language date type format source description relation coverage subject rights].each do |item|
|
37
54
|
next if @producer.params[item].nil?
|
38
55
|
if @producer.params[item].instance_of?(Array)
|
@@ -41,22 +58,23 @@ EOT
|
|
41
58
|
s << %Q[ <dc:#{item}>#{CGI.escapeHTML(@producer.params[item].to_s)}</dc:#{item}>\n]
|
42
59
|
end
|
43
60
|
end
|
44
|
-
|
61
|
+
|
45
62
|
# ID
|
46
63
|
if @producer.params["isbn"].nil?
|
47
64
|
s << %Q[ <dc:identifier id="BookId">#{@producer.params["urnid"]}</dc:identifier>\n]
|
48
65
|
else
|
49
66
|
s << %Q[ <dc:identifier id="BookId" opf:scheme="ISBN">#{@producer.params["isbn"]}</dc:identifier>\n]
|
50
67
|
end
|
51
|
-
|
52
|
-
# creator
|
68
|
+
|
69
|
+
# creator (should be array)
|
53
70
|
%w[aut a-adp a-ann a-arr a-art a-asn a-aqt a-aft a-aui a-ant a-bkp a-clb a-cmm a-dsr a-edt a-ill a-lyr a-mdc a-mus a-nrt a-oth a-pht a-prt a-red a-rev a-spn a-ths a-trc a-trl].each do |role|
|
54
71
|
next if @producer.params[role].nil?
|
55
72
|
@producer.params[role].each do |v|
|
56
73
|
s << %Q[ <dc:creator opf:role="#{role.sub('a-', '')}">#{CGI.escapeHTML(v)}</dc:creator>\n]
|
57
74
|
end
|
58
75
|
end
|
59
|
-
|
76
|
+
|
77
|
+
# contributor (should be array)
|
60
78
|
%w[adp ann arr art asn aqt aft aui ant bkp clb cmm dsr edt ill lyr mdc mus nrt oth pht prt red rev spn ths trc trl].each do |role|
|
61
79
|
next if @producer.params[role].nil?
|
62
80
|
@producer.params[role].each do |v|
|
@@ -66,56 +84,70 @@ EOT
|
|
66
84
|
end
|
67
85
|
end
|
68
86
|
end
|
69
|
-
|
87
|
+
|
88
|
+
s
|
89
|
+
end
|
90
|
+
|
91
|
+
def opf_coverimage
|
92
|
+
s = ""
|
70
93
|
if @producer.params["coverimage"]
|
94
|
+
file = nil
|
71
95
|
@producer.contents.each do |item|
|
72
96
|
if item.media =~ /\Aimage/ && item.file =~ /#{@producer.params["coverimage"]}\Z/
|
73
|
-
|
97
|
+
s << %Q[ <meta name="cover" content="#{item.id}"/>\n]
|
98
|
+
file = item.file
|
74
99
|
break
|
75
100
|
end
|
76
101
|
end
|
102
|
+
raise "coverimage #{@producer.params["coverimage"]} not found. Abort." if file.nil?
|
77
103
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
104
|
+
s
|
105
|
+
end
|
106
|
+
|
107
|
+
def opf_manifest
|
108
|
+
s = ""
|
82
109
|
s << <<EOT
|
83
110
|
<manifest>
|
84
111
|
<item id="ncx" href="#{@producer.params["bookname"]}.ncx" media-type="application/x-dtbncx+xml"/>
|
85
112
|
<item id="#{@producer.params["bookname"]}" href="#{@producer.params["cover"]}" media-type="application/xhtml+xml"/>
|
86
113
|
EOT
|
87
114
|
|
88
|
-
s << %Q[ <item id="toc" href="#{@producer.params["
|
89
|
-
|
115
|
+
s << %Q[ <item id="toc" href="#{@producer.params["bookname"]}-toc.#{@producer.params["htmlext"]}" media-type="application/xhtml+xml"/>\n] unless @producer.params["mytoc"].nil?
|
116
|
+
|
90
117
|
@producer.contents.each do |item|
|
91
118
|
next if item.file =~ /#/ # skip subgroup
|
92
119
|
s << %Q[ <item id="#{item.id}" href="#{item.file}" media-type="#{item.media}"/>\n]
|
93
120
|
end
|
94
121
|
s << %Q[ </manifest>\n]
|
95
|
-
|
96
|
-
|
122
|
+
s
|
123
|
+
end
|
124
|
+
|
125
|
+
def opf_tocx
|
126
|
+
s = ""
|
97
127
|
s << %Q[ <spine toc="ncx">\n]
|
98
128
|
s << %Q[ <itemref idref="#{@producer.params["bookname"]}" linear="no"/>\n]
|
99
129
|
s << %Q[ <itemref idref="toc" />\n] unless @producer.params["mytoc"].nil?
|
100
|
-
|
130
|
+
|
101
131
|
@producer.contents.each do |item|
|
102
132
|
next if item.media !~ /xhtml\+xml/ # skip non XHTML
|
103
133
|
s << %Q[ <itemref idref="#{item.id}"/>\n] if item.notoc.nil?
|
104
134
|
end
|
105
135
|
s << %Q[ </spine>\n]
|
106
|
-
|
107
|
-
|
136
|
+
s
|
137
|
+
end
|
138
|
+
|
139
|
+
def opf_guide
|
140
|
+
s = ""
|
108
141
|
s << %Q[ <guide>\n]
|
109
142
|
s << %Q[ <reference type="cover" title="#{@producer.res.v("covertitle")}" href="#{@producer.params["cover"]}"/>\n]
|
110
|
-
s << %Q[ <reference type="title-page" title="#{@producer.res.v("titlepagetitle")}" href="
|
111
|
-
s << %Q[ <reference type="toc" title="#{@producer.res.v("toctitle")}" href="#{@producer.params["
|
112
|
-
s << %Q[ <reference type="colophon" title="#{@producer.res.v("colophontitle")}" href="colophon.#{@producer.params["htmlext"]}"/>\n] unless @producer.params["colophon"].nil?
|
143
|
+
s << %Q[ <reference type="title-page" title="#{@producer.res.v("titlepagetitle")}" href="titlepage.#{@producer.params["htmlext"]}"/>\n] unless @producer.params["titlepage"].nil?
|
144
|
+
s << %Q[ <reference type="toc" title="#{@producer.res.v("toctitle")}" href="#{@producer.params["bookname"]}-toc.#{@producer.params["htmlext"]}"/>\n] unless @producer.params["mytoc"].nil?
|
145
|
+
s << %Q[ <reference type="colophon" title="#{@producer.res.v("colophontitle")}" href="colophon.#{@producer.params["htmlext"]}"/>\n] unless @producer.params["colophon"].nil?
|
113
146
|
s << %Q[ </guide>\n]
|
114
|
-
s
|
115
|
-
return s
|
147
|
+
s
|
116
148
|
end
|
117
149
|
|
118
|
-
# Return ncx content. +indentarray+
|
150
|
+
# Return ncx content. +indentarray+ has prefix marks for each level.
|
119
151
|
def ncx(indentarray)
|
120
152
|
s = <<EOT
|
121
153
|
<?xml version="1.0" encoding="UTF-8"?>
|
@@ -125,20 +157,41 @@ EOT
|
|
125
157
|
<meta name="dtb:totalPageCount" content="0"/>
|
126
158
|
<meta name="dtb:maxPageNumber" content="0"/>
|
127
159
|
EOT
|
160
|
+
s << ncx_isbn
|
161
|
+
|
162
|
+
s << <<EOT
|
163
|
+
</head>
|
164
|
+
EOT
|
165
|
+
s << ncx_doctitle
|
166
|
+
s << ncx_navmap(indentarray)
|
167
|
+
|
168
|
+
s << <<EOT
|
169
|
+
</ncx>
|
170
|
+
EOT
|
171
|
+
s
|
172
|
+
end
|
173
|
+
|
174
|
+
def ncx_isbn
|
128
175
|
if @producer.params["isbn"].nil?
|
129
|
-
|
176
|
+
%Q[ <meta name="dtb:uid" content="#{@producer.params["urnid"]}"/>\n]
|
130
177
|
else
|
131
|
-
|
178
|
+
%Q[ <meta name="dtb:uid" content="#{@producer.params["isbn"]}"/>\n]
|
132
179
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
180
|
+
end
|
181
|
+
|
182
|
+
def ncx_doctitle
|
183
|
+
<<EOT
|
136
184
|
<docTitle>
|
137
185
|
<text>#{CGI.escapeHTML(@producer.params["title"])}</text>
|
138
186
|
</docTitle>
|
139
187
|
<docAuthor>
|
140
188
|
<text>#{@producer.params["aut"].nil? ? "" : CGI.escapeHTML(@producer.params["aut"].join(", "))}</text>
|
141
189
|
</docAuthor>
|
190
|
+
EOT
|
191
|
+
end
|
192
|
+
|
193
|
+
def ncx_navmap(indentarray)
|
194
|
+
s = <<EOT
|
142
195
|
<navMap>
|
143
196
|
<navPoint id="top" playOrder="1">
|
144
197
|
<navLabel>
|
@@ -149,19 +202,19 @@ EOT
|
|
149
202
|
EOT
|
150
203
|
|
151
204
|
nav_count = 2
|
152
|
-
|
205
|
+
|
153
206
|
unless @producer.params["mytoc"].nil?
|
154
207
|
s << <<EOT
|
155
208
|
<navPoint id="toc" playOrder="#{nav_count}">
|
156
209
|
<navLabel>
|
157
210
|
<text>#{@producer.res.v("toctitle")}</text>
|
158
211
|
</navLabel>
|
159
|
-
<content src="#{@producer.params["
|
212
|
+
<content src="#{@producer.params["bookname"]}-toc.#{@producer.params["htmlext"]}"/>
|
160
213
|
</navPoint>
|
161
214
|
EOT
|
162
215
|
nav_count += 1
|
163
216
|
end
|
164
|
-
|
217
|
+
|
165
218
|
@producer.contents.each do |item|
|
166
219
|
next if item.title.nil?
|
167
220
|
indent = indentarray.nil? ? [""] : indentarray
|
@@ -177,14 +230,13 @@ EOT
|
|
177
230
|
EOT
|
178
231
|
nav_count += 1
|
179
232
|
end
|
180
|
-
|
233
|
+
|
181
234
|
s << <<EOT
|
182
235
|
</navMap>
|
183
|
-
</ncx>
|
184
236
|
EOT
|
185
|
-
|
237
|
+
s
|
186
238
|
end
|
187
|
-
|
239
|
+
|
188
240
|
# Return container content.
|
189
241
|
def container
|
190
242
|
s = <<EOT
|
@@ -195,9 +247,9 @@ EOT
|
|
195
247
|
</rootfiles>
|
196
248
|
</container>
|
197
249
|
EOT
|
198
|
-
|
250
|
+
s
|
199
251
|
end
|
200
|
-
|
252
|
+
|
201
253
|
# Return cover content.
|
202
254
|
def cover
|
203
255
|
s = common_header
|
@@ -224,13 +276,13 @@ EOT
|
|
224
276
|
<img src="#{file}" alt="#{CGI.escapeHTML(@producer.params["title"])}" class="max"/>
|
225
277
|
</div>
|
226
278
|
EOT
|
227
|
-
|
228
|
-
|
279
|
+
end
|
280
|
+
|
229
281
|
s << <<EOT
|
230
282
|
</body>
|
231
283
|
</html>
|
232
284
|
EOT
|
233
|
-
|
285
|
+
s
|
234
286
|
end
|
235
287
|
|
236
288
|
# Return title (copying) content.
|
@@ -249,7 +301,7 @@ EOT
|
|
249
301
|
<br />
|
250
302
|
<br />
|
251
303
|
</p>
|
252
|
-
<h2 class="tp-author">#{CGI.escapeHTML(@producer.params["aut"])}</h2>
|
304
|
+
<h2 class="tp-author">#{CGI.escapeHTML(@producer.params["aut"].join(", "))}</h2>
|
253
305
|
EOT
|
254
306
|
end
|
255
307
|
|
@@ -261,7 +313,7 @@ EOT
|
|
261
313
|
<br />
|
262
314
|
<br />
|
263
315
|
</p>
|
264
|
-
<h3 class="tp-publisher">#{CGI.escapeHTML(@producer.params["prt"])}</h3>
|
316
|
+
<h3 class="tp-publisher">#{CGI.escapeHTML(@producer.params["prt"].join(", "))}</h3>
|
265
317
|
EOT
|
266
318
|
end
|
267
319
|
|
@@ -269,7 +321,8 @@ EOT
|
|
269
321
|
</body>
|
270
322
|
</html>
|
271
323
|
EOT
|
272
|
-
|
324
|
+
|
325
|
+
s
|
273
326
|
end
|
274
327
|
|
275
328
|
# Return colophon content.
|
@@ -280,26 +333,65 @@ EOT
|
|
280
333
|
</head>
|
281
334
|
<body>
|
282
335
|
<div class="colophon">
|
336
|
+
EOT
|
337
|
+
|
338
|
+
if @producer.params["subtitle"].nil?
|
339
|
+
s << <<EOT
|
283
340
|
<p class="title">#{CGI.escapeHTML(@producer.params["title"])}</p>
|
284
341
|
EOT
|
342
|
+
else
|
343
|
+
s << <<EOT
|
344
|
+
<p class="title">#{CGI.escapeHTML(@producer.params["title"])}<br /><span class="subtitle">#{CGI.escapeHTML(@producer.params["subtitle"])}</span></p>
|
345
|
+
EOT
|
346
|
+
end
|
285
347
|
|
286
|
-
if @producer.params["
|
287
|
-
s << %Q[ <div class="pubhistory">\n
|
348
|
+
if @producer.params["date"] || @producer.params["history"]
|
349
|
+
s << %Q[ <div class="pubhistory">\n]
|
350
|
+
if @producer.params["history"]
|
351
|
+
@producer.params["history"].each_with_index do |items, edit|
|
352
|
+
items.each_with_index do |item, rev|
|
353
|
+
editstr = (edit == 0) ? "初版" : "第#{edit + 1}版" # FIXME:i18n
|
354
|
+
revstr = "第#{rev + 1}刷"
|
355
|
+
s << %Q[ <p>#{date_to_s(item)} #{editstr}#{revstr} 発行</p>\n] # FIXME:i18n
|
356
|
+
end
|
357
|
+
end
|
358
|
+
else
|
359
|
+
s << %Q[ <p>#{date_to_s(@producer.params["date"])} 発行</p>\n] #FIXME:i18n
|
360
|
+
end
|
361
|
+
s << %Q[ </div>\n]
|
288
362
|
end
|
289
|
-
|
363
|
+
|
290
364
|
s << %Q[ <table class="colophon">\n]
|
291
|
-
s << %Q[ <tr><th>#{@producer.res.v("c-aut")}</th><td>#{CGI.escapeHTML(@producer.params["aut"])}</td></tr>\n]
|
292
|
-
s << %Q[ <tr><th>#{@producer.res.v("c-
|
293
|
-
s << %Q[ <tr><th>#{@producer.res.v("c-
|
294
|
-
s << %Q[ <tr><th>#{@producer.res.v("c-
|
295
|
-
s << %Q[ <tr><th>#{@producer.res.v("c-
|
365
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-aut")}</th><td>#{CGI.escapeHTML(@producer.params["aut"].join(", "))}</td></tr>\n] unless @producer.params["aut"].nil?
|
366
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-csl")}</th><td>#{CGI.escapeHTML(@producer.params["csl"].join(", "))}</td></tr>\n] unless @producer.params["csl"].nil?
|
367
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-trl")}</th><td>#{CGI.escapeHTML(@producer.params["trl"].join(", "))}</td></tr>\n] unless @producer.params["trl"].nil?
|
368
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-dsr")}</th><td>#{CGI.escapeHTML(@producer.params["dsr"].join(", "))}</td></tr>\n] unless @producer.params["dsr"].nil?
|
369
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-ill")}</th><td>#{CGI.escapeHTML(@producer.params["ill"].join(", "))}</td></tr>\n] unless @producer.params["ill"].nil?
|
370
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-edt")}</th><td>#{CGI.escapeHTML(@producer.params["edt"].join(", "))}</td></tr>\n] unless @producer.params["edt"].nil?
|
371
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-prt")}</th><td>#{CGI.escapeHTML(@producer.params["prt"].join(", "))}</td></tr>\n] unless @producer.params["prt"].nil?
|
372
|
+
s << %Q[ <tr><th>#{@producer.res.v("c-pht")}</th><td>#{CGI.escapeHTML(@producer.params["pht"].join(", "))}</td></tr>\n] unless @producer.params["pht"].nil?
|
373
|
+
if @producer.params["isbn"].to_s =~ /\A\d{10}\Z/ || @producer.params["isbn"].to_s =~ /\A\d{13}\Z/
|
374
|
+
isbn = nil
|
375
|
+
str = @producer.params["isbn"].to_s
|
376
|
+
if str.size == 10
|
377
|
+
isbn = "#{str[0..0]}-#{str[1..5]}-#{str[6..8]}-#{str[9..9]}"
|
378
|
+
else
|
379
|
+
isbn = "#{str[0..2]}-#{str[3..3]}-#{str[4..8]}-#{str[9..11]}-#{str[12..12]}"
|
380
|
+
end
|
381
|
+
s << %Q[ <tr><th>ISBN</th><td>#{isbn}</td></tr>\n]
|
382
|
+
end
|
296
383
|
s << <<EOT
|
297
384
|
</table>
|
298
385
|
</div>
|
299
386
|
</body>
|
300
387
|
</html>
|
301
388
|
EOT
|
302
|
-
|
389
|
+
s
|
390
|
+
end
|
391
|
+
|
392
|
+
def date_to_s(date)
|
393
|
+
ymd = date.to_s.split('-')
|
394
|
+
"#{ymd[0]}年#{ymd[1].sub(/\A0/, '')}月#{ymd[2].sub(/\A0/, '')}日" # FIXME:i18n
|
303
395
|
end
|
304
396
|
|
305
397
|
# Return own toc content.
|
@@ -310,68 +402,109 @@ EOT
|
|
310
402
|
</head>
|
311
403
|
<body>
|
312
404
|
<h1 class="toc-title">#{@producer.res.v("toctitle")}</h1>
|
313
|
-
<ul class="toc-h1">
|
314
405
|
EOT
|
315
406
|
|
316
|
-
|
317
|
-
|
318
|
-
|
407
|
+
if @producer.params["flattoc"].nil?
|
408
|
+
s << hierarchy_ncx("ul")
|
409
|
+
else
|
410
|
+
s << flat_ncx("ul", @producer.params["flattocindent"])
|
411
|
+
end
|
412
|
+
|
413
|
+
s << <<EOT
|
414
|
+
</body>
|
415
|
+
</html>
|
416
|
+
EOT
|
417
|
+
s
|
418
|
+
end
|
419
|
+
|
420
|
+
def hierarchy_ncx(type)
|
421
|
+
require 'rexml/document'
|
422
|
+
level = 1
|
423
|
+
find_jump = nil
|
424
|
+
|
425
|
+
# check part existance
|
426
|
+
@producer.contents.each do |item|
|
427
|
+
if item.notoc.nil? && item.level == 0
|
428
|
+
level = 0
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
doc = REXML::Document.new(%Q[<#{type} class="toc-h#{level}"><li /></#{type}>])
|
433
|
+
|
434
|
+
e = doc.root.elements[1] # first <li/>
|
319
435
|
@producer.contents.each do |item|
|
320
436
|
next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > @producer.params["toclevel"].to_i
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
437
|
+
|
438
|
+
if item.level == level
|
439
|
+
e2 = e.parent.add_element("li")
|
440
|
+
e = e2
|
441
|
+
elsif item.level > level
|
442
|
+
find_jump = true if (item.level - level) > 1
|
443
|
+
# deeper
|
444
|
+
(level + 1).upto(item.level) do |n|
|
445
|
+
e2 = e.add_element(type, {"class" => "toc-h#{n}"})
|
446
|
+
e3 = e2.add_element("li")
|
447
|
+
e = e3
|
327
448
|
end
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
449
|
+
level = item.level
|
450
|
+
elsif item.level < level
|
451
|
+
# shallower
|
452
|
+
(level - 1).downto(item.level) do |n|
|
453
|
+
e = e.parent.parent
|
454
|
+
end
|
455
|
+
e2 = e.parent.add_element("li")
|
456
|
+
e = e2
|
457
|
+
level = item.level
|
334
458
|
end
|
335
|
-
|
336
|
-
|
337
|
-
end
|
338
|
-
|
339
|
-
(current - 1).downto(1) do |n|
|
340
|
-
s << %Q[</li>\n</ul>\n]
|
459
|
+
e2 = e.add_element("a", {"href" => item.file})
|
460
|
+
e2.add_text(REXML::Text.new(item.title, true))
|
341
461
|
end
|
342
|
-
|
343
|
-
|
462
|
+
|
463
|
+
warn "found level jumping in table of contents. consider to use 'flattoc: true' for strict ePUB validator." unless find_jump.nil?
|
464
|
+
|
465
|
+
doc.to_s.gsub("<li/>", "").gsub("</li>", "</li>\n").gsub("href='", "href=\"").gsub(" class='", " class=\"").gsub("'>", "\">").gsub("<#{type} ", "\n" + '\&') # ugly
|
466
|
+
end
|
467
|
+
|
468
|
+
def flat_ncx(type, indent=nil)
|
469
|
+
s = %Q[<#{type} class="toc-h1">\n]
|
470
|
+
@producer.contents.each do |item|
|
471
|
+
next if !item.notoc.nil? || item.level.nil? || item.file.nil? || item.title.nil? || item.level > @producer.params["toclevel"].to_i
|
472
|
+
is = indent == true ? " " * item.level : ""
|
473
|
+
s << %Q[<li><a href="#{item.file}">#{is}#{item.title}</a></li>\n]
|
344
474
|
end
|
345
|
-
s <<
|
346
|
-
|
347
|
-
|
348
|
-
</html>
|
349
|
-
EOT
|
350
|
-
return s
|
475
|
+
s << %Q[</#{type}>\n]
|
476
|
+
|
477
|
+
s
|
351
478
|
end
|
352
479
|
|
353
480
|
# Produce EPUB file +epubfile+.
|
354
481
|
# +basedir+ points the directory has contents.
|
355
482
|
# +tmpdir+ defines temporary directory.
|
356
483
|
def produce(epubfile, basedir, tmpdir)
|
484
|
+
produce_write_common(basedir, tmpdir)
|
485
|
+
|
486
|
+
File.open("#{tmpdir}/OEBPS/#{@producer.params["bookname"]}.ncx", "w") {|f| @producer.ncx(f, @producer.params["ncxindent"]) }
|
487
|
+
File.open("#{tmpdir}/OEBPS/#{@producer.params["bookname"]}-toc.#{@producer.params["htmlext"]}", "w") {|f| @producer.mytoc(f) } unless @producer.params["mytoc"].nil?
|
488
|
+
|
489
|
+
@producer.call_hook(@producer.params["hook_prepack"], tmpdir)
|
490
|
+
export_zip(tmpdir, epubfile)
|
491
|
+
end
|
492
|
+
|
493
|
+
def produce_write_common(basedir, tmpdir)
|
357
494
|
File.open("#{tmpdir}/mimetype", "w") {|f| @producer.mimetype(f) }
|
358
|
-
|
495
|
+
|
359
496
|
Dir.mkdir("#{tmpdir}/META-INF") unless File.exist?("#{tmpdir}/META-INF")
|
360
497
|
File.open("#{tmpdir}/META-INF/container.xml", "w") {|f| @producer.container(f) }
|
361
|
-
|
498
|
+
|
362
499
|
Dir.mkdir("#{tmpdir}/OEBPS") unless File.exist?("#{tmpdir}/OEBPS")
|
363
500
|
File.open("#{tmpdir}/OEBPS/#{@producer.params["bookname"]}.opf", "w") {|f| @producer.opf(f) }
|
364
|
-
|
365
|
-
File.open("#{tmpdir}/OEBPS/#{@producer.params["tocfile"]}", "w") {|f| @producer.mytoc(f) } unless @producer.params["mytoc"].nil?
|
366
|
-
|
501
|
+
|
367
502
|
if File.exist?("#{basedir}/#{@producer.params["cover"]}")
|
368
503
|
FileUtils.cp("#{basedir}/#{@producer.params["cover"]}", "#{tmpdir}/OEBPS")
|
369
504
|
else
|
370
505
|
File.open("#{tmpdir}/OEBPS/#{@producer.params["cover"]}", "w") {|f| @producer.cover(f) }
|
371
506
|
end
|
372
|
-
|
373
|
-
# FIXME:colophon and titlepage should be included in @producer.contents.
|
374
|
-
|
507
|
+
|
375
508
|
@producer.contents.each do |item|
|
376
509
|
next if item.file =~ /#/ # skip subgroup
|
377
510
|
fname = "#{basedir}/#{item.file}"
|
@@ -379,19 +512,11 @@ EOT
|
|
379
512
|
FileUtils.mkdir_p(File.dirname("#{tmpdir}/OEBPS/#{item.file}")) unless File.exist?(File.dirname("#{tmpdir}/OEBPS/#{item.file}"))
|
380
513
|
FileUtils.cp(fname, "#{tmpdir}/OEBPS/#{item.file}")
|
381
514
|
end
|
515
|
+
end
|
382
516
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
}
|
387
|
-
}
|
388
|
-
Process.waitall
|
389
|
-
fork {
|
390
|
-
Dir.chdir(tmpdir) {|d|
|
391
|
-
exec("zip", "-Xr9D", "#{epubfile}", "META-INF", "OEBPS")
|
392
|
-
}
|
393
|
-
}
|
394
|
-
Process.waitall
|
517
|
+
def export_zip(tmpdir, epubfile)
|
518
|
+
Dir.chdir(tmpdir) {|d| system("#{@producer.params["zip_stage1"]} #{epubfile} mimetype") }
|
519
|
+
Dir.chdir(tmpdir) {|d| system("#{@producer.params["zip_stage2"]} #{epubfile} META-INF OEBPS") }
|
395
520
|
end
|
396
521
|
|
397
522
|
private
|
@@ -411,8 +536,7 @@ EOT
|
|
411
536
|
@producer.params["stylesheet"].each do |file|
|
412
537
|
s << %Q[ <link rel="stylesheet" type="text/css" href="#{file}"/>\n]
|
413
538
|
end
|
414
|
-
|
539
|
+
s
|
415
540
|
end
|
416
541
|
end
|
417
|
-
|
418
542
|
end
|