review 5.0.0 → 5.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +35 -0
  3. data/.github/workflows/ruby-win.yml +8 -4
  4. data/.github/workflows/ruby.yml +6 -2
  5. data/.rubocop.yml +24 -9
  6. data/NEWS.ja.md +215 -0
  7. data/NEWS.md +215 -1
  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 +10 -20
  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 +30 -38
  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 +23 -5
  28. data/doc/config.yml.sample-simple +1 -1
  29. data/doc/format.ja.md +49 -12
  30. data/doc/format.md +52 -12
  31. data/doc/quickstart.ja.md +11 -1
  32. data/doc/quickstart.md +11 -2
  33. data/doc/writing_vertical.ja.md +6 -0
  34. data/lib/review/book/base.rb +4 -0
  35. data/lib/review/book/book_unit.rb +15 -2
  36. data/lib/review/book/chapter.rb +3 -0
  37. data/lib/review/book/index.rb +5 -1
  38. data/lib/review/book/volume.rb +1 -0
  39. data/lib/review/builder.rb +90 -54
  40. data/lib/review/call_hook.rb +20 -0
  41. data/lib/review/catalog.rb +2 -0
  42. data/lib/review/compiler.rb +88 -52
  43. data/lib/review/configure.rb +64 -7
  44. data/lib/review/epubmaker/content.rb +113 -0
  45. data/lib/review/epubmaker/epubcommon.rb +372 -0
  46. data/lib/review/epubmaker/epubv2.rb +178 -0
  47. data/lib/review/epubmaker/epubv3.rb +231 -0
  48. data/lib/review/epubmaker/producer.rb +167 -0
  49. data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
  50. data/lib/review/epubmaker/zip_exporter.rb +84 -0
  51. data/lib/review/epubmaker.rb +114 -129
  52. data/lib/review/exception.rb +13 -0
  53. data/lib/review/htmlbuilder.rb +109 -67
  54. data/lib/review/htmlutils.rb +1 -1
  55. data/lib/review/i18n.rb +1 -0
  56. data/lib/review/i18n.yml +6 -0
  57. data/lib/review/idgxmlbuilder.rb +72 -48
  58. data/lib/review/idgxmlmaker.rb +15 -14
  59. data/lib/review/img_math.rb +239 -0
  60. data/lib/review/index_builder.rb +90 -32
  61. data/lib/review/init.rb +4 -4
  62. data/lib/review/latexbox.rb +58 -0
  63. data/lib/review/latexbuilder.rb +79 -58
  64. data/lib/review/latexutils.rb +9 -1
  65. data/lib/review/lineinput.rb +112 -2
  66. data/lib/review/loggable.rb +27 -0
  67. data/lib/review/logger.rb +89 -2
  68. data/lib/review/makerhelper.rb +7 -206
  69. data/lib/review/markdownbuilder.rb +44 -4
  70. data/lib/review/pdfmaker.rb +70 -51
  71. data/lib/review/plaintextbuilder.rb +20 -11
  72. data/lib/review/preprocessor/directive.rb +35 -0
  73. data/lib/review/preprocessor/line.rb +34 -0
  74. data/lib/review/preprocessor/repository.rb +177 -0
  75. data/lib/review/preprocessor.rb +105 -301
  76. data/lib/review/rstbuilder.rb +13 -4
  77. data/lib/review/sec_counter.rb +1 -0
  78. data/lib/review/template.rb +11 -1
  79. data/lib/review/textmaker.rb +23 -20
  80. data/lib/review/textutils.rb +10 -17
  81. data/lib/review/tocprinter.rb +93 -71
  82. data/lib/review/topbuilder.rb +44 -19
  83. data/lib/review/update.rb +5 -6
  84. data/lib/review/version.rb +1 -1
  85. data/lib/review/volumeprinter.rb +11 -12
  86. data/lib/review/webmaker.rb +31 -27
  87. data/lib/review/webtocprinter.rb +10 -9
  88. data/lib/review/yamlloader.rb +2 -1
  89. data/lib/review.rb +1 -1
  90. data/review.gemspec +5 -3
  91. data/samples/sample-book/src/config-epub2.yml +1 -1
  92. data/samples/sample-book/src/config.yml +1 -1
  93. data/samples/sample-book/src/lib/tasks/review.rake +19 -1
  94. data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +2 -1
  95. data/samples/syntax-book/ch01.re +1 -1
  96. data/samples/syntax-book/ch02.re +30 -6
  97. data/samples/syntax-book/ch03.re +1 -1
  98. data/samples/syntax-book/images/img3-2.png +0 -0
  99. data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +2 -1
  100. data/templates/html/_colophon.html.erb +23 -0
  101. data/templates/html/_colophon_history.html.erb +9 -0
  102. data/templates/html/_cover.html.erb +10 -0
  103. data/templates/html/_part_body.html.erb +6 -0
  104. data/templates/html/_titlepage.html.erb +20 -0
  105. data/templates/html/layout-html5.html.erb +6 -0
  106. data/templates/html/layout-xhtml1.html.erb +6 -0
  107. data/templates/latex/config.erb +11 -0
  108. data/templates/latex/review-jlreq/review-base.sty +7 -9
  109. data/templates/latex/review-jlreq/review-jlreq.cls +48 -6
  110. data/templates/latex/review-jlreq/review-style.sty +6 -1
  111. data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
  112. data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
  113. data/templates/latex/review-jsbook/review-base.sty +13 -9
  114. data/templates/latex/review-jsbook/review-jsbook.cls +41 -6
  115. data/templates/latex/review-jsbook/review-style.sty +6 -1
  116. data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
  117. data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
  118. data/templates/opf/epubv2.opf.erb +7 -7
  119. data/templates/opf/epubv3.opf.erb +7 -7
  120. data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
  121. data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
  122. data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
  123. data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
  124. data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
  125. data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
  126. data/templates/web/html/layout-html5.html.erb +6 -5
  127. data/templates/web/html/layout-xhtml1.html.erb +6 -0
  128. data/test/assets/header_listener.html +35 -0
  129. data/test/assets/img_math/img1.png +0 -0
  130. data/test/assets/img_math/img2.png +0 -0
  131. data/test/assets/img_math/img3.png +0 -0
  132. data/test/assets/syntax_book_index_detail.txt +60 -0
  133. data/test/assets/test_template.tex +7 -1
  134. data/test/assets/test_template_backmatter.tex +7 -1
  135. data/test/run_test.rb +1 -1
  136. data/test/test_book_chapter.rb +27 -4
  137. data/test/test_builder.rb +10 -8
  138. data/test/test_catalog_converter_cmd.rb +1 -1
  139. data/test/test_epub3maker.rb +168 -124
  140. data/test/test_epubmaker.rb +248 -131
  141. data/test/test_epubmaker_cmd.rb +15 -4
  142. data/test/test_helper.rb +5 -4
  143. data/test/test_htmlbuilder.rb +170 -31
  144. data/test/test_idgxmlbuilder.rb +44 -23
  145. data/test/test_idgxmlmaker_cmd.rb +7 -3
  146. data/test/test_img_math.rb +111 -0
  147. data/test/test_index.rb +30 -4
  148. data/test/test_indexbuilder.rb +5 -5
  149. data/test/test_latexbuilder.rb +151 -26
  150. data/test/test_latexbuilder_v2.rb +18 -10
  151. data/test/test_lineinput.rb +20 -93
  152. data/test/test_markdownbuilder.rb +42 -0
  153. data/test/test_pdfmaker.rb +90 -0
  154. data/test/test_pdfmaker_cmd.rb +2 -2
  155. data/test/test_plaintextbuilder.rb +56 -40
  156. data/test/test_preprocessor.rb +188 -1
  157. data/test/test_reviewheaderlistener.rb +49 -0
  158. data/test/test_rstbuilder.rb +13 -0
  159. data/test/test_template.rb +12 -2
  160. data/test/test_textmaker_cmd.rb +5 -1
  161. data/test/test_tocprinter.rb +46 -0
  162. data/test/test_topbuilder.rb +50 -19
  163. data/test/test_update.rb +34 -34
  164. data/test/test_zip_exporter.rb +5 -6
  165. metadata +95 -17
  166. data/lib/epubmaker/content.rb +0 -111
  167. data/lib/epubmaker/epubcommon.rb +0 -449
  168. data/lib/epubmaker/epubv2.rb +0 -142
  169. data/lib/epubmaker/epubv3.rb +0 -235
  170. data/lib/epubmaker/producer.rb +0 -375
  171. data/lib/epubmaker/zip_exporter.rb +0 -81
  172. data/lib/epubmaker.rb +0 -23
  173. data/lib/lineinput.rb +0 -155
