review 5.0.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +31 -0
  3. data/.github/workflows/ruby-win.yml +3 -3
  4. data/.github/workflows/ruby.yml +1 -1
  5. data/.rubocop.yml +15 -7
  6. data/NEWS.ja.md +108 -0
  7. data/NEWS.md +108 -0
  8. data/README.md +7 -6
  9. data/Rakefile +7 -2
  10. data/bin/review +2 -4
  11. data/bin/review-catalog-converter +3 -3
  12. data/bin/review-check +6 -8
  13. data/bin/review-checkdep +1 -4
  14. data/bin/review-compile +2 -5
  15. data/bin/review-epub2html +1 -4
  16. data/bin/review-epubmaker +3 -4
  17. data/bin/review-idgxmlmaker +1 -3
  18. data/bin/review-index +11 -5
  19. data/bin/review-init +1 -4
  20. data/bin/review-pdfmaker +1 -3
  21. data/bin/review-preproc +2 -4
  22. data/bin/review-textmaker +1 -3
  23. data/bin/review-update +1 -4
  24. data/bin/review-validate +3 -3
  25. data/bin/review-vol +1 -4
  26. data/bin/review-webmaker +1 -3
  27. data/doc/config.yml.sample +21 -5
  28. data/doc/config.yml.sample-simple +1 -1
  29. data/doc/format.ja.md +21 -10
  30. data/doc/format.md +21 -10
  31. data/doc/quickstart.ja.md +11 -1
  32. data/doc/quickstart.md +11 -2
  33. data/lib/review.rb +1 -1
  34. data/lib/review/book/base.rb +4 -0
  35. data/lib/review/book/book_unit.rb +3 -0
  36. data/lib/review/book/chapter.rb +3 -0
  37. data/lib/review/book/index.rb +1 -0
  38. data/lib/review/book/volume.rb +1 -0
  39. data/lib/review/builder.rb +8 -1
  40. data/lib/review/call_hook.rb +20 -0
  41. data/lib/review/catalog.rb +1 -0
  42. data/lib/review/compiler.rb +27 -10
  43. data/lib/review/configure.rb +64 -7
  44. data/lib/review/epubmaker.rb +93 -96
  45. data/lib/review/epubmaker/content.rb +113 -0
  46. data/lib/review/epubmaker/epubcommon.rb +372 -0
  47. data/lib/review/epubmaker/epubv2.rb +178 -0
  48. data/lib/review/epubmaker/epubv3.rb +231 -0
  49. data/lib/review/epubmaker/producer.rb +168 -0
  50. data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
  51. data/lib/review/epubmaker/zip_exporter.rb +84 -0
  52. data/lib/review/exception.rb +6 -0
  53. data/lib/review/htmlbuilder.rb +36 -49
  54. data/lib/review/htmlutils.rb +1 -1
  55. data/lib/review/i18n.rb +1 -0
  56. data/lib/review/idgxmlbuilder.rb +33 -30
  57. data/lib/review/idgxmlmaker.rb +3 -1
  58. data/lib/review/img_math.rb +245 -0
  59. data/lib/review/index_builder.rb +1 -0
  60. data/lib/review/init.rb +4 -4
  61. data/lib/review/latexbox.rb +58 -0
  62. data/lib/review/latexbuilder.rb +30 -19
  63. data/lib/review/latexutils.rb +9 -1
  64. data/lib/review/lineinput.rb +112 -2
  65. data/lib/review/logger.rb +41 -2
  66. data/lib/review/makerhelper.rb +2 -205
  67. data/lib/review/markdownbuilder.rb +32 -1
  68. data/lib/review/pdfmaker.rb +31 -29
  69. data/lib/review/plaintextbuilder.rb +9 -1
  70. data/lib/review/preprocessor.rb +12 -6
  71. data/lib/review/rstbuilder.rb +1 -1
  72. data/lib/review/sec_counter.rb +1 -0
  73. data/lib/review/template.rb +6 -0
  74. data/lib/review/textmaker.rb +11 -7
  75. data/lib/review/textutils.rb +2 -10
  76. data/lib/review/tocprinter.rb +85 -68
  77. data/lib/review/topbuilder.rb +18 -11
  78. data/lib/review/update.rb +5 -6
  79. data/lib/review/version.rb +1 -1
  80. data/lib/review/volumeprinter.rb +4 -5
  81. data/lib/review/webmaker.rb +18 -13
  82. data/lib/review/webtocprinter.rb +10 -9
  83. data/lib/review/yamlloader.rb +2 -1
  84. data/review.gemspec +5 -3
  85. data/samples/sample-book/src/config-epub2.yml +1 -1
  86. data/samples/sample-book/src/config.yml +1 -1
  87. data/samples/sample-book/src/lib/tasks/review.rake +17 -1
  88. data/samples/syntax-book/ch01.re +1 -1
  89. data/samples/syntax-book/ch02.re +21 -6
  90. data/samples/syntax-book/ch03.re +1 -1
  91. data/samples/syntax-book/images/img3-2.png +0 -0
  92. data/templates/html/_colophon.html.erb +23 -0
  93. data/templates/html/_colophon_history.html.erb +9 -0
  94. data/templates/html/_cover.html.erb +10 -0
  95. data/templates/html/_part_body.html.erb +6 -0
  96. data/templates/html/_titlepage.html.erb +20 -0
  97. data/templates/html/layout-html5.html.erb +6 -0
  98. data/templates/html/layout-xhtml1.html.erb +6 -0
  99. data/templates/latex/config.erb +8 -0
  100. data/templates/latex/review-jlreq/review-base.sty +4 -5
  101. data/templates/latex/review-jlreq/review-jlreq.cls +10 -2
  102. data/templates/latex/review-jlreq/review-style.sty +6 -1
  103. data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
  104. data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
  105. data/templates/latex/review-jsbook/review-base.sty +5 -7
  106. data/templates/latex/review-jsbook/review-jsbook.cls +10 -2
  107. data/templates/latex/review-jsbook/review-style.sty +6 -1
  108. data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
  109. data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
  110. data/templates/opf/epubv2.opf.erb +7 -7
  111. data/templates/opf/epubv3.opf.erb +7 -7
  112. data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
  113. data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
  114. data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
  115. data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
  116. data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
  117. data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
  118. data/templates/web/html/layout-html5.html.erb +6 -5
  119. data/templates/web/html/layout-xhtml1.html.erb +6 -0
  120. data/test/assets/header_listener.html +35 -0
  121. data/test/assets/img_math/img1.png +0 -0
  122. data/test/assets/img_math/img2.png +0 -0
  123. data/test/assets/img_math/img3.png +0 -0
  124. data/test/assets/syntax_book_index_detail.txt +58 -0
  125. data/test/assets/test_template.tex +4 -1
  126. data/test/assets/test_template_backmatter.tex +4 -1
  127. data/test/run_test.rb +1 -1
  128. data/test/test_book_chapter.rb +2 -2
  129. data/test/test_catalog_converter_cmd.rb +1 -1
  130. data/test/test_epub3maker.rb +168 -124
  131. data/test/test_epubmaker.rb +243 -131
  132. data/test/test_epubmaker_cmd.rb +2 -2
  133. data/test/test_helper.rb +5 -4
  134. data/test/test_htmlbuilder.rb +64 -6
  135. data/test/test_idgxmlbuilder.rb +13 -0
  136. data/test/test_idgxmlmaker_cmd.rb +7 -3
  137. data/test/test_img_math.rb +111 -0
  138. data/test/test_indexbuilder.rb +5 -5
  139. data/test/test_latexbuilder.rb +107 -4
  140. data/test/test_lineinput.rb +20 -93
  141. data/test/test_markdownbuilder.rb +29 -0
  142. data/test/test_pdfmaker.rb +71 -0
  143. data/test/test_pdfmaker_cmd.rb +2 -2
  144. data/test/test_plaintextbuilder.rb +10 -18
  145. data/test/test_reviewheaderlistener.rb +49 -0
  146. data/test/test_template.rb +12 -2
  147. data/test/test_textmaker_cmd.rb +5 -1
  148. data/test/test_tocprinter.rb +46 -0
  149. data/test/test_topbuilder.rb +6 -1
  150. data/test/test_update.rb +34 -34
  151. data/test/test_zip_exporter.rb +5 -6
  152. metadata +91 -17
  153. data/lib/epubmaker.rb +0 -23
  154. data/lib/epubmaker/content.rb +0 -111
  155. data/lib/epubmaker/epubcommon.rb +0 -449
  156. data/lib/epubmaker/epubv2.rb +0 -142
  157. data/lib/epubmaker/epubv3.rb +0 -235
  158. data/lib/epubmaker/producer.rb +0 -375
  159. data/lib/epubmaker/zip_exporter.rb +0 -81
  160. data/lib/lineinput.rb +0 -155
