review 5.1.1 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +6 -2
  3. data/.github/workflows/ruby-win.yml +6 -2
  4. data/.github/workflows/ruby.yml +6 -2
  5. data/.rubocop.yml +5 -319
  6. data/NEWS.ja.md +149 -0
  7. data/NEWS.md +149 -1
  8. data/README.md +9 -8
  9. data/bin/review +1 -1
  10. data/bin/review-catalog-converter +15 -15
  11. data/bin/review-check +7 -7
  12. data/bin/review-compile +14 -23
  13. data/bin/review-index +1 -1
  14. data/bin/review-preproc +29 -35
  15. data/bin/review-validate +2 -2
  16. data/doc/config.yml.sample +9 -1
  17. data/doc/config.yml.sample-simple +1 -1
  18. data/doc/format.ja.md +29 -3
  19. data/doc/format.md +32 -3
  20. data/doc/writing_vertical.ja.md +6 -0
  21. data/lib/review/book/base.rb +3 -3
  22. data/lib/review/book/book_unit.rb +13 -3
  23. data/lib/review/book/chapter.rb +1 -1
  24. data/lib/review/book/index.rb +7 -4
  25. data/lib/review/book/part.rb +12 -13
  26. data/lib/review/book/volume.rb +1 -1
  27. data/lib/review/builder.rb +92 -65
  28. data/lib/review/catalog.rb +6 -5
  29. data/lib/review/compiler.rb +76 -57
  30. data/lib/review/configure.rb +5 -2
  31. data/lib/review/epub2html.rb +12 -12
  32. data/lib/review/epubmaker/content.rb +1 -1
  33. data/lib/review/epubmaker/epubcommon.rb +47 -45
  34. data/lib/review/epubmaker/epubv2.rb +2 -1
  35. data/lib/review/epubmaker/epubv3.rb +5 -4
  36. data/lib/review/epubmaker/producer.rb +6 -7
  37. data/lib/review/epubmaker/reviewheaderlistener.rb +1 -1
  38. data/lib/review/epubmaker.rb +56 -67
  39. data/lib/review/exception.rb +7 -0
  40. data/lib/review/extentions/string.rb +1 -1
  41. data/lib/review/htmlbuilder.rb +90 -34
  42. data/lib/review/htmlutils.rb +17 -17
  43. data/lib/review/i18n.rb +3 -3
  44. data/lib/review/i18n.yml +6 -0
  45. data/lib/review/idgxmlbuilder.rb +61 -39
  46. data/lib/review/idgxmlmaker.rb +27 -26
  47. data/lib/review/img_math.rb +12 -18
  48. data/lib/review/index_builder.rb +94 -53
  49. data/lib/review/init.rb +4 -4
  50. data/lib/review/latexbuilder.rb +84 -76
  51. data/lib/review/lineinput.rb +3 -3
  52. data/lib/review/location.rb +1 -1
  53. data/lib/review/loggable.rb +27 -0
  54. data/lib/review/logger.rb +69 -21
  55. data/lib/review/makerhelper.rb +8 -4
  56. data/lib/review/markdownbuilder.rb +21 -12
  57. data/lib/review/pdfmaker.rb +63 -42
  58. data/lib/review/plaintextbuilder.rb +16 -15
  59. data/lib/review/preprocessor/directive.rb +35 -0
  60. data/lib/review/preprocessor/line.rb +34 -0
  61. data/lib/review/preprocessor/repository.rb +177 -0
  62. data/lib/review/preprocessor.rb +94 -296
  63. data/lib/review/rstbuilder.rb +12 -3
  64. data/lib/review/template.rb +5 -1
  65. data/lib/review/textmaker.rb +32 -31
  66. data/lib/review/textutils.rb +5 -6
  67. data/lib/review/tocprinter.rb +12 -7
  68. data/lib/review/topbuilder.rb +96 -19
  69. data/lib/review/update.rb +16 -8
  70. data/lib/review/version.rb +1 -1
  71. data/lib/review/volumeprinter.rb +9 -9
  72. data/lib/review/webmaker.rb +45 -46
  73. data/lib/review/webtocprinter.rb +10 -10
  74. data/lib/review/yamlloader.rb +35 -2
  75. data/review.gemspec +2 -1
  76. data/samples/sample-book/src/config.yml +0 -1
  77. data/samples/sample-book/src/lib/tasks/review.rake +3 -1
  78. data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +2 -1
  79. data/samples/syntax-book/ch02.re +9 -0
  80. data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +2 -1
  81. data/templates/html/_titlepage.html.erb +9 -17
  82. data/templates/latex/config.erb +3 -0
  83. data/templates/latex/review-jlreq/review-base.sty +4 -5
  84. data/templates/latex/review-jlreq/review-jlreq.cls +39 -5
  85. data/templates/latex/review-jsbook/review-base.sty +9 -3
  86. data/templates/latex/review-jsbook/review-jsbook.cls +32 -5
  87. data/templates/opf/opf_manifest_epubv2.opf.erb +1 -1
  88. data/templates/opf/opf_manifest_epubv3.opf.erb +1 -1
  89. data/test/assets/syntax_book_index_detail.txt +10 -8
  90. data/test/assets/test_template.tex +4 -1
  91. data/test/assets/test_template_backmatter.tex +4 -1
  92. data/test/book_test_helper.rb +10 -10
  93. data/test/test_book_chapter.rb +25 -2
  94. data/test/test_builder.rb +10 -8
  95. data/test/test_epub3maker.rb +3 -3
  96. data/test/test_epubmaker.rb +27 -37
  97. data/test/test_epubmaker_cmd.rb +14 -3
  98. data/test/test_htmlbuilder.rb +111 -31
  99. data/test/test_idgxmlbuilder.rb +41 -33
  100. data/test/test_idgxmlmaker_cmd.rb +1 -1
  101. data/test/test_img_math.rb +11 -2
  102. data/test/test_index.rb +30 -4
  103. data/test/test_latexbuilder.rb +46 -25
  104. data/test/test_latexbuilder_v2.rb +18 -10
  105. data/test/test_markdownbuilder.rb +13 -0
  106. data/test/test_pdfmaker.rb +19 -0
  107. data/test/test_pdfmaker_cmd.rb +10 -10
  108. data/test/test_plaintextbuilder.rb +46 -22
  109. data/test/test_preprocessor.rb +188 -1
  110. data/test/test_rstbuilder.rb +13 -0
  111. data/test/test_textmaker_cmd.rb +1 -1
  112. data/test/test_topbuilder.rb +195 -29
  113. data/test/test_yamlloader.rb +28 -42
  114. metadata +11 -6
