review 1.2.0 → 1.3.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +36 -0
  3. data/.rubocop.yml +1 -0
  4. data/ChangeLog +102 -0
  5. data/README.rdoc +2 -2
  6. data/bin/review-check +18 -16
  7. data/bin/review-compile +49 -42
  8. data/bin/review-epubmaker +23 -993
  9. data/bin/review-epubmaker-legacy +1024 -0
  10. data/bin/review-index +17 -15
  11. data/bin/review-init +39 -9
  12. data/bin/review-pdfmaker +124 -89
  13. data/bin/review-preproc +16 -14
  14. data/bin/review-vol +17 -15
  15. data/debian/docs +1 -1
  16. data/doc/catalog.rdoc +34 -0
  17. data/doc/format.rdoc +16 -2
  18. data/doc/libepubmaker/{config.yaml → config.yml} +63 -19
  19. data/doc/quickstart.rdoc +1 -1
  20. data/doc/{sample.yaml → sample.yml} +0 -0
  21. data/lib/epubmaker.rb +1 -1
  22. data/lib/epubmaker/content.rb +9 -1
  23. data/lib/epubmaker/epubv2.rb +59 -7
  24. data/lib/epubmaker/epubv3.rb +14 -9
  25. data/lib/epubmaker/producer.rb +68 -27
  26. data/lib/epubmaker/resource.rb +3 -1
  27. data/lib/lineinput.rb +2 -2
  28. data/lib/review/book/base.rb +125 -24
  29. data/lib/review/book/chapter.rb +42 -0
  30. data/lib/review/book/compilable.rb +23 -4
  31. data/lib/review/book/image_finder.rb +64 -0
  32. data/lib/review/book/index.rb +64 -50
  33. data/lib/review/book/page_metric.rb +1 -1
  34. data/lib/review/builder.rb +19 -12
  35. data/lib/review/catalog.rb +47 -0
  36. data/lib/review/compiler.rb +3 -2
  37. data/lib/review/configure.rb +5 -3
  38. data/lib/review/epubmaker.rb +130 -46
  39. data/lib/review/ewbbuilder.rb +27 -31
  40. data/lib/review/extentions/string.rb +4 -4
  41. data/lib/review/htmlbuilder.rb +140 -79
  42. data/lib/review/htmllayout.rb +26 -4
  43. data/lib/review/htmlutils.rb +20 -1
  44. data/lib/review/i18n.rb +5 -2
  45. data/lib/review/{i18n.yaml → i18n.yml} +4 -2
  46. data/lib/review/idgxmlbuilder.rb +65 -39
  47. data/lib/review/latexbuilder.rb +72 -24
  48. data/lib/review/latexutils.rb +3 -1
  49. data/lib/review/makerhelper.rb +8 -2
  50. data/lib/review/preprocessor.rb +20 -20
  51. data/lib/review/review.tex.erb +4 -0
  52. data/lib/review/sec_counter.rb +9 -11
  53. data/lib/review/tocparser.rb +2 -2
  54. data/lib/review/tocprinter.rb +12 -12
  55. data/lib/review/topbuilder.rb +15 -15
  56. data/lib/review/version.rb +1 -1
  57. data/lib/uuid.rb +7 -7
  58. data/review.gemspec +2 -2
  59. data/rubocop-todo.yml +443 -0
  60. data/test/sample-book/src/config.yml +2 -2
  61. data/test/sample-book/src/{main.css → style.css} +0 -0
  62. data/test/test_book.rb +46 -48
  63. data/test/test_book_chapter.rb +25 -13
  64. data/test/test_builder.rb +3 -3
  65. data/test/test_catalog.rb +107 -0
  66. data/test/test_epubmaker.rb +6 -6
  67. data/test/test_htmlbuilder.rb +160 -39
  68. data/test/test_htmlutils.rb +22 -0
  69. data/test/test_i18n.rb +2 -2
  70. data/test/test_idgxmlbuilder.rb +33 -47
  71. data/test/test_image_finder.rb +82 -0
  72. data/test/test_inaobuilder.rb +1 -1
  73. data/test/test_latexbuilder.rb +35 -39
  74. data/test/test_lineinput.rb +2 -2
  75. data/test/test_markdownbuilder.rb +2 -2
  76. data/test/test_topbuilder.rb +39 -23
  77. metadata +23 -14
  78. data/bin/review-epubmaker-ng +0 -23
