review 2.5.0 → 3.0.0.preview1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +28 -10
  3. data/.travis.yml +11 -2
  4. data/NEWS.ja.md +89 -17
  5. data/NEWS.md +92 -0
  6. data/README.md +1 -1
  7. data/Rakefile +0 -13
  8. data/bin/review-catalog-converter +83 -37
  9. data/bin/review-check +17 -5
  10. data/bin/review-compile +1 -1
  11. data/bin/review-index +6 -0
  12. data/bin/review-init +3 -155
  13. data/bin/review-preproc +0 -5
  14. data/bin/review-validate +21 -7
  15. data/bin/review-vol +13 -5
  16. data/doc/config.yml.sample +12 -7
  17. data/doc/config.yml.sample-simple +1 -1
  18. data/doc/format.ja.md +39 -3
  19. data/doc/format.md +39 -3
  20. data/doc/format_idg.ja.md +0 -4
  21. data/doc/pdfmaker.ja.md +1 -1
  22. data/doc/pdfmaker.md +1 -1
  23. data/doc/sample.css +7 -0
  24. data/lib/epubmaker/content.rb +31 -12
  25. data/lib/epubmaker/epubcommon.rb +10 -3
  26. data/lib/epubmaker/epubv2.rb +11 -3
  27. data/lib/epubmaker/epubv3.rb +11 -3
  28. data/lib/epubmaker/producer.rb +55 -20
  29. data/lib/review/book/base.rb +63 -48
  30. data/lib/review/book/chapter.rb +19 -7
  31. data/lib/review/book/compilable.rb +5 -20
  32. data/lib/review/book/image_finder.rb +10 -3
  33. data/lib/review/book/index.rb +30 -9
  34. data/lib/review/book/part.rb +9 -6
  35. data/lib/review/book.rb +0 -14
  36. data/lib/review/builder.rb +110 -18
  37. data/lib/review/catalog.rb +24 -4
  38. data/lib/review/compiler.rb +3 -1
  39. data/lib/review/configure.rb +43 -9
  40. data/lib/review/epubmaker/reviewheaderlistener.rb +57 -0
  41. data/lib/review/epubmaker.rb +129 -85
  42. data/lib/review/htmlbuilder.rb +76 -58
  43. data/lib/review/htmlutils.rb +20 -13
  44. data/lib/review/i18n.rb +6 -2
  45. data/lib/review/idgxmlbuilder.rb +52 -41
  46. data/lib/review/init.rb +194 -0
  47. data/lib/review/latexbuilder.rb +118 -34
  48. data/lib/review/latexutils.rb +5 -5
  49. data/lib/review/logger.rb +2 -1
  50. data/lib/review/makerhelper.rb +1 -1
  51. data/lib/review/markdownbuilder.rb +66 -6
  52. data/lib/review/md2inaobuilder.rb +2 -2
  53. data/lib/review/pdfmaker.rb +74 -22
  54. data/lib/review/plaintextbuilder.rb +8 -4
  55. data/lib/review/preprocessor.rb +14 -17
  56. data/lib/review/sec_counter.rb +8 -2
  57. data/lib/review/textmaker.rb +2 -2
  58. data/lib/review/textutils.rb +9 -2
  59. data/lib/review/tocparser.rb +7 -4
  60. data/lib/review/tocprinter.rb +3 -1
  61. data/lib/review/version.rb +1 -1
  62. data/lib/review/webmaker.rb +19 -7
  63. data/lib/review/webtocprinter.rb +8 -4
  64. data/review.gemspec +4 -3
  65. data/templates/latex/config.erb +84 -0
  66. data/templates/latex/layout.tex.erb +76 -361
  67. data/templates/latex/review-jlreq/README.md +22 -0
  68. data/templates/latex/review-jlreq/review-base.sty +178 -0
  69. data/templates/latex/review-jlreq/review-custom.sty +1 -0
  70. data/templates/latex/review-jlreq/review-jlreq.cls +141 -0
  71. data/templates/latex/review-jlreq/review-style.sty +149 -0
  72. data/templates/latex/review-jlreq/reviewmacro.sty +8 -0
  73. data/templates/latex/review-jsbook/jumoline.sty +310 -0
  74. data/templates/latex/review-jsbook/plistings.sty +326 -0
  75. data/templates/latex/review-jsbook/review-base.sty +405 -0
  76. data/templates/latex/review-jsbook/review-custom.sty +1 -0
  77. data/templates/latex/review-jsbook/review-style.sty +38 -0
  78. data/templates/latex/review-jsbook/reviewmacro.sty +8 -0
  79. data/templates/latex-compat2/layout.tex.erb +387 -0
  80. data/test/assets/test_template.tex +105 -235
  81. data/test/assets/test_template_backmatter.tex +133 -14
  82. data/test/book_test_helper.rb +1 -1
  83. data/test/run_test.rb +2 -0
  84. data/test/sample-book/src/Rakefile +11 -6
  85. data/test/sample-book/src/config.yml +2 -2
  86. data/test/sample-book/src/sty/reviewmacro.sty +1 -39
  87. data/test/sample-book/src/style.css +6 -0
  88. data/test/syntax-book/config.yml +1 -1
  89. data/test/test_book.rb +13 -16
  90. data/test/test_book_chapter.rb +4 -10
  91. data/test/test_book_part.rb +4 -3
  92. data/test/test_catalog.rb +15 -4
  93. data/test/test_helper.rb +2 -2
  94. data/test/test_htmlbuilder.rb +78 -10
  95. data/test/test_htmlutils.rb +12 -5
  96. data/test/test_idgxmlbuilder.rb +1 -1
  97. data/test/test_latexbuilder.rb +94 -49
  98. data/test/test_latexbuilder_v2.rb +1077 -0
  99. data/test/test_logger.rb +20 -0
  100. data/test/test_markdownbuilder.rb +10 -0
  101. data/test/test_pdfmaker.rb +6 -7
  102. data/test/test_plaintextbuilder.rb +1 -1
  103. data/test/test_review_ext.rb +0 -1
  104. data/test/test_rstbuilder.rb +1 -1
  105. data/test/test_topbuilder.rb +19 -7
  106. data/test/test_webtocprinter.rb +14 -14
  107. data/{test/sample-book/src/vendor → vendor}/jumoline/README +0 -0
  108. data/{test/sample-book/src/vendor → vendor}/jumoline/jumoline.dtx +0 -0
  109. data/{test/sample-book/src/vendor → vendor}/jumoline/jumoline.ins +0 -0
  110. data/{test/sample-book/src/vendor → vendor}/jumoline/lppl.txt +0 -0
  111. data/vendor/plistings/.gitignore +9 -0
  112. data/vendor/plistings/LICENSE +21 -0
  113. data/vendor/plistings/README.md +18 -0
  114. data/vendor/plistings/plistings.sty +326 -0
  115. data/vendor/plistings/test1.tex +174 -0
  116. data/vendor/plistings/test2.tex +54 -0
  117. metadata +48 -19
  118. data/lib/review/unfold.rb +0 -129
  119. data/test/CHAPS +0 -2
  120. data/test/bib.re +0 -13
  121. data/test/test.re +0 -43
