review 2.0.0.beta1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +66 -1
  3. data/.rubocop_todo.yml +617 -0
  4. data/.travis.yml +16 -1
  5. data/ChangeLog +48 -0
  6. data/Dockerfile +22 -0
  7. data/Gemfile +0 -1
  8. data/README.md +97 -0
  9. data/Rakefile +10 -11
  10. data/appveyor.yml +9 -0
  11. data/bin/review +46 -0
  12. data/bin/review-check +8 -21
  13. data/bin/review-compile +26 -43
  14. data/bin/review-index +9 -22
  15. data/bin/review-init +21 -25
  16. data/bin/review-preproc +9 -13
  17. data/bin/review-validate +1 -1
  18. data/bin/review-vol +3 -17
  19. data/bin/review-webmaker +15 -0
  20. data/doc/NEWS.ja.md +534 -0
  21. data/doc/NEWS.md +538 -0
  22. data/doc/catalog.ja.md +10 -18
  23. data/doc/catalog.md +5 -9
  24. data/doc/config.yml.sample +319 -0
  25. data/doc/customize_epub.ja.md +42 -0
  26. data/doc/format.ja.md +320 -288
  27. data/doc/format.md +277 -170
  28. data/doc/format_idg.ja.md +82 -175
  29. data/doc/pdfmaker.ja.md +61 -0
  30. data/doc/pdfmaker.md +65 -0
  31. data/doc/quickstart.ja.md +88 -98
  32. data/doc/quickstart.md +72 -110
  33. data/doc/sample.css +41 -0
  34. data/doc/writing_vertical.ja.md +55 -0
  35. data/doc/writing_vertical.md +5 -0
  36. data/lib/epubmaker/content.rb +3 -3
  37. data/lib/epubmaker/epubcommon.rb +173 -145
  38. data/lib/epubmaker/epubv2.rb +24 -77
  39. data/lib/epubmaker/epubv3.rb +72 -73
  40. data/lib/epubmaker/producer.rb +54 -30
  41. data/lib/lineinput.rb +48 -0
  42. data/lib/review/book.rb +0 -1
  43. data/lib/review/book/base.rb +47 -27
  44. data/lib/review/book/chapter.rb +48 -19
  45. data/lib/review/book/compilable.rb +10 -14
  46. data/lib/review/book/index.rb +10 -19
  47. data/lib/review/book/page_metric.rb +0 -10
  48. data/lib/review/book/part.rb +17 -3
  49. data/lib/review/builder.rb +84 -68
  50. data/lib/review/catalog.rb +5 -1
  51. data/lib/review/compiler.rb +327 -4657
  52. data/lib/review/configure.rb +84 -10
  53. data/lib/review/converter.rb +28 -0
  54. data/lib/review/epubbuilder.rb +1 -1
  55. data/lib/review/epubmaker.rb +142 -158
  56. data/lib/review/ewbbuilder.rb +5 -5
  57. data/lib/review/exception.rb +1 -1
  58. data/lib/review/extentions.rb +1 -1
  59. data/lib/review/extentions/hash.rb +15 -0
  60. data/lib/review/extentions/string.rb +2 -1
  61. data/lib/review/htmlbuilder.rb +364 -348
  62. data/lib/review/htmltoc.rb +44 -0
  63. data/lib/review/htmlutils.rb +12 -6
  64. data/lib/review/i18n.rb +78 -6
  65. data/lib/review/i18n.yml +7 -4
  66. data/lib/review/idgxmlbuilder.rb +226 -267
  67. data/lib/review/latexbuilder.rb +281 -274
  68. data/lib/review/latexutils.rb +56 -49
  69. data/lib/review/makerhelper.rb +8 -4
  70. data/lib/review/markdownbuilder.rb +80 -124
  71. data/lib/review/pdfmaker.rb +197 -138
  72. data/lib/review/preprocessor.rb +16 -67
  73. data/lib/review/template.rb +24 -0
  74. data/lib/review/textbuilder.rb +1 -1
  75. data/lib/review/textutils.rb +18 -24
  76. data/lib/review/tocparser.rb +51 -106
  77. data/lib/review/tocprinter.rb +61 -117
  78. data/lib/review/topbuilder.rb +119 -126
  79. data/lib/review/unfold.rb +2 -2
  80. data/lib/review/version.rb +1 -1
  81. data/lib/review/webmaker.rb +302 -0
  82. data/lib/review/webtocprinter.rb +48 -0
  83. data/lib/review/yamlloader.rb +47 -0
  84. data/review.gemspec +3 -3
  85. data/templates/html/layout-html5.html.erb +17 -0
  86. data/templates/html/layout-xhtml1.html.erb +20 -0
  87. data/{lib/review → templates/latex}/layout.tex.erb +107 -115
  88. data/templates/ncx/epubv2.ncx.erb +11 -0
  89. data/templates/opf/epubv2.opf.erb +21 -0
  90. data/templates/opf/epubv3.opf.erb +18 -0
  91. data/templates/web/html/layout-html5.html.erb +56 -0
  92. data/templates/web/html/layout-xhtml1.html.erb +20 -0
  93. data/templates/xml/container.xml.erb +6 -0
  94. data/test/assets/test.xml.erb +3 -0
  95. data/test/assets/test_template.tex +28 -71
  96. data/test/assets/test_template_backmatter.tex +1 -9
  97. data/test/sample-book/src/Rakefile +12 -3
  98. data/{doc/sample.yml → test/sample-book/src/config-epub2.yml} +92 -147
  99. data/test/sample-book/src/config.yml +40 -154
  100. data/test/sample-book/src/style-web.css +45 -0
  101. data/test/sample-book/src/style.css +23 -1
  102. data/test/test.re +1 -1
  103. data/test/test_book.rb +15 -17
  104. data/test/test_book_chapter.rb +2 -80
  105. data/test/test_book_part.rb +1 -1
  106. data/test/test_builder.rb +28 -6
  107. data/test/test_catalog.rb +17 -0
  108. data/test/test_compiler.rb +14 -59
  109. data/test/test_configure.rb +94 -0
  110. data/test/test_converter.rb +21 -0
  111. data/test/test_epub3maker.rb +155 -3
  112. data/test/test_epubmaker.rb +245 -30
  113. data/test/test_epubmaker_cmd.rb +2 -2
  114. data/test/test_extentions_hash.rb +60 -0
  115. data/test/test_helper.rb +4 -47
  116. data/test/test_htmlbuilder.rb +282 -175
  117. data/test/test_htmltoc.rb +33 -0
  118. data/test/test_i18n.rb +134 -70
  119. data/test/test_idgxmlbuilder.rb +58 -39
  120. data/test/test_latexbuilder.rb +132 -14
  121. data/test/test_lineinput.rb +5 -26
  122. data/test/test_makerhelper.rb +6 -4
  123. data/test/test_markdownbuilder.rb +23 -5
  124. data/test/test_pdfmaker.rb +86 -20
  125. data/test/test_pdfmaker_cmd.rb +1 -3
  126. data/test/test_review_ext.rb +1 -1
  127. data/test/test_template.rb +27 -0
  128. data/test/test_textutils.rb +36 -0
  129. data/test/test_tocparser.rb +25 -0
  130. data/test/test_topbuilder.rb +34 -2
  131. data/test/test_yamlloader.rb +188 -0
  132. metadata +71 -29
  133. data/README.rdoc +0 -81
  134. data/bin/review-epubmaker-legacy +0 -1024
  135. data/doc/ruby-uuid/README +0 -11
  136. data/doc/ruby-uuid/README.ja +0 -34
  137. data/lib/review/compiler/literals_1_8.kpeg +0 -19
  138. data/lib/review/compiler/literals_1_8.rb +0 -432
  139. data/lib/review/compiler/literals_1_9.kpeg +0 -22
  140. data/lib/review/compiler/literals_1_9.rb +0 -435
  141. data/lib/review/extentions/array.rb +0 -25
  142. data/lib/review/htmllayout.rb +0 -41
  143. data/lib/review/inaobuilder.rb +0 -357
  144. data/lib/review/location.rb +0 -24
  145. data/lib/review/node.rb +0 -267
  146. data/lib/review/review.kpeg +0 -724
  147. data/lib/uuid.rb +0 -312
  148. data/rubocop-todo.yml +0 -456
  149. data/test/test_inaobuilder.rb +0 -247
  150. data/test/test_uuid.rb +0 -157
