tmtms-review 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +9 -0
  3. data/COPYING +515 -0
  4. data/ChangeLog +2083 -0
  5. data/README.rdoc +50 -0
  6. data/Rakefile +56 -0
  7. data/VERSION +1 -0
  8. data/bin/review-check +178 -0
  9. data/bin/review-checkdep +63 -0
  10. data/bin/review-compile +205 -0
  11. data/bin/review-epubmaker +661 -0
  12. data/bin/review-epubmaker-ng +176 -0
  13. data/bin/review-index +118 -0
  14. data/bin/review-pdfmaker +208 -0
  15. data/bin/review-preproc +142 -0
  16. data/bin/review-validate +51 -0
  17. data/bin/review-vol +102 -0
  18. data/debian/README.Debian +12 -0
  19. data/debian/README.source +5 -0
  20. data/debian/changelog +5 -0
  21. data/debian/compat +1 -0
  22. data/debian/control +22 -0
  23. data/debian/copyright +62 -0
  24. data/debian/docs +6 -0
  25. data/debian/manpage.1.ex +59 -0
  26. data/debian/patches/path.diff +91 -0
  27. data/debian/patches/series +1 -0
  28. data/debian/review.install +13 -0
  29. data/debian/review.links +4 -0
  30. data/debian/rules +13 -0
  31. data/debian/source/format +1 -0
  32. data/doc/format.rdoc +582 -0
  33. data/doc/format_idg.rdoc +180 -0
  34. data/doc/libepubmaker/sample.yaml +90 -0
  35. data/doc/quickstart.rdoc +188 -0
  36. data/doc/ruby-uuid/README +11 -0
  37. data/doc/ruby-uuid/README.ja +34 -0
  38. data/doc/sample.css +108 -0
  39. data/doc/sample.yaml +62 -0
  40. data/lib/epubmaker.rb +28 -0
  41. data/lib/epubmaker/content.rb +82 -0
  42. data/lib/epubmaker/epubv2.rb +418 -0
  43. data/lib/epubmaker/epubv3.rb +249 -0
  44. data/lib/epubmaker/producer.rb +204 -0
  45. data/lib/epubmaker/resource.rb +66 -0
  46. data/lib/lineinput.rb +155 -0
  47. data/lib/review.rb +3 -0
  48. data/lib/review/book.rb +46 -0
  49. data/lib/review/book/base.rb +235 -0
  50. data/lib/review/book/chapter.rb +81 -0
  51. data/lib/review/book/compilable.rb +159 -0
  52. data/lib/review/book/index.rb +339 -0
  53. data/lib/review/book/page_metric.rb +38 -0
  54. data/lib/review/book/parameters.rb +97 -0
  55. data/lib/review/book/part.rb +44 -0
  56. data/lib/review/book/volume.rb +65 -0
  57. data/lib/review/builder.rb +444 -0
  58. data/lib/review/compiler.rb +550 -0
  59. data/lib/review/configure.rb +38 -0
  60. data/lib/review/epubbuilder.rb +18 -0
  61. data/lib/review/exception.rb +21 -0
  62. data/lib/review/extentions.rb +3 -0
  63. data/lib/review/extentions/object.rb +9 -0
  64. data/lib/review/extentions/string.rb +33 -0
  65. data/lib/review/htmlbuilder.rb +1097 -0
  66. data/lib/review/htmllayout.rb +19 -0
  67. data/lib/review/htmlutils.rb +36 -0
  68. data/lib/review/i18n.rb +30 -0
  69. data/lib/review/i18n.yaml +34 -0
  70. data/lib/review/idgxmlbuilder.rb +1145 -0
  71. data/lib/review/latexbuilder.rb +815 -0
  72. data/lib/review/latexindex.rb +35 -0
  73. data/lib/review/latexutils.rb +79 -0
  74. data/lib/review/preprocessor.rb +563 -0
  75. data/lib/review/review.tex.erb +232 -0
  76. data/lib/review/textbuilder.rb +17 -0
  77. data/lib/review/textutils.rb +66 -0
  78. data/lib/review/tocparser.rb +342 -0
  79. data/lib/review/tocprinter.rb +221 -0
  80. data/lib/review/topbuilder.rb +785 -0
  81. data/lib/review/unfold.rb +138 -0
  82. data/lib/uuid.rb +312 -0
  83. data/review.gemspec +141 -0
  84. data/test/CHAPS +2 -0
  85. data/test/bib.re +13 -0
  86. data/test/book_test_helper.rb +35 -0
  87. data/test/test.re +43 -0
  88. data/test/test_book.rb +598 -0
  89. data/test/test_book_chapter.rb +418 -0
  90. data/test/test_book_parameter.rb +42 -0
  91. data/test/test_book_part.rb +50 -0
  92. data/test/test_builder.rb +144 -0
  93. data/test/test_compiler.rb +44 -0
  94. data/test/test_epubmaker.rb +507 -0
  95. data/test/test_helper.rb +27 -0
  96. data/test/test_htmlbuilder.rb +554 -0
  97. data/test/test_htmlutils.rb +28 -0
  98. data/test/test_i18n.rb +64 -0
  99. data/test/test_idgxmlbuilder.rb +589 -0
  100. data/test/test_index.rb +31 -0
  101. data/test/test_latexbuilder.rb +656 -0
  102. data/test/test_lineinput.rb +198 -0
  103. data/test/test_preprocessor.rb +23 -0
  104. data/test/test_textutils.rb +68 -0
  105. data/test/test_topbuilder.rb +244 -0
  106. data/test/test_uuid.rb +156 -0
  107. metadata +161 -0
