review 4.2.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-win.yml +11 -5
  3. data/.rubocop.yml +113 -24
  4. data/NEWS.ja.md +94 -0
  5. data/NEWS.md +94 -0
  6. data/bin/review-catalog-converter +1 -1
  7. data/bin/review-check +2 -4
  8. data/bin/review-checkdep +1 -1
  9. data/bin/review-compile +8 -14
  10. data/bin/review-validate +1 -1
  11. data/doc/config.yml.sample +4 -1
  12. data/doc/config.yml.sample-simple +1 -1
  13. data/doc/format.ja.md +83 -4
  14. data/doc/format.md +84 -7
  15. data/doc/makeindex.ja.md +2 -2
  16. data/doc/quickstart.ja.md +3 -3
  17. data/doc/quickstart.md +2 -2
  18. data/lib/epubmaker/content.rb +3 -2
  19. data/lib/epubmaker/epubcommon.rb +33 -25
  20. data/lib/epubmaker/epubv2.rb +5 -6
  21. data/lib/epubmaker/epubv3.rb +20 -18
  22. data/lib/review/book.rb +2 -2
  23. data/lib/review/book/base.rb +61 -25
  24. data/lib/review/book/bib.rb +21 -0
  25. data/lib/review/book/book_unit.rb +155 -0
  26. data/lib/review/book/chapter.rb +30 -26
  27. data/lib/review/book/index.rb +23 -185
  28. data/lib/review/book/index/item.rb +7 -1
  29. data/lib/review/book/part.rb +21 -9
  30. data/lib/review/book/volume.rb +1 -1
  31. data/lib/review/builder.rb +68 -13
  32. data/lib/review/catalog.rb +2 -2
  33. data/lib/review/compiler.rb +159 -73
  34. data/lib/review/configure.rb +22 -1
  35. data/lib/review/converter.rb +1 -1
  36. data/lib/review/epub2html.rb +6 -1
  37. data/lib/review/epubmaker.rb +12 -23
  38. data/lib/review/htmlbuilder.rb +36 -7
  39. data/lib/review/htmlutils.rb +7 -10
  40. data/lib/review/i18n.rb +1 -1
  41. data/lib/review/idgxmlbuilder.rb +51 -6
  42. data/lib/review/idgxmlmaker.rb +9 -14
  43. data/lib/review/index_builder.rb +653 -0
  44. data/lib/review/init.rb +5 -13
  45. data/lib/review/latexbuilder.rb +65 -4
  46. data/lib/review/logger.rb +2 -2
  47. data/lib/review/makerhelper.rb +11 -0
  48. data/lib/review/markdownbuilder.rb +19 -1
  49. data/lib/review/pdfmaker.rb +17 -36
  50. data/lib/review/plaintextbuilder.rb +48 -2
  51. data/lib/review/preprocessor.rb +5 -5
  52. data/lib/review/rstbuilder.rb +25 -6
  53. data/lib/review/sec_counter.rb +13 -0
  54. data/lib/review/textmaker.rb +4 -12
  55. data/lib/review/tocprinter.rb +2 -3
  56. data/lib/review/topbuilder.rb +26 -0
  57. data/lib/review/update.rb +7 -7
  58. data/lib/review/version.rb +1 -1
  59. data/lib/review/volumeprinter.rb +2 -3
  60. data/lib/review/webmaker.rb +9 -20
  61. data/review.gemspec +2 -2
  62. data/samples/sample-book/src/config.yml +1 -1
  63. data/samples/syntax-book/Gemfile +1 -1
  64. data/samples/syntax-book/config.yml +1 -1
  65. data/templates/latex/config.erb +27 -23
  66. data/templates/latex/review-jlreq/README.md +3 -1
  67. data/templates/latex/review-jlreq/review-base.sty +31 -15
  68. data/templates/latex/review-jlreq/review-jlreq.cls +8 -24
  69. data/templates/latex/review-jsbook/README.md +7 -5
  70. data/templates/latex/review-jsbook/review-base.sty +34 -16
  71. data/templates/latex/review-jsbook/review-jsbook.cls +4 -2
  72. data/templates/web/html/layout-html5.html.erb +1 -1
  73. data/test/assets/test_template.tex +3 -3
  74. data/test/assets/test_template_backmatter.tex +3 -3
  75. data/test/book_test_helper.rb +11 -5
  76. data/test/test_book.rb +54 -63
  77. data/test/test_book_chapter.rb +93 -52
  78. data/test/test_builder.rb +24 -15
  79. data/test/test_converter.rb +1 -0
  80. data/test/test_epub3maker.rb +2 -2
  81. data/test/test_epubmaker.rb +8 -0
  82. data/test/test_helper.rb +4 -1
  83. data/test/test_htmlbuilder.rb +627 -56
  84. data/test/test_htmlutils.rb +0 -12
  85. data/test/test_i18n.rb +33 -33
  86. data/test/test_idgxmlbuilder.rb +358 -11
  87. data/test/test_idgxmlmaker_cmd.rb +1 -1
  88. data/test/test_index.rb +62 -52
  89. data/test/test_indexbuilder.rb +52 -0
  90. data/test/test_latexbuilder.rb +547 -10
  91. data/test/test_latexbuilder_v2.rb +43 -5
  92. data/test/test_logger.rb +7 -7
  93. data/test/test_makerhelper.rb +0 -12
  94. data/test/test_markdownbuilder.rb +3 -0
  95. data/test/test_pdfmaker.rb +13 -12
  96. data/test/test_pdfmaker_cmd.rb +1 -1
  97. data/test/test_plaintextbuilder.rb +422 -7
  98. data/test/test_review_ext.rb +2 -1
  99. data/test/test_rstbuilder.rb +25 -1
  100. data/test/test_sec_counter.rb +156 -0
  101. data/test/test_textmaker_cmd.rb +1 -1
  102. data/test/test_topbuilder.rb +187 -10
  103. data/test/test_update.rb +10 -10
  104. data/test/test_webtocprinter.rb +12 -12
  105. data/vendor/gentombow/LICENSE +1 -1
  106. data/vendor/gentombow/Makefile +0 -1
  107. data/vendor/gentombow/bounddvi-en.pdf +0 -0
  108. data/vendor/gentombow/bounddvi-en.tex +1 -0
  109. data/vendor/gentombow/bounddvi.pdf +0 -0
  110. data/vendor/gentombow/bounddvi.sty +30 -7
  111. data/vendor/gentombow/bounddvi.tex +1 -0
  112. data/vendor/gentombow/create_archive.sh +1 -0
  113. data/vendor/gentombow/gentombow-ja.pdf +0 -0
  114. data/vendor/gentombow/gentombow-ja.tex +9 -0
  115. data/vendor/gentombow/gentombow.pdf +0 -0
  116. data/vendor/gentombow/gentombow.sty +32 -10
  117. data/vendor/gentombow/gentombow.tex +8 -0
  118. data/vendor/gentombow/tests/gentombow-01-pdfx.tex +8 -0
  119. data/vendor/gentombow/tests/gentombow-02-pdfx.tex +8 -0
  120. data/vendor/jsclasses/Makefile +3 -2
  121. data/vendor/jsclasses/create_archive.sh +5 -5
  122. data/vendor/jsclasses/jis/Makefile +3 -2
  123. data/vendor/jsclasses/jis/jsarticle.cls +22 -18
  124. data/vendor/jsclasses/jis/jsbook.cls +22 -18
  125. data/vendor/jsclasses/jis/jsclasses.dtx +94 -13
  126. data/vendor/jsclasses/jis/jsclasses.ins +15 -5
  127. data/vendor/jsclasses/jis/jslogo.ins +9 -0
  128. data/vendor/jsclasses/jis/jslogo.sty +1 -13
  129. data/vendor/jsclasses/jis/jspf.cls +22 -18
  130. data/vendor/jsclasses/jis/jsreport.cls +22 -18
  131. data/vendor/jsclasses/jis/jsverb.ins +9 -0
  132. data/vendor/jsclasses/jis/jsverb.sty +1 -13
  133. data/vendor/jsclasses/jis/kiyou.cls +22 -18
  134. data/vendor/jsclasses/jis/minijs.sty +65 -22
  135. data/vendor/jsclasses/jis/okumacro.ins +9 -0
  136. data/vendor/jsclasses/jis/okumacro.sty +1 -13
  137. data/vendor/jsclasses/jis/okuverb.ins +9 -0
  138. data/vendor/jsclasses/jis/okuverb.sty +1 -13
  139. data/vendor/jsclasses/jis/winjis.sty +23 -19
  140. data/vendor/jsclasses/jsarticle.cls +22 -18
  141. data/vendor/jsclasses/jsbook.cls +22 -18
  142. data/vendor/jsclasses/jsclasses.dtx +94 -13
  143. data/vendor/jsclasses/jsclasses.ins +15 -5
  144. data/vendor/jsclasses/jsclasses.pdf +0 -0
  145. data/vendor/jsclasses/jslogo.ins +9 -0
  146. data/vendor/jsclasses/jslogo.pdf +0 -0
  147. data/vendor/jsclasses/jslogo.sty +1 -13
  148. data/vendor/jsclasses/jspf.cls +22 -18
  149. data/vendor/jsclasses/jsreport.cls +22 -18
  150. data/vendor/jsclasses/jsverb.ins +9 -0
  151. data/vendor/jsclasses/jsverb.pdf +0 -0
  152. data/vendor/jsclasses/jsverb.sty +1 -13
  153. data/vendor/jsclasses/kiyou.cls +22 -18
  154. data/vendor/jsclasses/minijs.sty +68 -22
  155. data/vendor/jsclasses/okumacro.ins +9 -0
  156. data/vendor/jsclasses/okumacro.pdf +0 -0
  157. data/vendor/jsclasses/okumacro.sty +1 -13
  158. data/vendor/jsclasses/okuverb.ins +9 -0
  159. data/vendor/jsclasses/okuverb.pdf +0 -0
  160. data/vendor/jsclasses/okuverb.sty +1 -13
  161. data/vendor/jsclasses/tests/relfont.tex +10 -0
  162. data/vendor/jsclasses/winjis.sty +23 -19
  163. metadata +14 -6
  164. data/.rubocop_todo.yml +0 -7
  165. data/lib/review/book/compilable.rb +0 -174
