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
@@ -1,8 +1,11 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  module ReVIEW
3
3
  class Configure < Hash
4
+
5
+ attr_accessor :maker
6
+
4
7
  def self.values
5
- Configure[
8
+ conf = Configure[
6
9
  # These parameters can be overridden by YAML file.
7
10
  "bookname"=> "example", # it defines epub file name also
8
11
  "booktitle" => "Re:VIEW Sample Book",
@@ -27,26 +30,97 @@ module ReVIEW
27
30
  "params" => "", # specify review2html parameters
28
31
  "toclevel" => 3, # level of toc
29
32
  "secnolevel" => 2, # level of section #
30
- "epubversion" => 2,
33
+ "epubversion" => 3,
31
34
  "titlepage" => true, # Use title page
32
35
  "toc" => nil, # Use table of contents in body
33
36
  "colophon" => nil, # Use colophon
34
37
  "debug" => nil, # debug flag
35
38
  "catalogfile" => 'catalog.yml',
36
39
  "language" => 'ja', # XXX default language should be JA??
40
+ "mathml" => nil, # for HTML
41
+ "htmlext" => "html",
42
+ "htmlversion" => 5,
43
+ "imagedir" => "images",
44
+ "image_ext" => %w(png gif jpg jpeg svg ttf woff otf),
45
+ "fontdir" => "fonts",
37
46
 
38
47
  "chapter_file" => 'CHAPS',
39
- "part_file" => 'PART',
40
- "reject_file" => 'REJECT',
41
- "predef_file" => 'PREDEF',
48
+ "part_file" => 'PART',
49
+ "reject_file" => 'REJECT',
50
+ "predef_file" => 'PREDEF',
42
51
  "postdef_file" => 'POSTDEF',
43
- "page_metric" => ReVIEW::Book::PageMetric.a5,
44
- "ext" => '.re',
45
- "image_dir" => 'images',
46
- "image_types" => %w( .ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg ),
47
- "bib_file" => "bib.re",
52
+ "page_metric" => ReVIEW::Book::PageMetric::A5,
53
+ "ext" => '.re',
54
+ "image_dir" => 'images',
55
+ "image_types" => %w( .ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg ),
56
+ "image_scale2width" => true, # for LaTeX
57
+ "bib_file" => "bib.re",
48
58
  "colophon_order" => %w(aut csl trl dsr ill cov edt pbl contact prt),
59
+ "externallink" => true,
60
+ "tableopt" => nil, # for IDGXML
61
+ "listinfo" => nil, # for IDGXML
62
+ "nolf" => true, # for IDGXML
63
+ "chapref" => nil, # for IDGXML
64
+ "structuredxml" => nil, # for IDGXML
65
+ "pt_to_mm_unit" => 0.3528, # for IDGXML (DTP: 1pt = 0.3528mm, JIS: 1pt = 0.3514mm)
66
+ "footnotetext" => nil, # for LaTeX
67
+ "texcommand" => "uplatex", # for LaTeX
68
+ "texdocumentclass" => ["jsbook", "uplatex,oneside"], # for LaTeX
69
+ "dvicommand" => "dvipdfmx", # for LaTeX
70
+ "dvioptions" => "-d 5", # for LaTeX
49
71
  ]
72
+ conf.maker = nil
73
+ conf
74
+ end
75
+
76
+ def [](key)
77
+ maker = self.maker
78
+ if maker && self.key?(maker) && self.fetch(maker) && self.fetch(maker).key?(key)
79
+ return self.fetch(maker).fetch(key, nil)
80
+ end
81
+ if self.key?(key)
82
+ return self.fetch(key)
83
+ end
84
+ end
85
+
86
+ def check_version(version)
87
+ unless self.key?("review_version")
88
+ raise ReVIEW::ConfigError, "configuration file has no review_version property."
89
+ end
90
+
91
+ if self["review_version"].blank?
92
+ # do nothing
93
+ elsif self["review_version"].to_i != version.to_i ## major version
94
+ raise ReVIEW::ConfigError, "major version of configuration file is different."
95
+ elsif self["review_version"].to_f > version.to_f ## minor version
96
+ raise ReVIEW::ConfigError, "Re:VIEW version '#{version}' is older than configuration file's version '#{self["review_version"]}'."
97
+ end
98
+ end
99
+
100
+ def name_of(key)
101
+ if self[key].kind_of?(Array)
102
+ self[key].join(",") # i18n?
103
+ elsif self[key].kind_of?(Hash)
104
+ self[key]["name"]
105
+ else
106
+ self[key]
107
+ end
108
+ end
109
+
110
+ def names_of(key)
111
+ if self[key].kind_of?(Array)
112
+ self[key].map do |a|
113
+ if a.kind_of?(Hash)
114
+ a["name"]
115
+ else
116
+ a
117
+ end
118
+ end
119
+ elsif self[key].kind_of?(Hash)
120
+ [self[key]["name"]]
121
+ else
122
+ [self[key]]
123
+ end
50
124
  end
51
125
  end
52
126
  end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ #
3
+ # This program is free software.
4
+ # You can distribute or modify this program under the terms of
5
+ # the GNU LGPL, Lesser General Public License version 2.1.
6
+ #
7
+
8
+ module ReVIEW
9
+ class Converter
10
+ attr_accessor :target
11
+
12
+ def initialize(book, builder)
13
+ @book = book
14
+ @book.config["builder"] = builder.target_name
15
+ @compiler = ReVIEW::Compiler.new(builder)
16
+ end
17
+
18
+ def convert(file, output_path)
19
+ chap_name = File.basename(file, '.*')
20
+ chap = @book.chapter(chap_name)
21
+ result = @compiler.compile(chap)
22
+ File.open(output_path, 'w') do |f|
23
+ f.puts result
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -15,4 +15,4 @@ module ReVIEW
15
15
  class EPUBBuilder < HTMLBuilder
16
16
  end
17
17
 
18
- end # module ReVIEW
18
+ end # module ReVIEW
@@ -1,13 +1,26 @@
1
1
  # encoding: utf-8
2
2
  #
3
- # Copyright (c) 2010-2015 Kenshi Muto and Masayoshi Takahashi
3
+ # Copyright (c) 2010-2016 Kenshi Muto and Masayoshi Takahashi
4
4
  #
5
5
  # This program is free software.
6
6
  # You can distribute or modify this program under the terms of
7
7
  # the GNU LGPL, Lesser General Public License version 2.1.
8
8
  # For details of the GNU LGPL, see the file "COPYING".
9
9
  #
10
- require 'review'
10
+
11
+ require 'tmpdir'
12
+
13
+ require 'review/i18n'
14
+ require 'review/book'
15
+ require 'review/configure'
16
+ require 'review/converter'
17
+ require 'review/latexbuilder'
18
+ require 'review/yamlloader'
19
+ require 'review/version'
20
+ require 'review/htmltoc'
21
+ require 'review/htmlbuilder'
22
+
23
+ require 'review/yamlloader'
11
24
  require 'rexml/document'
12
25
  require 'rexml/streamlistener'
13
26
  require 'epubmaker'
@@ -19,7 +32,7 @@ module ReVIEW
19
32
 
20
33
  def initialize
21
34
  @producer = nil
22
- @tochtmltxt = "toc-html.txt"
35
+ @htmltoc = nil
23
36
  @buildlogtxt = "build-log.txt"
24
37
  end
25
38
 
@@ -28,10 +41,25 @@ module ReVIEW
28
41
  end
29
42
 
30
43
  def load_yaml(yamlfile)
31
- @params = ReVIEW::Configure.values.merge(YAML.load_file(yamlfile)) # FIXME:設定がRe:VIEW側とepubmaker/producer.rb側の2つに分かれて面倒
44
+ loader = ReVIEW::YAMLLoader.new
45
+ @params = ReVIEW::Configure.values.deep_merge(loader.load_file(yamlfile))
32
46
  @producer = Producer.new(@params)
33
47
  @producer.load(yamlfile)
34
48
  @params = @producer.params
49
+ @params.maker = "epubmaker"
50
+ end
51
+
52
+ def build_path
53
+ if @params["debug"]
54
+ path = File.expand_path("#{@params["bookname"]}-epub", Dir.pwd)
55
+ if File.exist?(path)
56
+ FileUtils.rm_rf(path, :secure => true)
57
+ end
58
+ Dir.mkdir(path)
59
+ return path
60
+ else
61
+ return Dir.mktmpdir("#{@params["bookname"]}-epub-")
62
+ end
35
63
  end
36
64
 
37
65
  def produce(yamlfile, bookname=nil)
@@ -40,17 +68,23 @@ module ReVIEW
40
68
  bookname = @params["bookname"] if bookname.nil?
41
69
  booktmpname = "#{bookname}-epub"
42
70
 
71
+ begin
72
+ @params.check_version(ReVIEW::VERSION)
73
+ rescue ReVIEW::ConfigError => e
74
+ warn e.message
75
+ end
43
76
  log("Loaded yaml file (#{yamlfile}). I will produce #{bookname}.epub.")
44
77
 
45
78
  FileUtils.rm_f("#{bookname}.epub")
46
79
  FileUtils.rm_rf(booktmpname) if @params["debug"]
47
80
 
48
- basetmpdir = Dir.mktmpdir("#{bookname}-", Dir.pwd)
81
+ basetmpdir = build_path()
49
82
  begin
50
83
  log("Created first temporary directory as #{basetmpdir}.")
51
84
 
52
85
  call_hook("hook_beforeprocess", basetmpdir)
53
86
 
87
+ @htmltoc = ReVIEW::HTMLToc.new(basetmpdir)
54
88
  ## copy all files into basetmpdir
55
89
  copy_stylesheet(basetmpdir)
56
90
 
@@ -84,14 +118,16 @@ module ReVIEW
84
118
 
85
119
  epubtmpdir = nil
86
120
  if @params["debug"].present?
87
- epubtmpdir = "#{Dir.pwd}/#{booktmpname}"
121
+ epubtmpdir = "#{basetmpdir}/#{booktmpname}"
88
122
  Dir.mkdir(epubtmpdir)
89
123
  end
90
124
  log("Call ePUB producer.")
91
125
  @producer.produce("#{bookname}.epub", basetmpdir, epubtmpdir)
92
126
  log("Finished.")
93
127
  ensure
94
- FileUtils.remove_entry_secure basetmpdir if @params["debug"].nil?
128
+ unless @params["debug"]
129
+ FileUtils.remove_entry_secure basetmpdir
130
+ end
95
131
  end
96
132
  end
97
133
 
@@ -162,7 +198,7 @@ module ReVIEW
162
198
  def recursive_copy_files(resdir, destdir, allow_exts)
163
199
  Dir.open(resdir) do |dir|
164
200
  dir.each do |fname|
165
- next if fname =~ /\A\./
201
+ next if fname.start_with?('.')
166
202
  if FileTest.directory?("#{resdir}/#{fname}")
167
203
  recursive_copy_files("#{resdir}/#{fname}", "#{destdir}/#{fname}", allow_exts)
168
204
  else
@@ -176,6 +212,13 @@ module ReVIEW
176
212
  end
177
213
  end
178
214
 
215
+ def check_compile_status
216
+ return unless @compile_errors
217
+
218
+ $stderr.puts "compile error, No EPUB file output."
219
+ exit 1
220
+ end
221
+
179
222
  def build_body(basetmpdir, yamlfile)
180
223
  @precount = 0
181
224
  @bodycount = 0
@@ -184,60 +227,68 @@ module ReVIEW
184
227
  @manifeststr = ""
185
228
  @ncxstr = ""
186
229
  @tocdesc = Array.new
187
- # toccount = 2 ## not used
188
230
 
189
- basedir = Dir.pwd
231
+ basedir = File.dirname(yamlfile)
190
232
  base_path = Pathname.new(basedir)
191
233
  book = ReVIEW::Book.load(basedir)
192
- book.load_config(yamlfile)
234
+ book.config = @params
235
+ @converter = ReVIEW::Converter.new(book, ReVIEW::HTMLBuilder.new)
236
+ @compile_errors = nil
193
237
  book.parts.each do |part|
194
238
  htmlfile = nil
195
239
  if part.name.present?
196
240
  if part.file?
197
- build_chap(part, base_path, basetmpdir, yamlfile, true)
241
+ build_chap(part, base_path, basetmpdir, true)
198
242
  else
199
243
  htmlfile = "part_#{part.number}.#{@params["htmlext"]}"
200
244
  build_part(part, basetmpdir, htmlfile)
201
245
  title = ReVIEW::I18n.t("part", part.number)
202
246
  title += ReVIEW::I18n.t("chapter_postfix") + part.name.strip if part.name.strip.present?
203
- write_tochtmltxt(basetmpdir, "0\t#{htmlfile}\t#{title}\tchaptype=part")
247
+ @htmltoc.add_item(0, htmlfile, title, {:chaptype => "part"})
204
248
  write_buildlogtxt(basetmpdir, htmlfile, "")
205
249
  end
206
250
  end
207
251
 
208
252
  part.chapters.each do |chap|
209
- build_chap(chap, base_path, basetmpdir, yamlfile, nil)
253
+ build_chap(chap, base_path, basetmpdir, false)
210
254
  end
211
255
 
212
256
  end
257
+ check_compile_status()
213
258
  end
214
259
 
215
260
  def build_part(part, basetmpdir, htmlfile)
216
261
  log("Create #{htmlfile} from a template.")
217
262
  File.open("#{basetmpdir}/#{htmlfile}", "w") do |f|
218
- f.puts header(CGI.escapeHTML(@params["booktitle"]))
219
- f.puts <<EOT
220
- <div class="part">
221
- <h1 class="part-number">#{ReVIEW::I18n.t("part", part.number)}</h1>
222
- EOT
263
+ @body = ""
264
+ @body << "<div class=\"part\">\n"
265
+ @body << "<h1 class=\"part-number\">#{CGI.escapeHTML(ReVIEW::I18n.t("part", part.number))}</h1>\n"
223
266
  if part.name.strip.present?
224
- f.puts <<EOT
225
- <h2 class="part-title">#{part.name.strip}</h2>
226
- EOT
267
+ @body << "<h2 class=\"part-title\">#{CGI.escapeHTML(part.name.strip)}</h2>\n"
227
268
  end
269
+ @body << "</div>\n"
270
+
271
+ @language = @producer.params['language']
272
+ @stylesheets = @producer.params["stylesheet"]
273
+ tmplfile = File.expand_path(template_name, ReVIEW::Template::TEMPLATE_DIR)
274
+ tmpl = ReVIEW::Template.load(tmplfile)
275
+ f.write tmpl.result(binding)
276
+ end
277
+ end
228
278
 
229
- f.puts <<EOT
230
- </div>
231
- EOT
232
- f.puts footer
279
+ def template_name
280
+ if @producer.params["htmlversion"].to_i == 5
281
+ './html/layout-html5.html.erb'
282
+ else
283
+ './html/layout-xhtml1.html.erb'
233
284
  end
234
285
  end
235
286
 
236
- def build_chap(chap, base_path, basetmpdir, yamlfile, ispart=nil)
287
+ def build_chap(chap, base_path, basetmpdir, ispart)
237
288
  filename = ""
238
289
 
239
290
  chaptype = "body"
240
- if ispart.present?
291
+ if ispart
241
292
  chaptype = "part"
242
293
  elsif chap.on_PREDEF?
243
294
  chaptype = "pre"
@@ -269,27 +320,32 @@ EOT
269
320
  write_buildlogtxt(basetmpdir, htmlfile, filename)
270
321
  log("Create #{htmlfile} from #{filename}.")
271
322
 
272
- level = @params["secnolevel"]
273
-
274
- # TODO: It would be nice if we can modify level in PART, PREDEF, or POSTDEF.
275
- # But we have to care about section number reference (@<hd>) also.
276
- #
277
- # if !ispart.nil?
278
- # level = @params["part_secnolevel"]
279
- # else
280
- # level = @params["pre_secnolevel"] if chap.on_PREDEF?
281
- # level = @params["post_secnolevel"] if chap.on_APPENDIX?
282
- # end
283
-
284
- stylesheet = ""
285
- if @params["stylesheet"].size > 0
286
- stylesheet = "--stylesheet=#{@params["stylesheet"].join(",")}"
323
+ if @params["params"].present?
324
+ warn "'params:' in config.yml is obsoleted."
325
+ if @params["params"] =~ /stylesheet=/
326
+ warn "stylesheets should be defined in 'stylesheet:', not in 'params:'"
327
+ end
287
328
  end
329
+ begin
330
+ @converter.convert(filename, File.join(basetmpdir, htmlfile))
331
+ write_info_body(basetmpdir, id, htmlfile, ispart, chaptype)
332
+ remove_hidden_title(basetmpdir, htmlfile)
333
+ rescue => e
334
+ @compile_errors = true
335
+ warn "compile error in #{filename} (#{e.class})"
336
+ warn e.message
337
+ end
338
+ end
288
339
 
289
- ENV["REVIEWFNAME"] = filename
290
- system("#{ReVIEW::MakerHelper.bindir}/review-compile --yaml=#{yamlfile} --target=html --level=#{level} --htmlversion=#{@params["htmlversion"]} --epubversion=#{@params["epubversion"]} #{stylesheet} #{@params["params"]} #{filename} > \"#{basetmpdir}/#{htmlfile}\"")
291
-
292
- write_info_body(basetmpdir, id, htmlfile, ispart, chaptype)
340
+ def remove_hidden_title(basetmpdir, htmlfile)
341
+ File.open("#{basetmpdir}/#{htmlfile}", "r+") do |f|
342
+ body = f.read.
343
+ gsub(/<h\d .*?hidden=['"]true['"].*?>.*?<\/h\d>\n/, '').
344
+ gsub(/(<h\d .*?)\s*notoc=['"]true['"]\s*(.*?>.*?<\/h\d>\n)/, '\1\2')
345
+ f.rewind
346
+ f.print body
347
+ f.truncate(f.tell)
348
+ end
293
349
  end
294
350
 
295
351
  def detect_properties(path)
@@ -308,7 +364,6 @@ EOT
308
364
 
309
365
  def write_info_body(basetmpdir, id, filename, ispart=nil, chaptype=nil)
310
366
  headlines = []
311
- # FIXME:nonumを修正する必要あり
312
367
  path = File.join(basetmpdir, filename)
313
368
  Document.parse_stream(File.new(path), ReVIEWHeaderListener.new(headlines))
314
369
  properties = detect_properties(path)
@@ -320,51 +375,30 @@ EOT
320
375
  headlines.each do |headline|
321
376
  headline["level"] = 0 if ispart.present? && headline["level"] == 1
322
377
  if first.nil?
323
- write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}##{headline["id"]}\t#{headline["title"]}\tchaptype=#{chaptype}")
378
+ @htmltoc.add_item(headline["level"], filename+"#"+headline["id"], headline["title"], {:chaptype => chaptype, :notoc => headline["notoc"]})
324
379
  else
325
- write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}\t#{headline["title"]}\tforce_include=true,chaptype=#{chaptype}#{prop_str}")
380
+ @htmltoc.add_item(headline["level"], filename, headline["title"], {:force_include => true, :chaptype => chaptype+prop_str, :notoc => headline["notoc"]})
326
381
  first = nil
327
382
  end
328
383
  end
329
384
  end
330
385
 
331
386
  def push_contents(basetmpdir)
332
- File.open("#{basetmpdir}/#{@tochtmltxt}") do |f|
333
- f.each_line do |l|
334
- force_include = nil
335
- customid = nil
336
- chaptype = nil
337
- properties = nil
338
- level, file, title, custom = l.chomp.split("\t")
339
- if custom.present?
340
- # custom setting
341
- vars = custom.split(/,\s*/)
342
- vars.each do |var|
343
- k, v = var.split("=")
344
- case k
345
- when "id"
346
- customid = v
347
- when "force_include"
348
- force_include = true
349
- when "chaptype"
350
- chaptype = v
351
- when "properties"
352
- properties = v
353
- end
354
- end
355
- end
356
- next if level.to_i > @params["toclevel"] && force_include.nil?
357
- log("Push #{file} to ePUB contents.")
387
+ @htmltoc.each_item do |level, file, title, args|
388
+ next if level.to_i > @params["toclevel"] && args[:force_include].nil?
389
+ log("Push #{file} to ePUB contents.")
358
390
 
359
- hash = {"file" => file, "level" => level.to_i, "title" => title, "chaptype" => chaptype}
360
- if customid.present?
361
- hash["id"] = customid
362
- end
363
- if properties.present?
364
- hash["properties"] = properties.split(" ")
365
- end
366
- @producer.contents.push(Content.new(hash))
391
+ hash = {"file" => file, "level" => level.to_i, "title" => title, "chaptype" => args[:chaptype]}
392
+ if args[:id].present?
393
+ hash["id"] = args[:id]
394
+ end
395
+ if args[:properties].present?
396
+ hash["properties"] = args[:properties].split(" ")
367
397
  end
398
+ if args[:notoc].present?
399
+ hash["notoc"] = args[:notoc]
400
+ end
401
+ @producer.contents.push(Content.new(hash))
368
402
  end
369
403
  end
370
404
 
@@ -386,75 +420,66 @@ EOT
386
420
  else
387
421
  FileUtils.cp(@params["titlefile"], "#{basetmpdir}/titlepage.#{@params["htmlext"]}")
388
422
  end
389
- write_tochtmltxt(basetmpdir, "1\ttitlepage.#{@params["htmlext"]}\t#{@producer.res.v("titlepagetitle")}\tchaptype=pre")
423
+ @htmltoc.add_item(1, "titlepage.#{@params['htmlext']}", @producer.res.v("titlepagetitle"), {:chaptype => "pre"})
390
424
  end
391
425
 
392
426
  if @params["originaltitlefile"].present? && File.exist?(@params["originaltitlefile"])
393
427
  FileUtils.cp(@params["originaltitlefile"], "#{basetmpdir}/#{File.basename(@params["originaltitlefile"])}")
394
- write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["originaltitlefile"])}\t#{@producer.res.v("originaltitle")}\tchaptype=pre")
428
+ @htmltoc.add_item(1, File.basename(@params["originaltitlefile"]), @producer.res.v("originaltitle"), {:chaptype => "pre"})
395
429
  end
396
430
 
397
431
  if @params["creditfile"].present? && File.exist?(@params["creditfile"])
398
432
  FileUtils.cp(@params["creditfile"], "#{basetmpdir}/#{File.basename(@params["creditfile"])}")
399
- write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["creditfile"])}\t#{@producer.res.v("credittitle")}\tchaptype=pre")
433
+ @htmltoc.add_item(1, File.basename(@params["creditfile"]), @producer.res.v("credittitle"), {:chaptype => "pre"})
400
434
  end