@@ -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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2017 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2009-2021 Minero Aoki, Kenshi Muto
2
2
  # 2002-2008 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -18,7 +18,8 @@ module ReVIEW
18
18
  attr_reader :lines
19
19
  attr_accessor :content
20
20
 
21
- attr_reader :list_index, :table_index, :equation_index, :footnote_index,
21
+ attr_reader :list_index, :table_index, :equation_index,
22
+ :footnote_index, :endnote_index,
22
23
  :numberless_image_index, :image_index, :icon_index, :indepimage_index,
23
24
  :headline_index, :column_index
24
25
 
@@ -56,6 +57,7 @@ module ReVIEW
56
57
  @table_index = @indexes.table_index
57
58
  @equation_index = @indexes.equation_index
58
59
  @footnote_index = @indexes.footnote_index
60
+ @endnote_index = @indexes.endnote_index
59
61
  @headline_index = @indexes.headline_index
60
62
  @column_index = @indexes.column_index
61
63
  if use_bib
@@ -82,6 +84,7 @@ module ReVIEW
82
84
 
83
85
  @title = ''
84
86
  return @title unless content
87
+
85
88
  content.each_line do |line|
86
89
  if line =~ /\A=+/
87
90
  @title = line.sub(/\A=+(\[.+?\])?(\{.+?\})?/, '').strip