@@ -114,9 +114,7 @@ module ReVIEW
114
114
  exit 1
115
115
  end
116
116
 
117
- initdir = File.expand_path(args[0])
118
-
119
- initdir
117
+ File.expand_path(args[0])
120
118
  end
121
119
 
122
120
  def generate_dir(dir)
@@ -135,8 +133,7 @@ module ReVIEW
135
133
  end
136
134
 
137
135
  def generate_catalog_file(dir)
138
- File.open(File.join(dir, 'catalog.yml'), 'w') do |file|
139
- file.write <<-EOS
136
+ File.write(File.join(dir, 'catalog.yml'), <<-EOS)
140
137
  PREDEF:
141
138
 
142
139
  CHAPS:
@@ -147,7 +144,6 @@ APPENDIX:
147
144
  POSTDEF:
148
145
 
149
146
  EOS
150
- end
151
147
  end
152
148
 
153
149
  def generate_images_dir(dir)
@@ -223,13 +219,11 @@ EOT
223
219
  def generate_rakefile(dir)
224
220
  FileUtils.mkdir_p(File.join(dir, 'lib/tasks'))
225
221
 
226
- File.open(File.join(dir, 'Rakefile'), 'w') do |file|
227
- file.write <<-EOS
222
+ File.write(File.join(dir, 'Rakefile'), <<-EOS)
228
223
  Dir.glob('lib/tasks/*.rake').sort.each do |file|