401
435
  end
402
436
 
403
437
  def build_titlepage(basetmpdir, htmlfile)
438
+ # TODO: should be created via epubcommon
439
+ @title = CGI.escapeHTML(@params.name_of("booktitle"))
404
440
  File.open("#{basetmpdir}/#{htmlfile}", "w") do |f|
405
- f.puts header(CGI.escapeHTML(@params["booktitle"]))
406
- f.puts <<EOT
407
- <div class="titlepage">
408
- <h1 class="tp-title">#{CGI.escapeHTML(@params["booktitle"])}</h1>
409
- EOT
410
-
441
+ @body = ""
442
+ @body << "<div class=\"titlepage\">\n"
443
+ @body << "<h1 class=\"tp-title\">#{CGI.escapeHTML(@params.name_of("booktitle"))}</h1>\n"
411
444
  if @params["aut"]
412
- f.puts <<EOT
413
- <h2 class="tp-author">#{@params["aut"].join(", ")}</h2>
414
- EOT
445
+ @body << "<h2 class=\"tp-author\">#{CGI.escapeHTML(@params.names_of("aut").join(ReVIEW::I18n.t("names_splitter")))}</h2>\n"
415
446
  end
416
447
  if @params["prt"]
417
- f.puts <<EOT
418
- <h3 class="tp-publisher">#{@params["prt"].join(", ")}</h3>
419
- EOT
448
+ @body << "<h3 class=\"tp-publisher\">#{CGI.escapeHTML(@params.names_of("prt").join(ReVIEW::I18n.t("names_splitter")))}</h3>\n"
420
449
  end