@@ -23,7 +23,9 @@ module ReVIEW
23
23
  if id = line.slice(/\[(.*?)\]/, 1)
24
24
  items.push item_class.new(id, seq)
25
25
  seq += 1
26
- ReVIEW.logger.warn "warning: no ID of #{item_type} in #{line}" if id.empty?
26
+ if id.empty?
27
+ ReVIEW.logger.warn "warning: no ID of #{item_type} in #{line}"
28
+ end
27
29
  end
28
30
  end
29
31
  new(items, *args)
@@ -46,7 +48,9 @@ module ReVIEW
46
48
  @index = {}
47
49
  @logger = ReVIEW.logger
48
50
  items.each do |i|
49
- @logger.warn "warning: duplicate ID: #{i.id} (#{i})" if @index[i.id]
51
+ if @index[i.id]
52
+ @logger.warn "warning: duplicate ID: #{i.id} (#{i})"
53
+ end
50
54
  @index[i.id] = i
51
55
  end
52
56
  @image_finder = nil
@@ -62,7 +66,9 @@ module ReVIEW
62
66
  end
63
67
 
64
68
  @items.each do |i|
65
- return i if i.id.split('|').include?(id)
69
+ if i.id.split('|').include?(id)
70
+ return i
71
+ end
66
72
  end