229
224
  load(file)
230
225
  end
231
226
  EOS
232
- end
233
227
 
234
228
  FileUtils.cp(File.join(@review_dir, 'samples/sample-book/src/lib/tasks/review.rake'),
235
229
  File.join(dir, 'lib/tasks/review.rake'))
@@ -240,14 +234,12 @@ EOS
240
234
  end
241
235
 
242
236
  def generate_gemfile(dir)
243
- File.open(File.join(dir, 'Gemfile'), 'w') do |file|
244
- file.write <<-EOS
237
+ File.write(File.join(dir, 'Gemfile'), <<-EOS)
245
238
  source 'https://rubygems.org'
246
239
 
247
240
  gem 'rake'
248
241
  gem 'review', '#{ReVIEW::VERSION}'
249
242
  EOS
250
- end
251
243
  end
252
244
 
253
245
  def generate_doc(dir)
@@ -342,7 +334,7 @@ EOS
342
334
  # validation
343
335
  if @web_result
344
336
  @web_result.each do |s|
345
- if s !~ /\A[a-z0-9=_,\.-]*\Z/i
337
+ if s !~ /\A[a-z0-9=_,.-]*\Z/i
346
338
  @web_result = nil
347
339
  break
348
340
  end
@@ -100,7 +100,21 @@ module ReVIEW
100
100
  if @chapter.is_a?(ReVIEW::Book::Part) && !@book.config.check_version('2', exception: false)