450
+ @body << "</div>"
421
451
 
422
- f.puts <<EOT
423
- </div>
424
- EOT
425
- f.puts footer
452
+ @language = @producer.params['language']
453
+ @stylesheets = @producer.params["stylesheet"]
454
+ tmplfile = File.expand_path(template_name, ReVIEW::Template::TEMPLATE_DIR)
455
+ tmpl = ReVIEW::Template.load(tmplfile)
456
+ f.write tmpl.result(binding)
426
457
  end
427
458
  end
428
459
 
429
460
  def copy_backmatter(basetmpdir)
430
461
  if @params["profile"]
431
462
  FileUtils.cp(@params["profile"], "#{basetmpdir}/#{File.basename(@params["profile"])}")
432
- write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["profile"])}\t#{@producer.res.v("profiletitle")}\tchaptype=post")
463
+ @htmltoc.add_item(1, File.basename(@params["profile"]), @producer.res.v("profiletitle"), {:chaptype => "post"})
433
464
  end
434
465
 
435
466
  if @params["advfile"]
436
467
  FileUtils.cp(@params["advfile"], "#{basetmpdir}/#{File.basename(@params["advfile"])}")
437
- write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["advfile"])}\t#{@producer.res.v("advtitle")}\tchaptype=post")
468
+ @htmltoc.add_item(1, File.basename(@params["advfile"]), @producer.res.v("advtitle"), {:chaptype => "post"})
438
469
  end