@@ -115,10 +118,19 @@ module ReVIEW
115
118
  footnote_index[id]
116
119
  end
117
120
 
121
+ def endnote(id)
122
+ endnote_index[id]
123
+ end
124
+
125
+ def endnotes
126
+ endnote_index
127
+ end
128
+
118
129
  def image(id)
119
130
  return image_index[id] if image_index.key?(id)
120
131
  return icon_index[id] if icon_index.key?(id)
121
132
  return numberless_image_index[id] if numberless_image_index.key?(id)
133
+
122
134
  indepimage_index[id]
123
135
  end
124
136
 
@@ -128,6 +140,7 @@ module ReVIEW
128
140
 
129
141
  def bibpaper_index
130
142
  raise FileNotFound, "no such bib file: #{@book.bib_file}" unless @book.bib_exist?
143
+
131
144
  @book.bibpaper_index
132
145
  end
133
146
 
@@ -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
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2008-2019 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2008-2021 Minero Aoki, Kenshi Muto
2
2
  # 2002-2007 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -125,6 +125,9 @@ module ReVIEW
125
125
  class FootnoteIndex < Index
126
126
  end
127
127
 
128
+ class EndnoteIndex < Index
129
+ end
130
+
128
131
  class ImageIndex < Index
129
132
  def self.item_type
130
133
  '(image|graph|imgtable)'
@@ -189,6 +192,7 @@ module ReVIEW
189
192
  # when notoc
190
193
  return ''
191
194
  end
195
+
192
196
  n = @chapter.number
193
197
  # XXX: remove magic number (move to lib/review/book/chapter.rb)