101
101
  puts '\end{reviewpart}'
102
102
  end
103
- @output.string
103
+ solve_nest(@output.string)
104
+ end
105
+
106
+ def solve_nest(s)
107
+ check_nest
108
+ s.gsub("\\end{description}\n\n\x01→dl←\x01\n", "\n").
109
+ gsub("\x01→/dl←\x01", "\\end{description}←END\x01").
110
+ gsub("\\end{itemize}\n\n\x01→ul←\x01\n", "\n").
111
+ gsub("\x01→/ul←\x01", "\\end{itemize}←END\x01").
112
+ gsub("\\end{enumerate}\n\n\x01→ol←\x01\n", "\n").
113
+ gsub("\x01→/ol←\x01", "\\end{enumerate}←END\x01").
114
+ gsub("\\end{description}←END\x01\n\n\\begin{description}", '').
115
+ gsub("\\end{itemize}←END\x01\n\n\\begin{itemize}", '').
116
+ gsub("\\end{enumerate}←END\x01\n\n\\begin{enumerate}", '').
117
+ gsub("←END\x01", '')
104
118
  end
105
119
 
106
120
  HEADLINE = {
@@ -212,7 +226,53 @@ module ReVIEW
212
226
  @doc_status[:column] = nil
213
227
  end
214
228
 
229
+ def common_block_begin(type, caption = nil)
230
+ check_nested_minicolumn
231
+ if @book.config.check_version('2', exception: false)
232
+ type = 'minicolumn'
233
+ end
234
+
235
+ @doc_status[:minicolumn] = type
236
+ print "\\begin{review#{type}}"
237
+
238
+ @doc_status[:caption] = true
239
+ if @book.config.check_version('2', exception: false)
240
+ puts
241
+ if caption.present?
242
+ puts "\\reviewminicolumntitle{#{compile_inline(caption)}}"
243
+ end
244
+ else
245
+ if caption.present?
246
+ print "[#{compile_inline(caption)}]"
247
+ end
248
+ puts
249
+ end
250
+ @doc_status[:caption] = nil
251
+ end
252
+
253
+ def common_block_end(type)
254
+ if @book.config.check_version('2', exception: false)
255
+ type = 'minicolumn'
256
+ end
257
+
258
+ puts "\\end{review#{type}}"
259
+ @doc_status[:minicolumn] = nil
260
+ end
261
+
262
+ CAPTION_TITLES.each do |name|
263
+ class_eval %Q(
264
+ def #{name}_begin(caption = nil)
265
+ common_block_begin('#{name}', caption)
266
+ end
267
+
268
+ def #{name}_end
269
+ common_block_end('#{name}')
270
+ end
271
+ ), __FILE__, __LINE__ - 8
272
+ end
273
+
215
274
  def captionblock(type, lines, caption)
275
+ check_nested_minicolumn
216
276
  if @book.config.check_version('2', exception: false)
217
277
  type = 'minicolumn'
218
278
  end
@@ -599,7 +659,8 @@ module ReVIEW
599
659
  end
600
660
  private :bib_label
601
661
 
602
- def column_label(id, chapter = @chapter)
662
+ def column_label(id, chapter = nil)
663
+ chapter ||= @chapter
603
664
  filename = chapter.id
604
665
  num = chapter.column(id).number
605
666
  "column:#{filename}:#{num}"
@@ -637,7 +698,7 @@ module ReVIEW
637
698
  else
638
699
  warn "image not bound: #{id}"
639
700
  puts '\begin{reviewdummyimage}'
640
- puts "--[[path = #{id} (#{existence(id)})]]--"
701
+ puts "--[[path = #{escape(id)} (#{existence(id)})]]--"
641
702
  lines.each do |line|
642
703
  puts detab(line.rstrip)
643
704
  end
@@ -1217,7 +1278,7 @@ module ReVIEW
1217
1278
  error "unknown column: #{id}"
1218
1279
  end
1219
1280
 
1220
- def inline_raw(str)
1281
+ def inline_raw(str) # rubocop:disable Lint/UselessMethodDefinition
1221
1282
  super(str)
1222
1283
  end
1223
1284
 
@@ -2,14 +2,14 @@ require 'logger'
2
2
 
3
3
  module ReVIEW
4
4
  class Logger < ::Logger
5
- def initialize(io = STDERR, progname: '--')
5
+ def initialize(io = $stderr, progname: '--')
6
6
  super(io, progname: progname)
7
7
  self.formatter = ->(severity, _datetime, name, msg) { "#{severity} #{name}: #{msg}\n" }
8
8
  end
9
9
  end
10
10
 
11
11
  def self.logger
12
- @logger ||= ReVIEW::Logger.new(STDERR, progname: File.basename($PROGRAM_NAME, '.*'))
12
+ @logger ||= ReVIEW::Logger.new($stderr, progname: File.basename($PROGRAM_NAME, '.*'))
13
13
  end
14
14
 
15
15
  def self.logger=(logger)
@@ -10,6 +10,12 @@ require 'fileutils'
10
10
  require 'yaml'
11
11
  require 'shellwords'
12
12
 
13
+ begin
14
+ require 'cgi/escape'
15
+ rescue
16
+ require 'cgi/util'
17
+ end
18
+
13
19
  module ReVIEW
14
20
  module MakerHelper
15
21
  # Return review/bin directory
@@ -18,6 +24,11 @@ module ReVIEW
18
24
  end
19
25
  module_function :bindir
20
26
 
27
+ def h(str)
28
+ CGI.escapeHTML(str)
29
+ end
30
+ module_function :h
31
+
21
32
  # Copy image files under from_dir to to_dir recursively
22
33
  # ==== Args
23
34
  # from_dir :: path to the directory which has image files to be copied
@@ -155,10 +155,28 @@ module ReVIEW
155
155
  puts %Q(<div class="#{type}">)
156
156
  puts %Q(<p class="caption">#{compile_inline(caption)}</p>) if caption.present?
157
157
  blocked_lines = split_paragraph(lines)
158
- puts blocked_lines.join("\n")
158
+ puts blocked_lines.join("\n\n")
159
159
  puts '</div>'
160
160
  end
161
161
 
162
+ CAPTION_TITLES.each do |name|
163
+ class_eval %Q(
164
+ def #{name}_begin(caption = nil)
165
+ check_nested_minicolumn
166
+ @doc_status[:minicolumn] = '#{name}'
167
+ puts %Q(<div class="#{name}">)
168
+ if caption.present?
169
+ puts %Q(<p class="caption">\#{compile_inline(caption)}</p>)
170
+ end
171
+ end
172
+
173
+ def #{name}_end
174
+ puts '</div>'
175
+ @doc_status[:minicolumn] = nil
176
+ end
177
+ ), __FILE__, __LINE__ - 14
178
+ end
179
+
162
180
  def hr
163
181
  puts '----'
164
182
  end
@@ -122,20 +122,13 @@ module ReVIEW
122
122
  end
123
123
 
124
124
  def execute(*args)
125
- @config = ReVIEW::Configure.values
126
- @config.maker = 'pdfmaker'
127
125
  cmd_config, yamlfile = parse_opts(args)
128
126
  error "#{yamlfile} not found." unless File.exist?(yamlfile)
129
127
 
130
- begin
131
- loader = ReVIEW::YAMLLoader.new
132
- @config.deep_merge!(loader.load_file(yamlfile))
133
- rescue => e
134
- error "yaml error #{e.message}"
135
- end
128
+ @config = ReVIEW::Configure.create(maker: 'pdfmaker',
129
+ yamlfile: yamlfile,
130
+ config: cmd_config)
136
131
 
137
- # YAML configs will be overridden by command line options.
138
- @config.deep_merge!(cmd_config)
139
132
  I18n.setup(@config['language'])
140
133
  @basedir = File.absolute_path(File.dirname(yamlfile))
141
134
 
@@ -272,8 +265,7 @@ module ReVIEW
272
265
  begin
273
266
  @compile_errors = nil
274
267
 
275
- book = ReVIEW::Book.load(@basedir)
276
- book.config = @config
268
+ book = ReVIEW::Book::Base.new(@basedir, config: @config)
277
269
  @converter = ReVIEW::Converter.new(book, ReVIEW::LATEXBuilder.new)
278
270
 
279
271
  @input_files = make_input_files(book)
@@ -311,23 +303,12 @@ module ReVIEW
311
303
  end
312
304
  end
313
305
 
314
- # PDFMaker#copy_images should copy image files _AND_ execute extractbb (or ebb).
306
+ # PDFMaker#copy_images should copy image files
315
307
  #
316
308
  def copy_images(from, to)
317
309
  return unless File.exist?(from)
318
310
  Dir.mkdir(to)
319
311
  ReVIEW::MakerHelper.copy_images_to_dir(from, to)
320
- Dir.chdir(to) do
321
- images = Dir.glob('**/*').find_all { |f| File.file?(f) and f =~ /\.(jpg|jpeg|png|pdf|ai|eps|tif)\z/i }
322
- break if images.empty?
323
- if @config['pdfmaker']['bbox']
324
- system_with_info('extractbb', '-B', @config['pdfmaker']['bbox'], *images)
325
- system_or_raise('ebb', '-B', @config['pdfmaker']['bbox'], *images) unless system('extractbb', '-B', @config['pdfmaker']['bbox'], '-m', *images)
326
- else
327
- system_with_info('extractbb', *images)
328
- system_or_raise('ebb', *images) unless system('extractbb', '-m', *images)
329
- end
330
- end
331
312
  end
332
313
 
333
314
  def make_custom_page(file)
@@ -385,11 +366,11 @@ module ReVIEW
385
366
  items.each_with_index do |item, rev|
386
367
  editstr = edit == 0 ? ReVIEW::I18n.t('first_edition') : ReVIEW::I18n.t('nth_edition', (edit + 1).to_s)
387
368
  revstr = ReVIEW::I18n.t('nth_impression', (rev + 1).to_s)
388
- if item =~ /\A\d+\-\d+\-\d+\Z/
369
+ if item =~ /\A\d+-\d+-\d+\Z/
389
370
  buf << ReVIEW::I18n.t('published_by1', [date_to_s(item), editstr + revstr])
390
- elsif item =~ /\A(\d+\-\d+\-\d+)[\s ](.+)/
371
+ elsif item =~ /\A(\d+-\d+-\d+)[\s ](.+)/
391
372
  # custom date with string
392
- item.match(/\A(\d+\-\d+\-\d+)[\s ](.+)/) { |m| buf << ReVIEW::I18n.t('published_by3', [date_to_s(m[1]), m[2]]) }
373
+ item.match(/\A(\d+-\d+-\d+)[\s ](.+)/) { |m| buf << ReVIEW::I18n.t('published_by3', [date_to_s(m[1]), m[2]]) }
393
374
  else
394
375
  # free format
395
376
  buf << item
@@ -455,15 +436,15 @@ module ReVIEW
455
436
  end
456
437
 
457
438
  @locale_latex = {}
458
- part_tuple = I18n.get('part').split(/\%[A-Za-z]{1,3}/, 2)
459
- chapter_tuple = I18n.get('chapter').split(/\%[A-Za-z]{1,3}/, 2)
460
- appendix_tuple = I18n.get('appendix').split(/\%[A-Za-z]{1,3}/, 2)
461
- @locale_latex['prepartname'] = part_tuple[0]
462
- @locale_latex['postpartname'] = part_tuple[1]
463
- @locale_latex['prechaptername'] = chapter_tuple[0]
464
- @locale_latex['postchaptername'] = chapter_tuple[1]
465
- @locale_latex['preappendixname'] = appendix_tuple[0]
466
- @locale_latex['postappendixname'] = appendix_tuple[1]
439
+ part_tuple = I18n.get('part').split(/%[A-Za-z]{1,3}/, 2)
440
+ chapter_tuple = I18n.get('chapter').split(/%[A-Za-z]{1,3}/, 2)
441
+ appendix_tuple = I18n.get('appendix').split(/%[A-Za-z]{1,3}/, 2)
442
+ @locale_latex['prepartname'] = part_tuple[0].to_s
443
+ @locale_latex['postpartname'] = part_tuple[1].to_s
444
+ @locale_latex['prechaptername'] = chapter_tuple[0].to_s
445
+ @locale_latex['postchaptername'] = chapter_tuple[1].to_s
446
+ @locale_latex['preappendixname'] = appendix_tuple[0].to_s
447
+ @locale_latex['postappendixname'] = appendix_tuple[1].to_s
467
448
  end
468
449
 
469
450
  def erb_content(file)
@@ -74,7 +74,26 @@ module ReVIEW
74
74
  private :blank
75
75
 
76
76
  def result
77
- @output.string
77
+ solve_nest(@output.string)
78
+ end
79
+
80
+ def solve_nest(s)
81
+ check_nest
82
+ lines = []
83
+ clevel = []
84
+ s.split("\n", -1).each do |l| # -1 means don't omit last "\n"
85
+ if l =~ /\A\x01→(dl|ul|ol)←\x01/
86
+ clevel.push($1)
87
+ lines.push("\x01→END←\x01")
88
+ elsif l =~ %r{\A\x01→/(dl|ul|ol)←\x01}
89
+ clevel.pop
90
+ lines.push("\x01→END←\x01")
91
+ else
92
+ lines.push("\t" * clevel.size + l)
93
+ end
94
+ end
95
+
96
+ lines.join("\n").gsub(/\n*\x01→END←\x01\n*/, "\n")
78
97
  end
79
98
 
80
99
  def headline(level, _label, caption)
@@ -501,18 +520,22 @@ module ReVIEW
501
520
  end
502
521
 
503
522
  def note(lines, caption = nil)
523
+ check_nested_minicolumn
504
524
  base_parablock('note', lines, caption)
505
525
  end
506
526
 
507
527
  def memo(lines, caption = nil)
528
+ check_nested_minicolumn
508
529
  base_parablock('memo', lines, caption)
509
530
  end
510
531
 
511
532
  def tip(lines, caption = nil)
533
+ check_nested_minicolumn
512
534
  base_parablock('tip', lines, caption)
513
535
  end
514
536
 
515
537
  def info(lines, caption = nil)
538
+ check_nested_minicolumn
516
539
  base_parablock('info', lines, caption)
517
540
  end
518
541
 
@@ -521,10 +544,12 @@ module ReVIEW
521
544
  end
522
545
 
523
546
  def best(lines, caption = nil)
547
+ check_nested_minicolumn
524
548
  base_parablock('best', lines, caption)
525
549
  end
526
550
 
527
551
  def important(lines, caption = nil)
552
+ check_nested_minicolumn
528
553
  base_parablock('important', lines, caption)
529
554
  end
530
555
 
@@ -533,6 +558,7 @@ module ReVIEW
533
558
  end
534
559
 
535
560
  def caution(lines, caption = nil)
561
+ check_nested_minicolumn
536
562
  base_parablock('caution', lines, caption)
537
563
  end
538
564
 
@@ -545,6 +571,7 @@ module ReVIEW
545
571
  end
546
572
 
547
573
  def notice(lines, caption = nil)
574
+ check_nested_minicolumn
548
575
  base_parablock('notice', lines, caption)
549
576
  end
550
577
 
@@ -573,11 +600,30 @@ module ReVIEW
573
600
  end
574
601
 
575
602
  def warning(lines, caption = nil)
603
+ check_nested_minicolumn
576
604
  base_parablock('warning', lines, caption)
577
605
  end
578
606
 
579
607
  alias_method :box, :insn
580
608
 
609
+ CAPTION_TITLES.each do |name|
610
+ class_eval %Q(
611
+ def #{name}_begin(caption = nil)
612
+ check_nested_minicolumn
613
+ @doc_status[:minicolumn] = '#{name}'
614
+ blank
615
+ if caption.present?
616
+ puts compile_inline(caption)
617
+ end
618
+ end
619
+
620
+ def #{name}_end
621
+ blank
622
+ @doc_status[:minicolumn] = nil
623
+ end
624
+ ), __FILE__, __LINE__ - 14
625
+ end
626
+
581
627
  def indepimage(_lines, _id, caption = nil, _metric = nil)
582
628
  blank
583
629
  puts "図 #{compile_inline(caption)}" if caption.present?
@@ -613,7 +659,7 @@ module ReVIEW
613
659
  str
614
660
  end
615
661
 
616
- def inline_chap(id)
662
+ def inline_chap(id) # rubocop:disable Lint/UselessMethodDefinition
617
663
  # "「第#{super}章 #{inline_title(id)}」"
618
664
  # "第#{super}章"
619
665
  super