439
470
 
440
471
  if @params["colophon"]
441
- if @params["colophon"].instance_of?(String) # FIXME:このやり方はやめる?
472
+ if @params["colophon"].kind_of?(String) # FIXME:このやり方はやめる?
442
473
  FileUtils.cp(@params["colophon"], "#{basetmpdir}/colophon.#{@params["htmlext"]}")
443
474
  else
444
475
  File.open("#{basetmpdir}/colophon.#{@params["htmlext"]}", "w") {|f| @producer.colophon(f) }
445
476
  end
446
- write_tochtmltxt(basetmpdir, "1\tcolophon.#{@params["htmlext"]}\t#{@producer.res.v("colophontitle")}\tchaptype=post")
477
+ @htmltoc.add_item(1, "colophon.#{@params["htmlext"]}", @producer.res.v("colophontitle"), {:chaptype => "post"})
447
478
  end
448
479
 
449
480
  if @params["backcover"]
450
481
  FileUtils.cp(@params["backcover"], "#{basetmpdir}/#{File.basename(@params["backcover"])}")
451
- write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["backcover"])}\t#{@producer.res.v("backcovertitle")}\tchaptype=post")
452
- end
453
- end
454
-
455
- def write_tochtmltxt(basetmpdir, s)
456
- File.open("#{basetmpdir}/#{@tochtmltxt}", "a") do |f|
457
- f.puts s
482
+ @htmltoc.add_item(1, File.basename(@params["backcover"]), @producer.res.v("backcovertitle"), {:chaptype => "post"})
458
483
  end