@@ -0,0 +1,1024 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #
4
+ # Copyright (c) 2010-2014 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
+ require 'time'
18
+
19
+ require 'pathname'
20
+
21
+ bindir = Pathname.new(__FILE__).realpath.dirname
22
+ $LOAD_PATH.unshift((bindir + '../lib').realpath)
23
+
24
+ require 'uuid'
25
+ require 'review'
26
+ require 'review/i18n'
27
+
28
+ require 'review/htmlutils'
29
+ include ReVIEW::HTMLUtils
30
+
31
+ $essential_files = ['top', 'toc', 'colophon']
32
+ def main
33
+ opts = OptionParser.new
34
+ opts.version = ReVIEW::VERSION
35
+ opts.banner = "Usage: #{File.basename($0)} [options] configfile"
36
+ opts.on('-h', '--help', 'print this message and quit.') {
37
+ puts opts.help
38
+ exit 0
39
+ }
40
+ opts.on('--[no-]debug', 'Keep temporary files.') do |debug|
41
+ config["debug"] = debug
42
+ end
43
+
44
+ begin
45
+ opts.parse!
46
+ rescue OptionParser::ParseError => err
47
+ $stderr.puts err.message
48
+ $stderr.puts opts.help
49
+ exit 1
50
+ end
51
+
52
+ if ARGV.empty?
53
+ $stderr.puts opts.help
54
+ exit 1
55
+ end
56
+
57
+ yamlfile = ARGV[0]
58
+ values = ReVIEW::Configure.values.merge(YAML.load_file(yamlfile))
59
+ bookname = values["bookname"]
60
+ $essential_files <<= bookname
61
+ tmp = values["debug"].nil? ? Dir.mktmpdir : "."
62
+ @bookdir = "#{tmp}/#{bookname}-epub"
63
+ @epubversion = values["epubversion"] || 2
64
+ @htmlversion = values["htmlversion"] || 4
65
+ if @epubversion == 3
66
+ ## if epubversion is 3, htmlversion should be 5
67
+ @htmlversion = 5
68
+ end
69
+
70
+ if File.exist?("#{bookname}.epub")
71
+ STDERR.puts "#{bookname}.epub exists. Please remove or rename first."
72
+ exit 1
73
+ end
74
+ if File.exist?(@bookdir)
75
+ STDERR.puts "#{@bookdir} directory exists. Please remove or rename first."
76
+ exit 1
77
+ end
78
+
79
+ @identifier = values["urnid"].nil? ? "urn:uuid:#{UUID.create}" : values["urnid"]
80
+
81
+ Dir.mkdir(@bookdir)
82
+
83
+ # MIME type
84
+ File.open("#{@bookdir}/mimetype", "w") {|f|
85
+ f.write "application/epub+zip"
86
+ }
87
+
88
+ Dir.mkdir("#{@bookdir}/OEBPS")
89
+ # XHTML
90
+ @manifeststr = ""
91
+ @ncxstr = ""
92
+ @tocdesc = Array.new
93
+
94
+ basedir = Dir.pwd
95
+ base_path = Pathname.new(basedir)
96
+ ReVIEW::Book.load(basedir).parts.each do |part|
97
+ if part.name.present?
98
+ if part.file?
99
+ filename = (base_path + part.path).to_s
100
+ output_chaps_by_file(filename, values)
101
+ htmlfile = File.basename(filename.chomp.strip,".*")+".html"
102
+ else
103
+ htmlfile = "part_#{part.number}.html"
104
+ make_part_page(part, htmlfile, values)
105
+ file_id = "part_#{part.number}"
106
+ part_name = "#{ReVIEW::I18n.t("part", part.number)} #{part.name.strip}"
107
+ @tocdesc << [1, htmlfile, nil, part_name]
108
+ @manifeststr << %Q(<item id="rv-#{file_id}" href="#{htmlfile}" media-type="application/xhtml+xml" />\n)
109
+ @ncxstr << %Q(<itemref idref="rv-#{file_id}" />\n)
110
+ end
111
+ end
112
+
113
+ part.chapters.each do |chap|
114
+ filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
115
+ output_chaps_by_file(filename, values)
116
+ end
117
+ end
118
+
119
+ # images
120
+ if File.exist?("images")
121
+ allow_exts = values["image_ext"] || %w(png gif jpg jpeg svg ttf woff otf)
122
+ Dir.mkdir("#{@bookdir}/OEBPS/images")
123
+ image_files = ReVIEW::MakerHelper.copy_images_to_dir("images", "#{@bookdir}/OEBPS/images", :exts=>allow_exts)
124
+ image_files.each do |image_file|
125
+ dirname = File.dirname(image_file)
126
+ fname = File.basename(image_file)
127
+ figid = getFigId(dirname.gsub(%r|/|,'-')+"-"+fname)
128
+ mime = nil
129
+ fname_pattern = /\.(#{allow_exts.join("|")})$/i
130
+ next unless fname =~ fname_pattern
131
+ case fname.downcase.match(fname_pattern)[1]
132
+ when "png"
133
+ mime = "image/png"
134
+ when "gif"
135
+ mime = "image/gif"
136
+ when "jpg", "jpeg"
137
+ mime = "image/jpeg"
138
+ when "svg"
139
+ mime = "image/svg+xml"
140
+ when "ttf", "otf"
141
+ mime = "application/vnd.ms-opentype"
142
+ when "woff"
143
+ mime = "application/font-woff"
144
+ else
145
+ raise "unsupported type #{fname}"
146
+ end
147
+ if @epubversion == 3 && File.join("images",values["coverimage"]) == image_file
148
+ properties = ' properties="cover-image"'
149
+ end
150
+ @manifeststr << %Q(<item id="#{figid}" href="#{image_file}"#{properties} media-type="#{mime}" />\n)
151
+ end
152
+ end
153
+
154
+ # fonts
155
+ fontdir = values["fontdir"] || "fonts"
156
+ if File.exist?(fontdir)
157
+ font_ext = values["font_ext"]
158
+ Dir.mkdir("#{@bookdir}/OEBPS/#{fontdir}")
159
+ font_files = ReVIEW::MakerHelper.copy_images_to_dir(fontdir, "#{@bookdir}/OEBPS/#{fontdir}", :exts=>font_ext)
160
+ font_files.each do |font_file|
161
+ dirname = File.dirname(font_file)
162
+ fname = File.basename(font_file)
163
+ font_id = "font-"+fname
164
+ mime = nil
165
+ fname_pattern = /\.(#{font_ext.join("|")})$/i
166
+ next unless fname =~ fname_pattern
167
+ case fname.downcase.match(fname_pattern)[1]
168
+ when "svg"
169
+ mime = "image/svg+xml"
170
+ when "ttf", "otf"
171
+ mime = "application/vnd.ms-opentype"
172
+ when "woff"
173
+ mime = "application/font-woff"
174
+ else
175
+ raise "unsupported type #{fname}"
176
+ end
177
+ @manifeststr << %Q(<item id="#{font_id}" href="#{font_file}" media-type="#{mime}" />\n)
178
+ end
179
+ end
180
+
181
+ # container
182
+ Dir.mkdir("#{@bookdir}/META-INF")
183
+ File.open("#{@bookdir}/META-INF/container.xml", "w") {|f|
184
+ f.puts <<EOT
185
+ <?xml version="1.0" encoding="UTF-8"?>
186
+ <container xmlns="urn:oasis:names:tc:opendocument:xmlns:container" version="1.0">
187
+ <rootfiles>
188
+ <rootfile full-path="OEBPS/#{bookname}.opf" media-type="application/oebps-package+xml" />
189
+ </rootfiles>
190
+ </container>
191
+ EOT
192
+ }
193
+
194
+ # opf (meta info)
195
+ if @epubversion == 3
196
+ make_opf_filev3(values, bookname)
197
+ else
198
+ make_opf_file(values, bookname)
199
+ end
200
+
201
+ # ncx (toc)
202
+ if values["toc"]
203
+ File.open("#{@bookdir}/OEBPS/#{bookname}.ncx", "w") {|f|
204
+ f.puts <<EOT
205
+ <?xml version="1.0" encoding="UTF-8"?>
206
+ <ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1">
207
+ <head>
208
+ <meta name="dtb:uid" content="#{@identifier}"/>
209
+ <meta name="dtb:depth" content="1"/>
210
+ <meta name="dtb:totalPageCount" content="0"/>
211
+ <meta name="dtb:maxPageNumber" content="0"/>
212
+ </head>
213
+ <docTitle>
214
+ <text>#{values["booktitle"]}</text>
215
+ </docTitle>
216
+ <docAuthor>
217
+ <text>#{values["aut"].nil? ? "" : values["aut"]}</text>
218
+ </docAuthor>
219
+ <navMap>
220
+ <navPoint id="top" playOrder="1">
221
+ <navLabel>
222
+ <text>#{values["booktitle"]}</text>
223
+ </navLabel>
224
+ <content src="#{bookname}.html"/>
225
+ </navPoint>
226
+ EOT
227
+
228
+ nav_count = 2
229
+
230
+ if values["mytoc"]
231
+ f.puts <<EOT
232
+ <navPoint id="toc" playOrder="2">
233
+ <navLabel>
234
+ <text>目次</text>
235
+ </navLabel>
236
+ <content src="toc.html"/>
237
+ </navPoint>
238
+ EOT
239
+ nav_count = 3
240
+ end
241
+
242
+ @tocdesc.each {|item|
243
+ level, file, id, content = item
244
+ # values["level"]
245
+ next if level > values["toclevel"].to_i
246
+ indent = ""
247
+ if level > values["secnolevel"].to_i
248
+ indent = "- "
249
+ end
250
+ fragment_id = (id ? '#'+id : '')
251
+ f.puts <<EOT
252
+ <navPoint id="navPoint-#{nav_count}" playOrder="#{nav_count}">
253
+ <navLabel>
254
+ <text>#{indent}#{strip_html(content)}</text>
255
+ </navLabel>
256
+ <content src="#{file}#{fragment_id}"/>
257
+ </navPoint>
258
+ EOT
259
+ nav_count += 1
260
+ }
261
+ f.puts <<EOT
262
+ </navMap>
263
+ </ncx>
264
+ EOT
265
+ }
266
+ end
267
+
268
+ # Cover page
269
+ File.open("#{@bookdir}/OEBPS/#{bookname}.html", "w") {|f|
270
+ f.puts <<EOT
271
+ <?xml version="1.0" encoding="UTF-8"?>
272
+ EOT
273
+ doctype = make_doctype()
274
+ f.puts doctype
275
+ f.puts <<EOT
276
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
277
+ <head>
278
+ EOT
279
+ if @htmlversion == 4
280
+ f.puts <<EOT
281
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
282
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
283
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
284
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
285
+ EOT
286
+ else
287
+ f.puts <<EOT
288
+ <meta charset="UTF-8" />
289
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
290
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
291
+ EOT
292
+ end
293
+ f.puts <<EOT
294
+ <title>#{values["booktitle"]}</title>
295
+ </head>
296
+ <body>
297
+ EOT
298
+ if !values["coverfile"].nil? && File.exist?(values["coverfile"])
299
+ File.open(values["coverfile"]) {|f2|
300
+ f2.each_line {|l|
301
+ f.puts l
302
+ }
303
+ }
304
+ else
305
+ f.puts <<EOT
306
+ <h1>#{values["booktitle"]}</h1>
307
+ EOT
308
+ end
309
+
310
+ f.puts <<EOT
311
+ </body>
312
+ </html>
313
+ EOT
314
+ }
315
+
316
+ if values["backcoverfile"]
317
+ make_backcover_image(bookname, values)
318
+ end
319
+
320
+ # Title page
321
+ File.open("#{@bookdir}/OEBPS/top.html", "w") {|f|
322
+ f.puts <<EOT
323
+ <?xml version="1.0" encoding="UTF-8"?>
324
+ EOT
325
+ doctype = make_doctype()
326
+ f.puts doctype
327
+ f.puts <<EOT
328
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
329
+ <head>
330
+ EOT
331
+ if @htmlversion == 4
332
+ f.puts <<EOT
333
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
334
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
335
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
336
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
337
+ EOT
338
+ else
339
+ f.puts <<EOT
340
+ <meta charset="UTF-8" />
341
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
342
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
343
+ EOT
344
+ end
345
+ f.puts <<EOT
346
+ <title>#{values["booktitle"]}</title>
347
+ </head>
348
+ <body>
349
+ EOT
350
+ if !values["titlepagefile"].nil? && File.exist?(values["titlepagefile"])
351
+ File.open(values["titlepagefile"]) {|f2|
352
+ f2.each_line {|l|
353
+ f.puts l
354
+ }
355
+ }
356
+ else
357
+ f.puts <<EOT
358
+ <h1 class="tp-title">#{values["booktitle"]}</h1>
359
+ EOT
360
+ if values["aut"]
361
+ f.puts <<EOT
362
+ <p>
363
+ <br />
364
+ <br />
365
+ </p>
366
+ <h2 class="tp-author">#{join_names(values["aut"])}</h2>
367
+ EOT
368
+ end
369
+ if values["prt"]
370
+ f.puts <<EOT
371
+ <p>
372
+ <br />
373
+ <br />
374
+ <br />
375
+ <br />
376
+ </p>
377
+ <h3 class="tp-publisher">#{values["prt"]}</h3>
378
+ EOT
379
+ end
380
+ end
381
+
382
+ f.puts <<EOT
383
+ </body>
384
+ </html>
385
+ EOT
386
+ }
387
+
388
+ # Additional toc page
389
+ if values["toc"] && values["mytoc"]
390
+ File.open("#{@bookdir}/OEBPS/toc.html", "w") {|f|
391
+ if @epubversion == 3
392
+ listelm = "ol"
393
+ else
394
+ listelm = "ul"
395
+ end
396
+ f.puts <<EOT
397
+ <?xml version="1.0" encoding="UTF-8"?>
398
+ EOT
399
+ doctype = make_doctype()
400
+ f.puts doctype
401
+ f.puts <<EOT
402
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
403
+ <head>
404
+ EOT
405
+ if @htmlversion == 4
406
+ f.puts <<EOT
407
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
408
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
409
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
410
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
411
+ EOT
412
+ else
413
+ f.puts <<EOT
414
+ <meta charset="UTF-8" />
415
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
416
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
417
+ EOT
418
+ end
419
+ f.puts <<EOT
420
+ <title>目次</title>
421
+ </head>
422
+ <body>
423
+ EOT
424
+ f.puts %q(<nav epub:type="toc" id="toc">) if @epubversion == 3
425
+ f.puts <<EOT
426
+ <h1>目次</h1>
427
+ <#{listelm} class=\"toc-h1\">
428
+ EOT
429
+ current = 1
430
+ init_item = true
431
+ @tocdesc.each {|item|
432
+ level, file, id, content = item
433
+ # values["level"]
434
+ next if level > values["toclevel"].to_i
435
+ if level > current
436
+ current += 1
437
+ f.puts ""
438
+ f.puts "<#{listelm} class=\"toc-h#{current}\">"
439
+ while current < level
440
+ current += 1
441
+ f.puts "<li>"
442
+ f.puts "<#{listelm} class=\"toc-h#{current}\">"
443
+ end
444
+ elsif level < current
445
+ current -= 1
446
+ f.puts "</li>"
447
+ f.puts "</#{listelm}>"
448
+ f.puts "</li>"
449
+ while current > level
450
+ current -= 1
451
+ f.puts "</#{listelm}>"
452
+ f.puts "</li>"
453
+ end
454
+ elsif init_item
455
+ # noop
456
+ else
457
+ f.puts "</li>"
458
+ end
459
+ fragment_id = (id ? '#'+id : '')
460
+ f.write "<li><a href=\"#{file}#{fragment_id}\">#{strip_html(content)}</a>"
461
+ init_item = false
462
+ }
463
+
464
+ (current - 1).downto(1) {|n|
465
+ f.puts "</li>"
466
+ f.puts "</#{listelm}>"
467
+ }
468
+ if !init_item
469
+ f.puts "</li>"
470
+ end
471
+
472
+ f.puts "</#{listelm}>"
473
+ f.puts %q(</nav>) if @epubversion == 3
474
+ f.puts <<EOT
475
+ </body>
476
+ </html>
477
+ EOT
478
+ }
479
+ end
480
+
481
+ # stylesheet
482
+ if File.exist?(values["stylesheet"])
483
+ FileUtils.cp values["stylesheet"], "#{@bookdir}/OEBPS/#{values["stylesheet"]}"
484
+ else
485
+ File.open("#{@bookdir}/OEBPS/#{values["stylesheet"]}", "w") {|f|
486
+ f.puts <<EOT
487
+ /* sample style sheet for epub */
488
+ @charset "utf-8";
489
+
490
+ body {
491
+ }
492
+ EOT
493
+ }
494
+ end
495
+
496
+ # Colophon page
497
+ if values["colophon"]
498
+ make_colophon_page(tmp, bookname, values)
499
+ end
500
+
501
+ # hook
502
+ if !values["posthook"].nil? && !values["posthook"].empty? && FileTest.executable?(values["posthook"])
503
+ system(values["posthook"], @bookdir, Dir.pwd, yamlfile)
504
+ end
505
+
506
+ # Zip epubファイルの作成。mimetypeは圧縮しないようにする
507
+ basedir = Dir.pwd
508
+ Dir.chdir(@bookdir) {|d|
509
+ system("zip", "-0X", "#{basedir}/#{bookname}.epub", "mimetype")
510
+ system("zip", "-Xr9D", "#{basedir}/#{bookname}.epub", "META-INF", "OEBPS")
511
+ }
512
+ FileUtils.rm_r(tmp) if values["debug"].nil?
513
+ end
514
+
515
+ def make_doctype
516
+ if @htmlversion == 5
517
+ %q(<!DOCTYPE html>)
518
+ else
519
+ %q(<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">)
520
+ end
521
+ end
522
+
523
+
524
+ def make_opf_file(values, bookname)
525
+ File.open("#{@bookdir}/OEBPS/#{bookname}.opf", "w") {|f|
526
+ f.puts <<EOT
527
+ <?xml version="1.0" encoding="UTF-8"?>
528
+ <package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
529
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
530
+ <dc:title>#{values["booktitle"]}</dc:title>
531
+ EOT
532
+
533
+ f.puts %Q(<dc:creator opf:role="aut">#{values["aut"]}</dc:creator>) unless values["aut"].nil? # FIXME: support multiple members
534
+
535
+ f.puts %Q(<dc:publisher>#{values["prt"]}</dc:publisher>) unless values["prt"].nil?
536
+
537
+ f.puts %Q(<dc:date>#{values["date"]}</dc:date>) unless values["date"].nil?
538
+ f.puts %Q(<dc:rights>#{values["rights"]}</dc:rights>) unless values["rights"].nil?
539
+
540
+ f.puts %Q(<dc:contributor opf:role="asn">#{values["asn"]}</dc:contributor>) unless values["asn"].nil?
541
+ f.puts %Q(<dc:contributor opf:role="ant">#{values["ant"]}</dc:contributor>) unless values["ant"].nil?
542
+ f.puts %Q(<dc:contributor opf:role="clb">#{values["clb"]}</dc:contributor>) unless values["clb"].nil?
543
+ f.puts %Q(<dc:contributor opf:role="edt">#{values["edt"]}</dc:contributor>) unless values["edt"].nil?
544
+ f.puts %Q(<dc:contributor opf:role="dsr">#{values["dsr"]}</dc:contributor>) unless values["dsr"].nil?
545
+ f.puts %Q(<dc:contributor opf:role="ill">#{values["ill"]}</dc:contributor>) unless values["ill"].nil?
546
+ f.puts %Q(<dc:contributor opf:role="pht">#{values["pht"]}</dc:contributor>) unless values["pht"].nil?
547
+ f.puts %Q(<dc:contributor opf:role="trl">#{values["trl"]}</dc:contributor>) unless values["trl"].nil?
548
+
549
+ f.puts %Q(<dc:description>#{values["description"]}</dc:description>) unless values["description"].nil?
550
+
551
+ if values["coverimage"]
552
+ f.puts %Q(<meta name="cover" content="#{getFigId("images-"+values["coverimage"])}"/>)
553
+ end
554
+ f.puts <<EOT
555
+ <dc:language>ja</dc:language>
556
+ <dc:identifier id="BookId">#{@identifier}</dc:identifier>
557
+ </metadata>
558
+ <manifest>
559
+ EOT
560
+
561
+ if values["toc"]
562
+ f.puts <<EOT
563
+ <item id="ncx" href="#{bookname}.ncx" media-type="application/x-dtbncx+xml" />
564
+ EOT
565
+ end
566
+
567
+ f.puts <<EOT
568
+ <item id="style" href="#{values["stylesheet"]}" media-type="text/css" />
569
+ <item id="#{bookname}" href="#{bookname}.html" media-type="application/xhtml+xml" />
570
+ <item id="top" href="top.html" media-type="application/xhtml+xml" />
571
+ EOT
572
+
573
+ if values["toc"] && values["mytoc"]
574
+ f.puts <<EOT
575
+ <item id="toc" href="toc.html" media-type="application/xhtml+xml" />
576
+ EOT
577
+ end
578
+
579
+ f.puts @manifeststr
580
+ if values["colophon"]
581
+ f.puts <<EOT
582
+ <item id="colophon" href="colophon.html" media-type="application/xhtml+xml" />
583
+ EOT
584
+ end
585
+ if values["backcoverfile"]
586
+ f.puts <<EOT
587
+ <item id="backcover" href="#{values["backcoverfile"]}" media-type="application/xhtml+xml" />
588
+ EOT
589
+ end
590
+
591
+ if values["cover_linear"] && values["cover_linear"] != "no"
592
+ cover_linear = "yes"
593
+ else
594
+ cover_linear = "no"
595
+ end
596
+
597
+ f.puts <<EOT
598
+ </manifest>
599
+ <spine toc="ncx">
600
+ <itemref idref="#{bookname}" linear="#{cover_linear}" />
601
+ <itemref idref="top" />
602
+ EOT
603
+
604
+ if values["toc"] && values["mytoc"]
605
+ f.puts <<EOT
606
+ <itemref idref="toc" />
607
+ EOT
608
+ end
609
+
610
+ f.puts @ncxstr
611
+ if values["colophon"]
612
+ f.puts <<EOT
613
+ <itemref idref="colophon" />
614
+ EOT
615
+ end
616
+ if values["backcoverfile"]
617
+ f.puts <<EOT
618
+ <itemref idref="backcover" />
619
+ EOT
620
+ end
621
+ f.puts <<EOT
622
+ </spine>
623
+ <guide>
624
+ EOT
625
+
626
+ if values["titlepage"]
627
+ f.puts <<EOT
628
+ <reference type="cover" title="表紙" href="#{bookname}.html"/>
629
+ <reference type="title-page" title="Title Page" href="top.html"/>
630
+ EOT
631
+ end
632
+
633
+ if values["toc"] && values["mytoc"]
634
+ f.puts <<EOT
635
+ <reference type="toc" title="目次" href="toc.html"/>
636
+ EOT
637
+ end
638
+ f.puts <<EOT
639
+ </guide>
640
+ </package>
641
+ EOT
642
+ }
643
+ end
644
+
645
+ def make_opf_filev3(values, bookname)
646
+ File.open("#{@bookdir}/OEBPS/#{bookname}.opf", "w") {|f|
647
+ f.puts <<EOT
648
+ <?xml version="1.0" encoding="UTF-8"?>
649
+ <package version="3.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="BookId">
650
+ <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
651
+ <dc:title>#{values["booktitle"]}</dc:title>
652
+ EOT
653
+ unless values["aut"].nil? # FIXME: support multiple members
654
+ f.puts %Q(<dc:creator id="author">#{values["aut"]}</dc:creator>)
655
+ f.puts %Q(<meta refines="#author" property="role" scheme="marc:relators" id="role">aut</meta>)
656
+ end
657
+ f.puts %Q(<dc:publisher id="publisher">#{values["prt"]}</dc:publisher>) unless values["prt"].nil?
658
+
659
+ f.puts %Q(<dc:date>#{values["date"]}</dc:date>) unless values["date"].nil?
660
+ f.puts %Q(<dc:rights>#{values["rights"]}</dc:rights>) unless values["rights"].nil?
661
+
662
+ %w(asn ant clb edt dsr ill pht trl).each do |attr|
663
+ unless values[attr].nil?
664
+ f.puts %Q(<dc:contributor id="#{attr}">#{values[attr]}</dc:contributor>)
665
+ f.puts %Q(<meta refines='##{attr}' property='role' scheme='marc:relators'>#{attr}</meta>)
666
+ end
667
+ end
668
+ f.puts %Q(<dc:description>#{values["description"]}</dc:description>) unless values["description"].nil?
669
+ f.puts %Q(<meta property="dcterms:modified">#{Time.now.utc.iso8601(0)}</meta>)
670
+ if values["coverimage"]
671
+ f.puts %Q(<meta name="cover" content="#{getFigId("images-"+values["coverimage"])}"/>)
672
+ end
673
+ f.puts <<EOT
674
+ <dc:language>ja</dc:language>
675
+ <dc:identifier id="BookId">#{@identifier}</dc:identifier>
676
+ </metadata>
677
+ <manifest>
678
+ EOT
679
+
680
+ if values["toc"]
681
+ f.puts <<EOT
682
+ <item id="ncx" href="#{bookname}.ncx" media-type="application/x-dtbncx+xml" />
683
+ EOT
684
+ end
685
+
686
+ f.puts <<EOT
687
+ <item id="style" href="#{values["stylesheet"]}" media-type="text/css" />
688
+ <item id="#{bookname}" href="#{bookname}.html" media-type="application/xhtml+xml" />
689
+ <item id="top" href="top.html" media-type="application/xhtml+xml" />
690
+ EOT
691
+
692
+ if values["toc"] && values["mytoc"]
693
+ f.puts <<EOT
694
+ <item id="toc" href="toc.html" properties="nav" media-type="application/xhtml+xml" />
695
+ EOT
696
+ end
697
+
698
+ f.puts @manifeststr
699
+ if values["colophon"]
700
+ f.puts <<EOT
701
+ <item id="colophon" href="colophon.html" media-type="application/xhtml+xml" />
702
+ EOT
703
+ end
704
+
705
+ if values["backcoverfile"]
706
+ f.puts <<EOT
707
+ <item id="backcover" href="#{values["backcoverfile"]}" media-type="application/xhtml+xml" />
708
+ EOT
709
+ end
710
+
711
+ if values["cover_linear"] && values["cover_linear"] != "no"
712
+ cover_linear = "yes"
713
+ else
714
+ cover_linear = "no"
715
+ end
716
+
717
+ f.puts <<EOT
718
+ </manifest>
719
+ <spine toc="ncx">
720
+ <itemref idref="#{bookname}" linear="#{cover_linear}" />
721
+ <itemref idref="top" />
722
+ EOT
723
+
724
+ if values["toc"] && values["mytoc"]
725
+ f.puts <<EOT
726
+ <itemref idref="toc" />
727
+ EOT
728
+ end
729
+
730
+ f.puts @ncxstr
731
+ if values["colophon"]
732
+ f.puts <<EOT
733
+ <itemref idref="colophon" />
734
+ EOT
735
+ end
736
+ if values["backcoverfile"]
737
+ f.puts <<EOT
738
+ <itemref idref="backcover" />
739
+ EOT
740
+ end
741
+ f.puts <<EOT
742
+ </spine>
743
+ <guide>
744
+ EOT
745
+
746
+ if values["titlepage"]
747
+ f.puts <<EOT
748
+ <reference type="cover" title="表紙" href="#{bookname}.html"/>
749
+ <reference type="title-page" title="Title Page" href="top.html"/>
750
+ EOT
751
+ end
752
+
753
+ if values["toc"] && values["mytoc"]
754
+ f.puts <<EOT
755
+ <reference type="toc" title="目次" href="toc.html"/>
756
+ EOT
757
+ end
758
+ f.puts <<EOT
759
+ </guide>
760
+ </package>
761
+ EOT
762
+ }
763
+ end
764
+
765
+
766
+ def output_chaps(chapsfile, values)
767
+ File.open(chapsfile) {|chaps|
768
+ chaps.each_line {|l|
769
+ next if l =~ /^#/
770
+ output_chaps_by_file(l, values)
771
+ }
772
+ }
773
+ end
774
+
775
+ def output_chaps_by_file(l, values)
776
+ file_id = File.basename(l.chomp.strip,".*")
777
+ if (idx = $essential_files.index(file_id))
778
+ if idx == $essential_files.size - 1
779
+ STDERR.puts "#{file_id} is book name. Please rename #{l.chomp.strip}."
780
+ else
781
+ STDERR.puts "#{file_id} is special name. Please rename #{l.chomp.strip}."
782
+ end
783
+ exit 1
784
+ end
785
+ filename = "#{file_id}.html"
786
+ system("#{ReVIEW::MakerHelper.bindir}/review-compile --target=html --level=#{values["secnolevel"]} --htmlversion=#{values["htmlversion"]} --epubversion=#{values["epubversion"]} #{values["params"]} #{l} > #{@bookdir}/OEBPS/#{filename}")
787
+ getanchors("#{@bookdir}/OEBPS/#{filename}")
788
+ if @epubversion == 3 && include_mathml?("#{@bookdir}/OEBPS/#{filename}")
789
+ @manifeststr << %Q(<item id="rv-#{file_id}" href="#{filename}" properties="mathml" media-type="application/xhtml+xml" />\n)
790
+ else
791
+ @manifeststr << %Q(<item id="rv-#{file_id}" href="#{filename}" media-type="application/xhtml+xml" />\n)
792
+ end
793
+ @ncxstr << %Q(<itemref idref="rv-#{file_id}" />\n)
794
+ end
795
+
796
+ def include_mathml?(filename)
797
+ File.open(filename) {|f|
798
+ REXML::Document.new(f).each_element("//math"){
799
+ return true
800
+ }
801
+ return false
802
+ }
803
+ rescue
804
+ false
805
+ end
806
+
807
+ def getFigId(filename)
808
+ figid = filename.sub(/\.(png|gif|jpg|jpeg|svg)$/, '')
809
+ "fig-#{figid}"
810
+ end
811
+
812
+ def getTitle(filename)
813
+ File.open(filename) {|f|
814
+ return REXML::Document.new(f).elements["//html/head/title"].text
815
+ }
816
+ end
817
+
818
+ def getanchors(filename)
819
+ File.open(filename) {|f|
820
+ file = filename.sub(/.+\//, '')
821
+ f.each_line {|l|
822
+ if l =~ /\A<h(\d)[^>]*><a id=\"(.+?)\"><\/a>(.+?)<\/h/
823
+ # level, ID, content
824
+ @tocdesc << [$1.to_i, file, $2, $3]
825
+ end
826
+ }
827
+ }
828
+ end
829
+
830
+ def join_names(param)
831
+ if param.respond_to?(:join)
832
+ param.join(ReVIEW::I18n.t("names_splitter"))
833
+ else
834
+ param
835
+ end
836
+ end
837
+
838
+ def make_colophon_page(tmp,bookname,values)
839
+
840
+ header = <<EOT
841
+ <?xml version="1.0" encoding="UTF-8"?>
842
+ EOT
843
+ header += make_doctype()
844
+ header += <<EOT
845
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
846
+ <head>
847
+ EOT
848
+ if @htmlversion == 4
849
+ header += <<EOT
850
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
851
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
852
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
853
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
854
+ EOT
855
+ else
856
+ header += <<EOT
857
+ <meta charset="UTF-8" />
858
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
859
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
860
+ EOT
861
+ end
862
+ header += <<EOT
863
+ <title>#{values["booktitle"]}</title>
864
+ </head>
865
+ <body>
866
+ EOT
867
+
868
+ footer = <<EOT
869
+ </body>
870
+ </html>
871
+ EOT
872
+
873
+ colophon_path = "#{@bookdir}/OEBPS/colophon.html"
874
+ colophon = values["colophon"]
875
+ if colophon.kind_of?(String) && File.exist?(colophon)
876
+ File.open(colophon_path, "w") {|f|
877
+ f.puts header
878
+ File.open(values["colophon"]) {|f2|
879
+ f2.each_line {|l|
880
+ f.puts l
881
+ }
882
+ }
883
+ f.puts footer
884
+ }
885
+ else
886
+ File.open(colophon_path, "w") {|f|
887
+ f.puts header
888
+ f.puts <<EOT
889
+ <div class="colophon">
890
+ <p class="title">#{values["booktitle"]}</p>
891
+ EOT
892
+ if values["pubhistory"]
893
+ f.puts %Q[<div class="pubhistory">\n<p>#{values["pubhistory"].gsub(/\n/,"<br />")}</p>\n</div>]
894
+ end
895
+
896
+ f.puts <<EOT
897
+ <table>
898
+ EOT
899
+ f.puts %Q[<tr>\n <th>著 者</th><td>#{join_names(values["aut"]) + ReVIEW::I18n.t("author_postfix")}</td>\n</tr>] if values["aut"]
900
+ f.puts %Q[<tr>\n <th>監 修</th><td>#{join_names(values["csl"]) + ReVIEW::I18n.t("supervisor_postfix")}</td>\n</tr>] if values["csl"]
901
+ f.puts %Q[<tr>\n <th>翻 訳</th><td>#{join_names(values["trl"]) + ReVIEW::I18n.t("translator_postfix")}</td>\n</tr>] if values["trl"]
902
+ f.puts %Q[<tr>\n <th>デザイン</th><td>#{join_names(values["dsr"])}</td>\n</tr>] if values["dsr"]
903
+ f.puts %Q[<tr>\n <th>イラスト</th><td>#{join_names(values["ill"])}</td>\n</tr>] if values["ill"]
904
+ f.puts %Q[<tr>\n <th>表 紙</th><td>#{join_names(values["cov"])}</td>\n</tr>] if values["cov"]
905
+ f.puts %Q[<tr>\n <th>編 集</th><td>#{join_names(values["edt"])}</td>\n</tr>] if values["edt"]
906
+ f.puts %Q[<tr>\n <th>発行所</th><td>#{values["prt"]}</td>\n</tr>] if values["prt"]
907
+ f.puts <<EOT
908
+ </table>
909
+ EOT
910
+ if values["rights"]
911
+ f.puts %Q[<p class="copyright">#{values["rights"]}</p>]
912
+ end
913
+
914
+ f.puts "</div>"
915
+ f.puts footer
916
+ }
917
+ end
918
+ end
919
+
920
+ def make_part_page(part, filename, values)
921
+ File.open("#{@bookdir}/OEBPS/#{filename}", "w") {|f|
922
+ f.puts <<-EOT
923
+ <?xml version="1.0" encoding="UTF-8"?>
924
+ EOT
925
+ doctype = make_doctype()
926
+ f.puts doctype
927
+ if @htmlversion == 4
928
+ header = <<-EOT
929
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
930
+ <head>
931
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
932
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
933
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
934
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
935
+ <title>#{values["booktitle"]}</title>
936
+ </head>
937
+ EOT
938
+ else
939
+ header = <<-EOT
940
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
941
+ <head>
942
+ <meta charset="UTF-8" />
943
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
944
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
945
+ <title>#{values["booktitle"]}</title>
946
+ </head>
947
+ EOT
948
+ end
949
+ f.puts header
950
+
951
+ f.puts <<-EOT
952
+ <body>
953
+ <h1 class="part-number">#{ReVIEW::I18n.t("part", part.number)}</h1>
954
+ EOT
955
+
956
+ if part.name.strip.present?
957
+ f.puts <<-EOT
958
+ <h2 class="part-title">#{part.name.strip}</h2>
959
+ EOT
960
+ end
961
+
962
+ f.puts <<-EOT
963
+ </body>
964
+ </html>
965
+ EOT
966
+ }
967
+ end
968
+
969
+ def make_backcover_image(bookname, values)
970
+ backcoverfile = values["backcoverfile"]
971
+ File.open("#{@bookdir}/OEBPS/#{backcoverfile}", "w") {|f|
972
+ f.puts <<EOT
973
+ <?xml version="1.0" encoding="UTF-8"?>
974
+ EOT
975
+ doctype = make_doctype()
976
+ f.puts doctype
977
+ f.puts <<EOT
978
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="ja">
979
+ <head>
980
+ EOT
981
+ if @htmlversion == 4
982
+ f.puts <<EOT
983
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
984
+ <meta http-equiv="Content-Style-Type" content="text/css"/>
985
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
986
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
987
+ EOT
988
+ else
989
+ f.puts <<EOT
990
+ <meta charset="UTF-8" />
991
+ <link rel="stylesheet" type="text/css" href="#{values["stylesheet"]}"/>
992
+ <meta name="generator" content="Re:VIEW EPUB Maker"/>
993
+ EOT
994
+ end
995
+ f.puts <<EOT
996
+ <title>#{values["booktitle"]}</title>
997
+ </head>
998
+ <body>
999
+ EOT
1000
+ if File.exist?(backcoverfile)
1001
+ File.open(backcoverfile) {|f2|
1002
+ f2.each_line {|l|
1003
+ f.puts l
1004
+ }
1005
+ }
1006
+ else
1007
+ f.puts <<EOT
1008
+ <div id="back-cover-image" class="full">
1009
+ <img src="images/#{backcoverfile}" alt="back-cover"/>
1010
+ </div>
1011
+ EOT
1012
+ end
1013
+
1014
+ f.puts <<EOT
1015
+ </body>
1016
+ </html>
1017
+ EOT
1018
+ }
1019
+ end
1020
+
1021
+
1022
+
1023
+
1024
+ main