@@ -9,7 +9,7 @@
9
9
 
10
10
  begin
11
11
  require 'cgi/escape'
12
- rescue
12
+ rescue StandardError
13
13
  require 'cgi/util'
14
14
  end
15
15
 
@@ -60,13 +60,13 @@ module ReVIEW
60
60
  def highlight_pygments(ops)
61
61
  body = ops[:body] || ''
62
62
  format = ops[:format] || ''
63
- if ops[:lexer].present?
64
- lexer = ops[:lexer]
65
- elsif @book.config['highlight'] && @book.config['highlight']['lang']
66
- lexer = @book.config['highlight']['lang'] # default setting
67
- else
68
- lexer = 'text'
69
- end
63
+ lexer = if ops[:lexer].present?
64
+ ops[:lexer]
65
+ elsif @book.config['highlight'] && @book.config['highlight']['lang']
66
+ @book.config['highlight']['lang'] # default setting
67
+ else
68
+ 'text'
69
+ end
70
70
  options = { nowrap: true, noclasses: true }
71
71
  if ops[:linenum]
72
72
  options[:nowrap] = false
@@ -93,13 +93,13 @@ module ReVIEW
93
93
 
94
94
  def highlight_rouge(ops)
95
95
  body = ops[:body] || ''
96
- if ops[:lexer].present?
97
- lexer = ops[:lexer]
98
- elsif @book.config['highlight'] && @book.config['highlight']['lang']
99
- lexer = @book.config['highlight']['lang'] # default setting
100
- else
101
- lexer = 'text'
102
- end
96
+ lexer = if ops[:lexer].present?
97
+ ops[:lexer]
98
+ elsif @book.config['highlight'] && @book.config['highlight']['lang']
99
+ @book.config['highlight']['lang'] # default setting
100
+ else
101
+ 'text'
102
+ end
103
103
  # format = ops[:format] || ''