@@ -9,11 +9,13 @@ Re:VIEW is free software under the terms of the GNU Lesser General Public Licens
9
9
 
10
10
  This article describes how to setup Re:VIEW and use it.
11
11
 
12
+ The supported version of the article is Re:VIEW 2.0.
13
+
12
14
  ## Set up Re:VIEW
13
15
 
14
- Re:VIEW is a software in Ruby and worked in Linux/Unix, Mac OS X, and Cygwin. You can install Re:VIEW with RubyGems, Git or Subversion.
16
+ Re:VIEW is a software in Ruby and worked in Linux/Unix, Mac OS X, and Windows. You can install Re:VIEW with RubyGems or Git.
15
17
 
16
- Note that Re:VIEW format is tagged text file, so you can write it on any editors and OSes.
18
+ Note that Re:VIEW format is plain texts with simple markups in UTF-8, so you can write it on any editors and OSes.
17
19
 
18
20
  ### using RubyGmes
19
21
 
@@ -55,23 +57,9 @@ You can update the sources as follows:
55
57
  $ git pull
56
58
  ```
57
59
 
58
- ### using Subversion
59
-
60
- For non git users and environments, Re:VIEW is also distributed with Subversion.
61
-
62
- ```bash
63
- $ svn co https://kmuto.jp/svn/review/trunk review
64
- ```
65
-
66
- You can use Re:VIEW to add `review/bin` directory to `$PATH` variable.
67
-
68
- You can update the sources as follows:
69
-
70
- ```bash
71
- $ svn up
72
- ```
60
+ ## Writing Re:VIEW Document
73
61
 
74
- # writing Re:VIEW documents and converting them
62
+ ### Generating template fiels
75
63
 
76
64
  After setup, you can use `review-init` command to generate Re:VIEW project directory.
77
65
 
@@ -84,32 +72,22 @@ $ ls hello
84
72
  Rakefile catalog.yml config.yml hello.re images/ layouts/ sty/ style.css
85
73
  ```
86
74
 
87
- In `hello` directory, many files are generated. `*.re` files are Re:VIEW format file.
88
- If you make `hello` project, a file `hello.re` is generated.
75
+ In `hello` directory, many files are generated.
89
76
 
90
- `catalog.yml` file is a catalog of Re:VIEW format files.
77
+ * `*.re` : Re:VIEW format file.
78
+ * config.yml : configuration file
79
+ * catalog.yml : catalog file (for TOC)
80
+ * Rakefile : rule file for `rake` command
81
+ * images : folder for images
82
+ * layouts : forlder for layout files
83
+ * style.css : sample stylesheet
84
+ * sty : style files for LaTeX
91
85
 
92
- ```bash
93
- $ cat catalog.yml
94
- PREDEF:
95
-
96
- CHAPS:
97
- - hello.re
98
-
99
- APPENDIX:
100
-
101
- POSTDEF:
102
- ```
103
-
104
- The first item in CHAPS is the first chapter, and the second item (if you add) is the second chapter. PREDEF is for front matter, APPENDIX is for appendix, and POSTDEF is for back matter.
105
-
106
- If you create new `*.re` files as new chapters, you should add the name of files into `catalog.yml`.
107
-
108
- Now you can edit `hello.re`. A simple example of Re:VIEW format text is as follows.
109
86
 
87
+ ### writing Re:VIEW documents and converting them
110
88
 
111
89
  ```review
112
- = my first Re:VIEW
90
+ = My First Re:VIEW
113
91
 
114
92
  //lead{
115
93
  "Hello, Re:VIEW."
@@ -130,81 +108,79 @@ You can install Re:VIEW with:
130
108
 
131
109
  1. RubyGems
132
110
  2. Git
133
- 3. Subversion
111
+ 3. Download from GitHub
134
112
 
135
- For more information, see @<tt>{https://github.com/kmuto/review/wiki/}.
113
+ The web site of Re:VIEW is @<tt>{https://reviewml.org/}.
136
114
  ```
