review 1.7.2 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -43
  3. data/.travis.yml +0 -9
  4. data/ChangeLog +0 -16
  5. data/Gemfile +1 -0
  6. data/README.rdoc +1 -1
  7. data/Rakefile +12 -1
  8. data/bin/review-check +21 -8
  9. data/bin/review-compile +15 -9
  10. data/bin/review-epubmaker-legacy +6 -6
  11. data/bin/review-index +13 -2
  12. data/bin/review-init +18 -12
  13. data/bin/review-preproc +14 -1
  14. data/bin/review-validate +1 -1
  15. data/bin/review-vol +13 -1
  16. data/doc/quickstart.ja.md +1 -1
  17. data/doc/quickstart.md +1 -1
  18. data/lib/epubmaker/content.rb +3 -3
  19. data/lib/epubmaker/epubcommon.rb +108 -91
  20. data/lib/epubmaker/epubv2.rb +67 -14
  21. data/lib/epubmaker/epubv3.rb +59 -25
  22. data/lib/epubmaker/producer.rb +1 -13
  23. data/lib/lineinput.rb +0 -48
  24. data/lib/review/book/base.rb +4 -12
  25. data/lib/review/book/compilable.rb +3 -1
  26. data/lib/review/book/index.rb +4 -4
  27. data/lib/review/builder.rb +54 -47
  28. data/lib/review/compiler.rb +4662 -326
  29. data/lib/review/compiler/literals_1_8.kpeg +19 -0
  30. data/lib/review/compiler/literals_1_8.rb +432 -0
  31. data/lib/review/compiler/literals_1_9.kpeg +22 -0
  32. data/lib/review/compiler/literals_1_9.rb +435 -0
  33. data/lib/review/configure.rb +8 -20
  34. data/lib/review/epubbuilder.rb +1 -1
  35. data/lib/review/epubmaker.rb +122 -52
  36. data/lib/review/ewbbuilder.rb +4 -4
  37. data/lib/review/exception.rb +1 -1
  38. data/lib/review/extentions.rb +1 -0
  39. data/lib/review/extentions/array.rb +25 -0
  40. data/lib/review/htmlbuilder.rb +286 -275
  41. data/lib/review/htmllayout.rb +0 -2
  42. data/lib/review/htmlutils.rb +4 -4
  43. data/lib/review/i18n.rb +2 -6
  44. data/lib/review/i18n.yml +1 -1
  45. data/lib/review/idgxmlbuilder.rb +239 -204
  46. data/lib/review/inaobuilder.rb +75 -73
  47. data/lib/review/latexbuilder.rb +265 -219
  48. data/lib/review/latexutils.rb +6 -6
  49. data/lib/review/layout.tex.erb +1 -1
  50. data/lib/review/location.rb +24 -0
  51. data/lib/review/markdownbuilder.rb +124 -79
  52. data/lib/review/node.rb +267 -0
  53. data/lib/review/pdfmaker.rb +92 -92
  54. data/lib/review/preprocessor.rb +51 -14
  55. data/lib/review/review.kpeg +724 -0
  56. data/lib/review/textbuilder.rb +1 -1
  57. data/lib/review/textutils.rb +24 -18
  58. data/lib/review/tocparser.rb +3 -3
  59. data/lib/review/tocprinter.rb +31 -8
  60. data/lib/review/topbuilder.rb +119 -111
  61. data/lib/review/unfold.rb +2 -2
  62. data/lib/review/version.rb +1 -1
  63. data/review.gemspec +2 -2
  64. data/rubocop-todo.yml +456 -0
  65. data/test/assets/test_template.tex +1 -1
  66. data/test/sample-book/src/config.yml +0 -1
  67. data/test/test.re +1 -1
  68. data/test/test_book.rb +4 -4
  69. data/test/test_book_chapter.rb +70 -0
  70. data/test/test_book_part.rb +1 -1
  71. data/test/test_builder.rb +6 -28
  72. data/test/test_compiler.rb +59 -14
  73. data/test/test_helper.rb +47 -4
  74. data/test/test_htmlbuilder.rb +104 -73
  75. data/test/test_i18n.rb +5 -3
  76. data/test/test_idgxmlbuilder.rb +5 -2
  77. data/test/test_inaobuilder.rb +4 -2
  78. data/test/test_latexbuilder.rb +18 -37
  79. data/test/test_lineinput.rb +25 -4
  80. data/test/test_markdownbuilder.rb +4 -22
  81. data/test/test_pdfmaker.rb +12 -11
  82. data/test/test_textutils.rb +0 -36
  83. data/test/test_topbuilder.rb +2 -0
  84. metadata +14 -28
  85. data/.rubocop_todo.yml +0 -605
  86. data/Dockerfile +0 -22
  87. data/doc/NEWS.ja.md +0 -362
  88. data/doc/NEWS.md +0 -366
  89. data/lib/review/htmltoc.rb +0 -45
  90. data/lib/review/template.rb +0 -21
  91. data/templates/html/layout-html5.html.erb +0 -17
  92. data/templates/html/layout-xhtml1.html.erb +0 -20
  93. data/templates/ncx/epubv2.ncx.erb +0 -11
  94. data/templates/opf/epubv2.opf.erb +0 -21
  95. data/templates/opf/epubv3.opf.erb +0 -18
  96. data/templates/xml/container.xml.erb +0 -6
  97. data/test/assets/test.xml.erb +0 -3
  98. data/test/sample-book/src/config-epub2.yml +0 -186
  99. data/test/test_configure.rb +0 -50
  100. data/test/test_htmltoc.rb +0 -32
  101. data/test/test_template.rb +0 -26
@@ -1,9 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  module ReVIEW
3
3
  class Configure < Hash
4
-
5
- attr_accessor :maker
6
-
7
4
  def self.values
8
5
  Configure[
9
6
  # These parameters can be overridden by YAML file.
@@ -39,26 +36,17 @@ module ReVIEW
39
36
  "language" => 'ja', # XXX default language should be JA??
40
37
 
41
38
  "chapter_file" => 'CHAPS',
42
- "part_file" => 'PART',
43
- "reject_file" => 'REJECT',
44
- "predef_file" => 'PREDEF',
39
+ "part_file" => 'PART',
40
+ "reject_file" => 'REJECT',
41
+ "predef_file" => 'PREDEF',
45
42
  "postdef_file" => 'POSTDEF',
46
- "page_metric" => ReVIEW::Book::PageMetric.a5,
47
- "ext" => '.re',
48
- "image_dir" => 'images',
49
- "image_types" => %w( .ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg ),
50
- "bib_file" => "bib.re",
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",
51
48
  "colophon_order" => %w(aut csl trl dsr ill cov edt pbl contact prt),
52
49
  ]
53
50
  end
54
-
55
- def [](key)
56
- if self.key?(key)
57
- return self.fetch(key)
58
- end
59
- if @maker && self.key?(@maker)
60
- return self.fetch(@maker).fetch(key, nil)
61
- end
62
- end
63
51
  end
64
52
  end
@@ -15,4 +15,4 @@ module ReVIEW
15
15
  class EPUBBuilder < HTMLBuilder
16
16
  end
17
17
 
18
- end # module ReVIEW
18
+ end # module ReVIEW
@@ -11,7 +11,6 @@ require 'review'
11
11
  require 'rexml/document'
12
12
  require 'rexml/streamlistener'
13
13
  require 'epubmaker'
14
- require 'review/htmltoc'
15
14
 
16
15
  module ReVIEW
17
16
  class EPUBMaker
@@ -20,7 +19,7 @@ module ReVIEW
20
19
 
21
20
  def initialize
22
21
  @producer = nil
23
- @htmltoc = nil
22
+ @tochtmltxt = "toc-html.txt"
24
23
  @buildlogtxt = "build-log.txt"
25
24
  end
26
25
 
@@ -52,7 +51,6 @@ module ReVIEW
52
51
 
53
52
  call_hook("hook_beforeprocess", basetmpdir)
54
53
 
55
- @htmltoc = ReVIEW::HTMLToc.new(basetmpdir)
56
54
  ## copy all files into basetmpdir
57
55
  copy_stylesheet(basetmpdir)
58
56
 
@@ -202,7 +200,7 @@ module ReVIEW
202
200
  build_part(part, basetmpdir, htmlfile)
203
201
  title = ReVIEW::I18n.t("part", part.number)
204
202
  title += ReVIEW::I18n.t("chapter_postfix") + part.name.strip if part.name.strip.present?