104
104
 
105
105
  first_line_num = 1 ## default
@@ -129,9 +129,9 @@ module ReVIEW
129
129
  end
130
130
 
131
131
  def normalize_id(id)
132
- if id =~ /\A[a-z][a-z0-9_.-]*\Z/i
132
+ if /\A[a-z][a-z0-9_.-]*\Z/i.match?(id)
133
133
  id
134
- elsif id =~ /\A[0-9_.-][a-z0-9_.-]*\Z/i
134
+ elsif /\A[0-9_.-][a-z0-9_.-]*\Z/i.match?(id)
135
135
  "id_#{id}" # dummy prefix
136
136
  else
137
137
  "id_#{CGI.escape(id.gsub('_', '__')).tr('%', '_').tr('+', '-')}" # escape all
data/lib/review/i18n.rb CHANGED
@@ -75,11 +75,11 @@ module ReVIEW
75
75
  end
76
76
 
77
77
  def load_file(path)
78
- @store = YAML.load_file(path)
78
+ @store = YAMLLoader.safe_load_file(path)
79
79
  end
80
80
 
81
81
  def update_localefile(path)
82
- user_i18n = YAML.load_file(path)
82
+ user_i18n = YAMLLoader.safe_load_file(path)
83
83
  locale = user_i18n['locale']
84
84
  if locale
85
85
  user_i18n.delete('locale')
@@ -171,7 +171,7 @@ module ReVIEW
171
171
  args_matched = (frmt.count('%') <= args.size)
172
172
  frmt.gsub!('##', '%%')
173
173
  args_matched ? (frmt % args) : frmt
174
- rescue
174
+ rescue StandardError
175
175
  str
176
176
  end
177
177
  end
data/lib/review/i18n.yml CHANGED
@@ -32,6 +32,8 @@ ja:
32
32
  html_footnote_refmark: "*%s"
33
33
  html_footnote_textmark: "[*%s] "
34
34
  html_footnote_backmark: "⏎"
35
+ html_endnote_refmark: "(%s)"
36
+ html_endnote_textmark: "(%s) "
35
37
  aut: "著 者"
36
38
  csl: "監 修"
37
39
  dsr: "デザイン"
@@ -120,6 +122,8 @@ en:
120
122
  html_footnote_refmark: "*%s"
121
123
  html_footnote_textmark: "[*%s] "
122
124
  html_footnote_backmark: "⏎"
125
+ html_endnote_refmark: "(%s)"
126
+ html_endnote_textmark: "(%s) "
123
127
  aut: "Author"
124
128
  csl: "Consultant"
125
129
  dsr: "Design"
@@ -188,6 +192,8 @@ zh-TW:
188
192
  html_footnote_refmark: "*%s"
189
193
  html_footnote_textmark: "[*%s] "
190
194
  html_footnote_backmark: "⏎"
195
+ html_endnote_refmark: "(%s)"
196
+ html_endnote_textmark: "(%s) "
191
197
  aut: "著作人"
192
198
  csl: "監 修"
193
199
  dsr: "美術編輯"
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2008-2020 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2008-2022 Minero Aoki, Kenshi Muto
2
2
  # 2002-2007 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -47,6 +47,7 @@ module ReVIEW
47
47
  end
48
48
 
49
49
  def builder_init_file
50
+ super
50
51
  @warns = []
51
52
  @errors = []
52
53
  @section = 0
@@ -77,13 +78,15 @@ module ReVIEW
77
78
  end
78
79
 
79
80
  def result
81
+ check_printendnotes
82
+
80
83
  s = ''
81
84
  if @secttags
82
85
  s += '</sect4>' if @subsubsubsection > 0
83
86
  s += '</sect3>' if @subsubsection > 0
84
87
  s += '</sect2>' if @subsection > 0
85
88
  s += '</sect>' if @section > 0
86
- s += '</chapter>' if @chapter.number > 0
89
+ s += '</chapter>'
87
90
  end