194
198
  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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2002-2020 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2002-2021 Minero Aoki, Kenshi Muto
2
2
  #
3
3
  # This program is free software.
4
4
  # You can distribute or modify this program under the terms of
@@ -10,6 +10,8 @@ require 'review/exception'
10
10
  require 'review/textutils'
11
11
  require 'review/compiler'
12
12
  require 'review/sec_counter'
13
+ require 'review/img_math'
14
+ require 'review/loggable'
13
15
  require 'stringio'
14
16
  require 'fileutils'
15
17
  require 'tempfile'
@@ -18,6 +20,7 @@ require 'csv'
18
20
  module ReVIEW
19
21
  class Builder
20
22
  include TextUtils
23
+ include Loggable
21
24
 
22
25
  CAPTION_TITLES = Compiler.minicolumn_names
23
26
 
@@ -29,15 +32,17 @@ module ReVIEW
29
32
  nil
30
33
  end
31
34
 
32
- attr_accessor :doc_status, :previous_list_type
35
+ attr_accessor :doc_status
36
+ attr_reader :location
33
37
 
34
- def initialize(strict = false, *_args)
38
+ def initialize(strict = false, *_args, img_math: nil)
35
39
  @strict = strict
36
40
  @output = nil
37
41
  @logger = ReVIEW.logger
38
42
  @doc_status = {}
39
43
  @dictionary = {}
40
- @previous_list_type = nil
44
+ @img_math = img_math
45
+ @shown_endnotes = true
41
46
  end
42
47
 
43
48
  def bind(compiler, chapter, location)
@@ -55,6 +60,7 @@ module ReVIEW
55
60
  @tabwidth = nil
56
61
  @tsize = nil
57
62
  if @book && @book.config
63
+ @img_math ||= ReVIEW::ImgMath.new(@book.config)
58
64
  if words_file_path = @book.config['words_file']
59
65
  if words_file_path.is_a?(String)
60
66
  words_files = [words_file_path]
@@ -73,7 +79,7 @@ module ReVIEW
73
79
  begin
74
80
  require 'unicode/eaw'
75
81
  rescue LoadError
76
- warn 'not found unicode/eaw. disabled join_lines_by_lang feature.'
82
+ warn 'not found unicode/eaw. disabled join_lines_by_lang feature.', location: @location
77
83
  @book.config['join_lines_by_lang'] = nil
78
84
  end
79
85
  end
@@ -98,11 +104,18 @@ module ReVIEW
98
104
 
99
105
  def check_nest
100
106
  if @children && !@children.empty?
101
- error "//beginchild of #{@children.reverse.join(',')} misses //endchild"
107
+ app_error "#{@location}: //beginchild of #{@children.reverse.join(',')} misses //endchild"
108
+ end
109
+ end
110
+
111
+ def check_printendnotes
112
+ if @shown_endnotes.nil?
113
+ app_error "#{@location}: //endnote is found but //printendnotes is not found."
102
114
  end
103
115
  end
104
116
 
105
117
  def result
118
+ check_printendnotes
106
119
  solve_nest(@output.string)
107
120
  end
108
121
 
@@ -145,6 +158,7 @@ module ReVIEW
145
158
 
146
159
  def line_num
147
160
  return 1 unless @first_line_num
161
+
148
162
  line_n = @first_line_num
149
163
  @first_line_num = nil
150
164
 
@@ -157,7 +171,7 @@ module ReVIEW
157
171
  list_body(id, lines, lang)
158
172
  list_header(id, caption, lang) unless caption_top?('list')
159
173
  rescue KeyError
160
- error "no such list: #{id}"
174
+ app_error "no such list: #{id}"
161
175
  end
162
176
  end
163
177
 
@@ -167,7 +181,7 @@ module ReVIEW
167
181
  listnum_body(lines, lang)
168
182
  list_header(id, caption, lang) unless caption_top?('list')