137
115
 
138
116
  You should use UTF-8 as encodings in text files.
139
117
 
140
- To convert hello.re, you can use `review-compile` command.
118
+ ### generating PDF and EPUB
119
+
120
+ You can generate a PDF file with `review-pdfmaker` command. Also you can generate an EPUB file with `review-epubmaker` command.
121
+
122
+ To generate PDF, you should install TeXLive 2012 or later. To generate EPUB, you should install zip command.
123
+ When you want to use MathML, you should install [MathML library](http://www.hinet.mydns.jp/?mathml.rb)
124
+
125
+ `review-pdfmaker` and `review-epubmaker` need `config.yml`, configuration YAML files. `review-init` command generates `config.yml` in default.
141
126
 
142
127
  ```bash
143
- $ review-compile --target html hello.re > hello.html ## generating HTML
144
- $ review-compile --target latex hello.re > hello.tex ## generating LaTeX
145
- $ review-compile --target idgxml hello.re > hello.xml ## generating XML for InDesing
128
+ $ review-pdfmaker config.yml ## generate PDF
129
+ $ review-epubmaker config.yml ## generate EPUB
146
130
  ```
147
131
 
148
- You can convert all `*.re` files in `catalog.yml` with `-a` option.
132
+ You also can generate them with Rake.
149
133
 
134
+ ```bash
135
+ $ rake pdf ## generate PDF
136
+ $ rake epub ## generate EPUB
150
137
  ```
151
- $ review-compile --target html -a ## convert all files into HTML
152
- ```
153
138
 
154
- You can get HTML file as follows:
155
-
156
- ```html
157
- <?xml version="1.0" encoding="UTF-8"?>
158
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
159
- <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
160
- <head>
161
- <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
162
- <meta http-equiv="Content-Style-Type" content="text/css" />
163
- <link rel="stylesheet" type="text/css" href="style.css" />
164
- <meta name="generator" content="Re:VIEW" />
165
- <title>my first Re:VIEW</title>
166
- </head>
167
- <body>
168
- <h1><a id="h1"></a>第1章 my first Re:VIEW</h1>
169
- <div class="lead">
170
- <p>&quot;Hello, Re:VIEW.&quot;</p>
171
- </div>
172
-
173
- <h2><a id="h1-1"></a>1.1 What's Re:VIEW</h2>
174
- <p><b>Re:VIEW</b> is a converter from simple markup documents into various formats.</p>
175
- <p>You can generate documents as follows:</p>
176
- <ul>
177
- <li>text with tagging</li>
178
- <li>LaTeX</li>
179
- <li>HTML</li>
180
- <li>XML</li>
181
- </ul>
182
- <p>You can install Re:VIEW with:</p>
183
- <ol>
184
- <li>RubyGems</li>
185
- <li>Git</li>
186
- <li>Subversion</li>
187
- </ol>
188
- <p>For more information, see <tt>https://github.com/kmuto/review/wiki/</tt>.</p>
189
-
190
- </body>
191
- </html>
139
+
140
+ There is a sample YAML file [config.yml.sample](https://github.com/kmuto/review/blob/master/doc/config.yml.sample) in the same directory of this document.
141
+
142
+ ### add chapters and modify them
143
+
144
+ `catalog.yml` file is a catalog of Re:VIEW format files.
145
+
146
+ If you create new `*.re` files as new chapters, you should add the name of files into `catalog.yml`.
147
+
148
+ ```bash
149
+ $ cat catalog.yml
150
+ PREDEF:
151
+
152
+ CHAPS:
153
+ - first-chapter.re
154
+ - second-chapter.re
155
+
156
+ APPENDIX:
157
+
158
+ POSTDEF:
192
159
  ```
193
160
 
194
- For more information about Re:VIEW format, see [format.rdoc](https://github.com/kmuto/review/blob/master/doc/format.rdoc).
161
+ The first item in CHAPS is the first chapter, and the second item (if you add) is the second chapter. PREDEF is for front matter, APPENDIX is for appendix, and POSTDEF is for back matter. You can see in detail with [catalog.md](https://github.com/kmuto/review/blob/master/doc/catalog.ja.md).
195
162
 
196
- review-compile and other commands in Re:VIEW has `--help` option to output help. `review-compile` has many options, so you may see them.
197
163
 
198
- If you don't want to type `--target` every time, you can use symbolic links to `review-compile`. You can use new commands `review2html` and so on.
164
+ ### more information
165
+
166
+ For more information about Re:VIEW format, see [format.md](https://github.com/kmuto/review/blob/master/doc/format.md).
167
+
168
+ ## convert file by file
169
+
170
+ You can convert a *.re file with `review-compile` command.
171
+
172
+ When you want to convert sample.re, you can do as belows:
199
173
 
200
174
  ```bash
201
- $ cd path/to/review/bin
202
- $ ln -s review-compile review2text
203
- $ ln -s review-compile review2html
204
- $ ln -s review-compile review2latex
205
- $ ln -s review-compile review2idgxml
175
+ $ review-compile --target text sample.re > sample.txt ## for text
176
+ $ review-compile --target html sample.re > sample.html ## for HTML
177
+ $ review-compile --target latex sample.re > sample.tex ## for LaTeX
178
+ $ review-compile --target idgxml sample.re > sample.xml ## for XML
179
+ $ review-compile --target markdown sample.re > sample.md ## for Markdown
206
180
  ```
207
181
 
182
+ `review-compile` and other commands in Re:VIEW has `--help` option to output help. `review-compile` has many options, so you may see them.
183
+
208
184
  ## preprocessor and other commands
209
185
 
210
186
  With Re:VIEW tags such as `#@mapfile`, `#@maprange` and `#@mapoutput`, you can include content of files or result of command execution. To do so, you use `review-preproc` command.
@@ -228,25 +204,11 @@ You can also use `review-index` command to generate header list.
228
204
  $ review-index --level <heading level> -a
229
205
  ```
230
206
 
231
- ## generating PDF and EPUB
232
-
233
- You can generate PDF and EPUB as:
234
-
235
- ```bash
236
- $ review-pdfmaker config.yml ## generate PDF
237
- $ review-epubmaker config.yml ## generate EPUB
238
- ```
239
-
240
- To generate PDF, you should install TeXLive 2012 or later. To generate EPUB, you should install zip command.
241
- When you want to use MathML, you should install [MathML library](http://www.hinet.mydns.jp/?mathml.rb)
242
-
243
- `review-pdfmaker` and `review-epubmaker` need `config.yml`, configuration YAML files. There is a sample YAML file [sample.yml](https://github.com/kmuto/review/blob/master/doc/sample.yml) in the same directory of this document.
244
-
245
-
246
207
  ## Copyright
247
208
 
248
- The original author of Re:VIEW is Minero Aoki. The current maintainer is Kenshi Muto(@kmuto), and committers are Masayoshi Takahashi and Masanori Kado (2015/01).
209
+ The original author of Re:VIEW is Minero Aoki. The current maintainer is Kenshi Muto(@kmuto), and committers are Masayoshi Takahashi and Masanori Kado (2016/04).
249
210
 
250
211
  If you want to report bugs and patches, or to get more information, see:
251
212
 
213
+ * http://reviewml.org/
252
214
  * https://github.com/kmuto/review/wiki
@@ -106,3 +106,44 @@ p.noindent {
106
106
  p.flushright {
107
107
  text-align: right;
108
108
  }
109
+
110
+
111
+ /**
112
+ * from EBPAJ EPUB 3 File Creation Guide sample style
113
+ *
114
+ * cf. http://ebpaj.jp/counsel/guide
115
+ */
116
+
117
+ /* image width definition(pacentage) */
118
+ .width-010per { width: 10%; }
119
+ .width-020per { width: 20%; }
120
+ .width-025per { width: 25%; }
121
+ .width-030per { width: 30%; }
122
+ .width-033per { width: 33%; }
123
+ .width-040per { width: 40%; }
124
+ .width-050per { width: 50%; }
125
+ .width-060per { width: 60%; }
126
+ .width-067per { width: 67%; }
127
+ .width-070per { width: 70%; }
128
+ .width-075per { width: 75%; }
129
+ .width-080per { width: 80%; }
130
+ .width-090per { width: 90%; }
131
+ .width-100per { width: 100%; }
132
+
133
+ .tcy {
134
+ -webkit-text-combine: horizontal;
135
+ -webkit-text-combine-upright: all;
136
+ text-combine-upright: all;
137
+ -epub-text-combine: horizontal;
138
+ }
139
+
140
+ upright-1 {
141
+ -webkit-text-combine: horizontal;
142
+ -webkit-text-combine-upright: all;
143
+ text-combine-upright: all;
144
+ -epub-text-combine: horizontal;
145
+ }
146
+ .upright {
147
+ -webkit-text-orientation: upright;
148
+ -epub-text-orientation: upright;
149
+ }
@@ -0,0 +1,55 @@
1
+ # 縦書きのサポート(実験的)
2
+
3
+ Re:VIEW 2.0 より、縦書きの実験的なサポートを含めています。このドキュメントでその利用方法を説明します。
4
+
5
+ このドキュメントは、Re:VIEW 2.0 に基づいています。
6
+
7
+ ## Re:VIEW フォーマットテキストファイルでの利用
8
+ 縦書きのドキュメントをサポートするため、次のような機能を提供します。
9
+
10
+ ### 縦中横文字
11
+ 縦書き中の1〜2文字を横置きに回転させる目的で、インライン命令 `@<tcy>` を用意しました。
12
+
13
+ ```
14
+ @<tcy>{縦中横化する文字}
15
+ ```
16
+
17
+ 図表などの大きなブロックを回転させる用途ではありません。2桁の半角アラビア数字などのごく小さな箇所の回転に対応するものです。
18
+
19
+ ### 採番の漢数字や全角対応
20
+ locale.yml の番号付けに縦書き向けの以下のカスタムフォーマットを用意しています。
21
+
22
+ * `%pAW` : アルファベット(大文字・いわゆる全角)A, B, C, ...
23
+ * `%paW` : アルファベット(小文字・いわゆる全角)a, b, c, ...
24
+ * `%pJ` : 漢数字 一, 二, 三, ...
25
+ * `%pdW' : アラビア数字(0〜9まではいわゆる全角、10以降半角)1, 2, ... 10, ...
26
+ * `%pDW' : アラビア数字(すべて全角)1, 2, ... 10, ...
27
+
28
+ ## EPUB(review-epubmaker)
29
+ HTML のボディ部が縦書きになるよう、CSS ファイル(review-init コマンドで作成した雛型を利用しているのであれば style.css)にスタイルを追加します。
30
+
31
+ ```css
32
+ body {
33
+ (…既存の設定…)
34
+ -webkit-writing-mode: vertical-rl;
35
+ -epub-writing-mode: vertical-rl;
36
+ writing-mode: tb-rl;
37
+ }
38
+ ```
39
+
40
+ また、縦書きの書籍は通常、「左開き」(右ページから左ページへ進む)となるので、config.yml の direction パラメータを設定します。
41
+
42
+ ```yaml
43
+ direction: "rtl"
44
+ ```
45
+
46
+ なお、仕様としては正しくても、正しく表示されるかは EPUB リーダーおよび使用フォントに強く依存します(たとえばフォントの選択によっては、句読点が横書き位置のままで崩れた表示になることがあります)。
47
+
48
+ ## TeX PDF(review-pdfmaker)
49
+ review-pdfmaker のバックエンドとなっている TeX で縦書きを利用するには、ドキュメントクラスファイルを縦書き対応のものに変更する必要があります。config.yml に次のように追加します(`"oneside"` の箇所は必要に応じて変更してください)。
50
+
51
+ ```yaml
52
+ texdocumentclass: ["utbook", "oneside"]
53
+ ```
54
+
55
+ utbook クラスは uplatex に合わせた縦書きの紙面デザインを提供します(platex を使用する場合は tbook クラスを使います)。マクロや追加パッケージが縦書きに対応していない場合、エラーあるいは予想外の結果になることがあります。
@@ -0,0 +1,5 @@
1
+ # Supporing Vertical Writing (experimental)
2
+
3
+ From Re:VIEW 2.0, Re:VIEW supports vertical writings, especially for Japanese document.
4
+
5
+ If you need any further information, please read [writing_vertical.ja.md](writing_vertical.ja.md) (in Japanese).
@@ -60,12 +60,12 @@ module EPUBMaker
60
60
  complement
61
61
  end
62
62
 
63
- def ==(obj)
64
- if self.class != obj.class
63
+ def ==(other)
64
+ if self.class != other.class
65
65
  return false
66
66
  end
67
67
  [self.id, self.file, self.media, self.title, self.level, self.notoc, self.chaptype, self.properties] ==
68
- [obj.id, obj.file, obj.media, obj.title, obj.level, obj.notoc, obj.chaptype, obj.properties]
68
+ [other.id, other.file, other.media, other.title, other.level, other.notoc, other.chaptype, other.properties]
69
69
  end
70
70
 
71
71
  private
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  # = epubcommon.rb -- super class for EPUBv2 and EPUBv3
3
3
  #
4
- # Copyright (c) 2010-2014 Kenshi Muto and Masayoshi Takahashi
4
+ # Copyright (c) 2010-2016 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
@@ -9,10 +9,15 @@
9
9
  # For details of the GNU LGPL, see the file "COPYING".
10
10
  #
11
11
 
12
- require 'epubmaker/producer'
13
12
  require 'review/i18n'
13
+ require 'review/template'
14
14
  require 'cgi'
15
15
  require 'shellwords'
16
+ begin
17
+ require 'zip'
18
+ rescue LoadError
19
+ ## I cannot find rubyzip library, so I use external zip command.
20
+ end
16
21
 
17
22
  module EPUBMaker
18
23
 
@@ -20,7 +25,9 @@ module EPUBMaker
20
25
  class EPUBCommon
21
26
  # Construct object with parameter hash +params+ and message resource hash +res+.
22
27
  def initialize(producer)
28
+ @body_ext = ''
23
29
  @producer = producer
30
+ @body_ext = nil
24
31
  end
25
32
 
26
33
  # Return mimetype content.
@@ -28,12 +35,16 @@ module EPUBMaker
28
35
  "application/epub+zip"
29
36
  end
30
37
 
38
+ def opf_path
39
+ "OEBPS/#{@producer.params["bookname"]}.opf"
40
+ end
41
+
31
42
  def opf_coverimage
32
43
  s = ""
33
44
  if @producer.params["coverimage"]
34
45
  file = nil
35
46
  @producer.contents.each do |item|
36
- if item.media =~ /\Aimage/ && item.file =~ /#{@producer.params["coverimage"]}\Z/
47
+ if item.media.start_with?('image') && item.file =~ /#{@producer.params["coverimage"]}\Z/
37
48
  s << %Q[ <meta name="cover" content="#{item.id}"/>\n]
38
49
  file = item.file
39
50
  break
@@ -45,11 +56,8 @@ module EPUBMaker
45
56
  end
46
57
 
47
58
  def ncx_isbn
48
- if @producer.params["isbn"].nil?
49
- %Q[ <meta name="dtb:uid" content="#{@producer.params["urnid"]}"/>\n]
50
- else
51
- %Q[ <meta name="dtb:uid" content="#{@producer.params["isbn"]}"/>\n]
52
- end
59
+ uid = @producer.params["isbn"] || @producer.params["urnid"]
60
+ %Q[ <meta name="dtb:uid" content="#{uid}"/>\n]
53
61
  end
54
62
 
55
63
  def ncx_doctitle
@@ -58,7 +66,7 @@ module EPUBMaker
58
66
  <text>#{CGI.escapeHTML(@producer.params["title"])}</text>
59
67
  </docTitle>
60
68
  <docAuthor>
61
- <text>#{@producer.params["aut"].nil? ? "" : CGI.escapeHTML(@producer.params["aut"].join(", "))}</text>
69
+ <text>#{@producer.params["aut"].nil? ? "" : CGI.escapeHTML(join_with_separator(@producer.params["aut"], ReVIEW::I18n.t("names_splitter")))}</text>
62
70
  </docAuthor>
63
71
  EOT
64
72
  end
@@ -80,7 +88,7 @@ EOT
80
88
  s << <<EOT
81
89
  <navPoint id="toc" playOrder="#{nav_count}">
82
90
  <navLabel>
83
- <text>#{@producer.res.v("toctitle")}</text>
91
+ <text>#{CGI.escapeHTML(@producer.res.v("toctitle"))}</text>
84
92
  </navLabel>
85
93
  <content src="#{@producer.params["bookname"]}-toc.#{@producer.params["htmlext"]}"/>
86
94
  </navPoint>
@@ -112,171 +120,158 @@ EOT
112
120
 
113
121
  # Return container content.
114
122
  def container
115
- s = <<EOT
116
- <?xml version="1.0" encoding="UTF-8"?>
117
- <container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
118
- <rootfiles>
119
- <rootfile full-path="OEBPS/#{@producer.params["bookname"]}.opf" media-type="application/oebps-package+xml" />
120
- </rootfiles>
121
- </container>
122
- EOT
123
- s
123
+ @opf_path = opf_path
124
+ tmplfile = File.expand_path('./xml/container.xml.erb', ReVIEW::Template::TEMPLATE_DIR)
125
+ tmpl = ReVIEW::Template.load(tmplfile)
126
+ tmpl.result(binding)
124
127
  end
125
128
 
126
129
  # Return cover content.
127
130
  def cover(type=nil)
128
- bodyext = type.nil? ? "" : " epub:type=\"#{type}\""
131
+ @body_ext = type.nil? ? "" : " epub:type=\"#{type}\""
129
132
 
130
- s = common_header
131
- s << <<EOT
132
- <title>#{CGI.escapeHTML(@producer.params["title"])}</title>
133
- </head>
134
- <body#{bodyext}>
135
- EOT
136
- if @producer.params["coverimage"].nil?
137
- s << <<EOT
138
- <h1 class="cover-title">#{CGI.escapeHTML(@producer.params["title"])}</h1>
139
- EOT
140
- else
141
- file = nil
142
- @producer.contents.each do |item|
143
- if item.media =~ /\Aimage/ && item.file =~ /#{@producer.params["coverimage"]}\Z/ # /
144
- file = item.file
145
- break
146
- end
133
+ if @producer.params["coverimage"]
134
+ file = @producer.coverimage
135
+ if !file
136
+ raise "coverimage #{@producer.params["coverimage"]} not found. Abort."
147
137
  end
148
- raise "coverimage #{@producer.params["coverimage"]} not found. Abort." if file.nil?
149
- s << <<EOT
138
+ @body = <<-EOT
150
139
  <div id="cover-image" class="cover-image">
151
- <img src="#{file}" alt="#{CGI.escapeHTML(@producer.params["title"])}" class="max"/>
140
+ <img src="#{file}" alt="#{CGI.escapeHTML(@producer.params.name_of("title"))}" class="max"/>
152
141
  </div>
153
- EOT
142
+ EOT
143
+ else
144
+ @body = <<-EOT
145
+ <h1 class="cover-title">#{CGI.escapeHTML(@producer.params.name_of("title"))}</h1>
146
+ EOT
154
147
  end
155
148
 
156
- s << <<EOT
157
- </body>
158
- </html>
159
- EOT
160
- s
149
+ @title = CGI.escapeHTML(@producer.params.name_of("title"))
150
+ @language = @producer.params['language']
151
+ @stylesheets = @producer.params["stylesheet"]
152
+ if @producer.params["htmlversion"].to_i == 5
153
+ tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
154
+ else
155
+ tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
156
+ end
157
+ tmpl = ReVIEW::Template.load(tmplfile)
158
+ tmpl.result(binding)
161
159
  end
162
160
 
163
161
  # Return title (copying) content.
164
162
  def titlepage
165
- s = common_header
166
- s << <<EOT
167
- <title>#{CGI.escapeHTML(@producer.params["title"])}</title>
168
- </head>
169
- <body>
170
- <h1 class="tp-title">#{CGI.escapeHTML(@producer.params["title"])}</h1>
171
- EOT
163
+ @title = CGI.escapeHTML(@producer.params.name_of("title"))
172
164
 
165
+ @body = <<EOT
166
+ <h1 class="tp-title">#{@title}</h1>
167
+ EOT
173
168
  if @producer.params["aut"]
174
- s << <<EOT
169
+ @body << <<EOT
175
170
  <p>
176
171
  <br />
177
172
  <br />
178
173
  </p>
179
- <h2 class="tp-author">#{CGI.escapeHTML(@producer.params["aut"].join(", "))}</h2>
174
+ <h2 class="tp-author">#{CGI.escapeHTML(join_with_separator(@producer.params.names_of("aut"), ReVIEW::I18n.t("names_splitter")))}</h2>
180
175
  EOT
181
176
  end
182
177
 
183
- publisher = @producer.params["pbl"] || @producer.params["prt"] # XXX Backward Compatiblity
178
+ publisher = @producer.params.names_of("pbl")
184
179
  if publisher
185
- s << <<EOT
180
+ @body << <<EOT
186
181
  <p>
187
182
  <br />
188
183
  <br />
189
184
  <br />
190
185
  <br />
191
186
  </p>
192
- <h3 class="tp-publisher">#{CGI.escapeHTML(publisher.join(", "))}</h3>
187
+ <h3 class="tp-publisher">#{CGI.escapeHTML(join_with_separator(publisher, ReVIEW::I18n.t("names_splitter")))}</h3>
193
188
  EOT
194
189
  end
195
190
 
196
- s << <<EOT
197
- </body>
198
- </html>
199
- EOT
200
-
201
- s
191
+ @language = @producer.params['language']
192
+ @stylesheets = @producer.params["stylesheet"]
193
+ if @producer.params["htmlversion"].to_i == 5
194
+ tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
195
+ else
196
+ tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
197
+ end
198
+ tmpl = ReVIEW::Template.load(tmplfile)
199
+ tmpl.result(binding)
202
200
  end
203
201
 
204
202
  # Return colophon content.
205
203
  def colophon
206
- s = common_header
207
- s << <<EOT
208
- <title>#{@producer.res.v("colophontitle")}</title>
209
- </head>
210
- <body>
204
+ @title = CGI.escapeHTML(@producer.res.v("colophontitle"))
205
+ @body = <<EOT
211
206
  <div class="colophon">
212
207
  EOT
213
208
 
214
209
  if @producer.params["subtitle"].nil?
215
- s << <<EOT
216
- <p class="title">#{CGI.escapeHTML(@producer.params["title"])}</p>
210
+ @body << <<EOT
211
+ <p class="title">#{CGI.escapeHTML(@producer.params.name_of("title"))}</p>
217
212
  EOT
218
213
  else
219
- s << <<EOT
220
- <p class="title">#{CGI.escapeHTML(@producer.params["title"])}<br /><span class="subtitle">#{CGI.escapeHTML(@producer.params["subtitle"])}</span></p>
214
+ @body << <<EOT
215
+ <p class="title">#{CGI.escapeHTML(@producer.params.name_of("title"))}<br /><span class="subtitle">#{CGI.escapeHTML(@producer.params.name_of("subtitle"))}</span></p>
221
216
  EOT
222
217
  end
223
218
 
224
219
  if @producer.params["date"] || @producer.params["history"]
225
- s << %Q[ <div class="pubhistory">\n]
226
- if @producer.params["history"]
227
- @producer.params["history"].each_with_index do |items, edit|
228
- items.each_with_index do |item, rev|
229
- editstr = (edit == 0) ? ReVIEW::I18n.t("first_edition") : ReVIEW::I18n.t("nth_edition","#{edit+1}")
230
- revstr = ReVIEW::I18n.t("nth_impression", "#{rev+1}")
231
- if item =~ /\A\d+\-\d+\-\d+\Z/
232
- s << %Q[ <p>#{ReVIEW::I18n.t("published_by1", [date_to_s(item), editstr+revstr])}</p>\n]
233
- else
234
- # custom date with string
235
- item.match(/\A(\d+\-\d+\-\d+)[\s ](.+)/) do |m|
236
- s << %Q[ <p>#{ReVIEW::I18n.t("published_by3", [date_to_s(m[1]), m[2]])}</p>\n]
237
- end
238
- end
239
- end
240
- end
241
- else
242
- s << %Q[ <p>#{ReVIEW::I18n.t("published_by2", date_to_s(@producer.params["date"]))}</p>\n]
243
- end
244
- s << %Q[ </div>\n]
220
+ @body << colophon_history
245
221
  end
246
222
 
247
- s << %Q[ <table class="colophon">\n]
248
- s << %Q[ <tr><th>#{@producer.res.v("aut")}</th><td>#{CGI.escapeHTML(@producer.params["aut"].join(", "))}</td></tr>\n] unless @producer.params["aut"].nil?
249
- s << %Q[ <tr><th>#{@producer.res.v("csl")}</th><td>#{CGI.escapeHTML(@producer.params["csl"].join(", "))}</td></tr>\n] unless @producer.params["csl"].nil?
250
- s << %Q[ <tr><th>#{@producer.res.v("trl")}</th><td>#{CGI.escapeHTML(@producer.params["trl"].join(", "))}</td></tr>\n] unless @producer.params["trl"].nil?
251
- s << %Q[ <tr><th>#{@producer.res.v("dsr")}</th><td>#{CGI.escapeHTML(@producer.params["dsr"].join(", "))}</td></tr>\n] unless @producer.params["dsr"].nil?
252
- s << %Q[ <tr><th>#{@producer.res.v("ill")}</th><td>#{CGI.escapeHTML(@producer.params["ill"].join(", "))}</td></tr>\n] unless @producer.params["ill"].nil?
253
- s << %Q[ <tr><th>#{@producer.res.v("edt")}</th><td>#{CGI.escapeHTML(@producer.params["edt"].join(", "))}</td></tr>\n] unless @producer.params["edt"].nil?
254
- s << %Q[ <tr><th>#{@producer.res.v("pbl")}</th><td>#{CGI.escapeHTML(@producer.params["pbl"].join(", "))}</td></tr>\n] unless @producer.params["pbl"].nil?
255
- s << %Q[ <tr><th>#{@producer.res.v("prt")}</th><td>#{CGI.escapeHTML(@producer.params["prt"].join(", "))}</td></tr>\n] unless @producer.params["prt"].nil?
256
- s << %Q[ <tr><th>#{@producer.res.v("pht")}</th><td>#{CGI.escapeHTML(@producer.params["pht"].join(", "))}</td></tr>\n] unless @producer.params["pht"].nil?
257
- if @producer.params["isbn"].to_s =~ /\A\d{10}\Z/ || @producer.params["isbn"].to_s =~ /\A\d{13}\Z/
258
- isbn = nil
259
- str = @producer.params["isbn"].to_s
260
- if str.size == 10
261
- isbn = "#{str[0..0]}-#{str[1..5]}-#{str[6..8]}-#{str[9..9]}"
223
+ @body << %Q[ <table class="colophon">\n]
224
+ @body << @producer.params["colophon_order"].map{ |role|
225
+ if @producer.params[role]
226
+ %Q[ <tr><th>#{CGI.escapeHTML(@producer.res.v(role))}</th><td>#{CGI.escapeHTML(join_with_separator(@producer.params.names_of(role), ReVIEW::I18n.t("names_splitter")))}</td></tr>\n]
262
227
  else
263
- isbn = "#{str[0..2]}-#{str[3..3]}-#{str[4..8]}-#{str[9..11]}-#{str[12..12]}"
228
+ ""
264
229
  end
265
- s << %Q[ <tr><th>ISBN</th><td>#{isbn}</td></tr>\n]
230
+ }.join("")
231
+
232
+ if @producer.isbn_hyphen
233
+ @body << %Q[ <tr><th>ISBN</th><td>#{@producer.isbn_hyphen}</td></tr>\n]
266
234
  end
267
- s << <<EOT
268
- </table>
269
- EOT
235
+ @body << %Q[ </table>\n]
270
236
  if !@producer.params["rights"].nil? && @producer.params["rights"].size > 0
271
- s << %Q[ <p class="copyright">#{@producer.params["rights"].join("<br />")}</p>]
237
+ @body << %Q[ <p class="copyright">#{join_with_separator(@producer.params.names_of("rights").map {|m| CGI.escapeHTML(m)}, "<br />")}</p>\n]
272
238
  end
239
+ @body << %Q[ </div>\n]
273
240
 
274
- s << <<EOT
275
- </div>
276
- </body>
277
- </html>
278
- EOT
279
- s
241
+ @language = @producer.params['language']
242
+ @stylesheets = @producer.params["stylesheet"]
243
+ if @producer.params["htmlversion"].to_i == 5
244
+ tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
245
+ else
246
+ tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
247
+ end
248
+ tmpl = ReVIEW::Template.load(tmplfile)
249
+ tmpl.result(binding)
250
+ end
251
+
252
+ def colophon_history
253
+ buf = ""
254
+ buf << %Q[ <div class="pubhistory">\n]
255
+ if @producer.params["history"]
256
+ @producer.params["history"].each_with_index do |items, edit|
257
+ items.each_with_index do |item, rev|
258
+ editstr = (edit == 0) ? ReVIEW::I18n.t("first_edition") : ReVIEW::I18n.t("nth_edition","#{edit+1}")
259
+ revstr = ReVIEW::I18n.t("nth_impression", "#{rev+1}")
260
+ if item =~ /\A\d+\-\d+\-\d+\Z/
261
+ buf << %Q[ <p>#{ReVIEW::I18n.t("published_by1", [date_to_s(item), editstr+revstr])}</p>\n]
262
+ else
263
+ # custom date with string
264
+ item.match(/\A(\d+\-\d+\-\d+)[\s ](.+)/) do |m|
265
+ buf << %Q[ <p>#{ReVIEW::I18n.t("published_by3", [date_to_s(m[1]), m[2]])}</p>\n]
266
+ end
267
+ end
268
+ end
269
+ end
270
+ else
271
+ buf << %Q[ <p>#{ReVIEW::I18n.t("published_by2", date_to_s(@producer.params["date"]))}</p>\n]
272
+ end
273
+ buf << %Q[ </div>\n]
274
+ buf
280
275
  end
281
276
 
282
277
  def date_to_s(date)
@@ -287,25 +282,24 @@ EOT
287
282
 
288
283
  # Return own toc content.
289
284
  def mytoc
290
- s = common_header
291
- s << <<EOT
292
- <title>#{@producer.res.v("toctitle")}</title>
293
- </head>
294
- <body>
295
- <h1 class="toc-title">#{@producer.res.v("toctitle")}</h1>
296
- EOT
285
+ @title = CGI.escapeHTML(@producer.res.v("toctitle"))
297
286
 
287
+ @body = %Q[ <h1 class="toc-title">#{CGI.escapeHTML(@producer.res.v("toctitle"))}</h1>\n]
298
288
  if @producer.params["epubmaker"]["flattoc"].nil?
299
- s << hierarchy_ncx("ul")
289
+ @body << hierarchy_ncx("ul")
300
290
  else
301
- s << flat_ncx("ul", @producer.params["epubmaker"]["flattocindent"])
291
+ @body << flat_ncx("ul", @producer.params["epubmaker"]["flattocindent"])
302
292
  end
303
293
 
304
- s << <<EOT
305
- </body>
306
- </html>
307
- EOT
308
- s
294
+ @language = @producer.params['language']
295
+ @stylesheets = @producer.params["stylesheet"]
296
+ if @producer.params["htmlversion"].to_i == 5
297
+ tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
298
+ else
299
+ tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
300
+ end
301
+ tmpl = ReVIEW::Template.load(tmplfile)
302
+ tmpl.result(binding)
309
303
  end
310
304
 
311
305
  def hierarchy_ncx(type)
@@ -394,7 +388,7 @@ EOT
394
388
  File.open("#{tmpdir}/META-INF/container.xml", "w") {|f| @producer.container(f) }
395
389
 
396
390
  FileUtils.mkdir_p("#{tmpdir}/OEBPS")
397
- File.open("#{tmpdir}/OEBPS/#{@producer.params["bookname"]}.opf", "w") {|f| @producer.opf(f) }
391
+ File.open(File.join(tmpdir, opf_path), "w") {|f| @producer.opf(f) }
398
392
 
399
393
  if File.exist?("#{basedir}/#{@producer.params["cover"]}")
400
394
  FileUtils.cp("#{basedir}/#{@producer.params["cover"]}", "#{tmpdir}/OEBPS")
@@ -412,30 +406,64 @@ EOT
412
406
  end
413
407
 
414
408
  def export_zip(tmpdir, epubfile)
409
+ if defined?(Zip)
410
+ export_zip_rubyzip(tmpdir, epubfile)
411
+ else
412
+ export_zip_extcmd(tmpdir, epubfile)
413
+ end
414
+ end
415
+
416
+ def export_zip_extcmd(tmpdir, epubfile)
415
417
  Dir.chdir(tmpdir) {|d| `#{@producer.params["epubmaker"]["zip_stage1"]} #{epubfile.shellescape} mimetype` }
416
418
  Dir.chdir(tmpdir) {|d| `#{@producer.params["epubmaker"]["zip_stage2"]} #{epubfile.shellescape} META-INF OEBPS #{@producer.params["epubmaker"]["zip_addpath"]}` }
417
419
  end
418
420
 
421
+ def export_zip_rubyzip(tmpdir, epubfile)
422
+ Dir.chdir(tmpdir) do |d|
423
+ Zip::OutputStream.open(epubfile) do |epub|
424
+ root_pathname = Pathname.new(tmpdir)
425
+ # relpath = Pathname.new(File.join(tmpdir,'mimetype')).relative_path_from(root_pathname)
426
+ epub.put_next_entry('mimetype', nil, nil, Zip::Entry::STORED)
427
+ epub << "application/epub+zip"
428
+
429
+ export_zip_rubyzip_addpath(epub, File.join(tmpdir,'META-INF'), root_pathname)
430
+ export_zip_rubyzip_addpath(epub, File.join(tmpdir,'OEBPS'), root_pathname)
431
+ if @producer.params["zip_addpath"].present?
432
+ export_zip_rubyzip_addpath(epub, File.join(tmpdir,@producer.params["zip_addpath"]), root_pathname)
433
+ end
434
+ end
435
+ end
436
+ end
437
+
438
+ def export_zip_rubyzip_addpath(epub, dirname, rootdir)
439
+ Dir[File.join(dirname,'**','**')].each do |path|
440
+ next if File.directory?(path)
441
+ relpath = Pathname.new(path).relative_path_from(rootdir)
442
+ epub.put_next_entry(relpath)
443
+ epub << File.binread(path)
444
+ end
445
+ end
446
+
419
447
  def legacy_cover_and_title_file(loadfile, writefile)
420
- s = common_header
421
- s << <<EOT
422
- <title>#{@producer.params["booktitle"]}</title>
423
- </head>
424
- <body>
425
- EOT
448
+ @title = @producer.params["booktitle"]
449
+ s = ""
426
450
  File.open(loadfile) do |f|
427
451
  f.each_line do |l|
428
452
  s << l
429
453
  end
430
454
  end
431
- s << <<EOT
432
- </body>
433
- </html>
434
- EOT
435
455
 
436
456
  File.open(writefile, "w") do |f|
437
457
  f.puts s
438
458
  end
439
459
  end
460
+
461
+ def join_with_separator(value, sep)
462
+ if value.kind_of? Array
463
+ value.join(sep)
464
+ else
465
+ value
466
+ end
467
+ end
440
468
  end
441
469
  end