@@ -0,0 +1,661 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #
4
+ # Copyright (c) 2010 Kenshi Muto and Masayoshi Takahashi
5
+ #
6
+ # This program is free software.
7
+ # You can distribute or modify this program under the terms of
8
+ # the GNU LGPL, Lesser General Public License version 2.1.
9
+ # For details of the GNU LGPL, see the file "COPYING".
10
+ #
11
+
12
+ require 'tmpdir'
13
+ require 'fileutils'
14
+ require 'yaml'
15
+ require 'optparse'
16
+ require 'rexml/document'
17
+
18
+ require 'pathname'
19
+
20
+ bindir = Pathname.new(__FILE__).realpath.dirname
21
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
22
+
23
+ require 'uuid'
24
+ require 'review'
25
+ require 'review/i18n'
26
+
27
+ require 'review/htmlutils'
28
+ include ReVIEW::HTMLUtils
29
+
30
+ $essential_files = ['top', 'toc', 'colophon']
31
+ def main
32
+ if ARGV.size != 1
33
+ puts "Usage: #{$0} configfile"
34
+ exit 0
35
+ end
36
+
37
+ yamlfile = ARGV[0]
38
+ values = ReVIEW::Configure.values.merge(YAML.load_file(yamlfile))
39
+ bookname = values["bookname"]
40
+ $essential_files <<= bookname
41
+ tmp = values["debug"].nil? ? Dir.mktmpdir : "."
42
+ @bookdir = "#{tmp}/#{bookname}-epub"
43
+
44
+ if File.exist?("#{bookname}.epub")
45
+ STDERR.puts "#{bookname}.epub exists. Please remove or rename first."
46
+ exit 1
47
+ end
48
+ if File.exist?(@bookdir)
49
+ STDERR.puts "#{@bookdir} directory exists. Please remove or rename first."
50
+ exit 1
51
+ end
52
+
53
+ identifier = values["urnid"].nil? ? "urn:uuid:#{UUID.create}" : values["urnid"]
54
+
55
+ Dir.mkdir(@bookdir)
56
+
57
+ # MIME type
58
+ File.open("#{@bookdir}/mimetype", "w") {|f|
59
+ f.write "application/epub+zip"
60
+ }
61
+
62
+ Dir.mkdir("#{@bookdir}/OEBPS")
63
+ # XHTML
64
+ @manifeststr = ""
65
+ @ncxstr = ""
66
+ @tocdesc = Array.new
67
+
68
+ basedir = Dir.pwd
69
+ base_path = Pathname.new(basedir)
70
+ ReVIEW::Book.load(basedir).parts.each do |part|
71
+ if part.name.present?
72
+ if part.file?
73
+ filename = Pathname.new(part.path).relative_path_from(base_path).to_s
74
+ output_chaps_by_file(filename, values)
75
+ htmlfile = File.basename(filename.chomp.strip,".*")+".html"
76
+ else
77
+ htmlfile = "part_#{part.number}.html"
78
+ make_part_page(part, htmlfile, values)
79
+ end
80
+ file_id = "part_#{part.number}"
81
+ part_name = "#{ReVIEW::I18n.t("part", part.number)} #{part.name.strip}"
82
+ @tocdesc << [1, htmlfile, nil, part_name]
83
+ @manifeststr << %Q(<item id="#{file_id}" href="#{htmlfile}" media-type="application/xhtml+xml" />\n)
84
+ @ncxstr << %Q(<itemref idref="#{file_id}" />\n)
85
+ end
86
+
87
+ part.chapters.each do |chap|
88
+ filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
89
+ output_chaps_by_file(filename, values)
90
+ end
91
+ end
92
+
93
+ if File.exist?("images")
94
+ Dir.mkdir("#{@bookdir}/OEBPS/images")
95
+ image_files = ReVIEW::MakerHelper.copy_images_to_dir("images", "#{@bookdir}/OEBPS/images")
96
+ image_files.each do |image_file|
97
+ dirname = File.dirname(image_file)
98
+ fname = File.basename(image_file)
99
+ figid = getFigId(dirname.gsub(%r|/|,'-')+"-"+fname)
100
+ mime = nil
101
+ next unless fname =~ /\.(png|gif|jpg|jpeg|svg)$/i
102
+ case fname.downcase.match(/\.(png|gif|jpg|jpeg|svg)$/)[1]
103
+ when "png"
104
+ mime = "image/png"
105
+ when "gif"
106
+ mime = "image/gif"
107
+ when "jpg", "jpeg"
108
+ mime = "image/jpeg"
109
+ when "svg"
110
+ mime = "image/svg+xml"
111
+ else
112
+ raise "unsupported type #{fname}"
113
+ end
114
+ @manifeststr << %Q(<item id="#{figid}" href="#{image_file}" media-type="#{mime}" />\n)
115
+ end
116
+ end
117
+
118
+ # container
119
+ Dir.mkdir("#{@bookdir}/META-INF")
120
+ File.open("#{@bookdir}/META-INF/container.xml", "w") {|f|
121
+ f.puts <<EOT
122
+ <?xml version="1.0" encoding="UTF-8"?>
123
+ <container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
124
+ <rootfiles>
125
+ <rootfile full-path="OEBPS/#{bookname}.opf" media-type="application/oebps-package+xml" />
126
+ </rootfiles>
127
+ </container>
128
+ EOT
129
+ }
130
+
131
+ # opf (meta info)
132
+ File.open("#{@bookdir}/OEBPS/#{bookname}.opf", "w") {|f|
133
+ f.puts <<EOT
134
+ <?xml version="1.0" encoding="UTF-8"?>
135
+ <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
136
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
137
+ <dc:title>#{values["booktitle"]}</dc:title>
138
+ EOT
139
+
140
+ f.puts %Q(<dc:creator opf:role="aut">#{values["aut"]}</dc:creator>) unless values["aut"].nil? # FIXME: support multiple members
141
+
142
+ f.puts %Q(<dc:publisher>#{values["prt"]}</dc:publisher>) unless values["prt"].nil?
143
+
144
+ f.puts %Q(<dc:date>#{values["date"]}</dc:date>) unless values["date"].nil?
145
+ f.puts %Q(<dc:rights>#{values["rights"]}</dc:rights>) unless values["rights"].nil?
146
+
147
+ f.puts %Q(<dc:contributor opf:role="asn">#{values["asn"]}</dc:contributor>) unless values["asn"].nil?
148
+ f.puts %Q(<dc:contributor opf:role="ant">#{values["ant"]}</dc:contributor>) unless values["ant"].nil?
149
+ f.puts %Q(<dc:contributor opf:role="clb">#{values["clb"]}</dc:contributor>) unless values["clb"].nil?
150
+ f.puts %Q(<dc:contributor opf:role="edt">#{values["edt"]}</dc:contributor>) unless values["edt"].nil?
151
+ f.puts %Q(<dc:contributor opf:role="dsr">#{values["dsr"]}</dc:contributor>) unless values["dsr"].nil?
152
+ f.puts %Q(<dc:contributor opf:role="ill">#{values["ill"]}</dc:contributor>) unless values["ill"].nil?
153
+ f.puts %Q(<dc:contributor opf:role="pht">#{values["pht"]}</dc:contributor>) unless values["pht"].nil?
154
+ f.puts %Q(<dc:contributor opf:role="trl">#{values["trl"]}</dc:contributor>) unless values["trl"].nil?
155
+
156
+ f.puts %Q(<dc:description>#{values["description"]}</dc:description>) unless values["description"].nil?
157
+
158
+ if values["coverimage"]
159
+ f.puts %Q(<meta name="cover" content="#{getFigId("images-"+values["coverimage"])}"/>)
160
+ end
161
+ f.puts <<EOT
162
+ <dc:language>ja</dc:language>
163
+ <dc:identifier id="BookId">#{identifier}</dc:identifier>
164
+ </metadata>
165
+ <manifest>
166
+ EOT
167
+
168
+ if values["toc"]
169
+ f.puts <<EOT
170
+ <item id="ncx" href="#{bookname}.ncx" media-type="application/x-dtbncx+xml" />
171
+ EOT
172
+ end
173
+
174
+ f.puts <<EOT
175
+ <item id="style" href="#{values["stylesheet"]}" media-type="text/css" />
176
+ <item id="#{bookname}" href="#{bookname}.html" media-type="application/xhtml+xml" />
177
+ <item id="top" href="top.html" media-type="application/xhtml+xml" />
178
+ EOT
179
+
180
+ if values["toc"] && values["mytoc"]
181
+ f.puts <<EOT
182
+ <item id="toc" href="toc.html" media-type="application/xhtml+xml" />
183
+ EOT
184
+ end
185
+
186
+ f.puts @manifeststr
187
+ if values["colophon"]
188
+ f.puts <<EOT
189
+ <item id="colophon" href="colophon.html" media-type="application/xhtml+xml" />
190
+ EOT
191
+ end
192
+
193
+ if values["cover_linear"] && values["cover_linear"] != "no"
194
+ cover_linear = "yes"
195
+ else
196
+ cover_linear = "no"
197
+ end
198
+
199
+ f.puts <<EOT
200
+ </manifest>
201
+ <spine toc="ncx">
202
+ <itemref idref="#{bookname}" linear="#{cover_linear}" />
203
+ <itemref idref="top" />
204
+ EOT
205
+
206
+ if values["toc"] && values["mytoc"]
207
+ f.puts <<EOT
208
+ <itemref idref="toc" />
209
+ EOT
210
+ end
211
+
212
+ f.puts @ncxstr
213
+ if values["colophon"]
214
+ f.puts <<EOT
215
+ <itemref idref="colophon" />
216
+ EOT
217
+ end
218
+ f.puts <<EOT
219
+ </spine>
220
+ <guide>
221
+ EOT
222
+
223
+ if values["titlepage"]
224
+ f.puts <<EOT
225
+ <reference type="cover" title="表紙" href="#{bookname}.html"/>
226
+ <reference type="title-page" title="Title Page" href="top.html"/>
227
+ EOT
228
+ end
229
+
230
+ if values["toc"] && values["mytoc"]
231
+ f.puts <<EOT
232
+ <reference type="toc" title="目次" href="toc.html"/>
233
+ EOT
234
+ end
235
+ f.puts <<EOT
236
+ </guide>
237
+ </package>
238
+ EOT
239
+ }
240
+
241
+ # ncx (toc)
242
+ if values["toc"]
243
+ File.open("#{@bookdir}/OEBPS/#{bookname}.ncx", "w") {|f|
244
+ f.puts <<EOT
245
+ <?xml version="1.0" encoding="UTF-8"?>
246
+ <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
247
+ <head>
248
+ <meta name="dtb:uid" content="#{identifier}"/>
249
+ <meta name="dtb:depth" content="1"/>
250
+ <meta name="dtb:totalPageCount" content="0"/>
251
+ <meta name="dtb:maxPageNumber" content="0"/>
252
+ </head>
253
+ <docTitle>
254
+ <text>#{values["booktitle"]}</text>
255
+ </docTitle>
256
+ <docAuthor>
257
+ <text>#{values["aut"].nil? ? "" : values["aut"]}</text>
258
+ </docAuthor>
259
+ <navMap>
260
+ <navPoint id="top" playOrder="1">
261
+ <navLabel>
262
+ <text>#{values["booktitle"]}</text>
263
+ </navLabel>
264
+ <content src="#{bookname}.html"/>
265
+ </navPoint>
266
+ EOT
267
+
268
+ nav_count = 2
269
+
270
+ if values["mytoc"]
271
+ f.puts <<EOT
272
+ <navPoint id="toc" playOrder="2">
273
+ <navLabel>
274
+ <text>目次</text>
275
+ </navLabel>
276
+ <content src="toc.html"/>
277
+ </navPoint>
278
+ EOT
279
+ nav_count = 3
280
+ end
281
+
282
+ @tocdesc.each {|item|
283
+ level, file, id, content = item
284
+ # values["level"]
285
+ next if level > values["toclevel"].to_i
286
+ indent = ""
287
+ if level > values["secnolevel"].to_i
288
+ indent = "- "
289
+ end
290
+ fragment_id = (id ? '#'+id : '')
291
+ f.puts <<EOT
292
+ <navPoint id="navPoint-#{nav_count}" playOrder="#{nav_count}">
293
+ <navLabel>
294
+ <text>#{indent}#{strip_html(content)}</text>
295
+ </navLabel>
296
+ <content src="#{file}#{fragment_id}"/>
297
+ </navPoint>
298
+ EOT
299
+ nav_count += 1
300
+ }
301
+ f.puts <<EOT
302
+ </navMap>
303
+ </ncx>
304
+ EOT
305
+ }
306
+ end
307
+
308
+ # Cover page
309
+ File.open("#{@bookdir}/OEBPS/#{bookname}.html", "w") {|f|
310
+ f.puts <<EOT
311
+ <?xml version="1.0" encoding="UTF-8"?>
312
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
313
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
314
+ <head>
315
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
316
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
317
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
318
+ <meta name="generator" content="ReVIEW"/>
319
+ <title>#{values["booktitle"]}</title>
320
+ </head>
321
+ <body>
322
+ EOT
323
+ if !values["coverfile"].nil? && File.exist?(values["coverfile"])
324
+ File.open(values["coverfile"]) {|f2|
325
+ f2.each_line {|l|
326
+ f.puts l
327
+ }
328
+ }
329
+ else
330
+ f.puts <<EOT
331
+ <h1>#{values["booktitle"]}</h1>
332
+ EOT
333
+ end
334
+
335
+ f.puts <<EOT
336
+ </body>
337
+ </html>
338
+ EOT
339
+ }
340
+
341
+
342
+ # Title page
343
+ File.open("#{@bookdir}/OEBPS/top.html", "w") {|f|
344
+ f.puts <<EOT
345
+ <?xml version="1.0" encoding="UTF-8"?>
346
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
347
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
348
+ <head>
349
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
350
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
351
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
352
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
353
+ <title>#{values["booktitle"]}</title>
354
+ </head>
355
+ <body>
356
+ EOT
357
+ if !values["titlepagefile"].nil? && File.exist?(values["titlepagefile"])
358
+ File.open(values["titlepagefile"]) {|f2|
359
+ f2.each_line {|l|
360
+ f.puts l
361
+ }
362
+ }
363
+ else
364
+ f.puts <<EOT
365
+ <h1 class="tp-title">#{values["booktitle"]}</h1>
366
+ EOT
367
+ if values["aut"]
368
+ f.puts <<EOT
369
+ <p>
370
+ <br />
371
+ <br />
372
+ </p>
373
+ <h2 class="tp-author">#{values["aut"]}</h2>
374
+ EOT
375
+ end
376
+ if values["prt"]
377
+ f.puts <<EOT
378
+ <p>
379
+ <br />
380
+ <br />
381
+ <br />
382
+ <br />
383
+ </p>
384
+ <h3 class="tp-publisher">#{values["prt"]}</h3>
385
+ EOT
386
+ end
387
+ end
388
+
389
+ f.puts <<EOT
390
+ </body>
391
+ </html>
392
+ EOT
393
+ }
394
+
395
+ # Additional toc page
396
+ if values["toc"] && values["mytoc"]
397
+ File.open("#{@bookdir}/OEBPS/toc.html", "w") {|f|
398
+ f.puts <<EOT
399
+ <?xml version="1.0" encoding="UTF-8"?>
400
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
401
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
402
+ <head>
403
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
404
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
405
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
406
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
407
+ <title>目次</title>
408
+ </head>
409
+ <body>
410
+ <h1>目次</h1>
411
+ <ul class=\"toc-h1\">
412
+ EOT
413
+
414
+ current = 1
415
+ init_item = true
416
+ @tocdesc.each {|item|
417
+ level, file, id, content = item
418
+ # values["level"]
419
+ next if level > values["toclevel"].to_i
420
+ if level > current
421
+ current += 1
422
+ f.puts ""
423
+ f.puts "<ul class=\"toc-h#{current}\">"
424
+ while current < level
425
+ current += 1
426
+ f.puts "<li>"
427
+ f.puts "<ul class=\"toc-h#{current}\">"
428
+ end
429
+ elsif level < current
430
+ current -= 1
431
+ f.puts "</li>"
432
+ f.puts "</ul>"
433
+ f.puts "</li>"
434
+ while current > level
435
+ current -= 1
436
+ f.puts "</ul>"
437
+ f.puts "</li>"
438
+ end
439
+ elsif init_item
440
+ # noop
441
+ else
442
+ f.puts "</li>"
443
+ end
444
+ fragment_id = (id ? '#'+id : '')
445
+ f.write "<li><a href=\"#{file}#{fragment_id}\">#{content}</a>"
446
+ init_item = false
447
+ }
448
+
449
+ (current - 1).downto(1) {|n|
450
+ f.puts "</li>"
451
+ f.puts "</ul>"
452
+ }
453
+ if !init_item
454
+ f.puts "</li>"
455
+ end
456
+
457
+ f.puts <<EOT
458
+ </ul>
459
+ </body>
460
+ </html>
461
+ EOT
462
+ }
463
+ end
464
+
465
+ # stylesheet
466
+ if File.exist?(values["stylesheet"])
467
+ FileUtils.cp values["stylesheet"], "#{@bookdir}/OEBPS/#{values["stylesheet"]}"
468
+ else
469
+ File.open("#{@bookdir}/OEBPS/#{values["stylesheet"]}", "w") {|f|
470
+ f.puts <<EOT
471
+ /* sample style sheet for epub */
472
+ @charset "utf-8";
473
+
474
+ body {
475
+ }
476
+ EOT
477
+ }
478
+ end
479
+
480
+ # Colophon page
481
+ if values["colophon"]
482
+ make_colophon_page(tmp, bookname, values)
483
+ end
484
+
485
+ # hook
486
+ if !values["posthook"].nil? && !values["posthook"].empty? && FileTest.executable?(values["posthook"])
487
+ fork {
488
+ exec(values["posthook"], @bookdir, Dir.pwd, yamlfile)
489
+ }
490
+ Process.waitall
491
+ end
492
+
493
+ # Zip epubファイルの作成。mimetypeは圧縮しないようにする
494
+ fork {
495
+ basedir = Dir.pwd
496
+ Dir.chdir(@bookdir) {|d|
497
+ exec("zip", "-0X", "#{basedir}/#{bookname}.epub", "mimetype")
498
+ }
499
+ }
500
+ Process.waitall
501
+ fork {
502
+ basedir = Dir.pwd
503
+ Dir.chdir(@bookdir) {|d|
504
+ exec("zip", "-Xr9D", "#{basedir}/#{bookname}.epub", "META-INF", "OEBPS")
505
+ }
506
+ }
507
+ Process.waitall
508
+
509
+ FileUtils.rm_r(tmp) if values["debug"].nil?
510
+ end
511
+
512
+ def output_chaps(chapsfile, values)
513
+ File.open(chapsfile) {|chaps|
514
+ chaps.each_line {|l|
515
+ next if l =~ /^#/
516
+ output_chaps_by_file(l, values)
517
+ }
518
+ }
519
+ end
520
+
521
+ def output_chaps_by_file(l, values)
522
+ file_id = File.basename(l.chomp.strip,".*")
523
+ if (idx = $essential_files.index(file_id))
524
+ if idx == $essential_files.size - 1
525
+ STDERR.puts "#{file_id} is book name. Please rename #{l.chomp.strip}."
526
+ else
527
+ STDERR.puts "#{file_id} is special name. Please rename #{l.chomp.strip}."
528
+ end
529
+ exit 1
530
+ end
531
+ filename = "#{file_id}.html"
532
+ fork {
533
+ STDOUT.reopen("#{@bookdir}/OEBPS/#{filename}")
534
+ exec("review-compile --target=html --level=#{values["secnolevel"]} #{values["params"]} #{l}")
535
+ }
536
+ Process.waitall
537
+ getanchors("#{@bookdir}/OEBPS/#{filename}")
538
+ @manifeststr << %Q(<item id="#{file_id}" href="#{filename}" media-type="application/xhtml+xml" />\n)
539
+ @ncxstr << %Q(<itemref idref="#{file_id}" />\n)
540
+ end
541
+
542
+ def getFigId(filename)
543
+ figid = filename.sub(/\.(png|gif|jpg|jpeg|svg)$/, '')
544
+ "fig-#{figid}"
545
+ end
546
+
547
+ def getTitle(filename)
548
+ File.open(filename) {|f|
549
+ return REXML::Document.new(f).elements["//html/head/title"].text
550
+ }
551
+ end
552
+
553
+ def getanchors(filename)
554
+ File.open(filename) {|f|
555
+ file = filename.sub(/.+\//, '')
556
+ f.each_line {|l|
557
+ if l =~ /\A<h(\d)><a id=\"(.+?)\"><\/a>(.+?)<\/h/
558
+ # level, ID, content
559
+ @tocdesc << [$1.to_i, file, $2, $3]
560
+ end
561
+ }
562
+ }
563
+ end
564
+
565
+ def make_colophon_page(tmp,bookname,values)
566
+
567
+ header = <<EOT
568
+ <?xml version="1.0" encoding="UTF-8"?>
569
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
570
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
571
+ <head>
572
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
573
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
574
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
575
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
576
+ <title>#{values["booktitle"]}</title>
577
+ </head>
578
+ <body>
579
+ EOT
580
+
581
+ footer = <<EOT
582
+ </body>
583
+ </html>
584
+ EOT
585
+
586
+ colophon_path = "#{@bookdir}/OEBPS/colophon.html"
587
+ colophon = values["colophon"]
588
+ if colophon.kind_of?(String) && File.exist?(colophon)
589
+ File.open(colophon_path, "w") {|f|
590
+ f.puts header
591
+ File.open(values["colophon"]) {|f2|
592
+ f2.each_line {|l|
593
+ f.puts l
594
+ }
595
+ }
596
+ f.puts footer
597
+ }
598
+ else
599
+ File.open(colophon_path, "w") {|f|
600
+ f.puts header
601
+ f.puts <<EOT
602
+ <div class="colophon">
603
+ <p class="title">#{values["booktitle"]}</p>
604
+ EOT
605
+ if values["pubhistory"]
606
+ f.puts %Q[<div class="pubhistory">\n<p>#{values["pubhistory"].gsub(/\n/,"<br />")}</p>\n</div>]
607
+ end
608
+
609
+ f.puts <<EOT
610
+ <table>
611
+ EOT
612
+ f.puts %Q[<tr>\n <th>著 者</th><td>#{values["aut"]}</td>\n</tr>] if values["aut"]
613
+ f.puts %Q[<tr>\n <th>翻 訳</th><td>#{values["trl"]}</td>\n</tr>] if values["trl"]
614
+ f.puts %Q[<tr>\n <th>デザイン</th><td>#{values["dsr"]}</td>\n</tr>] if values["dsr"]
615
+ f.puts %Q[<tr>\n <th>イラスト</th><td>#{values["ill"]}</td>\n</tr>] if values["ill"]
616
+ f.puts %Q[<tr>\n <th>編 集</th><td>#{values["edt"]}</td>\n</tr>] if values["edt"]
617
+ f.puts %Q[<tr>\n <th>発行所</th><td>#{values["prt"]}</td>\n</tr>] if values["prt"]
618
+ f.puts <<EOT
619
+ </table>
620
+ EOT
621
+ if values["rights"]
622
+ f.puts %Q[<p class="copyright">#{values["rights"]}</p>]
623
+ end
624
+
625
+ f.puts "</div>"
626
+ f.puts footer
627
+ }
628
+ end
629
+ end
630
+
631
+ def make_part_page(part, filename, values)
632
+ File.open("#{@bookdir}/OEBPS/#{filename}", "w") {|f|
633
+ f.puts <<-EOT
634
+ <?xml version="1.0" encoding="UTF-8"?>
635
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
636
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="ja">
637
+ <head>
638
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
639
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
640
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
641
+ <meta name="generator" content="ReVIEW EPUB Maker"/>
642
+ <title>#{values["booktitle"]}</title>
643
+ </head>
644
+ <body>
645
+ <h1 class="part-number">#{ReVIEW::I18n.t("part", part.number)}</h1>
646
+ EOT
647
+
648
+ if part.name.strip.present?
649
+ f.puts <<-EOT
650
+ <h2 class="part-title">#{part.name.strip}</h2>
651
+ EOT
652
+ end
653
+
654
+ f.puts <<-EOT
655
+ </body>
656
+ </html>
657
+ EOT
658
+ }
659
+ end
660
+
661
+ main