169
183
  rescue KeyError
170
- error "no such list: #{id}"
184
+ app_error "no such list: #{id}"
171
185
  end
172
186
  end
173
187
 
@@ -181,7 +195,7 @@ module ReVIEW
181
195
  if @chapter.image_bound?(id)
182
196
  image_image(id, caption, metric)
183
197
  else
184
- warn "image not bound: #{id}" if @strict
198
+ warn "image not bound: #{id}", location: @location if @strict
185
199
  image_dummy(id, caption, lines)
186
200
  end
187
201
  end
@@ -199,7 +213,7 @@ module ReVIEW
199
213
  table_header(id, caption)
200
214
  end
201
215
  rescue KeyError
202
- error "no such table: #{id}"
216
+ app_error "no such table: #{id}"
203
217
  end
204
218
  end
205
219
 
@@ -214,7 +228,7 @@ module ReVIEW
214
228
  when 'verticalbar'
215
229
  Regexp.new('\s*\\' + escape('|') + '\s*')
216
230
  else
217
- error "Unknown value for 'table_row_separator', shold be: tabs, singletab, spaces, verticalbar"
231
+ app_error "Unknown value for 'table_row_separator', shold be: tabs, singletab, spaces, verticalbar"
218
232
  end
219
233
  end
220
234
 
@@ -229,7 +243,7 @@ module ReVIEW
229
243
  rows.push(line.strip.split(table_row_separator_regexp).map { |s| s.sub(/\A\./, '') })
230
244
  end
231
245
  rows = adjust_n_cols(rows)
232
- error 'no rows in the table' if rows.empty?
246
+ app_error 'no rows in the table' if rows.empty?
233
247
  [sepidx, rows]
234
248
  end
235
249
 
@@ -267,17 +281,28 @@ module ReVIEW
267
281
  table(lines, nil, caption)
268
282
  end
269
283
 
270
- # def footnote(id, str)
271
- # @footnotes.push [id, str]
272
- # end
273
- #
274
- # def flush_footnote
275
- # footnote_begin
276
- # @footnotes.each do |id, str|
277
- # footnote_item(id, str)
278
- # end
279
- # footnote_end
280
- # end
284
+ def printendnotes
285
+ @shown_endnotes = true
286
+ endnote_begin
287
+ @chapter.endnotes.each do |en|
288
+ endnote_item(en.id)
289
+ end
290
+ endnote_end
291
+ end
292
+
293
+ def endnote(_id, _str)
294
+ @shown_endnotes = nil
295
+ end
296
+
297
+ def endnote_begin
298
+ end
299
+
300
+ def endnote_end
301
+ end
302
+
303
+ def endnote_item(id)
304
+ puts "(#{@chapter.endnote(id).number}) #{compile_inline(@chapter.endnote(id).content)}"
305
+ end
281
306
 
282
307
  def blankline
283
308
  puts ''
@@ -290,19 +315,19 @@ module ReVIEW
290
315
  def inline_chapref(id)
291
316
  compile_inline(@book.chapter_index.display_string(id))
292
317
  rescue KeyError
293
- error "unknown chapter: #{id}"
318
+ app_error "unknown chapter: #{id}"
294
319
  end
295
320
 
296
321
  def inline_chap(id)
297
322
  @book.chapter_index.number(id)
298
323
  rescue KeyError
299
- error "unknown chapter: #{id}"
324
+ app_error "unknown chapter: #{id}"
300
325
  end
301
326
 
302
327
  def inline_title(id)
303
328
  compile_inline(@book.chapter_index.title(id))
304
329
  rescue KeyError
305
- error "unknown chapter: #{id}"
330
+ app_error "unknown chapter: #{id}"
306
331
  end
307
332
 
308
333
  def inline_list(id)