88
91
  solve_nest(@output.string) + s + "</#{@rootelement}>\n"
89
92
  end
@@ -200,7 +203,7 @@ module ReVIEW
200
203
 
201
204
  def ol_begin
202
205
  puts '<ol>'
203
- @ol_num ||= 1
206
+ @ol_num ||= 1 # rubocop:disable Naming/MemoizedInstanceVariableName
204
207
  end
205
208
 
206
209
  def ol_item(lines, num)
@@ -265,7 +268,7 @@ module ReVIEW
265
268
  I18n.t('column', compile_inline(chapter.column(id).caption))
266
269
  end
267
270
  rescue KeyError
268
- error "unknown column: #{id}"
271
+ app_error "unknown column: #{id}"
269
272
  end
270
273
 
271
274
  def inline_list(id)
@@ -436,7 +439,7 @@ module ReVIEW
436
439
  print '</pre>'
437
440
  image_header(id, caption) unless caption_top?('image')
438
441
  puts '</img>'
439
- warn "image not bound: #{id}"
442
+ warn "image not bound: #{id}", location: location
440
443
  end
441
444
 
442
445
  def image_header(id, caption)
@@ -454,11 +457,11 @@ module ReVIEW
454
457
  caption_str = nil
455
458
  if id
456
459
  puts '<equationblock>'