205
- @htmltoc.add_item(0, htmlfile, title, {:chaptype => "part"})
203
+ write_tochtmltxt(basetmpdir, "0\t#{htmlfile}\t#{title}\tchaptype=part")
206
204
  write_buildlogtxt(basetmpdir, htmlfile, "")
207
205
  end
208
206
  end
@@ -217,23 +215,21 @@ module ReVIEW
217
215
  def build_part(part, basetmpdir, htmlfile)
218
216
  log("Create #{htmlfile} from a template.")
219
217
  File.open("#{basetmpdir}/#{htmlfile}", "w") do |f|
220
- @body = ""
221
- @body << "<div class=\"part\">\n"
222
- @body << "<h1 class=\"part-number\">#{ReVIEW::I18n.t("part", part.number)}</h1>\n"
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
223
223
  if part.name.strip.present?
224
- @body << "<h2 class=\"part-title\">#{part.name.strip}</h2>\n"
224
+ f.puts <<EOT
225
+ <h2 class="part-title">#{part.name.strip}</h2>
226
+ EOT
225
227
  end
226
- @body << "</div>\n"
227
228
 
228
- @language = @producer.params['language']
229
- @stylesheets = @producer.params["stylesheet"]
230
- if @producer.params["htmlversion"].to_i == 5
231
- tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
232
- else
233
- tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
234
- end
235
- tmpl = ReVIEW::Template.load(tmplfile)
236
- f.write tmpl.result(binding)
229
+ f.puts <<EOT
230
+ </div>
231
+ EOT
232
+ f.puts footer
237
233
  end
238
234
  end
239
235
 
@@ -324,27 +320,51 @@ module ReVIEW
324
320
  headlines.each do |headline|
325
321
  headline["level"] = 0 if ispart.present? && headline["level"] == 1
326
322
  if first.nil?
327
- @htmltoc.add_item(headline["level"], filename+"#"+headline["id"], headline["title"], {:chaptype => chaptype})
323
+ write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}##{headline["id"]}\t#{headline["title"]}\tchaptype=#{chaptype}")
328
324
  else
329
- @htmltoc.add_item(headline["level"], filename, headline["title"], {:force_include => true, :chaptype => chaptype+prop_str})
325
+ write_tochtmltxt(basetmpdir, "#{headline["level"]}\t#{filename}\t#{headline["title"]}\tforce_include=true,chaptype=#{chaptype}#{prop_str}")
330
326
  first = nil
331
327
  end
332
328
  end
333
329
  end
334
330
 
335
331
  def push_contents(basetmpdir)
336
- @htmltoc.each_item do |level, file, title, args|
337
- next if level.to_i > @params["toclevel"] && args[:force_include].nil?
338
- log("Push #{file} to ePUB contents.")
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.")
339
358
 
340
- hash = {"file" => file, "level" => level.to_i, "title" => title, "chaptype" => args[:chaptype]}
341
- if args[:id].present?
342
- hash["id"] = args[:id]
343
- end
344
- if args[:properties].present?
345
- hash["properties"] = args[:properties].split(" ")
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))
346
367
  end
347
- @producer.contents.push(Content.new(hash))
348
368
  end
349
369
  end
350
370
 
@@ -366,54 +386,55 @@ module ReVIEW
366
386
  else
367
387
  FileUtils.cp(@params["titlefile"], "#{basetmpdir}/titlepage.#{@params["htmlext"]}")
368
388
  end
369
- @htmltoc.add_item(1, "titlepage.#{@params['htmlext']}", @producer.res.v("titlepagetitle"), {:chaptype => "pre"})
389
+ write_tochtmltxt(basetmpdir, "1\ttitlepage.#{@params["htmlext"]}\t#{@producer.res.v("titlepagetitle")}\tchaptype=pre")
370
390
  end
371
391
 
372
392
  if @params["originaltitlefile"].present? && File.exist?(@params["originaltitlefile"])
373
393
  FileUtils.cp(@params["originaltitlefile"], "#{basetmpdir}/#{File.basename(@params["originaltitlefile"])}")
374
- @htmltoc.add_item(1, File.basename(@params["originaltitlefile"]), @producer.res.v("originaltitle"), {:chaptype => "pre"})
394
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["originaltitlefile"])}\t#{@producer.res.v("originaltitle")}\tchaptype=pre")
375
395
  end
376
396
 
377
397
  if @params["creditfile"].present? && File.exist?(@params["creditfile"])
378
398
  FileUtils.cp(@params["creditfile"], "#{basetmpdir}/#{File.basename(@params["creditfile"])}")
379
- @htmltoc.add_item(1, File.basename(@params["creditfile"]), @producer.res.v("credittitle"), {:chaptype => "pre"})
399
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["creditfile"])}\t#{@producer.res.v("credittitle")}\tchaptype=pre")
380
400
  end
381
401
  end
382
402
 
383
403
  def build_titlepage(basetmpdir, htmlfile)
384
404
  File.open("#{basetmpdir}/#{htmlfile}", "w") do |f|
385
- @body = ""
386
- @body << "<div class=\"titlepage\">"
387
- @body << "<h1 class=\"tp-title\">#{CGI.escapeHTML(@params["booktitle"])}</h1>"
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
+
388
411
  if @params["aut"]
389
- @body << "<h2 class=\"tp-author\">#{@params["aut"].join(", ")}</h2>"
412
+ f.puts <<EOT
413
+ <h2 class="tp-author">#{@params["aut"].join(", ")}</h2>
414
+ EOT
390
415
  end
391
416
  if @params["prt"]
392
- @body << "<h3 class=\"tp-publisher\">#{@params["prt"].join(", ")}</h3>"
417
+ f.puts <<EOT
418
+ <h3 class="tp-publisher">#{@params["prt"].join(", ")}</h3>
419
+ EOT
393
420
  end
394
- @body << "</div>"
395
421
 
396
- @language = @producer.params['language']
397
- @stylesheets = @producer.params["stylesheet"]
398
- if @producer.params["htmlversion"].to_i == 5
399
- tmplfile = File.expand_path('./html/layout-html5.html.erb', ReVIEW::Template::TEMPLATE_DIR)
400
- else
401
- tmplfile = File.expand_path('./html/layout-xhtml1.html.erb', ReVIEW::Template::TEMPLATE_DIR)
402
- end
403
- tmpl = ReVIEW::Template.load(tmplfile)
404
- f.write tmpl.result(binding)
422
+ f.puts <<EOT
423
+ </div>
424
+ EOT
425
+ f.puts footer
405
426
  end
406
427
  end
407
428
 
408
429
  def copy_backmatter(basetmpdir)
409
430
  if @params["profile"]
410
431
  FileUtils.cp(@params["profile"], "#{basetmpdir}/#{File.basename(@params["profile"])}")
411
- @htmltoc.add_item(1, File.basename(@params["profile"]), @producer.res.v("profiletitle"), {:chaptype => "post"})
432
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["profile"])}\t#{@producer.res.v("profiletitle")}\tchaptype=post")
412
433
  end
413
434
 
414
435
  if @params["advfile"]
415
436
  FileUtils.cp(@params["advfile"], "#{basetmpdir}/#{File.basename(@params["advfile"])}")
416
- @htmltoc.add_item(1, File.basename(@params["advfile"]), @producer.res.v("advtitle"), {:chaptype => "post"})
437
+ write_tochtmltxt(basetmpdir, "1\t#{File.basename(@params["advfile"])}\t#{@producer.res.v("advtitle")}\tchaptype=post")
417
438
  end
418
439
 
419
440
  if @params["colophon"]
@@ -422,12 +443,18 @@ module ReVIEW
422
443
  else
423
444
  File.open("#{basetmpdir}/colophon.#{@params["htmlext"]}", "w") {|f| @producer.colophon(f) }
424
445
  end
425
- @htmltoc.add_item(1, "colophon.#{@params["htmlext"]}", @producer.res.v("colophontitle"), {:chaptype => "post"})
446
+ write_tochtmltxt(basetmpdir, "1\tcolophon.#{@params["htmlext"]}\t#{@producer.res.v("colophontitle")}\tchaptype=post")
426
447
  end
427
448
 
428
449
  if @params["backcover"]
429
450
  FileUtils.cp(@params["backcover"], "#{basetmpdir}/#{File.basename(@params["backcover"])}")
430
- @htmltoc.add_item(1, File.basename(@params["backcover"]), @producer.res.v("backcovertitle"), {:chaptype => "post"})
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
431
458
  end