@@ -313,7 +338,7 @@ module ReVIEW
313
338
  %Q(#{I18n.t('list')}#{I18n.t('format_number_without_chapter', [chapter.list(id).number])})
314
339
  end
315
340
  rescue KeyError
316
- error "unknown list: #{id}"
341
+ app_error "unknown list: #{id}"
317
342
  end
318
343
 
319
344
  def inline_img(id)
@@ -324,7 +349,7 @@ module ReVIEW
324
349
  %Q(#{I18n.t('image')}#{I18n.t('format_number_without_chapter', [chapter.image(id).number])})
325
350
  end
326
351
  rescue KeyError
327
- error "unknown image: #{id}"
352
+ app_error "unknown image: #{id}"
328
353
  end
329
354
 
330
355
  def inline_imgref(id)
@@ -345,7 +370,7 @@ module ReVIEW
345
370
  %Q(#{I18n.t('table')}#{I18n.t('format_number_without_chapter', [chapter.table(id).number])})
346
371
  end
347
372
  rescue KeyError
348
- error "unknown table: #{id}"
373
+ app_error "unknown table: #{id}"
349
374
  end
350
375
 
351
376
  def inline_eq(id)
@@ -356,13 +381,19 @@ module ReVIEW
356
381
  %Q(#{I18n.t('equation')}#{I18n.t('format_number_without_chapter', [chapter.equation(id).number])})
357
382
  end
358
383
  rescue KeyError
359
- error "unknown equation: #{id}"
384
+ app_error "unknown equation: #{id}"
360
385
  end
361
386
 
362
387
  def inline_fn(id)
363
388
  @chapter.footnote(id).content
364
389
  rescue KeyError
365
- error "unknown footnote: #{id}"
390
+ app_error "unknown footnote: #{id}"
391
+ end
392
+
393
+ def inline_endnote(id)
394
+ "(#{@chapter.endnote(id).number})"
395
+ rescue KeyError
396
+ app_error "unknown endnote: #{id}"
366
397
  end
367
398
 
368
399
  def inline_bou(str)
@@ -418,7 +449,7 @@ module ReVIEW
418
449
  inline_hd_chap(@chapter, id)
419
450
  end
420
451
  rescue KeyError
421
- error "unknown headline: #{id}"
452
+ app_error "unknown headline: #{id}"
422
453
  end
423
454
 
424
455
  def inline_column(id)
@@ -432,7 +463,7 @@ module ReVIEW
432
463
  inline_column_chap(@chapter, id)
433
464
  end
434
465
  rescue KeyError
435
- error "unknown column: #{id}"
466
+ app_error "unknown column: #{id}"
436
467
  end
437
468
 
438
469
  def inline_column_chap(chapter, id)
@@ -456,7 +487,7 @@ module ReVIEW
456
487
  if translated
457
488
  escape(translated)
458
489
  else
459
- warn "word not bound: #{s}"
490
+ warn "word not bound: #{s}", location: @location
460
491
  escape("[missing word: #{s}]")
461
492
  end
462
493
  end
@@ -492,18 +523,6 @@ module ReVIEW
492
523
  end
493
524
  end
494
525
 
495
- def warn(msg)
496
- @logger.warn "#{@location}: #{msg}"
497
- end
498
-
499
- def error(msg)
500
- if msg =~ /:\d+: error: /
501
- raise ApplicationError, msg
502
- else
503
- raise ApplicationError, "#{@location}: error: #{msg}"
504
- end
505
- end
506
-
507
526
  def handle_metric(str)
508
527
  str
509
528
  end
@@ -514,11 +533,13 @@ module ReVIEW
514
533
 
515
534
  def parse_metric(type, metric)
516
535
  return '' if metric.blank?
536
+
517
537
  params = metric.split(/,\s*/)
518
538
  results = []
519
539
  params.each do |param|
520
540
  if param =~ /\A.+?::/
521
541
  next unless param =~ /\A#{type}::/
542
+
522
543
  param.sub!(/\A#{type}::/, '')
523
544
  end
524
545
  param2 = handle_metric(param)
@@ -543,6 +564,7 @@ module ReVIEW
543
564
  if m
544
565
  ch = @book.contents.detect { |chap| chap.id == m[1] }
545
566
  raise KeyError unless ch
567
+
546
568
  return [ch, m[2]]
547
569
  end
548
570
  [@chapter, chap_ref]
@@ -575,7 +597,7 @@ module ReVIEW
575
597
 
576
598
  def check_nested_minicolumn
577
599
  if @doc_status[:minicolumn]
578
- error "#{@location}: nested mini-column is not allowed"
600
+ app_error "#{@location}: nested mini-column is not allowed"
579
601
  end
580
602
  end
581
603
 
@@ -647,7 +669,17 @@ EOTGNUPLOT
647
669
  ext = 'eps'
648
670
  file_path.sub!(/\.pdf\Z/, '.eps')
649
671
  end
650
- system_graph(id, 'java', '-jar', 'plantuml.jar', "-t#{ext}", '-charset', 'UTF-8', tf_path)
672
+ plant_path = nil
673
+ if File.exist?('plantuml.jar')
674
+ plant_path = 'plantuml.jar'
675
+ elsif File.exist?('/usr/share/plantuml/plantuml.jar')
676
+ plant_path = '/usr/share/plantuml/plantuml.jar'
677
+ elsif File.exist?('/usr/share/java/plantuml.jar')
678
+ plant_path = '/usr/share/java/plantuml.jar'
679
+ else
680
+ error!('missing plantuml.jar. Please put plantuml.jar at the working folder.')
681
+ end
682
+ system_graph(id, 'java', '-jar', plant_path, "-t#{ext}", '-charset', 'UTF-8', tf_path)
651
683
  FileUtils.mv("#{tf_path}.#{ext}", file_path)
652
684
  file_path
653
685
  end
@@ -725,18 +757,22 @@ EOTGNUPLOT
725
757
  str
726
758
  end
727
759
 
760
+ def previous_list_type
761
+ @compiler.previous_list_type
762
+ end
763
+
728
764
  def beginchild
729
765
  @children ||= []
730
- unless @previous_list_type
731
- error "//beginchild is shown, but previous element isn't ul, ol, or dl"
766
+ unless previous_list_type
767
+ app_error "#{@location}: //beginchild is shown, but previous element isn't ul, ol, or dl"
732
768
  end
733
- puts "\x01→#{@previous_list_type}←\x01"
734
- @children.push(@previous_list_type)
769
+ puts "\x01→#{previous_list_type}←\x01"
770
+ @children.push(previous_list_type)
735
771
  end
736
772
 
737
773
  def endchild
738
774
  if @children.nil? || @children.empty?
739
- error "//endchild is shown, but any opened //beginchild doesn't exist"
775
+ app_error "#{@location}: //endchild is shown, but any opened //beginchild doesn't exist"
740
776
  else
741
777
  puts "\x01→/#{@children.pop}←\x01"
742
778
  end
@@ -744,7 +780,7 @@ EOTGNUPLOT
744
780
 
745
781
  def caption_top?(type)
746
782
  unless %w[top bottom].include?(@book.config['caption_position'][type])
747
- warn("invalid caption_position/#{type} parameter. 'top' is assumed")
783
+ warn "invalid caption_position/#{type} parameter. 'top' is assumed", location: @location
748
784
  end
749
785
  @book.config['caption_position'][type] != 'bottom'
750
786
  end
@@ -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
@@ -1,4 +1,5 @@
1
1
  require 'yaml'
2
+ require 'date'
2
3
 
3
4
  module ReVIEW
4
5
  class Catalog
@@ -50,6 +51,7 @@ module ReVIEW
50
51
 
51
52
  def parts_with_chaps
52
53
  return [] unless @yaml['CHAPS']
54
+
53
55
  @yaml['CHAPS'].flatten.compact
54
56
  end
55
57