67
73
  raise KeyError, "not found key '#{id}' for #{self.class}"
68
74
  end
@@ -150,7 +156,9 @@ module ReVIEW
150
156
  items.push item_class.new(elements[1], seq, elements[3])
151
157
  seq += 1
152
158
  end
153
- ReVIEW.logger.warn "warning: no ID of #{item_type} in #{line}" if elements[1] == ''
159
+ if elements[1] == ''
160
+ ReVIEW.logger.warn "warning: no ID of #{item_type} in #{line}"
161
+ end
154
162
  end
155
163
  end
156
164
  new(items, *args)
@@ -295,7 +303,9 @@ module ReVIEW
295
303
  end
296
304
 
297
305
  m = HEADLINE_PATTERN.match(line)
298
- next if m.nil? || m[1].size > 10 # Ignore too deep index
306
+ if m.nil? || m[1].size > 10 # Ignore too deep index
307
+ next
308
+ end
299
309
  index = m[1].size - 2
300
310
 
301
311
  # column
@@ -307,7 +317,9 @@ module ReVIEW
307
317
  inside_column = false
308
318
  next
309
319
  end
310
- inside_column = false if indexs.blank? || index <= column_level
320
+ if indexs.blank? || index <= column_level
321
+ inside_column = false
322
+ end
311
323
  next if inside_column
312
324
  next if m[4].strip.empty? # no title
313
325
 
@@ -316,7 +328,11 @@ module ReVIEW
316
328
  indexs = indexs.take(index + 1)
317
329
  headlines = headlines.take(index + 1)
318
330
  end
319
- (0..index).each { |i| indexs[i] = 0 if indexs[i].nil? } if indexs[index].nil?
331
+ if indexs[index].nil?
332
+ (0..index).each do |i|
333
+ indexs[i] ||= 0
334
+ end
335
+ end
320
336
  indexs[index] += 1
321
337
  headlines[index] = m[3].present? ? m[3].strip : m[4].strip
322
338
  items.push Item.new(headlines.join('|'), indexs.dup, m[4].strip)
@@ -330,14 +346,19 @@ module ReVIEW
330
346
  @index = {}
331
347
  @logger = ReVIEW.logger
332
348
  items.each do |i|
333
- @logger.warn "warning: duplicate ID: #{i.id}" if @index[i.id]
349
+ if @index[i.id]
350
+ @logger.warn "warning: duplicate ID: #{i.id}"
351
+ end
334
352
  @index[i.id] = i
335
353
  end
336
354
  end
337
355
 
338
356
  def number(id)
339
357
  n = @chap.number
340
- n = @chap.format_number(false) if @chap.on_appendix? && @chap.number > 0 && @chap.number < 28
358
+ # XXX: remove magic number (move to lib/review/book/chapter.rb)
359
+ if @chap.on_appendix? && @chap.number > 0 && @chap.number < 28
360
+ n = @chap.format_number(false)
361
+ end
341
362
  ([n] + self[id].number).join('.')
342
363
  end
343
364
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2017 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2009-2018 Minero Aoki, Kenshi Muto
2
2
  # 2002-2008 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -24,12 +24,15 @@ module ReVIEW
24
24
  @content = nil
25
25
  if io
26
26
  @content = io.read
27
- elsif @path && File.exist?(@path)
28
- @content = File.read(@path, mode: 'r:BOM|utf-8')
27
+ elsif @path.present? && File.exist?(File.join(@book.config['contentdir'], @path))
28
+ @content = File.read(File.join(@book.config['contentdir'], @path), mode: 'r:BOM|utf-8')
29
29
  @name = File.basename(@name, '.re')
30
30
  end
31
- @title = name
32
- @title = nil if file?
31
+ if file?
32
+ @title = nil
33
+ else
34
+ @title = name
35
+ end
33
36
  @volume = nil
34
37
  end
35
38
 
@@ -48,7 +51,7 @@ module ReVIEW
48
51
  end
49
52
 
50
53
  def file?
51
- name.present? and path.end_with?('.re') ? true : false
54
+ name.present? and path.end_with?('.re')
52
55
  end
53
56
 
54
57
  def format_number(heading = true)