457
- if get_chap.nil?
458
- caption_str = %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number_without_chapter', [@chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
459
- else
460
- caption_str = %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number', [get_chap, @chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
461
- end
460
+ caption_str = if get_chap.nil?
461
+ %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number_without_chapter', [@chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
462
+ else
463
+ %Q(<caption>#{I18n.t('equation')}#{I18n.t('format_number', [get_chap, @chapter.equation(id).number])}#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}</caption>)
464
+ end
462
465
  puts caption_str if caption_top?('equation')
463
466
  end
464
467
 
@@ -477,7 +480,7 @@ module ReVIEW
477
480
  def table(lines, id = nil, caption = nil)
478
481
  @tablewidth = nil
479
482
  if @book.config['tableopt']
480
- @tablewidth = @book.config['tableopt'].split(',')[0].to_f / @book.config['pt_to_mm_unit'].to_f
483
+ @tablewidth = @book.config['tableopt'].split(',')[0].to_f / @book.config['pt_to_mm_unit'].to_f # rubocop:disable Style/FloatDivision
481
484
  end
482
485
  @col = 0
483
486
 
@@ -502,7 +505,7 @@ module ReVIEW
502
505
  table_header(id, caption)
503
506
  end
504
507
  rescue KeyError
505
- error "no such table: #{id}"
508
+ app_error "no such table: #{id}"
506
509
  end
507
510
  puts '</table>'
508
511
  @tsize = nil
@@ -512,7 +515,7 @@ module ReVIEW
512
515
  sepidx = nil
513
516
  rows = []
514
517
  lines.each_with_index do |line, idx|
515
- if /\A[=\-]{12}/ =~ line
518
+ if /\A[=\-]{12}/.match?(line)
516
519
  sepidx ||= idx
517
520
  next
518
521
  end
@@ -524,7 +527,7 @@ module ReVIEW
524
527
  col2 = rows[rows.length - 1].split(table_row_separator_regexp).length
525
528
  @col = col2 if col2 > @col
526
529
  end
527
- error 'no rows in the table' if rows.empty?
530
+ app_error 'no rows in the table' if rows.empty?
528
531
  [sepidx, rows]
529
532
  end
530
533
 
@@ -537,13 +540,13 @@ module ReVIEW
537
540
  cellwidth = @tsize.split(/\s*,\s*/)
538
541
  totallength = 0
539
542
  cellwidth.size.times do |n|
540
- cellwidth[n] = cellwidth[n].to_f / @book.config['pt_to_mm_unit'].to_f
543
+ cellwidth[n] = cellwidth[n].to_f / @book.config['pt_to_mm_unit'].to_f # rubocop:disable Style/FloatDivision
541
544
  totallength += cellwidth[n]
542
- warn "total length exceeds limit for table: #{@table_id}" if totallength > @tablewidth
545
+ warn "total length exceeds limit for table: #{@table_id}", location: location if totallength > @tablewidth
543
546
  end
544
547
  if cellwidth.size < @col
545
548
  cw = (@tablewidth - totallength) / (@col - cellwidth.size)
546
- warn "auto cell sizing exceeds limit for table: #{@table_id}" if cw <= 0
549
+ warn "auto cell sizing exceeds limit for table: #{@table_id}", location: location if cw <= 0
547
550
  (cellwidth.size..(@col - 1)).each { |i| cellwidth[i] = cw }
548
551
  end
549
552
  end
@@ -627,7 +630,7 @@ module ReVIEW
627
630
  end
628
631
  puts '</table>'
629
632
  else
630
- warn "image not bound: #{id}" if @strict
633
+ warn "image not bound: #{id}", location: location if @strict
631
634
  image_dummy(id, caption, lines)
632
635
  end
633
636
  end
@@ -656,7 +659,25 @@ module ReVIEW
656
659
  def inline_fn(id)
657
660
  %Q(<footnote>#{compile_inline(@chapter.footnote(id).content.strip)}</footnote>)
658
661
  rescue KeyError
659
- error "unknown footnote: #{id}"
662
+ app_error "unknown footnote: #{id}"
663
+ end
664
+
665
+ def inline_endnote(id)
666
+ %Q(<span type='endnoteref' idref='endnoteb-#{normalize_id(id)}'>(#{@chapter.endnote(id).number})</span>)
667
+ rescue KeyError
668
+ app_error "unknown endnote: #{id}"
669
+ end
670
+
671
+ def endnote_begin
672
+ puts '<endnotes>'
673
+ end
674
+
675
+ def endnote_end
676
+ puts '</endnotes>'
677
+ end
678
+
679
+ def endnote_item(id)
680
+ puts %Q(<endnote id='endnoteb-#{normalize_id(id)}'><span type='endnotenumber'>(#{@chapter.endnote(id).number})</span>\t#{compile_inline(@chapter.endnote(id).content)}</endnote>)
660
681
  end
661
682
 
662
683
  def compile_ruby(base, ruby)
@@ -666,8 +687,9 @@ module ReVIEW
666
687
  def compile_kw(word, alt)
667
688
  '<keyword>' +
668
689
  if alt
669
- then escape("#{word}(#{alt.strip})")
670
- else escape(word)
690
+ escape("#{word}(#{alt.strip})")
691
+ else
692
+ escape(word)
671
693
  end +
672
694
  '</keyword>' +
673
695
  %Q(<index value="#{escape(word)}" />) +
@@ -703,22 +725,22 @@ module ReVIEW
703
725
  end
704
726
 
705
727
  def inline_maru(str)
706
- if str =~ /\A\d+\Z/
728
+ if /\A\d+\Z/.match?(str)
707
729
  sprintf('&#x%x;', 9311 + str.to_i)
708
- elsif str =~ /\A[A-Z]\Z/
730
+ elsif /\A[A-Z]\Z/.match?(str)
709
731
  begin
710
732
  sprintf('&#x%x;', 9398 + str.codepoints.to_a[0] - 65)
711
733
  rescue NoMethodError
712
734
  sprintf('&#x%x;', 9398 + str[0] - 65)
713
735
  end
714
- elsif str =~ /\A[a-z]\Z/
736
+ elsif /\A[a-z]\Z/.match?(str)
715
737
  begin
716
738
  sprintf('&#x%x;', 9392 + str.codepoints.to_a[0] - 65)
717
739
  rescue NoMethodError
718
740
  sprintf('&#x%x;', 9392 + str[0] - 65)
719
741
  end
720
742
  else
721
- error "can't parse maru: #{str}"
743
+ app_error "can't parse maru: #{str}"
722
744
  end
723
745
  end
724
746
 
@@ -779,8 +801,8 @@ module ReVIEW
779
801
  def inline_icon(id)
780
802
  begin
781
803
  %Q(<Image href="file://#{@chapter.image(id).path.sub(%r{\A\./}, '')}" type="inline" />)
782
- rescue
783
- warn "image not bound: #{id}"
804
+ rescue StandardError
805
+ warn "image not bound: #{id}", location: location
784
806
  ''
785
807
  end
786
808
  end
@@ -1121,16 +1143,16 @@ module ReVIEW
1121
1143
  def indepimage(_lines, id, caption = nil, metric = nil)
1122
1144
  metrics = parse_metric('idgxml', metric)
1123
1145
  puts '<img>'
1124
- if caption_top?('image')
1125
- puts %Q(<caption>#{compile_inline(caption)}</caption>) if caption.present?
1146
+ if caption_top?('image') && caption.present?
1147
+ puts %Q(<caption>#{compile_inline(caption)}</caption>)
1126
1148
  end
1127
1149
  begin
1128
1150
  puts %Q(<Image href="file://#{@chapter.image(id).path.sub(%r{\A\./}, '')}"#{metrics} />)
1129
- rescue
1130
- warn %Q(image not bound: #{id})
1151
+ rescue StandardError
1152
+ warn %Q(image not bound: #{id}), location: location
1131
1153
  end
1132
- unless caption_top?('image')
1133
- puts %Q(<caption>#{compile_inline(caption)}</caption>) if caption.present?
1154
+ if !caption_top?('image') && caption.present?
1155
+ puts %Q(<caption>#{compile_inline(caption)}</caption>)
1134
1156
  end
1135
1157
  puts '</img>'
1136
1158
  end
@@ -1188,7 +1210,7 @@ module ReVIEW
1188
1210
  if chs2.size == 3
1189
1211
  chs = chs2
1190
1212
  else
1191
- error '--chapsplitter must have exactly 3 parameters with comma.'
1213
+ app_error '--chapsplitter must have exactly 3 parameters with comma.'
1192
1214
  end
1193
1215
  end
1194
1216
  s = "#{chs[0]}#{@book.chapter_index.number(id)}#{chs[1]}#{@book.chapter_index.title(id)}#{chs[2]}"
@@ -1206,7 +1228,7 @@ module ReVIEW
1206
1228
  end
1207
1229
  end
1208
1230
  rescue KeyError
1209
- error "unknown chapter: #{id}"
1231
+ app_error "unknown chapter: #{id}"
1210
1232
  end
1211
1233
 
1212
1234
  def inline_chap(id)
@@ -1216,7 +1238,7 @@ module ReVIEW
1216
1238
  @book.chapter_index.number(id)
1217
1239
  end
1218
1240
  rescue KeyError
1219
- error "unknown chapter: #{id}"
1241
+ app_error "unknown chapter: #{id}"
1220
1242
  end
1221
1243
 
1222
1244
  def inline_title(id)
@@ -1227,7 +1249,7 @@ module ReVIEW
1227
1249
  title
1228
1250
  end
1229
1251
  rescue KeyError
1230
- error "unknown chapter: #{id}"
1252
+ app_error "unknown chapter: #{id}"
1231
1253
  end
1232
1254
 
1233
1255
  def source(lines, caption = nil, lang = nil)
@@ -1270,7 +1292,7 @@ module ReVIEW
1270
1292
  def inline_bib(id)
1271
1293
  %Q(<span type='bibref' idref='#{id}'>[#{@chapter.bibpaper(id).number}]</span>)
1272
1294
  rescue KeyError
1273
- error "unknown bib: #{id}"
1295
+ app_error "unknown bib: #{id}"
1274
1296
  end
1275
1297
 
1276
1298
  def inline_hd_chap(chap, id)
@@ -1281,7 +1303,7 @@ module ReVIEW
1281
1303
  I18n.t('hd_quote_without_number', compile_inline(chap.headline(id).caption))
1282
1304
  end
1283
1305
  rescue KeyError
1284
- error "unknown headline: #{id}"
1306
+ app_error "unknown headline: #{id}"
1285
1307
  end
1286
1308
 
1287
1309
  def inline_recipe(id)
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2019-2021 Kenshi Muto
1
+ # Copyright (c) 2019-2022 Kenshi Muto
2
2
  #
3
3
  # This program is free software.
4
4
  # You can distribute or modify this program under the terms of
@@ -16,10 +16,12 @@ require 'review/yamlloader'
16
16
  require 'review/idgxmlbuilder'
17
17
  require 'review/version'
18
18
  require 'review/makerhelper'
19
+ require 'review/loggable'
19
20
 
20
21
  module ReVIEW
21
22
  class IDGXMLMaker
22
23
  include MakerHelper
24
+ include Loggable
23
25
 
24
26
  attr_accessor :config, :basedir
25
27
 
@@ -27,15 +29,7 @@ module ReVIEW
27
29
  @basedir = nil
28
30
  @logger = ReVIEW.logger
29
31
  @plaintext = nil
30
- end
31
-
32
- def error(msg)
33
- @logger.error "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
34
- exit 1
35
- end
36
-
37
- def warn(msg)
38
- @logger.warn "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
32
+ @compile_errors = nil
39
33
  end
40
34
 
41
35
  def self.execute(*args)
@@ -78,11 +72,15 @@ module ReVIEW
78
72
 
79
73
  def execute(*args)
80
74
  cmd_config, yamlfile = parse_opts(args)
81
- error "#{yamlfile} not found." unless File.exist?(yamlfile)
75
+ error! "#{yamlfile} not found." unless File.exist?(yamlfile)
82
76
 
83
- @config = ReVIEW::Configure.create(maker: 'idgxmlmaker',
84
- yamlfile: yamlfile,
85
- config: cmd_config)
77
+ begin
78
+ @config = ReVIEW::Configure.create(maker: 'idgxmlmaker',
79
+ yamlfile: yamlfile,
80
+ config: cmd_config)
81
+ rescue ReVIEW::ConfigError => e
82
+ error! e.message
83
+ end
86
84
  I18n.setup(@config['language'])
87
85
  begin
88
86
  generate_idgxml_files(yamlfile)
@@ -90,7 +88,7 @@ module ReVIEW
90
88
  rescue ApplicationError => e
91
89
  raise if @config['debug']
92
90
 
93
- error(e.message)
91
+ error! e.message
94
92
  end
95
93
  end
96
94
 
@@ -106,6 +104,10 @@ module ReVIEW
106
104
  end
107
105
 
108
106
  build_body(@path, yamlfile)
107
+
108
+ if @compile_errors
109
+ app_error 'compile error, No IDGXML file output.'
110
+ end
109
111
  end
110
112
 
111
113
  def apply_filter(xmlfile)
@@ -121,7 +123,7 @@ module ReVIEW
121
123
  if s.success?
122
124
  File.write(xmlfile, o) # override
123
125
  end
124
- rescue => e
126
+ rescue StandardError => e
125
127
  warn("filter error for #{xmlfile}: #{e.message}")
126
128
  end
127
129
  end
@@ -161,13 +163,11 @@ module ReVIEW
161
163
  end
162
164
 
163
165
  def build_chap(chap, base_path, basetmpdir, ispart)
164
- filename = ''
165
-
166
- if ispart.present?
167
- filename = chap.path
168
- else
169
- filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
170
- end
166
+ filename = if ispart.present?
167
+ chap.path
168
+ else
169
+ Pathname.new(chap.path).relative_path_from(base_path).to_s
170
+ end
171
171
  id = File.basename(filename).sub(/\.re\Z/, '')
172
172
  if @buildonly && !@buildonly.include?(id)
173
173
  warn "skip #{id}.re"
@@ -179,9 +179,10 @@ module ReVIEW
179
179
  begin
180
180
  @converter.convert(filename, File.join(basetmpdir, xmlfile))
181
181
  apply_filter(File.join(basetmpdir, xmlfile))
182
- rescue => e
183
- warn "compile error in #{filename} (#{e.class})"
184
- warn e.message
182
+ rescue StandardError => e
183
+ @compile_errors = true
184
+ error "compile error in #{filename} (#{e.class})"
185
+ error e.message
185
186
  end
186
187
  end
187
188
  end
@@ -1,8 +1,11 @@
1
1
  require 'fileutils'
2
2
  require 'shellwords'
3
+ require 'review/loggable'
3
4
 
4
5
  module ReVIEW
5
6
  class ImgMath
7
+ include Loggable
8
+
6
9
  def initialize(config, path_name: '_review_math')
7
10
  @config = config
8
11
  @logger = ReVIEW.logger
@@ -50,7 +53,7 @@ module ReVIEW
50
53
  cmd = "latex --interaction=nonstopmode --output-directory=#{tmpdir} #{tex_path} && dvipng -T tight -z9 -o #{img_path} #{dvi_path}"
51
54
  out, status = Open3.capture2e(cmd)
52
55
  unless status.success?
53
- raise ApplicationError, "latex compile error\n\nError log:\n" + out
56
+ raise ApplicationError, "latex compile error\n\nError log:\n#{out}"
54
57
  end
55
58
 
56
59
  img_path
@@ -97,15 +100,14 @@ module ReVIEW
97
100
  when 'dvipng'
98
101
  make_math_images_dvipng(tmpdir, tex_path, math_real_dir)
99
102
  else
100
- error "unknown math converter error. imgmath_options/converter parameter should be 'pdfcrop' or 'dvipng'."
101
- exit 1
103
+ error! "unknown math converter error. imgmath_options/converter parameter should be 'pdfcrop' or 'dvipng'."
102
104
  end
103
105
  rescue CompileError
104
106
  FileUtils.cp([tex_path,
107
+ File.join(File.dirname(tex_path), '__IMGMATH_BODY__.tex'),
105
108
  File.join(File.dirname(tex_path), '__IMGMATH__.log')],
106
109
  math_real_dir)
107
- error "LaTeX math compile error. See #{math_real_dir}/__IMGMATH__.log for details."
108
- exit 1
110
+ error! "LaTeX math compile error. See #{math_real_dir}/__IMGMATH__.log for details."
109
111
  end
110
112
  end
111
113
  @math_maps.clear
@@ -113,14 +115,6 @@ module ReVIEW
113
115
 
114
116
  private
115
117
 
116
- def error(msg)
117
- @logger.error msg
118
- end
119
-
120
- def warn(msg)
121
- @logger.warn msg
122
- end
123
-
124
118
  def default_imgmath_preamble
125
119
  <<-EOB
126
120
  \\documentclass[uplatex,a3paper,landscape]{jsarticle}
@@ -156,7 +150,7 @@ module ReVIEW
156
150
  if File.exist?(dvi_path)
157
151
  out, status = Open3.capture2e(*[@config['dvicommand'], @config['dvioptions'].shellsplit, dvi_path].flatten.compact)
158
152
  if !status.success? || !File.exist?(pdf_path)
159
- warn "error in #{@config['dvicommand']}. Error log:\n#{out}"
153
+ @logger.error "error in #{@config['dvicommand']}. Error log:\n#{out}"
160
154
  raise CompileError
161
155
  end
162
156
  end
@@ -167,7 +161,7 @@ module ReVIEW
167
161
  end
168
162
  out, status = Open3.capture2e(*args)
169
163
  unless status.success?
170
- warn "error in pdfcrop. Error log:\n#{out}"
164
+ @logger.error "error in pdfcrop. Error log:\n#{out}"
171
165
  raise CompileError
172
166
  end
173
167
  pdf_path = '__IMGMATH__pdfcrop.pdf'
@@ -192,7 +186,7 @@ module ReVIEW
192
186
  end
193
187
  out, status = Open3.capture2e(*args)
194
188
  unless status.success?
195
- warn "error in pdf extracting. Error log:\n#{out}"
189
+ @logger.error "error in pdf extracting. Error log:\n#{out}"
196
190
  raise CompileError
197
191
  end
198
192
 
@@ -209,7 +203,7 @@ module ReVIEW
209
203
  end
210
204
  out, status = Open3.capture2e(*args)
211
205
  unless status.success?
212
- warn "error in pdf pixelizing. Error log:\n#{out}"
206
+ @logger.error "error in pdf pixelizing. Error log:\n#{out}"
213
207
  raise CompileError
214
208
  end
215
209
  end
@@ -235,7 +229,7 @@ module ReVIEW
235
229
  end
236
230
  out, status = Open3.capture2e(*args)
237
231
  unless status.success?
238
- warn "error in dvipng. Error log:\n#{out}"
232
+ @logger.error "error in dvipng. Error log:\n#{out}"
239
233
  raise CompileError
240
234
  end
241
235
  end