432
459
  end
433
460
 
@@ -437,6 +464,49 @@ module ReVIEW
437
464
  end
438
465
  end
439
466
 
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
+
440
510
  class ReVIEWHeaderListener
441
511
  include REXML::StreamListener
442
512
  def initialize(headlines)
@@ -62,7 +62,7 @@ module ReVIEW
62
62
  lines.each do |line|
63
63
  if noescape
64
64
  puts detab(line)
65
- elsif /\AC:.*?>(.+)/ =~ line # DOS prompt hack
65
+ elsif /\AC:.*?>(.+)/ =~ line # DOS prompt hack
66
66
  prompt, cmd = *line.split('>', 2)
67
67
  puts "#{escape(prompt)}>//command{#{escape(cmd)}}//}"
68
68
  else
@@ -198,7 +198,7 @@ module ReVIEW
198
198
  # FIXME
199
199
  end
200
200
 
201
- Z_SPACE = "\241\241" # zen-kaku space in EUC-JP
201
+ Z_SPACE = "\241\241" # zen-kaku space in EUC-JP
202
202
 
203
203
  def paragraph(lines)
204
204
  if @noindent
@@ -263,10 +263,10 @@ module ReVIEW
263
263
  if abbr
264
264
  add_index(word) + "//g{#{word}//}" +
265
265
  add_index(abbr) + "(#{abbr}, " +
266
- add_index(eng) + "#{eng})"
266
+ add_index(eng) + "#{eng})"
267
267
  elsif eng
268
268
  add_index(word) + "//g{#{word}//}" +
269
- add_index(eng) + "(#{eng})"
269
+ add_index(eng) + "(#{eng})"
270
270
  else
271
271
  add_index(word) + "//g{#{word}//}"
272
272
  end
@@ -17,5 +17,5 @@ module ReVIEW
17
17
  class CompileError < ApplicationError; end
18
18
  class SyntaxError < CompileError; end
19
19
  class FileNotFound < ApplicationError; end
20
- class KeyError < CompileError; end
20
+ class KeyError < CompileError; end
21
21
  end
@@ -1,3 +1,4 @@
1
1
  require 'review/extentions/object'
2
2
  require 'review/extentions/string'
3
+ require 'review/extentions/array'
3
4
 
@@ -0,0 +1,25 @@
1
+ class Array
2
+
3
+ # for ReVIEW::Node
4
+ #
5
+ def to_doc
6
+ self.map(&:to_doc).join("")
7
+ end
8
+
9
+ # for ReVIEW::Node
10
+ #
11
+ def to_raw
12
+ self.map(&:to_raw).join("")
13
+ end
14
+
15
+ if [].map.kind_of?(Array)
16
+ # Ruby 1.8
17
+ def map(&block)
18
+ if !block_given?
19
+ return to_enum :map
20
+ else
21
+ collect(&block) ## XXX same as original
22
+ end
23
+ end
24
+ end
25
+ end
@@ -34,13 +34,6 @@ module ReVIEW
34
34
  Compiler.defblock(:point, 0..1)
35
35
  Compiler.defblock(:shoot, 0..1)
36
36
 
37
- def pre_paragraph
38
- '<p>'
39
- end
40
- def post_paragraph
41
- '</p>'
42
- end
43
-
44
37
  def extname
45
38
  ".#{@book.config["htmlext"]}"
46
39
  end
@@ -70,14 +63,12 @@ module ReVIEW
70
63
  if ENV["REVIEW_SAFE_MODE"].to_i & 4 > 0
71
64
  warn "user's layout is prohibited in safe mode. ignored."
72
65
  else
73
- title = strip_html(compile_inline(@chapter.title))
74
- language = @book.config['language']
75
- stylesheets = @book.config["stylesheet"]
66
+ title = convert_outencoding(strip_html(@chapter.title), @book.config["outencoding"])
76
67
 
77
68
  toc = ""
78
69
  toc_level = 0
79
70
  @chapter.headline_index.items.each do |i|
80
- caption = "<li>#{strip_html(compile_inline(i.caption))}</li>\n"
71
+ caption = "<li>#{strip_html(i.caption)}</li>\n"
81
72
  if toc_level == i.number.size
82
73
  # do nothing
83
74
  elsif toc_level < i.number.size
@@ -96,8 +87,6 @@ module ReVIEW
96
87
  HTMLLayout.new(
97
88
  {'body' => @output.string, 'title' => title, 'toc' => toc,
98
89
  'builder' => self,
99
- 'language' => language,
100
- 'stylesheets' => stylesheets,
101
90
  'next' => @chapter.next_chapter,
102
91
  'prev' => @chapter.prev_chapter},
103
92
  layout_file).result
@@ -105,21 +94,44 @@ module ReVIEW
105
94
  end
106
95
 
107
96
  # default XHTML header/footer
108
- @error_messages = error_messages
109
- @warning_messages = warning_messages
110
- @title = strip_html(compile_inline(@chapter.title))
111
- @body = @output.string
112
- @language = @book.config['language']
113
- @stylesheets = @book.config["stylesheet"]
114
-
115
- if @book.htmlversion == 5
116
- htmlfilename = "layout-html5.html.erb"
97
+ header = <<EOT
98
+ <?xml version="1.0" encoding="#{@book.config["outencoding"] || "UTF-8"}"?>
99
+ EOT
100
+ if @book.config["htmlversion"].to_i == 5
101
+ header += <<EOT
102
+ <!DOCTYPE html>
103
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:#{xmlns_ops_prefix}="http://www.idpf.org/2007/ops" xml:lang="#{@book.config["language"]}">
104
+ <head>
105
+ <meta charset="#{@book.config["outencoding"] || "UTF-8"}" />
106
+ EOT
117
107
  else
118
- htmlfilename = "layout-xhtml1.html.erb"
108
+ header += <<EOT
109
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
110
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ops="http://www.idpf.org/2007/ops" xml:lang="#{@book.config["language"]}">
111
+ <head>
112
+ <meta http-equiv="Content-Type" content="text/html;charset=#{@book.config["outencoding"] || "UTF-8"}" />
113
+ <meta http-equiv="Content-Style-Type" content="text/css" />
114
+ EOT
115
+ end
116
+
117
+ unless @book.config["stylesheet"].nil?
118
+ @book.config["stylesheet"].each do |style|
119
+ header += <<EOT
120
+ <link rel="stylesheet" type="text/css" href="#{style}" />
121
+ EOT
122
+ end
119
123
  end
120
- tmplfile = File.expand_path('./html/'+htmlfilename, ReVIEW::Template::TEMPLATE_DIR)
121
- tmpl = ReVIEW::Template.load(tmplfile)
122
- tmpl.result(binding)
124
+ header += <<EOT
125
+ <meta name="generator" content="Re:VIEW" />
126
+ <title>#{convert_outencoding(strip_html(@chapter.title), @book.config["outencoding"])}</title>
127
+ </head>
128
+ <body>
129
+ EOT
130
+ footer = <<EOT
131
+ </body>
132
+ </html>
133
+ EOT
134
+ header + messages() + convert_outencoding(@output.string, @book.config["outencoding"]) + footer
123
135
  end
124
136
 
125
137
  def xmlns_ops_prefix
@@ -158,7 +170,7 @@ module ReVIEW
158
170
  "<ul>\n" +
159
171
  @errors.map {|file, line, msg|
160
172
  "<li>#{escape_html(file)}:#{line}: #{escape_html(msg.to_s)}</li>\n"
161
- }.join('') +
173
+ }.join('') +
162
174
  "</ul>\n"
163
175
  end
164
176
 
@@ -173,88 +185,94 @@ module ReVIEW
173
185
  end
174
186
 
175
187
  def headline(level, label, caption)
188
+ buf = ""
176
189
  prefix, anchor = headline_prefix(level)
177
190
  unless prefix.nil?