data/lib/review/book.rb CHANGED
@@ -17,23 +17,9 @@ require 'review/book/volume'
17
17
  require 'review/book/index'
18
18
 
19
19
  module ReVIEW
20
- @default_book = nil
21
-
22
- def self.book
23
- @default_book ||= Book::Base.load
24
- end
25
-
26
20
  module Book
27
- def self.load_default
28
- Base.load_default
29
- end
30
-
31
21
  def self.load(dir)
32
22
  Base.load dir
33
23
  end
34
-
35
- def self.update_rubyenv(dir)
36
- Base.update_rubyenv dir
37
- end
38
24
  end
39
25
  end
@@ -13,6 +13,8 @@ require 'review/sec_counter'
13
13
  require 'stringio'
14
14
  require 'cgi'
15
15
  require 'fileutils'
16
+ require 'tempfile'
17
+ require 'csv'
16
18
 
17
19
  module ReVIEW
18
20
  class Builder
@@ -35,6 +37,7 @@ module ReVIEW
35
37
  @output = nil
36
38
  @logger = ReVIEW.logger
37
39
  @doc_status = {}
40
+ @dictionary = {}
38
41
  builder_init(*args)
39
42
  end
40
43
 
@@ -47,10 +50,19 @@ module ReVIEW
47
50
  @chapter = chapter
48
51
  @location = location
49
52
  @output = StringIO.new
50
- @book = @chapter.book if @chapter.present?
53
+ if @chapter.present?
54
+ @book = @chapter.book
55
+ end
51
56
  @tabwidth = nil
52
57
  @tsize = nil
53
- @tabwidth = @book.config['tabwidth'] if @book && @book.config && @book.config['tabwidth']
58
+ if @book && @book.config
59
+ if @book.config['words_file']
60
+ load_words(@book.config['words_file'])
61
+ end
62
+ if @book.config['tabwidth']
63
+ @tabwidth = @book.config['tabwidth']
64
+ end
65
+ end
54
66
  builder_init_file
55
67
  end
56
68
 
@@ -77,6 +89,16 @@ module ReVIEW
77
89
  self.class.to_s.gsub(/ReVIEW::/, '').gsub(/Builder/, '').downcase
78
90
  end
79
91
 
92
+ def load_words(file)
93
+ if File.exist?(file)
94
+ if file =~ /\.csv\Z/i
95
+ CSV.foreach(file) do |row|
96
+ @dictionary[row[0]] = row[1]
97
+ end
98
+ end
99
+ end
100
+ end
101
+
80
102
  def headline_prefix(level)
81
103
  @sec_counter.inc(level)
82
104
  anchor = @sec_counter.anchor(level)
@@ -145,7 +167,9 @@ module ReVIEW
145
167
  rows = adjust_n_cols(rows)
146
168
 
147
169
  begin
148
- table_header id, caption if caption.present?
170
+ if caption.present?
171
+ table_header id, caption
172
+ end
149
173
  rescue KeyError
150
174
  error "no such table: #{id}"
151
175
  end
@@ -339,6 +363,24 @@ module ReVIEW
339
363
  "#{arg}[rotate 90 degree]"
340
364
  end
341
365
 
366
+ def inline_balloon(arg)
367
+ "← #{arg}"
368
+ end
369
+
370
+ def inline_w(s)
371
+ translated = @dictionary[s]
372
+ if translated
373
+ escape(translated)
374
+ else
375
+ warn "word not bound: #{s}"
376
+ escape("[missing word: #{s}]")
377
+ end
378
+ end
379
+
380
+ def inline_wb(s)
381
+ inline_b(unescape(inline_w(s)))
382
+ end
383
+
342
384
  def raw(str)
343
385
  if matched = str.match(/\|(.*?)\|(.*)/)
344
386
  builders = matched[1].split(',').map { |i| i.gsub(/\s/, '') }
@@ -427,31 +469,71 @@ module ReVIEW
427
469
  )
428
470
  end
429
471
 
430
- def graph(lines, id, command, caption = nil)
472
+ def graph(lines, id, command, caption = '')
431
473
  c = target_name
432
- dir = File.join(@book.basedir, @book.image_dir, c)
474
+ dir = File.join(@book.imagedir, c)
433
475
  FileUtils.mkdir_p(dir)