data/doc/quickstart.ja.md CHANGED
@@ -8,7 +8,7 @@ Re:VIEW は GNU Lesser General Public License Version 2.1 に基づいて配布
8
8
 
9
9
  このドキュメントでは、Re:VIEW のセットアップから変換の例までを簡単に説明します。
10
10
 
11
- このドキュメントは、Re:VIEW 4.2 に基づいています。
11
+ このドキュメントは、Re:VIEW 5.1 に基づいています。
12
12
 
13
13
  ## セットアップ
14
14
 
@@ -160,6 +160,16 @@ config.yml のサンプルについては以下を参照してください。
160
160
 
161
161
  * [config.yml.sample](https://github.com/kmuto/review/blob/master/doc/config.yml.sample)
162
162
 
163
+ #### Vivliostyle CLI を使った PDF 化
164
+
165
+ TeX (`review-pdfmaker`、`rake pdf`) を利用する代わりに、[Vivliostyle CLI](https://github.com/vivliostyle/vivliostyle-cli) を使って PDF を作成することもできます。Re:VIEW が EPUB を作成したあと、VivliostyleCLI がそれを PDF に変換します。
166
+
167
+ ```bash
168
+ $ rake vivliostyle:build ← Vivliostyle を使って PDF を作成
169
+ $ rake vivliostyle:preview ← Chrome/Chromium ブラウザでプレビュー
170
+ $ rake vivliostyle ← vivliostyle:buildのショートカット
171
+ ```
172
+
163
173
  ### 章を増やす、カスタマイズする
164
174
  作成した PDF あるいは EPUB を見ると、先に作成した RE:VIEW フォーマットテキストファイルが「第1章」となっていることがわかります。
165
175
 
data/doc/quickstart.md CHANGED
@@ -9,7 +9,7 @@ Re:VIEW is free software under the terms of the GNU Lesser General Public Licens
9
9
 
10
10
  This article describes how to setup Re:VIEW and use it.
11
11
 
12
- The supported version of the article is Re:VIEW 4.2.
12
+ The supported version of the article is Re:VIEW 5.1.
13
13
 
14
14
  ## Set up Re:VIEW
15
15
 
@@ -161,6 +161,16 @@ $ rake idgxml ## generate InDesign XML
161
161
 
162
162
  There is a sample YAML file [config.yml.sample](https://github.com/kmuto/review/blob/master/doc/config.yml.sample) in the same directory of this document.
163
163
 
164
+ #### generate PDF using Vivliostyle CLI
165
+
166
+ Instead of using TeX (`review-pdfmaker` or `rake pdf`), you can also create a PDF use [Vivliostyle CLI](https://github.com/vivliostyle/vivliostyle-cli). Re:VIEW creates EPUB first and then converts it to PDF with Vivliostyle CLI.
167
+
168
+ ```bash
169
+ $ rake vivliostyle:build ## build PDF using Viliostyle
170
+ $ rake vivliostyle:preview ## preview pages in Chrome/Chromium browser
171
+ $ rake vivliostyle ## shortcut of vivliostyle:build
172
+ ```
173
+
164
174
  ### add chapters and modify them
165
175
 
166
176
  `catalog.yml` file is a catalog of Re:VIEW format files.
@@ -182,7 +192,6 @@ POSTDEF:
182
192
 
183
193
  The first item in CHAPS is the first chapter, and the second item (if you add) is the second chapter. PREDEF is for front matter, APPENDIX is for appendix, and POSTDEF is for back matter. You can see in detail with [catalog.md](https://github.com/kmuto/review/blob/master/doc/catalog.ja.md).
184
194
 
185
-
186
195
  ### more information
187
196
 
188
197
  For more information about Re:VIEW format, see [format.md](https://github.com/kmuto/review/blob/master/doc/format.md).
data/lib/review.rb CHANGED
@@ -1,3 +1,3 @@
1
- Dir["#{File.dirname(__FILE__)}/review/*.rb"].sort.each do |path|
1
+ Dir["#{__dir__}/review/*.rb"].sort.each do |path|
2
2
  require "review/#{File.basename(path, '.rb')}"
3
3
  end
@@ -176,6 +176,7 @@ module ReVIEW
176
176
 
177
177
  def chapter_index
178
178
  return @chapter_index if @chapter_index
179
+
179
180
  @chapter_index = create_chapter_index
180
181
  @chapter_index
181
182
  end
@@ -188,6 +189,7 @@ module ReVIEW
188
189
  finded = false
189
190
  each_chapter do |c|
190
191
  return c if finded
192
+
191
193
  if c == chapter
192
194
  finded = true
193
195
  end
@@ -199,6 +201,7 @@ module ReVIEW
199
201
  finded = false
200
202
  each_chapter_r do |c|
201
203
  return c if finded
204
+
202
205
  if c == chapter
203
206
  finded = true
204
207
  end
@@ -392,6 +395,7 @@ module ReVIEW
392
395
  File.open(filename_join(@basedir, filename), 'rt:BOM|utf-8') do |f|
393
396
  f.each_line do |line|
394
397
  next if line.start_with?('#')
398
+
395
399
  line.gsub!(/#.*\Z/, '')
396
400
  res << line
397
401
  end
@@ -82,6 +82,7 @@ module ReVIEW
82
82
 
83
83
  @title = ''
84
84
  return @title unless content
85
+
85
86
  content.each_line do |line|
86
87
  if line =~ /\A=+/
87
88
  @title = line.sub(/\A=+(\[.+?\])?(\{.+?\})?/, '').strip
@@ -119,6 +120,7 @@ module ReVIEW
119
120
  return image_index[id] if image_index.key?(id)
120
121
  return icon_index[id] if icon_index.key?(id)
121
122
  return numberless_image_index[id] if numberless_image_index.key?(id)
123
+
122
124
  indepimage_index[id]
123
125
  end
124
126
 
@@ -128,6 +130,7 @@ module ReVIEW
128
130
 
129
131
  def bibpaper_index
130
132
  raise FileNotFound, "no such bib file: #{@book.bib_file}" unless @book.bib_exist?
133
+
131
134
  @book.bibpaper_index
132
135
  end
133
136
 
@@ -20,6 +20,7 @@ module ReVIEW
20
20
  name += book.ext if File.extname(name).empty?
21
21
  path = File.join(book.contentdir, name)
22
22
  raise FileNotFound, "file not exist: #{path}" unless File.file?(path)
23
+
23
24
  Chapter.new(book, number, name, path)
24
25
  end
25
26
 
@@ -85,6 +86,8 @@ module ReVIEW
85
86
  nil
86
87
  rescue ArgumentError => e
87
88
  raise ReVIEW::CompileError, "#{@name}: #{e}"
89
+ rescue SyntaxError => e
90
+ raise ReVIEW::SyntaxError, "#{@name}:#{f.lineno}: #{e}"
88
91
  end
89
92
  end
90
93
 
@@ -189,6 +189,7 @@ module ReVIEW
189
189
  # when notoc
190
190
  return ''
191
191
  end
192
+
192
193
  n = @chapter.number
193
194
  # XXX: remove magic number (move to lib/review/book/chapter.rb)
194
195
  if @chapter.on_appendix? && @chapter.number > 0 && @chapter.number < 28
@@ -13,6 +13,7 @@ module ReVIEW
13
13
  b = c = l = 0
14
14
  File.foreach(path) do |line|
15
15
  next if /\A\#@/ =~ line
16
+
16
17
  text = line.gsub(/\s+/, '')
17
18
  b += text.bytesize
18
19
  c += text.size
@@ -10,6 +10,7 @@ require 'review/exception'
10
10
  require 'review/textutils'
11
11
  require 'review/compiler'
12
12
  require 'review/sec_counter'
13
+ require 'review/img_math'
13
14
  require 'stringio'
14
15
  require 'fileutils'
15
16
  require 'tempfile'
@@ -31,13 +32,14 @@ module ReVIEW
31
32
 
32
33
  attr_accessor :doc_status, :previous_list_type
33
34
 
34
- def initialize(strict = false, *_args)
35
+ def initialize(strict = false, *_args, img_math: nil)
35
36
  @strict = strict
36
37
  @output = nil
37
38
  @logger = ReVIEW.logger
38
39
  @doc_status = {}
39
40
  @dictionary = {}
40
41
  @previous_list_type = nil
42
+ @img_math = img_math
41
43
  end
42
44
 
43
45
  def bind(compiler, chapter, location)
@@ -55,6 +57,7 @@ module ReVIEW
55
57
  @tabwidth = nil
56
58
  @tsize = nil
57
59
  if @book && @book.config
60
+ @img_math ||= ReVIEW::ImgMath.new(@book.config)
58
61
  if words_file_path = @book.config['words_file']
59
62
  if words_file_path.is_a?(String)
60
63
  words_files = [words_file_path]
@@ -145,6 +148,7 @@ module ReVIEW
145
148
 
146
149
  def line_num
147
150
  return 1 unless @first_line_num
151
+
148
152
  line_n = @first_line_num
149
153
  @first_line_num = nil
150
154
 
@@ -514,11 +518,13 @@ module ReVIEW
514
518
 
515
519
  def parse_metric(type, metric)
516
520
  return '' if metric.blank?
521
+
517
522
  params = metric.split(/,\s*/)
518
523
  results = []
519
524
  params.each do |param|
520
525
  if param =~ /\A.+?::/
521
526
  next unless param =~ /\A#{type}::/
527
+
522
528
  param.sub!(/\A#{type}::/, '')
523
529
  end
524
530
  param2 = handle_metric(param)
@@ -543,6 +549,7 @@ module ReVIEW
543
549
  if m
544
550
  ch = @book.contents.detect { |chap| chap.id == m[1] }
545
551
  raise KeyError unless ch
552
+
546
553
  return [ch, m[2]]
547
554
  end
548
555
  [@chapter, chap_ref]
@@ -0,0 +1,20 @@
1
+ module ReVIEW
2
+ module CallHook
3
+ def call_hook(hook_name, *params, base_dir: nil)
4
+ maker = @config.maker
5
+ filename = @config.dig(maker, hook_name)
6
+ return unless filename
7
+
8
+ hook = File.absolute_path(filename, base_dir)
9
+ @logger.debug("Call #{hook_name}. (#{hook})")
10
+
11
+ return if !File.exist?(hook) || !FileTest.executable?(hook)
12
+
13
+ if ENV['REVIEW_SAFE_MODE'].to_i & 1 > 0
14
+ warn 'hook configuration is prohibited in safe mode. ignored.'
15
+ else
16
+ system(hook, *params)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -50,6 +50,7 @@ module ReVIEW
50
50
 
51
51
  def parts_with_chaps
52
52
  return [] unless @yaml['CHAPS']
53
+
53
54
  @yaml['CHAPS'].flatten.compact
54
55
  end
55
56
 
@@ -14,6 +14,8 @@ require 'strscan'
14
14
 
15
15
  module ReVIEW
16
16
  class Compiler
17
+ MAX_HEADLINE_LEVEL = 6
18
+
17
19
  def initialize(builder)
18
20
  @builder = builder
19
21
 
@@ -59,6 +61,7 @@ module ReVIEW
59
61
  unless @argc_spec === args.size
60
62
  raise CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})"
61
63
  end
64
+
62
65
  if @checker
63
66
  @checker.call(*args)
64
67
  end
@@ -331,6 +334,8 @@ module ReVIEW
331
334
  end
332
335
  end
333
336
  close_all_tagged_section
337
+ rescue SyntaxError => e
338
+ error e
334
339
  end
335
340
 
336
341
  def compile_minicolumn_begin(name, caption = nil)
@@ -364,24 +369,28 @@ module ReVIEW
364
369
  @headline_indexs ||= [@chapter.number.to_i - 1]
365
370
  m = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/.match(line)
366
371
  level = m[1].size
372
+ if level > MAX_HEADLINE_LEVEL
373
+ raise CompileError, "Invalid header: max headline level is #{MAX_HEADLINE_LEVEL}"
374
+ end
375
+
367
376
  tag = m[2]
368
377
  label = m[3]
369
378
  caption = m[4].strip
370
379
  index = level - 1
371
380
  if tag
372
- if tag !~ %r{\A/}
373
- if caption.empty?
374
- warn 'headline is empty.'
375
- end
376
- close_current_tagged_section(level)
377
- open_tagged_section(tag, level, label, caption)
378
- else
381
+ if tag.start_with?('/')
379
382
  open_tag = tag[1..-1]
380
383
  prev_tag_info = @tagged_section.pop
381
384
  if prev_tag_info.nil? || prev_tag_info.first != open_tag
382
385
  error "#{open_tag} is not opened."
383
386
  end
384
387
  close_tagged_section(*prev_tag_info)
388
+ else
389
+ if caption.empty?
390
+ warn 'headline is empty.'
391
+ end
392
+ close_current_tagged_section(level)
393
+ open_tagged_section(tag, level, label, caption)
385
394
  end
386
395
  else
387
396
  if caption.empty?
@@ -504,7 +513,10 @@ module ReVIEW
504
513
  @builder.doc_status[:dt] = true
505
514
  @builder.dt(text(f.gets.sub(/\A\s*:/, '').strip))
506
515
  @builder.doc_status[:dt] = nil
507
- desc = f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) }
516
+ desc = []
517
+ f.until_match(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/) do |line|
518
+ desc << text(line.strip)
519
+ end
508
520
  @builder.dd(desc)
509
521
  f.skip_blank_lines
510
522
  f.skip_comment_lines
@@ -516,6 +528,7 @@ module ReVIEW
516
528
  buf = []
517
529
  f.until_match(%r{\A//|\A\#@}) do |line|
518
530
  break if line.strip.empty?
531
+
519
532
  buf.push(text(line.sub(/^(\t+)\s*/) { |m| '<!ESCAPETAB!>' * m.size }.strip.gsub('<!ESCAPETAB!>', "\t")))
520
533
  end
521
534
  @builder.paragraph(buf)
@@ -557,6 +570,7 @@ module ReVIEW
557
570
 
558
571
  def parse_args(str, _name = nil)
559
572
  return [] if str.empty?
573
+
560
574
  scanner = StringScanner.new(str)
561
575
  words = []
562
576
  while word = scanner.scan(/(\[\]|\[.*?[^\\]\])/)
@@ -621,13 +635,13 @@ module ReVIEW
621
635
  if arg =~ /[\x01\x02\x03\x04]/
622
636
  error "invalid character in '#{str}'"
623
637
  end
624
- replaced = arg.gsub('@', "\x01").gsub('\\', "\x02").gsub('{', "\x03").gsub('}', "\x04")
638
+ replaced = arg.tr('@', "\x01").tr('\\', "\x02").tr('{', "\x03").tr('}', "\x04")
625
639
  "@<#{op}>{#{replaced}}"
626
640
  end
627
641
  end
628
642
 
629
643
  def revert_replace_fence(str)
630
- str.gsub("\x01", '@').gsub("\x02", '\\').gsub("\x03", '{').gsub("\x04", '}')
644
+ str.tr("\x01", '@').tr("\x02", '\\').tr("\x03", '{').tr("\x04", '}')
631
645
  end
632
646
 
633
647
  def in_non_escaped_command?
@@ -637,6 +651,7 @@ module ReVIEW
637
651
 
638
652
  def text(str, block_mode = false)
639
653
  return '' if str.empty?
654
+
640
655
  words = replace_fence(str).split(/(@<\w+>\{(?:[^}\\]|\\.)*?\})/, -1)
641
656
  words.each do |w|
642
657
  if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w)
@@ -651,6 +666,7 @@ module ReVIEW
651
666
  result << @builder.nofunc_text(revert_replace_fence(words.shift))
652
667
  end
653
668
  break if words.empty?
669
+
654
670
  result << compile_inline(revert_replace_fence(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\')))
655
671
  end
656
672
  result
@@ -667,6 +683,7 @@ module ReVIEW
667
683
  unless @builder.respond_to?("inline_#{op}")
668
684
  raise "builder does not support inline op: @<#{op}>"
669
685
  end
686
+
670
687
  @builder.__send__("inline_#{op}", arg)
671
688
  rescue => e
672
689
  error e.message
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (c) 2012-2020 Masanori Kado, Masayoshi Takahashi, Kenshi Muto
2
+ # Copyright (c) 2012-2021 Masanori Kado, Masayoshi Takahashi, Kenshi Muto
3
3
  #
4
4
  # This program is free software.
5
5
  # You can distribute or modify this program under the terms of
@@ -7,12 +7,13 @@
7
7
  # For details of the GNU LGPL, see the file "COPYING".
8
8
  #
9
9
  require 'securerandom'
10
+ require 'review/yamlloader'
10
11
 
11
12
  module ReVIEW
12
13
  class Configure < Hash
13
14
  attr_accessor :maker
14
15
 
15
- def self.values
16
+ def self.values # rubocop:disable Metrics/MethodLength
16
17
  conf = Configure[
17
18
  # These parameters can be overridden by YAML file.
18
19
  'bookname' => 'book', # it defines epub file name also
@@ -31,7 +32,7 @@ module ReVIEW
31
32
  'date' => Time.now.strftime('%Y-%m-%d'), # publishing date
32
33
  'rights' => nil, # Copyright messages
33
34
  'description' => nil, # Description
34
- 'urnid' => "urn:uid:#{SecureRandom.uuid}", # Identifier
35
+ 'urnid' => "urn:uuid:#{SecureRandom.uuid}", # Identifier
35
36
  'stylesheet' => [], # stylesheet file
36
37
  'coverfile' => nil, # content file of body of cover page
37
38
  'mytoc' => nil, # whether make own table of contents or not
@@ -45,8 +46,7 @@ module ReVIEW
45
46
  'debug' => nil, # debug flag
46
47
  'catalogfile' => 'catalog.yml',
47
48
  'language' => 'ja', # XXX default language should be JA??
48
- 'mathml' => nil, # for HTML
49
- 'imgmath' => nil, # for HTML
49
+ 'math_format' => nil,
50
50
  'htmlext' => 'html',
51
51
  'htmlversion' => 5,
52
52
  'contentdir' => '.',
@@ -63,7 +63,7 @@ module ReVIEW
63
63
  'image_types' => %w[.ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg],
64
64
  'bib_file' => 'bib.re',
65
65
  'words_file' => nil,
66
- 'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt],
66
+ 'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt pht],
67
67
  'chapterlink' => true,
68
68
  'externallink' => true,
69
69
  'join_lines_by_lang' => nil, # experimental. default should be nil
@@ -113,6 +113,34 @@ module ReVIEW
113
113
  'image' => 'bottom',
114
114
  'table' => 'top',
115
115
  'equation' => 'top'
116
+ },
117
+ # for EPUBMaker
118
+ 'modified' => Time.now.utc.strftime('%Y-%02m-%02dT%02H:%02M:%02SZ'),
119
+ 'isbn' => nil,
120
+ 'titlefile' => nil,
121
+ 'originaltitlefile' => nil,
122
+ 'profile' => nil,
123
+ 'direction' => 'ltr',
124
+ 'image_maxpixels' => 4_000_000,
125
+ 'font_ext' => %w[ttf woff otf],
126
+ 'epubmaker' => {
127
+ 'flattoc' => nil,
128
+ 'flattocindent' => true,
129
+ 'ncx_indent' => [],
130
+ 'zip_stage1' => 'zip -0Xq',
131
+ 'zip_stage2' => 'zip -Xr9Dq',
132
+ 'zip_addpath' => nil,
133
+ 'hook_beforeprocess' => nil,
134
+ 'hook_afterfrontmatter' => nil,
135
+ 'hook_afterbody' => nil,
136
+ 'hook_afterbackmatter' => nil,
137
+ 'hook_aftercopyimage' => nil,
138
+ 'hook_prepack' => nil,
139
+ 'rename_for_legacy' => nil,
140
+ 'verify_target_images' => nil,
141
+ 'force_include_images' => [],
142
+ 'cover_linear' => nil,
143
+ 'back_footnote' => nil
116
144
  }
117
145
  ]
118
146
  conf.maker = nil
@@ -128,17 +156,45 @@ module ReVIEW
128
156
  loader = ReVIEW::YAMLLoader.new
129
157
  conf.deep_merge!(loader.load_file(yamlfile))
130
158
  rescue => e
131
- error "yaml error #{e.message}"
159
+ raise ReVIEW::ConfigError, "yaml error #{e.message}"
132
160
  end
133
161
  end
162
+
134
163
  # YAML configs will be overridden by command line options.
135
164
  if config
136
165
  conf.deep_merge!(config)
137
166
  end
138
167
 
168
+ conf.migrate_parameters
169
+
139
170
  conf
140
171
  end
141
172
 
173
+ def migrate_parameters
174
+ # string to array
175
+ %w[subject aut
176
+ a-adp a-ann a-arr a-art a-asn a-aqt a-aft a-aui a-ant a-bkp a-clb a-cmm a-dsr a-edt
177
+ a-ill a-lyr a-mdc a-mus a-nrt a-oth a-pht a-prt a-red a-rev a-spn a-ths a-trc a-trl
178
+ adp ann arr art asn aut aqt aft aui ant bkp clb cmm dsr edt
179
+ ill lyr mdc mus nrt oth pht pbl prt red rev spn ths trc trl
180
+ stylesheet rights].each do |item|
181
+ if self[item] && self[item].is_a?(String)
182
+ self[item] = [self[item]]
183
+ end
184
+ end
185
+
186
+ # backward compatibility
187
+ if self['mathml']
188
+ warn '"mathml: true" is obsoleted. Please use "math_format: mathml"'
189
+ self['math_format'] = 'mathml'
190
+ end
191
+
192
+ if self['imgmath']
193
+ warn '"imgmath: true" is obsoleted. Please use "math_format: imgmath"'
194
+ self['math_format'] = 'imgmath'
195
+ end
196
+ end
197
+
142
198
  def [](key)
143
199
  maker = self.maker
144
200
  if maker && self.key?(maker) && self.fetch(maker) && self.fetch(maker).key?(key)
@@ -147,6 +203,7 @@ module ReVIEW
147
203
  if self.key?(key)
148
204
  return self.fetch(key)
149
205
  end
206
+
150
207
  nil
151
208
  end
152
209