178
191
  prefix = %Q[<span class="secno">#{prefix}</span>]
179
192
  end
180
- puts '' if level > 1
181
193
  a_id = ""
182
194
  unless anchor.nil?
183
195
  a_id = %Q[<a id="h#{anchor}"></a>]
184
196
  end
185
197
  if caption.empty?
186
- puts a_id unless label.nil?
198
+ buf << a_id+"\n" unless label.nil?
187
199
  else
188
200
  if label.nil?
189
- puts %Q[<h#{level}>#{a_id}#{prefix}#{compile_inline(caption)}</h#{level}>]
201
+ buf << %Q[<h#{level}>#{a_id}#{prefix}#{caption}</h#{level}>\n]
190
202
  else
191
- puts %Q[<h#{level} id="#{normalize_id(label)}">#{a_id}#{prefix}#{compile_inline(caption)}</h#{level}>]
203
+ buf << %Q[<h#{level} id="#{normalize_id(label)}">#{a_id}#{prefix}#{caption}</h#{level}>\n]
192
204
  end
193
205
  end
206
+ buf
194
207
  end
195
208
 
196
209
  def nonum_begin(level, label, caption)
197
- puts '' if level > 1
210
+ buf = ""
211
+ buf << "\n" if level > 1
198
212
  unless caption.empty?
199
213
  if label.nil?
200
- puts %Q[<h#{level}>#{compile_inline(caption)}</h#{level}>]
214
+ buf << %Q[<h#{level}>#{caption}</h#{level}>\n]
201
215
  else
202
- puts %Q[<h#{level} id="#{normalize_id(label)}">#{compile_inline(caption)}</h#{level}>]
216
+ buf << %Q[<h#{level} id="#{normalize_id(label)}">#{caption}</h#{level}>\n]
203
217
  end
204
218
  end
219
+ buf
205
220
  end
206
221
 
207
222
  def nonum_end(level)
208
223
  end
209
224
 
210
225
  def column_begin(level, label, caption)
211
- puts %Q[<div class="column">]
226
+ buf = %Q[<div class="column">\n]
212
227
 
213
228
  @column += 1
214
- puts '' if level > 1
229
+ buf << "\n" if level > 1
215
230
  a_id = %Q[<a id="column-#{@column}"></a>]
216
231
 
217
232
  if caption.empty?
218
- puts a_id unless label.nil?
233
+ buf << a_id + "\n" unless label.nil?
219
234
  else
220
235
  if label.nil?
221
- puts %Q[<h#{level}>#{a_id}#{compile_inline(caption)}</h#{level}>]
236
+ buf << %Q[<h#{level}>#{a_id}#{caption}</h#{level}>\n]
222
237
  else
223
- puts %Q[<h#{level} id="#{normalize_id(label)}">#{a_id}#{compile_inline(caption)}</h#{level}>]
238
+ buf << %Q[<h#{level} id="#{normalize_id(label)}">#{a_id}#{caption}</h#{level}>\n]
224
239
  end
225
240
  end
226
- # headline(level, label, caption)
241
+ buf
227
242
  end
228
243
 
229
244
  def column_end(level)
230
- puts '</div>'
245
+ "</div>\n"
231
246
  end
232
247
 
233
248
  def xcolumn_begin(level, label, caption)
234
- puts %Q[<div class="xcolumn">]
235
- headline(level, label, caption)
249
+ buf << %Q[<div class="xcolumn">\n]
250
+ buf << headline(level, label, caption)
251
+ buf
236
252
  end
237
253
 
238
254
  def xcolumn_end(level)
239
- puts '</div>'
255
+ "</div>\n"
240
256
  end
241
257
 
242
258
  def ref_begin(level, label, caption)
243
- print %Q[<div class="reference">]
244
- headline(level, label, caption)
259
+ buf << %Q[<div class="reference">\n]
260
+ buf << headline(level, label, caption)
261
+ buf
245
262
  end
246
263
 
247
264
  def ref_end(level)
248
- puts '</div>'
265
+ "</div>\n"
249
266
  end
250
267
 
251
268
  def sup_begin(level, label, caption)
252
- print %Q[<div class="supplement">]
253
- headline(level, label, caption)
269
+ buf << %Q[<div class="supplement">\n]
270
+ buf << headline(level, label, caption)
271
+ buf
254
272
  end
255
273
 
256
274
  def sup_end(level)
257
- puts '</div>'
275
+ "</div>\n"
258
276
  end
259
277
 
260
278
  def tsize(str)
@@ -262,17 +280,17 @@ module ReVIEW
262
280
  end
263
281
 
264
282
  def captionblock(type, lines, caption)
265
- puts %Q[<div class="#{type}">]
283
+ buf = %Q[<div class="#{type}">\n]
266
284
  unless caption.nil?
267
- puts %Q[<p class="caption">#{compile_inline(caption)}</p>]
285
+ buf << %Q[<p class="caption">#{caption}</p>\n]
268
286
  end
269
287
  if @book.config["deprecated-blocklines"].nil?
270
- blocked_lines = split_paragraph(lines)
271
- puts blocked_lines.join("\n")
288
+ buf << lines.join("")
272
289
  else
273
- lines.each {|l| puts "<p>#{l}</p>" }
290
+ error "deprecated-blocklines is obsoleted."
274
291
  end
275
- puts '</div>'
292
+ buf << "</div>\n"
293
+ buf
276
294
  end
277
295
 
278
296
  def memo(lines, caption = nil)
@@ -320,12 +338,14 @@ module ReVIEW
320
338
  end
321
339
 
322
340
  def box(lines, caption = nil)
323
- puts %Q[<div class="syntax">]
324
- puts %Q[<p class="caption">#{compile_inline(caption)}</p>] unless caption.nil?
325
- print %Q[<pre class="syntax">]
326
- lines.each {|line| puts detab(line) }
327
- puts '</pre>'
328
- puts '</div>'
341
+ buf = ""
342
+ buf << %Q[<div class="syntax">\n]
343
+ buf << %Q[<p class="caption">#{caption}</p>\n] unless caption.nil?
344
+ buf << %Q[<pre class="syntax">]
345
+ lines.each {|line| buf << detab(line) << "\n" }
346
+ buf << "</pre>\n"
347
+ buf << "</div>\n"
348
+ buf
329
349
  end
330
350
 
331
351
  def note(lines, caption = nil)
@@ -333,268 +353,254 @@ module ReVIEW
333
353
  end
334
354
 
335
355
  def ul_begin
336
- puts '<ul>'
356
+ "<ul>\n"
337
357
  end
338
358
 
339
359
  def ul_item(lines)
340
- puts "<li>#{lines.join}</li>"
360
+ "<li>#{lines.map(&:to_s).join}</li>\n"
341
361
  end
342
362
 
343
363
  def ul_item_begin(lines)
344
- print "<li>#{lines.join}"
364
+ "<li>#{lines.map(&:to_s).join}"
345
365
  end
346
366
 
347
367
  def ul_item_end
348
- puts "</li>"
368
+ "</li>\n"
349
369
  end
350
370
 
351
371
  def ul_end
352
- puts '</ul>'
372
+ "</ul>\n"
353
373
  end
354
374
 
355
375
  def ol_begin
356
376
  if @ol_num
357
- puts "<ol start=\"#{@ol_num}\">" ## it's OK in HTML5, but not OK in XHTML1.1
377
+ num = @ol_num
358
378
  @ol_num = nil
379
+ "<ol start=\"#{num}\">\n" ## it's OK in HTML5, but not OK in XHTML1.1
359
380
  else
360
- puts '<ol>'
381
+ "<ol>\n"
361
382
  end
362
383
  end
363
384
 
364
385
  def ol_item(lines, num)
365
- puts "<li>#{lines.join}</li>"
386
+ "<li>#{lines.map(&:to_s).join}</li>\n"
366
387
  end
367
388
 
368
389
  def ol_end
369
- puts '</ol>'
390
+ "</ol>\n"
370
391
  end
371
392
 
372
393
  def dl_begin
373
- puts '<dl>'
394
+ "<dl>\n"
374
395
  end
375
396
 
376
397
  def dt(line)
377
- puts "<dt>#{line}</dt>"
398
+ "<dt>#{line}</dt>\n"
378
399
  end
379
400
 
380
401
  def dd(lines)
381
- puts "<dd>#{lines.join}</dd>"
402
+ "<dd>#{lines.join}</dd>\n"
382
403
  end
383
404
 
384
405
  def dl_end
385
- puts '</dl>'
406
+ "</dl>\n"
386
407
  end
387
408
 
388
409
  def paragraph(lines)
389
410
  if @noindent.nil?
390
- puts "<p>#{lines.join}</p>"
411
+ "<p>#{lines.join}</p>\n"
391
412
  else
392
- puts %Q[<p class="noindent">#{lines.join}</p>]
393
413
  @noindent = nil
414
+ %Q[<p class="noindent">#{lines.join}</p>\n]
394
415
  end
395
416
  end
396
417
 
397
- def parasep
398
- puts '<br />'
418
+ def parasep()
419
+ "<br />\n"
399
420
  end
400
421
 
401
422
  def read(lines)
402
423
  if @book.config["deprecated-blocklines"].nil?
403
- blocked_lines = split_paragraph(lines)
404
- puts %Q[<div class="lead">\n#{blocked_lines.join("\n")}\n</div>]
424
+ %Q[<div class="lead">\n#{lines.join("")}\n</div>\n]
405
425
  else
406
- puts %Q[<p class="lead">\n#{lines.join("\n")}\n</p>]
426
+ error "deprecated-blocklines is obsoleted."
407
427
  end
408
428
  end
409
429
 
410
430
  alias_method :lead, :read
411
431
 
412
432
  def list(lines, id, caption, lang = nil)
413
- puts %Q[<div class="caption-code">]
433
+ buf = %Q[<div class="caption-code">\n]
414
434
  begin
415
- list_header id, caption, lang
435
+ buf << list_header(id, caption, lang)
416
436
  rescue KeyError
417
437
  error "no such list: #{id}"
418
438
  end
419
- list_body id, lines, lang
420
- puts '</div>'
439
+ buf << list_body(id, lines, lang)
440
+ buf << "</div>\n"
441
+ buf
421
442
  end
422
443
 
423
444
  def list_header(id, caption, lang)
424
445
  if get_chap.nil?
425
- puts %Q[<p class="caption">#{I18n.t("list")}#{I18n.t("format_number_header_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}</p>]
446
+ %Q[<p class="caption">#{I18n.t("list")}#{I18n.t("format_number_header_without_chapter", [@chapter.list(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
426
447
  else
427
- puts %Q[<p class="caption">#{I18n.t("list")}#{I18n.t("format_number_header", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}</p>]
448
+ %Q[<p class="caption">#{I18n.t("list")}#{I18n.t("format_number_header", [get_chap, @chapter.list(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
428
449
  end
429
450
  end
430
451
 
431
452
  def list_body(id, lines, lang)
432
453
  id ||= ''
433
- print %Q[<pre class="list">]
454
+ buf = %Q[<pre class="list">]
434
455
  body = lines.inject(''){|i, j| i + detab(j) + "\n"}
435
456
  lexer = lang || File.extname(id).gsub(/\./, '')
436
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
437
- puts '</pre>'
457
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
458
+ buf << "</pre>\n"
459
+ buf
438
460
  end
439
461
 
440
- def source(lines, caption = nil, lang = nil)
441
- puts %Q[<div class="source-code">]
442
- source_header caption
443
- source_body caption, lines, lang
444
- puts '</div>'
462
+ def source(lines, caption = nil)
463
+ buf = %Q[<div class="source-code">\n]
464
+ buf << source_header(caption)
465
+ buf << source_body(caption, lines)
466
+ buf << "</div>\n"
467
+ buf
445
468
  end
446
469
 
447
470
  def source_header(caption)
448
471
  if caption.present?
449
- puts %Q[<p class="caption">#{compile_inline(caption)}</p>]
472
+ %Q[<p class="caption">#{caption}</p>\n]
450
473
  end
451
474
  end
452
475
 
453
- def source_body(id, lines, lang)
476
+ def source_body(id, lines)
454
477
  id ||= ''
455
- print %Q[<pre class="source">]
478
+ buf = %Q[<pre class="source">]
456
479
  body = lines.inject(''){|i, j| i + detab(j) + "\n"}
457
- lexer = lang || File.extname(id).gsub(/\./, '')
458
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
459
- puts '</pre>'
480
+ lexer = File.extname(id).gsub(/\./, '')
481
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
482
+ buf << "</pre>\n"
483
+ buf
460
484
  end
461
485
 
462
486
  def listnum(lines, id, caption, lang = nil)
463
- puts %Q[<div class="code">]
487
+ buf = %Q[<div class="code">\n]
464
488
  begin
465
- list_header id, caption, lang
489
+ buf << list_header(id, caption, lang)
466
490
  rescue KeyError
467
491
  error "no such list: #{id}"
468
492
  end
469
- listnum_body lines, lang
470
- puts '</div>'
493
+ buf << listnum_body(lines, lang)
494
+ buf << "</div>"
495
+ buf
471
496
  end
472
497
 
473
498
  def listnum_body(lines, lang)
474
- if highlight?
475
- body = lines.inject(''){|i, j| i + detab(j) + "\n"}
476
- lexer = lang
477
- puts highlight(:body => body, :lexer => lexer, :format => 'html',
478
- :options => {:linenos => 'inline', :nowrap => false})
479
- else
480
- print '<pre class="list">'
481
- lines.each_with_index do |line, i|
482
- puts detab((i+1).to_s.rjust(2) + ": " + line)
483
- end
484
- puts '</pre>'
485
- end
499
+ buf = ""
500
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
501
+ lexer = lang
502
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html',
503
+ :options => {:linenos => 'inline', :nowrap => false})
504
+ buf
486
505
  end
487
506
 
488
507
  def emlist(lines, caption = nil, lang = nil)
489
- puts %Q[<div class="emlist-code">]
508
+ buf = %Q[<div class="emlist-code">\n]
490
509
  if caption.present?
491
- puts %Q(<p class="caption">#{compile_inline(caption)}</p>)
510
+ buf << %Q(<p class="caption">#{caption}</p>\n)
492
511
  end
493
- print %Q[<pre class="emlist">]
512
+ buf << %Q[<pre class="emlist">]
494
513
  body = lines.inject(''){|i, j| i + detab(j) + "\n"}
495
514
  lexer = lang
496
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
497
- puts '</pre>'
498
- puts '</div>'
515
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
516
+ buf << "</pre>\n"
517
+ buf << "</div>\n"
518
+ buf
499
519
  end
500
520
 
501
521
  def emlistnum(lines, caption = nil, lang = nil)
502
- puts %Q[<div class="emlistnum-code">]
522
+ buf = %Q[<div class="emlistnum-code">\n]
503
523
  if caption.present?
504
- puts %Q(<p class="caption">#{compile_inline(caption)}</p>)
505
- end
506
-
507
- if highlight?
508
- body = lines.inject(''){|i, j| i + detab(j) + "\n"}
509
- lexer = lang
510
- puts highlight(:body => body, :lexer => lexer, :format => 'html',
511
- :options => {:linenos => 'inline', :nowrap => false})
512
- else
513
- print '<pre class="emlist">'
514
- lines.each_with_index do |line, i|
515
- puts detab((i+1).to_s.rjust(2) + ": " + line)
516
- end
517
- puts '</pre>'
524
+ buf << %Q(<p class="caption">#{caption}</p>\n)
518
525
  end
519
-
520
- puts '</div>'
526
+ body = lines.inject(''){|i, j| i + detab(j) + "\n"}
527
+ lexer = lang
528
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html',
529
+ :options => {:linenos => 'inline', :nowrap => false})
530
+ buf << "</div>\n"
531
+ buf
521
532
  end
522
533
 
523
534
  def cmd(lines, caption = nil)
524
- puts %Q[<div class="cmd-code">]
535
+ buf = %Q[<div class="cmd-code">\n]
525
536
  if caption.present?
526
- puts %Q(<p class="caption">#{compile_inline(caption)}</p>)
537
+ buf << %Q(<p class="caption">#{caption}</p>\n)
527
538
  end
528
- print %Q[<pre class="cmd">]
539
+ buf << %Q[<pre class="cmd">]
529
540
  body = lines.inject(''){|i, j| i + detab(j) + "\n"}
530
541
  lexer = 'shell-session'
531
- puts highlight(:body => body, :lexer => lexer, :format => 'html')
532
- puts '</pre>'
533
- puts '</div>'
542
+ buf << highlight(:body => body, :lexer => lexer, :format => 'html')
543
+ buf << "</pre>\n"
544
+ buf << "</div>\n"
545
+ buf
534
546
  end
535
547
 
536
548
  def quotedlist(lines, css_class)
537
- print %Q[<blockquote><pre class="#{css_class}">]
549
+ buf = %Q[<blockquote><pre class="#{css_class}">\n]
538
550
  lines.each do |line|
539
- puts detab(line)
551
+ buf << detab(line) << "\n"
540
552
  end
541
- puts '</pre></blockquote>'
553
+ buf << "</pre></blockquote>\n"
542
554
  end
543
555
  private :quotedlist
544
556
 
545
557
  def quote(lines)
546
558
  if @book.config["deprecated-blocklines"].nil?
547
- blocked_lines = split_paragraph(lines)
548
- puts "<blockquote>#{blocked_lines.join("\n")}</blockquote>"
559
+ "<blockquote>#{lines.join("")}</blockquote>\n"
549
560
  else
550
- puts "<blockquote><pre>#{lines.join("\n")}</pre></blockquote>"
561
+ error "deprecated-blocklines is obsoleted."
551
562
  end
552
563
  end
553
564
 
554
565
  def doorquote(lines, ref)
566
+ buf = ""
555
567
  if @book.config["deprecated-blocklines"].nil?
556
- blocked_lines = split_paragraph(lines)
557
- puts %Q[<blockquote style="text-align:right;">]
558
- puts "#{blocked_lines.join("\n")}"
559
- puts %Q[<p>#{ref}より</p>]
560
- puts %Q[</blockquote>]
568
+ buf << %Q[<blockquote style="text-align:right;">\n]
569
+ buf << "#{lines.join("")}\n"
570
+ buf << %Q[<p>#{ref}より</p>\n]
571
+ buf << %Q[</blockquote>\n]
561
572
  else
562
- puts <<-QUOTE
563
- <blockquote style="text-align:right;">
564
- <pre>#{lines.join("\n")}
565
-
566
- #{ref}より</pre>
567
- </blockquote>
568
- QUOTE
573
+ error "deprecated-blocklines is obsoleted."
569
574
  end
575
+ buf
570
576
  end
571
577
 
572
578
  def talk(lines)
573
- puts %Q[<div class="talk">]
579
+ buf = ""
580
+ buf << %Q[<div class="talk">\n]
574
581
  if @book.config["deprecated-blocklines"].nil?
575
- blocked_lines = split_paragraph(lines)
576
- puts "#{blocked_lines.join("\n")}"
582
+ buf << "#{lines.join("\n")}\n"
577
583
  else
578
- print '<pre>'
579
- puts "#{lines.join("\n")}"
580
- puts '</pre>'
584
+ error "deprecated-blocklines is obsoleted."
581
585
  end
582
- puts '</div>'
586
+ buf << "</div>\n"
587
+ buf
583
588
  end
584
589
 
585
590
  def texequation(lines)
586
- puts %Q[<div class="equation">]
591
+ buf << %Q[<div class="equation">\n]
587
592
  if @book.config["mathml"]
588
593
  require 'math_ml'
589
594
  require 'math_ml/symbol/character_reference'
590
595
  p = MathML::LaTeX::Parser.new(:symbol=>MathML::Symbol::CharacterReference)
591
- puts p.parse(unescape_html(lines.join("\n")), true)
596
+ buf << p.parse(unescape_html(lines.join("\n")), true) << "\n
592
597
  else
593
- print '<pre>'
594
- puts "#{lines.join("\n")}"
595
- puts '</pre>'
598
+ buf << '<pre>'
599
+ buf << "#{lines.join("\n")}\n"
600
+ buf << "</pre>\n"
596
601
  end
597
- puts '</div>'
602
+ buf << "</div>\n"
603
+ buf
598
604
  end
599
605
 
600
606
  def handle_metric(str)
@@ -602,7 +608,7 @@ QUOTE
602
608
  return "width=\"#{($1.to_f * 100).round}%\""
603
609
  else
604
610
  k, v = str.split('=', 2)
605
- return %Q|#{k}=\"#{v.sub(/\A["']/, '').sub(/["']\Z/, '')}\"|
611
+ return %Q|#{k}=\"#{v.sub(/\A&quot;/, '').sub(/\A["']/, '').sub(/&quot;\Z/, '').sub(/["']\Z/, '')}\"|
606
612
  end
607
613
  end
608
614
 
@@ -612,32 +618,35 @@ QUOTE
612
618
 
613
619
  def image_image(id, caption, metric)
614
620
  metrics = parse_metric("html", metric)
615
- puts %Q[<div id="#{normalize_id(id)}" class="image">]
616
- puts %Q[<img src="#{@chapter.image(id).path.sub(/\A\.\//, "")}" alt="#{escape_html(compile_inline(caption))}"#{metrics} />]
617
- image_header id, caption
618
- puts %Q[</div>]
621
+ buf = %Q[<div id="#{normalize_id(id)}" class="image">\n]
622
+ buf << %Q[<img src="#{@chapter.image(id).path.sub(/\A\.\//, "")}" alt="#{escape_html(caption)}"#{metrics} />\n]
623
+ buf << image_header(id, caption)
624
+ buf << %Q[</div>\n]
625
+ buf
619
626
  end
620
627
 
621
628
  def image_dummy(id, caption, lines)
622
- puts %Q[<div class="image">]
623
- puts %Q[<pre class="dummyimage">]
629
+ buf = %Q[<div class="image">\n]
630
+ buf << %Q[<pre class="dummyimage">\n]
624
631
  lines.each do |line|
625
- puts detab(line)
632
+ buf << detab(line) << "\n"
626
633
  end
627
- puts %Q[</pre>]
628
- image_header id, caption
629
- puts %Q[</div>]
634
+ buf << %Q[</pre>\n]
635
+ buf << image_header(id, caption)
636
+ buf << %Q[</div>\n]
630
637
  warn "no such image: #{id}"
638
+ buf
631
639
  end
632
640
 
633
641
  def image_header(id, caption)
634
- puts %Q[<p class="caption">]
642
+ buf = %Q[<p class="caption">\n]
635
643
  if get_chap.nil?
636
- puts %Q[#{I18n.t("image")}#{I18n.t("format_number_header_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
644
+ buf << %Q[#{I18n.t("image")}#{I18n.t("format_number_header_without_chapter", [@chapter.image(id).number])}#{I18n.t("caption_prefix")}#{caption}\n]
637
645
  else
638
- puts %Q[#{I18n.t("image")}#{I18n.t("format_number_header", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
646
+ buf << %Q[#{I18n.t("image")}#{I18n.t("format_number_header", [get_chap, @chapter.image(id).number])}#{I18n.t("caption_prefix")}#{caption}\n]
639
647
  end
640
- puts %Q[</p>]
648
+ buf << %Q[</p>\n]
649
+ buf
641
650
  end
642
651
 
643
652
  def table(lines, id = nil, caption = nil)
@@ -655,48 +664,49 @@ QUOTE
655
664
  rows = adjust_n_cols(rows)
656
665
 
657
666
  if id
658
- puts %Q[<div id="#{normalize_id(id)}" class="table">]
667
+ buf = %Q[<div id="#{normalize_id(id)}" class="table">\n]
659
668
  else
660
- puts %Q[<div class="table">]
669
+ buf = %Q[<div class="table">\n]
661
670
  end
662
671
  begin
663
- table_header id, caption unless caption.nil?
672
+ buf << table_header(id, caption) unless caption.nil?
664
673
  rescue KeyError
665
674
  error "no such table: #{id}"
666
675
  end
667
- table_begin rows.first.size
676
+ buf << table_begin(rows.first.size)
668
677
  return if rows.empty?
669
678
  if sepidx
670
679
  sepidx.times do
671
- tr rows.shift.map {|s| th(s) }
680
+ buf << tr(rows.shift.map {|s| th(s) })
672
681
  end
673
682
  rows.each do |cols|
674
- tr cols.map {|s| td(s) }
683
+ buf << tr(cols.map {|s| td(s) })
675
684
  end
676
685
  else
677
686
  rows.each do |cols|
678
687
  h, *cs = *cols
679
- tr [th(h)] + cs.map {|s| td(s) }
688
+ buf << tr([th(h)] + cs.map {|s| td(s) })
680
689
  end
681
690
  end
682
- table_end
683
- puts %Q[</div>]
691
+ buf << table_end
692
+ buf << %Q[</div>\n]
693
+ buf
684
694
  end
685
695
 
686
696
  def table_header(id, caption)
687
697
  if get_chap.nil?
688
- puts %Q[<p class="caption">#{I18n.t("table")}#{I18n.t("format_number_header_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}</p>]
698
+ %Q[<p class="caption">#{I18n.t("table")}#{I18n.t("format_number_header_without_chapter", [@chapter.table(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
689
699
  else
690
- puts %Q[<p class="caption">#{I18n.t("table")}#{I18n.t("format_number_header", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix")}#{compile_inline(caption)}</p>]
700
+ %Q[<p class="caption">#{I18n.t("table")}#{I18n.t("format_number_header", [get_chap, @chapter.table(id).number])}#{I18n.t("caption_prefix")}#{caption}</p>\n]
691
701
  end
692
702
  end
693
703
 
694
704
  def table_begin(ncols)
695
- puts '<table>'
705
+ "<table>\n"
696
706
  end
697
707
 
698
708
  def tr(rows)
699
- puts "<tr>#{rows.join}</tr>"
709
+ "<tr>#{rows.join}</tr>\n"
700
710
  end
701
711
 
702
712
  def th(str)
@@ -708,71 +718,73 @@ QUOTE
708
718
  end
709
719
 
710
720
  def table_end
711
- puts '</table>'
721
+ "</table>\n"
712
722
  end
713
723
 
714
724
  def comment(lines, comment = nil)
715
725
  lines ||= []
716
726
  lines.unshift comment unless comment.blank?
717
727
  if @book.config["draft"]
718
- str = lines.join("<br />")
719
- puts %Q(<div class="draft-comment">#{str}</div>)
728
+ str = lines.map{|line| escape_html(line) }.join("<br />")
729
+ return %Q(<div class="draft-comment">#{str}</div>\n)
720
730
  else
721
731
  str = lines.join("\n")
722
- puts %Q(<!-- #{escape_comment(str)} -->)
732
+ return %Q(<!-- #{escape_comment(str)} -->\n)
723
733
  end
724
734
  end
725
735
 
726
736
  def footnote(id, str)
727
737
  if @book.config["epubversion"].to_i == 3
728
- puts %Q(<div class="footnote" epub:type="footnote" id="fn-#{normalize_id(id)}"><p class="footnote">[*#{@chapter.footnote(id).number}] #{compile_inline(str)}</p></div>)
738
+ %Q(<div class="footnote" epub:type="footnote" id="fn-#{normalize_id(id)}"><p class="footnote">[*#{@chapter.footnote(id).number}] #{str}</p></div>\n)
729
739
  else
730
- puts %Q(<div class="footnote" id="fn-#{normalize_id(id)}"><p class="footnote">[<a href="#fnb-#{normalize_id(id)}">*#{@chapter.footnote(id).number}</a>] #{compile_inline(str)}</p></div>)
740
+ %Q(<div class="footnote" id="fn-#{normalize_id(id)}"><p class="footnote">[<a href="#fnb-#{normalize_id(id)}">*#{@chapter.footnote(id).number}</a>] #{str}</p></div>\n)
731
741
  end
732
742
  end
733
743
 
734
744
  def indepimage(id, caption="", metric=nil)
735
745
  metrics = parse_metric("html", metric)
736
746
  caption = "" if caption.nil?
737
- puts %Q[<div class="image">]
747
+ buf = %Q[<div class="image">\n]
738
748
  begin
739
- puts %Q[<img src="#{@chapter.image(id).path.sub(/\A\.\//, "")}" alt="#{escape_html(compile_inline(caption))}"#{metrics} />]
749
+ buf << %Q[<img src="#{@chapter.image(id).path.sub(/\A\.\//, "")}" alt="#{escape_html(caption)}"#{metrics} />\n]
740
750
  rescue
741
- puts %Q[<pre>missing image: #{id}</pre>]
751
+ buf << %Q[<pre>missing image: #{id}</pre>\n]
742
752
  end
743
753
 
744
754
  unless caption.empty?
745
- puts %Q[<p class="caption">]
746
- puts %Q[#{I18n.t("numberless_image")}#{I18n.t("caption_prefix")}#{compile_inline(caption)}]
747
- puts %Q[</p>]
755
+ buf << %Q[<p class="caption">\n]
756
+ buf << %Q[#{I18n.t("numberless_image")}#{I18n.t("caption_prefix")}#{caption}\n]
757
+ buf << %Q[</p>\n]
748
758
  end
749
- puts %Q[</div>]
759
+ buf << %Q[</div>\n]
760
+ buf
750
761
  end
751
762
 
752
763
  alias_method :numberlessimage, :indepimage
753
764
 
754
765
  def hr
755
- puts "<hr />"
766
+ "<hr />\n"
756
767
  end
757
768
 
758
769
  def label(id)
759
- puts %Q(<a id="#{normalize_id(id)}"></a>)
770
+ %Q(<a id="#{normalize_id(id)}"></a>\n)
760
771
  end
761
772
 
762
773
  def linebreak
763
- puts "<br />"
774
+ "<br />\n"
764
775
  end
765
776
 
766
777
  def pagebreak
767
- puts %Q(<br class="pagebreak" />)
778
+ %Q(<br class="pagebreak" />\n)
768
779
  end
769
780
 
770
781
  def bpo(lines)
771
- puts "<bpo>"
782
+ buf = "<bpo>\n"
772
783
  lines.each do |line|
773
- puts detab(line)
784
+ buf << detab(line) + "\n"
774
785
  end
775
- puts "</bpo>"
786
+ buf << "</bpo>\n"
787
+ buf
776
788
  end
777
789
 
778
790
  def noindent
@@ -780,7 +792,7 @@ QUOTE
780
792
  end
781
793
 
782
794
  def inline_labelref(idref)
783
- %Q[<a target='#{escape_html(idref)}'>「#{I18n.t("label_marker")}#{escape_html(idref)}」</a>]
795
+ %Q[<a target='#{(idref)}'>「#{I18n.t("label_marker")}#{(idref)}」</a>]
784
796
  end
785
797
 
786
798
  alias_method :inline_ref, :inline_labelref
@@ -829,10 +841,10 @@ QUOTE
829
841
  end
830
842
 
831
843
  def compile_ruby(base, ruby)
832
- if @book.htmlversion == 5
833
- %Q[<ruby>#{escape_html(base)}<rp>#{I18n.t("ruby_prefix")}</rp><rt>#{escape_html(ruby)}</rt><rp>#{I18n.t("ruby_postfix")}</rp></ruby>]
844
+ if @book.config["htmlversion"].to_i == 5
845
+ %Q[<ruby>#{(base)}<rp>#{I18n.t("ruby_prefix")}</rp><rt>#{(ruby)}</rt><rp>#{I18n.t("ruby_postfix")}</rp></ruby>]
834
846
  else
835
- %Q[<ruby><rb>#{escape_html(base)}</rb><rp>#{I18n.t("ruby_prefix")}</rp><rt>#{ruby}</rt><rp>#{I18n.t("ruby_postfix")}</rp></ruby>]
847
+ %Q[<ruby><rb>#{(base)}</rb><rp>#{I18n.t("ruby_prefix")}</rp><rt>#{ruby}</rt><rp>#{I18n.t("ruby_postfix")}</rp></ruby>]
836
848
  end
837
849
  end
838
850
 
@@ -846,34 +858,34 @@ QUOTE
846
858
  end
847
859
 
848
860
  def inline_i(str)
849
- %Q(<i>#{escape_html(str)}</i>)
861
+ %Q(<i>#{str}</i>)
850
862
  end
851
863
 
852
864
  def inline_b(str)
853
- %Q(<b>#{escape_html(str)}</b>)
865
+ %Q(<b>#{str}</b>)
854
866
  end
855
867
 
856
868
  def inline_ami(str)
857
- %Q(<span class="ami">#{escape_html(str)}</span>)
869
+ %Q(<span class="ami">#{(str)}</span>)
858
870
  end
859
871
 
860
872
  def inline_bou(str)
861
- %Q(<span class="bou">#{escape_html(str)}</span>)
873
+ %Q(<span class="bou">#{(str)}</span>)
862
874
  end
863
875
 
864
876
  def inline_tti(str)
865
- if @book.htmlversion == 5
866
- %Q(<code class="tt"><i>#{escape_html(str)}</i></code>)
877
+ if @book.config["htmlversion"].to_i == 5
878
+ %Q(<code class="tt"><i>#{(str)}</i></code>)
867
879
  else
868
- %Q(<tt><i>#{escape_html(str)}</i></tt>)
880
+ %Q(<tt><i>#{(str)}</i></tt>)
869
881
  end
870
882
  end
871
883
 
872
884
  def inline_ttb(str)
873
- if @book.htmlversion == 5
874
- %Q(<code class="tt"><b>#{escape_html(str)}</b></code>)
885
+ if @book.config["htmlversion"].to_i == 5
886
+ %Q(<code class="tt"><b>#{(str)}</b></code>)
875
887
  else
876
- %Q(<tt><b>#{escape_html(str)}</b></tt>)
888
+ %Q(<tt><b>#{(str)}</b></tt>)
877
889
  end
878
890
  end
879
891
 
@@ -882,15 +894,15 @@ QUOTE
882
894
  end
883
895
 
884
896
  def inline_code(str)
885
- if @book.htmlversion == 5
886
- %Q(<code class="inline-code tt">#{escape_html(str)}</code>)
897
+ if @book.config["htmlversion"].to_i == 5
898
+ %Q(<code class="inline-code tt">#{(str)}</code>)
887
899
  else
888
- %Q(<tt class="inline-code">#{escape_html(str)}</tt>)
900
+ %Q(<tt class="inline-code">#{(str)}</tt>)
889
901
  end
890
902
  end
891
903
 
892
904
  def inline_idx(str)
893
- %Q(#{escape_html(str)}<!-- IDX:#{escape_comment(escape_html(str))} -->)
905
+ %Q(#{(str)}<!-- IDX:#{escape_comment(escape_html(str))} -->)
894
906
  end
895
907
 
896
908
  def inline_hidx(str)
@@ -909,7 +921,7 @@ QUOTE
909
921
  :symbol => MathML::Symbol::CharacterReference)
910
922
  %Q[<span class="equation">#{parser.parse(str, nil)}</span>]
911
923
  else
912
- %Q[<span class="equation">#{escape_html(str)}</span>]
924
+ %Q[<span class="equation">#{(str)}</span>]
913
925
  end
914
926
  end
915
927
 
@@ -918,35 +930,36 @@ QUOTE
918
930
  end
919
931
 
920
932
  def bibpaper(lines, id, caption)
921
- puts %Q[<div class="bibpaper">]
922
- bibpaper_header id, caption
933
+ buf = %Q[<div class="bibpaper">\n]
934
+ buf << bibpaper_header(id, caption)
923
935
  unless lines.empty?
924
- bibpaper_bibpaper id, caption, lines
936
+ buf << bibpaper_bibpaper(id, caption, lines)
925
937
  end
926
- puts "</div>"
938
+ buf << "</div>" << "\n"
939
+ buf
927
940
  end
928
941
 
929
942
  def bibpaper_header(id, caption)
930
- print %Q(<a id="bib-#{normalize_id(id)}">)
931
- print "[#{@chapter.bibpaper(id).number}]"
932
- print %Q(</a>)
933
- puts " #{compile_inline(caption)}"
943
+ buf = %Q(<a id="bib-#{normalize_id(id)}">)
944
+ buf << "[#{@chapter.bibpaper(id).number}]"
945
+ buf << %Q(</a>)
946
+ buf << " #{(caption)}" << "\n"
934
947
  end
935
948
 
936
949
  def bibpaper_bibpaper(id, caption, lines)
937
- print split_paragraph(lines).join("")
950
+ lines.join("")
938
951
  end
939
952
 
940
953
  def inline_bib(id)
941
- %Q(<a href="#{@book.bib_file.gsub(/\.re\Z/, ".#{@book.config['htmlext']}")}#bib-#{normalize_id(id)}">[#{@chapter.bibpaper(id).number}]</a>)
954
+ %Q(<a href="#{@book.bib_file.gsub(/re\Z/, "html")}#bib-#{normalize_id(id)}">[#{@chapter.bibpaper(id).number}]</a>)
942
955
  end
943
956
 
944
957
  def inline_hd_chap(chap, id)
945
958
  n = chap.headline_index.number(id)
946
959
  if chap.number and @book.config["secnolevel"] >= n.split('.').size
947
- str = I18n.t("chapter_quote", "#{n} #{compile_inline(chap.headline(id).caption)}")
960
+ str = I18n.t("chapter_quote", "#{n} #{chap.headline(id).caption}")
948
961
  else
949
- str = I18n.t("chapter_quote", compile_inline(chap.headline(id).caption))
962
+ str = I18n.t("chapter_quote", chap.headline(id).caption)
950
963
  end
951
964
  if @book.config["chapterlink"]
952
965
  anchor = "h"+n.gsub(/\./, "-")
@@ -964,9 +977,9 @@ QUOTE
964
977
 
965
978
  def inline_column(id)
966
979
  if @book.config["chapterlink"]
967
- %Q(<a href="\##{column_label(id)}" class="columnref">#{I18n.t("column", escape_html(@chapter.column(id).caption))}</a>)
980
+ %Q(<a href="\##{column_label(id)}" class="columnref">#{I18n.t("column", (@chapter.column(id).caption))}</a>)
968
981
  else
969
- I18n.t("column", escape_html(@chapter.column(id).caption))
982
+ I18n.t("column", (@chapter.column(id).caption))
970
983
  end
971
984
  rescue KeyError
972
985
  error "unknown column: #{id}"
@@ -1022,7 +1035,7 @@ QUOTE
1022
1035
  end
1023
1036
 
1024
1037
  def inline_asis(str, tag)
1025
- %Q(<#{tag}>#{escape_html(str)}</#{tag}>)
1038
+ %Q(<#{tag}>#{(str)}</#{tag}>)
1026
1039
  end
1027
1040
 
1028
1041
  def inline_abbr(str)
@@ -1078,10 +1091,10 @@ QUOTE
1078
1091
  end
1079
1092
 
1080
1093
  def inline_tt(str)
1081
- if @book.htmlversion == 5
1082
- %Q(<code class="tt">#{escape_html(str)}</code>)
1094
+ if @book.config["htmlversion"].to_i == 5
1095
+ %Q(<code class="tt">#{(str)}</code>)
1083
1096
  else
1084
- %Q(<tt>#{escape_html(str)}</tt>)
1097
+ %Q(<tt>#{(str)}</tt>)
1085
1098
  end
1086
1099
  end
1087
1100
 
@@ -1094,11 +1107,11 @@ QUOTE
1094
1107
  end
1095
1108
 
1096
1109
  def inline_u(str)
1097
- %Q(<u>#{escape_html(str)}</u>)
1110
+ %Q(<u>#{(str)}</u>)
1098
1111
  end
1099
1112
 
1100
1113
  def inline_recipe(str)
1101
- %Q(<span class="recipe">「#{escape_html(str)}」</span>)
1114
+ %Q(<span class="recipe">「#{(str)}」</span>)
1102
1115
  end
1103
1116
 
1104
1117
  def inline_icon(id)
@@ -1115,7 +1128,7 @@ QUOTE
1115
1128
 
1116
1129
  def inline_comment(str)
1117
1130
  if @book.config["draft"]
1118
- %Q(<span class="draft-comment">#{escape_html(str)}</span>)
1131
+ %Q(<span class="draft-comment">#{(str)}</span>)
1119
1132
  else
1120
1133
  %Q(<!-- #{escape_comment(escape_html(str))} -->)
1121
1134
  end
@@ -1130,23 +1143,21 @@ QUOTE
1130
1143
  end
1131
1144
 
1132
1145
  def compile_href(url, label)
1133
- %Q(<a href="#{escape_html(url)}" class="link">#{label.nil? ? escape_html(url) : escape_html(label)}</a>)
1146
+ %Q(<a href="#{escape_html(url)}" class="link">#{label.nil? ? (url) : (label)}</a>)
1134
1147
  end
1135
1148
 
1136
1149
  def flushright(lines)
1150
+ result = ""
1137
1151
  if @book.config["deprecated-blocklines"].nil?
1138
- puts split_paragraph(lines).join("\n").gsub("<p>", "<p class=\"flushright\">")
1152
+ result << lines.join("").gsub("<p>", "<p class=\"flushright\">")
1139
1153
  else
1140
- puts %Q[<div style="text-align:right;">]
1141
- print %Q[<pre class="flushright">]
1142
- lines.each {|line| puts detab(line) }
1143
- puts '</pre>'
1144
- puts '</div>'
1154
+ error "deprecated-blocklines is obsoleted."
1145
1155
  end
1156
+ result
1146
1157
  end
1147
1158
 
1148
1159
  def centering(lines)
1149
- puts split_paragraph(lines).join("\n").gsub("<p>", "<p class=\"center\">")
1160
+ lines.join("").gsub("<p>", "<p class=\"center\">")
1150
1161
  end
1151
1162
 
1152
1163
  def image_ext
@@ -1158,4 +1169,4 @@ QUOTE
1158
1169
  end
1159
1170
  end
1160
1171
 
1161
- end # module ReVIEW
1172
+ end # module ReVIEW