459
484
  end
460
485
 
@@ -464,49 +489,6 @@ EOT
464
489
  end
465
490
  end
466
491
 
467
- def header(title)
468
- # titleはすでにエスケープ済みと想定
469
- s = <<EOT
470
- <?xml version="1.0" encoding="UTF-8"?>
471
- EOT
472
- if @params["htmlversion"] == 5
473
- s << <<EOT
474
- <!DOCTYPE html>
475
- <html xml:lang='ja' xmlns:ops='http://www.idpf.org/2007/ops' xmlns='http://www.w3.org/1999/xhtml'>
476
- <head>
477
- <meta charset="UTF-8" />
478
- EOT
479
- else
480
- s << <<EOT
481
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
482
- <html xml:lang='ja' xmlns:ops='http://www.idpf.org/2007/ops' xmlns='http://www.w3.org/1999/xhtml'>
483
- <head>
484
- <meta http-equiv='Content-Type' content='text/html;charset=UTF-8' />
485
- <meta http-equiv='Content-Style-Type' content='text/css' />
486
- EOT
487
- end
488
- if @params["stylesheet"].size > 0
489
- @params["stylesheet"].each do |sfile|
490
- s << <<EOT
491
- <link rel='stylesheet' type='text/css' href='#{sfile}' />
492
- EOT
493
- end
494
- end
495
- s << <<EOT
496
- <meta content='Re:VIEW' name='generator'/>
497
- <title>#{title}</title>
498
- </head>
499
- <body>
500
- EOT
501
- end
502
-
503
- def footer
504
- <<EOT
505
- </body>
506
- </html>
507
- EOT
508
- end
509
-
510
492
  class ReVIEWHeaderListener
511
493
  include REXML::StreamListener
512
494
  def initialize(headlines)
@@ -522,6 +504,7 @@ EOT
522
504
  end
523
505
  @level = $1.to_i
524
506
  @id = attrs["id"] if attrs["id"].present?
507
+ @notoc = attrs["notoc"] if attrs["notoc"].present?
525
508
  elsif !@level.nil?
526
509
  if name == "img" && attrs["alt"].present?
527
510
  @content << attrs["alt"]
@@ -533,10 +516,11 @@ EOT
533
516
 
534
517
  def tag_end(name)
535
518
  if name =~ /\Ah\d+/
536
- @headlines.push({"level" => @level, "id" => @id, "title" => @content}) if @id.present?
519
+ @headlines.push({"level" => @level, "id" => @id, "title" => @content, "notoc" => @notoc}) if @id.present?
537
520
  @content = ""
538
521
  @level = nil
539
522
  @id = nil
523
+ @notoc = nil
540
524
  end
541
525
  end
542
526