434
476
  file = "#{id}.#{image_ext}"
435
477
  file_path = File.join(dir, file)
436
478
 
437
479
  line = self.unescape(lines.join("\n"))
438
- cmds = {
439
- graphviz: "echo '#{line}' | dot -T#{image_ext} -o#{file_path}",
440
- gnuplot: %Q(echo 'set terminal ) +
441
- "#{image_ext == 'eps' ? 'postscript eps' : image_ext}\n" +
442
- %Q( set output "#{file_path}"\n#{line}' | gnuplot),
443
- blockdiag: "echo '#{line}' " +
444
- "| blockdiag -a -T #{image_ext} -o #{file_path} /dev/stdin",
445
- aafigure: "echo '#{line}' | aafigure -t#{image_ext} -o#{file_path}"
446
- }
447
- cmd = cmds[command.to_sym]
448
- warn cmd
449
- system cmd
480
+
481
+ tf = Tempfile.new('review_graph')
482
+ tf.puts line
483
+ tf.close
484
+ begin
485
+ file_path = send("graph_#{command}".to_sym, id, file_path, line, tf.path)
486
+ ensure
487
+ tf.unlink
488
+ end
450
489
  @chapter.image_index.image_finder.add_entry(file_path)
451
490
 
452
491
  image(lines, id, caption)
453
492
  end
454
493
 
494
+ def system_graph(id, *args)
495
+ @logger.info args.join(' ')
496
+ Kernel.system(*args) or @logger.error("failed to run command for id #{id}: #{args.join(' ')}")
497
+ end
498
+
499
+ def graph_graphviz(id, file_path, _line, tf_path)
500
+ system_graph(id, 'dot', "-T#{image_ext}", "-o#{file_path}", tf_path)
501
+ file_path
502
+ end
503
+
504
+ def graph_gnuplot(id, file_path, line, tf_path)
505
+ File.open(tf_path, 'w') do |tf|
506
+ tf.puts <<EOTGNUPLOT
507
+ set terminal #{image_ext == 'eps' ? 'postscript eps' : image_ext}
508
+ set output "#{file_path}"
509
+ #{line}
510
+ EOTGNUPLOT
511
+ end
512
+ system_graph(id, 'gnuplot', tf_path)
513
+ file_path
514
+ end
515
+
516
+ def graph_blockdiag(id, file_path, _line, tf_path)
517
+ system_graph(id, 'blockdiag', '-a', '-T', image_ext, '-o', file_path, tf_path)
518
+ file_path
519
+ end
520
+
521
+ def graph_aafigure(id, file_path, _line, tf_path)
522
+ system_graph(id, 'aafigure', '-t', image_ext, '-o', file_path, tf_path)
523
+ file_path
524
+ end
525
+
526
+ def graph_plantuml(id, file_path, _line, tf_path)
527
+ ext = image_ext
528
+ if ext == 'pdf'
529
+ ext = 'eps'
530
+ file_path.sub!(/\.pdf\Z/, '.eps')
531
+ end
532
+ system_graph(id, 'java', '-jar', 'plantuml.jar', "-t#{ext}", '-charset', 'UTF-8', tf_path)
533
+ FileUtils.mv "#{tf_path}.#{ext}", file_path
534
+ file_path
535
+ end
536
+
455
537
  def image_ext
456
538
  raise NotImplementedError
457
539
  end
@@ -471,7 +553,9 @@ module ReVIEW
471
553
  if matched = str.match(/\A\|(.*?)\|(.*)/)
472
554
  builders = matched[1].split(',').map { |i| i.gsub(/\s/, '') }
473
555
  c = self.class.to_s.gsub('ReVIEW::', '').gsub('Builder', '').downcase
474
- @tsize = matched[2] if builders.include?(c)
556
+ if builders.include?(c)
557
+ @tsize = matched[2]
558
+ end
475
559
  else
476
560
  @tsize = str
477
561
  end
@@ -514,5 +598,13 @@ module ReVIEW
514
598
  super(str)
515
599
  end
516
600
  end
601
+
602
+ def escape(str)
603
+ str
604
+ end
605
+
606
+ def unescape(str)
607
+ str
608
+ end
517
609
  end
518
610
  end # module ReVIEW
@@ -31,7 +31,22 @@ module ReVIEW
31
31
  def parts
32
32
  return '' unless @yaml['CHAPS']
33
33
 
34
- @yaml['CHAPS'].map { |entry| entry.keys if entry.is_a?(Hash) }.flatten.compact.join("\n")
34
+ part_list = @yaml['CHAPS'].map do |entry|
35
+ if entry.is_a?(Hash)
36
+ entry.keys
37
+ end
38
+ end
39
+
40
+ part_list.flatten.compact.join("\n")
41
+ end
42
+
43
+ def replace_part(old_name, new_name)
44
+ @yaml['CHAPS'].map! do |e|
45
+ if e.is_a?(Hash) and (e.keys.first == old_name)
46
+ e = { new_name => e.values.first }
47
+ end
48
+ e
49
+ end
35
50
  end
36
51
 
37
52
  def parts_with_chaps
@@ -49,7 +64,11 @@ module ReVIEW
49
64
  @yaml['POSTDEF'].join("\n")
50
65
  end
51
66
 
52
- def validate!(basedir)
67
+ def to_s
68
+ YAML.dump(@yaml).gsub(/\A---\n/, '') # remove yaml header
69
+ end
70
+
71
+ def validate!(config, basedir)
53
72
  filenames = []
54
73
  if predef.present?
55
74
  filenames.concat(predef.split(/\n/))
@@ -73,8 +92,9 @@ module ReVIEW
73
92
  filenames.concat(postdef.split(/\n/))
74
93
  end
75
94
  filenames.each do |filename|
76
- unless File.exist?(File.join(basedir, filename))
77
- raise FileNotFound, "file not found in catalog.yml: #{basedir}/#{filename}"
95
+ refile = File.join(basedir, config['contentdir'], filename)
96
+ unless File.exist?(refile)
97
+ raise FileNotFound, "file not found in catalog.yml: #{refile}"
78
98
  end
79
99
  end
80
100
  end
@@ -198,6 +198,7 @@ module ReVIEW
198
198
  definline :recipe
199
199
  definline :column
200
200
  definline :tcy
201
+ definline :balloon
201
202
 
202
203
  definline :abbr
203
204
  definline :acronym
@@ -228,9 +229,10 @@ module ReVIEW
228
229
  definline :hidx
229
230
  definline :comment
230
231
  definline :include
231
- definline :tcy
232
232
  definline :embed
233
233
  definline :pageref
234
+ definline :w
235
+ definline :wb
234
236
 
235
237
  private
236
238
 
@@ -1,3 +1,11 @@
1
+ #
2
+ # Copyright (c) 2012-2018 Masanori Kado, Masayoshi Takahashi, Kenshi Muto
3
+ #
4
+ # This program is free software.
5
+ # You can distribute or modify this program under the terms of
6
+ # the GNU LGPL, Lesser General Public License version 2.1.
7
+ # For details of the GNU LGPL, see the file "COPYING".
8
+ #
1
9
  require 'securerandom'
2
10
 
3
11
  module ReVIEW
@@ -41,6 +49,7 @@ module ReVIEW
41
49
  'imgmath' => nil, # for HTML
42
50
  'htmlext' => 'html',
43
51
  'htmlversion' => 5,
52
+ 'contentdir' => '.',
44
53
  'imagedir' => 'images',
45
54
  'image_ext' => %w[png gif jpg jpeg svg ttf woff otf],
46
55
  'fontdir' => 'fonts',
@@ -51,9 +60,9 @@ module ReVIEW
51
60
  'postdef_file' => 'POSTDEF',
52
61
  'page_metric' => ReVIEW::Book::PageMetric::A5,
53
62
  'ext' => '.re',
54
- 'image_dir' => 'images',
55
63
  'image_types' => %w[.ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg],
56
64
  'bib_file' => 'bib.re',
65
+ 'words_file' => nil,
57
66
  'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt],
58
67
  'externallink' => true,
59
68
  # for IDGXML
@@ -67,9 +76,10 @@ module ReVIEW
67
76
  'image_scale2width' => true,
68
77
  'footnotetext' => nil,
69
78
  'texcommand' => 'uplatex',
79
+ 'texoptions' => '-interaction=nonstopmode -file-line-error',
70
80
  'texdocumentclass' => ['jsbook', 'uplatex,oneside'],
71
81
  'dvicommand' => 'dvipdfmx',
72
- 'dvioptions' => '-d 5',
82
+ 'dvioptions' => '-d 5 -z 9',
73
83
  # for PDFMaker
74
84
  'pdfmaker' => {
75
85
  'makeindex' => nil, # Make index page
@@ -87,18 +97,42 @@ module ReVIEW
87
97
 
88
98
  def [](key)
89
99
  maker = self.maker
90
- return self.fetch(maker).fetch(key, nil) if maker && self.key?(maker) && self.fetch(maker) && self.fetch(maker).key?(key)
91
- return self.fetch(key) if self.key?(key)
100
+ if maker && self.key?(maker) && self.fetch(maker) && self.fetch(maker).key?(key)
101
+ return self.fetch(maker).fetch(key, nil)
102
+ end
103
+ if self.key?(key)
104
+ return self.fetch(key)
105
+ end
92
106
  nil
93
107
  end
94
108
 
95
- def check_version(version)
96
- raise ReVIEW::ConfigError, 'configuration file has no review_version property.' unless self.key?('review_version')
109
+ def check_version(version, exception: true)
110
+ unless self.key?('review_version')
111
+ if exception
112
+ raise ReVIEW::ConfigError, 'configuration file has no review_version property.'
113
+ else
114
+ return false
115
+ end
116
+ end
97
117
 
98
- return true if self['review_version'].blank?
118
+ if self['review_version'].blank?
119
+ return true
120
+ end
99
121
 
100
- raise ReVIEW::ConfigError, 'major version of configuration file is different.' if self['review_version'].to_i != version.to_i ## major version
101
- raise ReVIEW::ConfigError, "Re:VIEW version '#{version}' is older than configuration file's version '#{self['review_version']}'." if self['review_version'].to_f > version.to_f ## minor version
122
+ if self['review_version'].to_i != version.to_i ## major version
123
+ if exception
124
+ raise ReVIEW::ConfigError, 'major version of configuration file is different.'
125
+ else
126
+ return false
127
+ end
128
+ elsif self['review_version'].to_f > version.to_f ## minor version
129
+ if exception
130
+ raise ReVIEW::ConfigError, "Re:VIEW version '#{version}' is older than configuration file's version '#{self['review_version']}'."
131
+ else
132
+ return false
133
+ end
134
+ end
135
+ return true
102
136
  end
103
137
 
104
138
  def name_of(key)
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2010-2018 Kenshi Muto and Masayoshi Takahashi
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
+ # For details of the GNU LGPL, see the file "COPYING".
7
+ #
8
+ module ReVIEW
9
+ class EPUBMaker
10
+ class ReVIEWHeaderListener
11
+ include REXML::StreamListener
12
+ def initialize(headlines)
13
+ @level = nil
14
+ @content = ''
15
+ @headlines = headlines
16
+ end
17
+
18
+ def tag_start(name, attrs)
19
+ if name =~ /\Ah(\d+)/
20
+ raise "#{name}, #{attrs}" if @level.present?
21
+ @level = $1.to_i
22
+ @id = attrs['id'] if attrs['id'].present?
23
+ @notoc = attrs['notoc'] if attrs['notoc'].present?
24
+ elsif !@level.nil?
25
+ if name == 'img' && attrs['alt'].present?
26
+ @content << attrs['alt']
27
+ elsif name == 'a' && attrs['id'].present?
28
+ @id = attrs['id']
29
+ end
30
+ end
31
+ end
32
+
33
+ def tag_end(name)
34
+ if name =~ /\Ah\d+/
35
+ if @id.present?
36
+ @headlines.push({ 'level' => @level,
37
+ 'id' => @id,
38
+ 'title' => @content,
39
+ 'notoc' => @notoc })
40
+ end
41
+ @content = ''
42
+ @level = nil
43
+ @id = nil
44
+ @notoc = nil
45
+ end
46
+
47
+ true
48
+ end
49
+
50
+ def text(text)
51
+ if @level.present?
52
+ @content << text.gsub("\t", ' ')
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end