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
@@ -3,21 +3,20 @@ require 'tmpdir'
3
3
  require 'fileutils'
4
4
  require 'yaml'
5
5
  require 'rbconfig'
6
+ require 'zip'
6
7
 
7
- REVIEW_EPUBMAKER = File.expand_path('../bin/review-epubmaker', File.dirname(__FILE__))
8
+ REVIEW_EPUBMAKER = File.expand_path('../bin/review-epubmaker', __dir__)
8
9
 
9
10
  class EPUBMakerCmdTest < Test::Unit::TestCase
10
11
  def setup
11
12
  @tmpdir1 = Dir.mktmpdir
12
- @tmpdir2 = Dir.mktmpdir
13
13
 
14
14
  @old_rubylib = ENV['RUBYLIB']
15
- ENV['RUBYLIB'] = File.expand_path('../lib', File.dirname(__FILE__))
15
+ ENV['RUBYLIB'] = File.expand_path('lib', __dir__)
16
16
  end
17
17
 
18
18
  def teardown
19
19
  FileUtils.rm_rf(@tmpdir1)
20
- FileUtils.rm_rf(@tmpdir2)
21
20
  ENV['RUBYLIB'] = @old_rubylib
22
21
  end
23
22
 
@@ -35,11 +34,23 @@ class EPUBMakerCmdTest < Test::Unit::TestCase
35
34
  end
36
35
  end
37
36
 
37
+ def check_filesize(epubfile)
38
+ if /mswin|mingw|cygwin/ !~ RUBY_PLATFORM
39
+ Zip::File.open(epubfile) do |zio|
40
+ zio.each do |entry|
41
+ assert_not_equal(0, entry.size, "#{entry.name} is 0 byte.")
42
+ end
43
+ end
44
+ end
45
+ end
46
+
38
47
  def test_epubmaker_cmd_samplebook
39
48
  common_buildepub('sample-book/src', 'config.yml', 'book.epub')
49
+ check_filesize(File.join(@tmpdir1, 'book.epub'))
40
50
  end
41
51
 
42
52
  def test_epubmaker_cmd_syntaxbook
43
53
  common_buildepub('syntax-book', 'config.yml', 'syntax-book.epub')
54
+ check_filesize(File.join(@tmpdir1, 'syntax-book.epub'))
44
55
  end
45
56
  end
data/test/test_helper.rb CHANGED
@@ -1,4 +1,5 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib/')
1
+ $LOAD_PATH.unshift(File.realpath('../lib', __dir__))
2
+
2
3
  require 'test/unit'
3
4
  require 'fileutils'
4
5
  require 'review/yamlloader'
@@ -9,18 +10,18 @@ def touch_file(path)
9
10
  end
10
11
 
11
12
  def assets_dir
12
- File.join(File.dirname(__FILE__), 'assets')
13
+ File.join(__dir__, 'assets')
13
14
  end
14
15
 
15
16
  def prepare_samplebook(srcdir, bookdir, latextemplatedir, configfile)
16
- samplebook_dir = File.expand_path("../samples/#{bookdir}/", File.dirname(__FILE__))
17
+ samplebook_dir = File.expand_path("../samples/#{bookdir}/", __dir__)
17
18
  files = Dir.glob(File.join(samplebook_dir, '*'))
18
19
  # ignore temporary built files
19
20
  files.delete_if { |file| file =~ /.*-(pdf|epub|text)/ || file == 'webroot' }
20
21
  FileUtils.cp_r(files, srcdir)
21
22
  if latextemplatedir
22
23
  # copy from review-jsbook or review-jlreq
23
- template_dir = File.expand_path("../templates/latex/#{latextemplatedir}/", File.dirname(__FILE__))
24
+ template_dir = File.expand_path("../templates/latex/#{latextemplatedir}/", __dir__)
24
25
  FileUtils.cp(Dir.glob(File.join(template_dir, '*')), File.join(srcdir, 'sty'))
25
26
  end
26
27
  loader = ReVIEW::YAMLLoader.new
@@ -8,7 +8,6 @@ class HTMLBuidlerTest < Test::Unit::TestCase
8
8
 
9
9
  def setup
10
10
  ReVIEW::I18n.setup
11
- @builder = HTMLBuilder.new
12
11
  @config = ReVIEW::Configure.values
13
12
  @config['secnolevel'] = 2
14
13
  @config['stylesheet'] = nil
@@ -16,11 +15,16 @@ class HTMLBuidlerTest < Test::Unit::TestCase
16
15
  @config['epubmaker'] = {}
17
16
  @book = Book::Base.new('.')
18
17
  @book.config = @config
18
+ img_math = ReVIEW::ImgMath.new(@config)
19
+ @log_io = StringIO.new
20
+ ReVIEW.logger = ReVIEW::Logger.new(@log_io)
21
+ @builder = HTMLBuilder.new(img_math: img_math)
19
22
  @compiler = ReVIEW::Compiler.new(@builder)
20
23
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
21
24
  location = Location.new(nil, nil)
22
25
  @builder.bind(@compiler, @chapter, location)
23
26
  I18n.setup('ja')
27
+ @skip_pygments = true # temporary suppress pygments test
24
28
  end
25
29
 
26
30
  def test_xmlns_ops_prefix_epub3
@@ -131,6 +135,48 @@ class HTMLBuidlerTest < Test::Unit::TestCase
131
135
  assert_equal %Q(\n<h3 id="test"><a id="h1-0-1"></a><span class="secno">1.0.1 </span>this is test.</h3>\n), actual
132
136
  end
133
137
 
138
+ def test_headline_sections
139
+ @book.config['epubmaker']['use_section'] = true
140
+ actual = compile_block("= H1\n== H2\n== H2-2\n")
141
+ expected = <<-EOS
142
+ <section class="level1"><h1><a id="h1"></a><span class="secno">第1章 </span>H1</h1>
143
+ <section class="level2">
144
+ <h2><a id="h1-1"></a><span class="secno">1.1 </span>H2</h2>
145
+ </section>
146
+ <section class="level2">
147
+ <h2><a id="h1-2"></a><span class="secno">1.2 </span>H2-2</h2>
148
+ </section>
149
+ </section>
150
+ EOS
151
+ assert_equal expected, actual
152
+
153
+ actual = compile_block("= H1\n== H2\n==== H4\n== H2-2\n")
154
+ expected = <<-EOS
155
+ <section class="level1"><h1><a id="h1"></a><span class="secno">第1章 </span>H1</h1>
156
+ <section class="level2">
157
+ <h2><a id="h1-1"></a><span class="secno">1.1 </span>H2</h2>
158
+ <section class="level4">
159
+ <h4><a id="h1-1-0-1"></a>H4</h4>
160
+ </section>
161
+ </section>
162
+ <section class="level2">
163
+ <h2><a id="h1-2"></a><span class="secno">1.2 </span>H2-2</h2>
164
+ </section>
165
+ </section>
166
+ EOS
167
+ assert_equal expected, actual
168
+
169
+ actual = compile_block("===== H5\n= H1\n")
170
+ expected = <<-EOS
171
+ <section class="level5">
172
+ <h5><a id="h1-0-0-0-1"></a>H5</h5>
173
+ </section>
174
+ <section class="level1"><h1><a id="h1"></a><span class="secno">第1章 </span>H1</h1>
175
+ </section>
176
+ EOS
177
+ assert_equal expected, actual
178
+ end
179
+
134
180
  def test_label
135
181
  actual = compile_block("//label[label_test]\n")
136
182
  assert_equal %Q(<a id="label_test"></a>\n), actual
@@ -358,12 +404,26 @@ EOS
358
404
  rescue LoadError
359
405
  return true
360
406
  end
361
- @config['mathml'] = true
407
+ @config['math_format'] = 'mathml'
362
408
  actual = compile_inline('@<m>{\\frac{-b \\pm \\sqrt{b^2 - 4ac\\}\\}{2a\\}}')
363
- @config['mathml'] = nil
364
409
  assert_equal %Q(<span class="equation"><math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mfrac><mrow><mo stretchy='false'>-</mo><mi>b</mi><mo stretchy='false'>&#xb1;</mo><msqrt><mrow><msup><mi>b</mi><mn>2</mn></msup><mo stretchy='false'>-</mo><mn>4</mn><mi>a</mi><mi>c</mi></mrow></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></math></span>), actual
365
410
  end
366
411
 
412
+ def test_inline_mathjax
413
+ @config['math_format'] = 'mathjax'
414
+ actual = compile_inline('@<m>{\\frac{-b \\pm \\sqrt{b^2 - 4ac\\}\\}{2a\\}}')
415
+ assert_equal %Q(<span class="equation">\\( \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a} \\)</span>), actual
416
+
417
+ content = <<-EOF
418
+ //texequation{
419
+ \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}
420
+ //}
421
+ EOF
422
+ actual = compile_block(content)
423
+ expected = %Q(<div class="equation">\n$$\\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$$\n</div>\n)
424
+ assert_equal expected, actual
425
+ end
426
+
367
427
  def test_inline_img
368
428
  def @chapter.image(_id)
369
429
  item = Book::Index::Item.new('sampleimg', 1, 'sample photo')
@@ -614,6 +674,20 @@ EOS
614
674
  EOS
615
675
  assert_equal expected, actual
616
676
 
677
+ actual = compile_block("//image[sampleimg][]{\n//}\n")
678
+ expected = <<-EOS
679
+ <div id="sampleimg" class="image">
680
+ <img src="images/chap1-sampleimg.png" alt="" />
681
+ <p class="caption">
682
+ 図1.1:
683
+ </p>
684
+ </div>
685
+ EOS
686
+ assert_equal expected, actual
687
+
688
+ actual = compile_block("//image[sampleimg][][]{\n//}\n")
689
+ assert_equal expected, actual
690
+
617
691
  @config['caption_position']['image'] = 'top'
618
692
  actual = compile_block("//image[sampleimg][sample photo]{\n//}\n")
619
693
  expected = <<-EOS
@@ -730,6 +804,12 @@ EOS
730
804
  </div>
731
805
  EOS
732
806
  assert_equal expected, actual
807
+
808
+ actual = compile_block("//indepimage[sampleimg][]\n")
809
+ assert_equal expected, actual
810
+
811
+ actual = compile_block("//indepimage[sampleimg][][]\n")
812
+ assert_equal expected, actual
733
813
  end
734
814
 
735
815
  def test_indepimage_with_metric
@@ -944,6 +1024,8 @@ EOS
944
1024
  end
945
1025
 
946
1026
  def test_list_pygments
1027
+ return true if @skip_pygments
1028
+
947
1029
  def @chapter.list(_id)
948
1030
  Book::Index::Item.new('samplelist', 1)
949
1031
  end
@@ -971,6 +1053,8 @@ test&lt;i&gt;2&lt;/i&gt;
971
1053
  end
972
1054
 
973
1055
  def test_list_pygments_lang
1056
+ return true if @skip_pygments
1057
+
974
1058
  def @chapter.list(_id)
975
1059
  Book::Index::Item.new('samplelist', 1)
976
1060
  end
@@ -999,6 +1083,8 @@ EOS
999
1083
  end
1000
1084
 
1001
1085
  def test_list_pygments_nulllang
1086
+ return true if @skip_pygments
1087
+
1002
1088
  def @chapter.list(_id)
1003
1089
  Book::Index::Item.new('samplelist', 1)
1004
1090
  end
@@ -1191,6 +1277,8 @@ EOS
1191
1277
  end
1192
1278
 
1193
1279
  def test_listnum_pygments_lang
1280
+ return true if @skip_pygments
1281
+
1194
1282
  def @chapter.list(_id)
1195
1283
  Book::Index::Item.new('samplelist', 1)
1196
1284
  end
@@ -1218,6 +1306,8 @@ EOS
1218
1306
  end
1219
1307
 
1220
1308
  def test_listnum_pygments_lang_linenum
1309
+ return true if @skip_pygments
1310
+
1221
1311
  def @chapter.list(_id)
1222
1312
  Book::Index::Item.new('samplelist', 1)
1223
1313
  end
@@ -1246,6 +1336,8 @@ EOS
1246
1336
  end
1247
1337
 
1248
1338
  def test_listnum_pygments_lang_without_lang
1339
+ return true if @skip_pygments
1340
+
1249
1341
  def @chapter.list(_id)
1250
1342
  Book::Index::Item.new('samplelist', 1)
1251
1343
  end
@@ -1432,6 +1524,8 @@ EOS
1432
1524
  end
1433
1525
 
1434
1526
  def test_emlist_pygments_lang
1527
+ return true if @skip_pygments
1528
+
1435
1529
  begin
1436
1530
  require 'pygments'
1437
1531
  rescue LoadError
@@ -1568,6 +1662,8 @@ EOS
1568
1662
  end
1569
1663
 
1570
1664
  def test_cmd_pygments
1665
+ return true if @skip_pygments
1666
+
1571
1667
  begin
1572
1668
  require 'pygments'
1573
1669
  rescue LoadError
@@ -1614,13 +1710,16 @@ EOS
1614
1710
  def test_texequation
1615
1711
  return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1616
1712
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1713
+
1617
1714
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
1618
1715
  'ch01.re' => "= test\n\n//texequation{\np \\land \\bm{P} q\n//}\n") do |dir, book, _files|
1619
1716
  @book = book
1620
1717
  @book.config = @config
1621
- @config['imgmath'] = true
1718
+ @config['math_format'] = 'imgmath'
1622
1719
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
1623
1720
  location = Location.new(nil, nil)
1721
+ img_math = ReVIEW::ImgMath.new(@config)
1722
+ @builder = HTMLBuilder.new(img_math: img_math)
1624
1723
  @builder.bind(@compiler, @chapter, location)
1625
1724
  FileUtils.mkdir_p(File.join(dir, 'images'))
1626
1725
  expected = <<-EOB
@@ -1644,14 +1743,17 @@ EOS
1644
1743
  # Re:VIEW 3 never fail on defer mode. This test is only for Re:VIEW 2.
1645
1744
  return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1646
1745
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1746
+
1647
1747
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
1648
1748
  'ch01.re' => "= test\n\n//texequation{\np \\land \\bm{P}} q\n//}\n") do |dir, book, _files|
1649
1749
  @book = book
1650
1750
  @book.config = @config
1651
1751
  @config['review_version'] = 2
1652
- @config['imgmath'] = true
1752
+ @config['math_format'] = 'imgmath'
1653
1753
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
1654
1754
  location = Location.new(nil, nil)
1755
+ img_math = ReVIEW::ImgMath.new(@config)
1756
+ @builder = HTMLBuilder.new(img_math: img_math)
1655
1757
  @builder.bind(@compiler, @chapter, location)
1656
1758
  FileUtils.mkdir_p(File.join(dir, 'images'))
1657
1759
  tmpio = $stderr
@@ -1971,8 +2073,8 @@ EOS
1971
2073
  * AA
1972
2074
  EOS
1973
2075
 
1974
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1975
- assert_equal ':1: error: too many *.', e.message
2076
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2077
+ assert_match(/too many \*\./, @log_io.string)
1976
2078
  end
1977
2079
 
1978
2080
  def test_ul_nest4
@@ -2220,6 +2322,43 @@ EOS
2220
2322
  assert_equal expected, fn
2221
2323
  end
2222
2324
 
2325
+ def test_endnote
2326
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block("//endnote[foo][bar]\n\n@<endnote>{foo}\n") }
2327
+ assert_equal ':4: //endnote is found but //printendnotes is not found.', e.message
2328
+
2329
+ actual = compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n//printendnotes\n")
2330
+ expected = <<-'EOS'
2331
+ <p><a id="endnoteb-foo" href="#endnote-foo" class="noteref" epub:type="noteref">(1)</a></p>
2332
+ <div class="endnotes">
2333
+ <div class="endnote" id="endnote-foo"><p class="endnote">(1) bar</p></div>
2334
+ </div>
2335
+ EOS
2336
+ assert_equal expected, actual
2337
+
2338
+ @book.config['epubmaker'] ||= {}
2339
+ @book.config['epubmaker']['back_footnote'] = true
2340
+ actual = compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n//printendnotes\n")
2341
+ expected = <<-'EOS'
2342
+ <p><a id="endnoteb-foo" href="#endnote-foo" class="noteref" epub:type="noteref">(1)</a></p>
2343
+ <div class="endnotes">
2344
+ <div class="endnote" id="endnote-foo"><p class="endnote"><a href="#endnoteb-foo">⏎</a>(1) bar</p></div>
2345
+ </div>
2346
+ EOS
2347
+ assert_equal expected, actual
2348
+
2349
+ I18n.set('html_endnote_textmark', '+%s:')
2350
+ I18n.set('html_endnote_refmark', '+%s:')
2351
+ I18n.set('html_footnote_backmark', '←')
2352
+ actual = compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n//printendnotes\n")
2353
+ expected = <<-'EOS'
2354
+ <p><a id="endnoteb-foo" href="#endnote-foo" class="noteref" epub:type="noteref">+1:</a></p>
2355
+ <div class="endnotes">
2356
+ <div class="endnote" id="endnote-foo"><p class="endnote"><a href="#endnoteb-foo">←</a>+1:bar</p></div>
2357
+ </div>
2358
+ EOS
2359
+ assert_equal expected, actual
2360
+ end
2361
+
2223
2362
  def test_inline_hd
2224
2363
  book = ReVIEW::Book::Base.new
2225
2364
  book.catalog = ReVIEW::Catalog.new('CHAPS' => %w[ch1.re ch2.re])
@@ -2320,10 +2459,10 @@ EOS
2320
2459
 
2321
2460
  def test_empty_table
2322
2461
  e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") }
2323
- assert_equal ':2: error: no rows in the table', e.message
2462
+ assert_equal 'no rows in the table', e.message
2324
2463
 
2325
2464
  e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") }
2326
- assert_equal ':3: error: no rows in the table', e.message
2465
+ assert_equal 'no rows in the table', e.message
2327
2466
  end
2328
2467
 
2329
2468
  def test_inline_table
@@ -2678,8 +2817,8 @@ EOS
2678
2817
 
2679
2818
  //}
2680
2819
  EOS
2681
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2682
- assert_match(/minicolumn cannot be nested:/, e.message)
2820
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2821
+ assert_match(/minicolumn cannot be nested:/, @log_io.string)
2683
2822
  end
2684
2823
  end
2685
2824
 
@@ -2695,8 +2834,8 @@ EOS
2695
2834
 
2696
2835
  //}
2697
2836
  EOS
2698
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2699
- assert_match(/minicolumn cannot be nested:/, e.message)
2837
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2838
+ assert_match(/minicolumn cannot be nested:/, @log_io.string)
2700
2839
  end
2701
2840
  end
2702
2841
 
@@ -2712,8 +2851,8 @@ EOS
2712
2851
 
2713
2852
  //}
2714
2853
  EOS
2715
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2716
- assert_match(/minicolumn cannot be nested:/, e.message)
2854
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2855
+ assert_match(/minicolumn cannot be nested:/, @log_io.string)
2717
2856
  end
2718
2857
  end
2719
2858
 
@@ -2755,28 +2894,28 @@ EOS
2755
2894
  EOB
2756
2895
  end
2757
2896
  @book.config['words_file'] = File.join(dir, 'words.csv')
2758
- io = StringIO.new
2759
- @builder.instance_eval{ @logger = ReVIEW::Logger.new(io) }
2760
2897
  actual = compile_block('@<w>{F} @<w>{B} @<wb>{B} @<w>{N}')
2761
2898
  assert_equal %Q(<p>foo bar&quot;\\&lt;&gt;_@&lt;b&gt;{BAZ} <b>bar&quot;\\&lt;&gt;_@&lt;b&gt;{BAZ}</b> [missing word: N]</p>\n), actual
2762
- assert_match(/WARN --: :1: word not bound: N/, io.string)
2899
+ assert_match(/WARN --: :1: word not bound: N/, @log_io.string)
2763
2900
  end
2764
2901
  end
2765
2902
 
2766
2903
  def test_inline_unknown
2767
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<img>{n}\n") }
2768
- assert_equal ':1: error: unknown image: n', e.message
2769
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<fn>{n}\n") }
2770
- assert_equal ':1: error: unknown footnote: n', e.message
2771
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<hd>{n}\n") }
2772
- assert_equal ':1: error: unknown headline: n', e.message
2904
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<img>{n}\n") }
2905
+ assert_match(/unknown image: n/, @log_io.string)
2906
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<fn>{n}\n") }
2907
+ assert_match(/unknown footnote: n/, @log_io.string)
2908
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<endnote>{n}\n") }
2909
+ assert_match(/unknown endnote: n/, @log_io.string)
2910
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<hd>{n}\n") }
2911
+ assert_match(/unknown headline: n/, @log_io.string)
2773
2912
  %w[list table column].each do |name|
2774
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2775
- assert_equal ":1: error: unknown #{name}: n", e.message
2913
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2914
+ assert_match(/unknown #{name}: n/, @log_io.string)
2776
2915
  end
2777
2916
  %w[chap chapref title].each do |name|
2778
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2779
- assert_equal ':1: error: key not found: "n"', e.message
2917
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2918
+ assert_match(/key not found: "n"/, @log_io.string)
2780
2919
  end
2781
2920
  end
2782
2921
 
@@ -2851,7 +2990,7 @@ EOS
2851
2990
  //beginchild
2852
2991
  EOS
2853
2992
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2854
- assert_equal ":1: error: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message
2993
+ assert_equal ":1: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message
2855
2994
  end
2856
2995
 
2857
2996
  def test_nest_error_close2
@@ -2869,7 +3008,7 @@ EOS
2869
3008
  //beginchild
2870
3009
  EOS
2871
3010
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2872
- assert_equal ':12: error: //beginchild of dl,ol,ul misses //endchild', e.message
3011
+ assert_equal ':12: //beginchild of dl,ol,ul misses //endchild', e.message
2873
3012
  end
2874
3013
 
2875
3014
  def test_nest_error_close3
@@ -2889,7 +3028,7 @@ EOS
2889
3028
  //endchild
2890
3029
  EOS
2891
3030
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2892
- assert_equal ':14: error: //beginchild of ol,ul misses //endchild', e.message
3031
+ assert_equal ':14: //beginchild of ol,ul misses //endchild', e.message
2893
3032
  end
2894
3033
 
2895
3034
  def test_nest_ul
@@ -14,6 +14,8 @@ class IDGXMLBuidlerTest < Test::Unit::TestCase
14
14
  @config['tableopt'] = '10'
15
15
  @book = Book::Base.new
16
16
  @book.config = @config
17
+ @log_io = StringIO.new
18
+ ReVIEW.logger = ReVIEW::Logger.new(@log_io)
17
19
  @compiler = ReVIEW::Compiler.new(@builder)
18
20
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
19
21
  location = Location.new(nil, nil)
@@ -48,6 +50,19 @@ class IDGXMLBuidlerTest < Test::Unit::TestCase
48
50
  assert_equal %Q(<title id="test" aid:pstyle="h3">1.0.1 this is test.</title><?dtp level="3" section="1.0.1 this is test."?>), actual
49
51
  end
50
52
 
53
+ def test_headline_secttags
54
+ @config['structuredxml'] = true
55
+ actual = compile_block("= HEAD1\n== HEAD1-1\n\n=== HEAD1-1-1\n\n== HEAD1-2\n\n==== HEAD1-2-0-1\n\n===== HEAD1-2-0-1-1\n\n== HEAD1-3\n")
56
+ expected = '<chapter id="chap:1"><title aid:pstyle="h1">第1章 HEAD1</title><?dtp level="1" section="第1章 HEAD1"?>' +
57
+ '<sect id="sect:1.1"><title aid:pstyle="h2">1.1 HEAD1-1</title><?dtp level="2" section="1.1 HEAD1-1"?>' +
58
+ '<sect2 id="sect:1.1.1"><title aid:pstyle="h3">HEAD1-1-1</title><?dtp level="3" section="HEAD1-1-1"?></sect2></sect>' +
59
+ '<sect id="sect:1.2"><title aid:pstyle="h2">1.2 HEAD1-2</title><?dtp level="2" section="1.2 HEAD1-2"?>' +
60
+ '<sect3 id="sect:1.2.0.1"><title aid:pstyle="h4">HEAD1-2-0-1</title><?dtp level="4" section="HEAD1-2-0-1"?>' +
61
+ '<sect4 id="sect:1.2.0.1.1"><title aid:pstyle="h5">HEAD1-2-0-1-1</title><?dtp level="5" section="HEAD1-2-0-1-1"?></sect4></sect3></sect>' +
62
+ '<sect id="sect:1.3"><title aid:pstyle="h2">1.3 HEAD1-3</title><?dtp level="2" section="1.3 HEAD1-3"?></sect></chapter>'
63
+ assert_equal expected, actual
64
+ end
65
+
51
66
  def test_label
52
67
  actual = compile_block("//label[label_test]\n")
53
68
  assert_equal %Q(<label id='label_test' />), actual
@@ -156,10 +171,10 @@ EOS
156
171
 
157
172
  def test_empty_table
158
173
  e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") }
159
- assert_equal ':2: error: no rows in the table', e.message
174
+ assert_equal 'no rows in the table', e.message
160
175
 
161
176
  e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") }
162
- assert_equal ':3: error: no rows in the table', e.message
177
+ assert_equal 'no rows in the table', e.message
163
178
  end
164
179
 
165
180
  def test_emtable
@@ -423,8 +438,8 @@ EOS
423
438
 
424
439
  //}
425
440
  EOS
426
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
427
- assert_match(/minicolumn cannot be nested:/, e.message)
441
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
442
+ assert_match(/minicolumn cannot be nested:/, @log_io.string)
428
443
  end
429
444
  end
430
445
 
@@ -440,8 +455,8 @@ EOS
440
455
 
441
456
  //}
442
457
  EOS
443
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
444
- assert_match(/minicolumn cannot be nested:/, e.message)
458
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
459
+ assert_match(/minicolumn cannot be nested:/, @log_io.string)
445
460
  end
446
461
  end
447
462
 
@@ -456,8 +471,8 @@ EOS
456
471
 
457
472
  //}
458
473
  EOS
459
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
460
- assert_match(/minicolumn cannot be nested:/, e.message)
474
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
475
+ assert_match(/minicolumn cannot be nested:/, @log_io.string)
461
476
  end
462
477
  end
463
478
 
@@ -1082,8 +1097,8 @@ EOS
1082
1097
  * AA
1083
1098
  EOS
1084
1099
 
1085
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1086
- assert_equal ':1: error: too many *.', e.message
1100
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1101
+ assert_match(/too many \*\./, @log_io.string)
1087
1102
  end
1088
1103
 
1089
1104
  def test_ul_nest4
@@ -1118,19 +1133,25 @@ EOS
1118
1133
  end
1119
1134
 
1120
1135
  def test_inline_unknown
1121
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<img>{n}\n") }
1122
- assert_equal ':1: error: unknown image: n', e.message
1123
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<fn>{n}\n") }
1124
- assert_equal ':1: error: unknown footnote: n', e.message
1125
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<hd>{n}\n") }
1126
- assert_equal ':1: error: unknown headline: n', e.message
1136
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<img>{n}\n") }
1137
+ assert_match(/unknown image: n/, @log_io.string)
1138
+
1139
+ @log_io.string = ''
1140
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<fn>{n}\n") }
1141
+ assert_match(/unknown footnote: n/, @log_io.string)
1142
+
1143
+ @log_io.string = ''
1144
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<hd>{n}\n") }
1145
+ assert_match(/unknown headline: n/, @log_io.string)
1127
1146
  %w[list table column].each do |name|
1128
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
1129
- assert_equal ":1: error: unknown #{name}: n", e.message
1147
+ @log_io.string = ''
1148
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
1149
+ assert_match(/unknown #{name}: n/, @log_io.string)
1130
1150
  end
1131
1151
  %w[chap chapref title].each do |name|
1132
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
1133
- assert_equal ':1: error: key not found: "n"', e.message
1152
+ @log_io.string = ''
1153
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
1154
+ assert_match(/key not found: "n"/, @log_io.string)
1134
1155
  end
1135
1156
  end
1136
1157
 
@@ -1270,7 +1291,7 @@ EOS
1270
1291
  //beginchild
1271
1292
  EOS
1272
1293
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1273
- assert_equal ":1: error: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message
1294
+ assert_equal ":1: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message
1274
1295
  end
1275
1296
 
1276
1297
  def test_nest_error_close2
@@ -1288,7 +1309,7 @@ EOS
1288
1309
  //beginchild
1289
1310
  EOS
1290
1311
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1291
- assert_equal ':12: error: //beginchild of dl,ol,ul misses //endchild', e.message
1312
+ assert_equal ':12: //beginchild of dl,ol,ul misses //endchild', e.message
1292
1313
  end
1293
1314
 
1294
1315
  def test_nest_error_close3
@@ -1308,7 +1329,7 @@ EOS
1308
1329
  //endchild
1309
1330
  EOS
1310
1331
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1311
- assert_equal ':14: error: //beginchild of ol,ul misses //endchild', e.message
1332
+ assert_equal ':14: //beginchild of ol,ul misses //endchild', e.message
1312
1333
  end
1313
1334
 
1314
1335
  def test_nest_ul
@@ -5,14 +5,14 @@ require 'yaml'
5
5
  require 'rbconfig'
6
6
  require 'open3'
7
7
 
8
- REVIEW_IDGXMLMAKER = File.expand_path('../bin/review-idgxmlmaker', File.dirname(__FILE__))
8
+ REVIEW_IDGXMLMAKER = File.expand_path('../bin/review-idgxmlmaker', __dir__)
9
9
 
10
10
  class IDGXMLMakerCmdTest < Test::Unit::TestCase
11
11
  def setup
12
12
  @tmpdir1 = Dir.mktmpdir
13
13
 
14
14
  @old_rubylib = ENV['RUBYLIB']
15
- ENV['RUBYLIB'] = File.expand_path('../lib', File.dirname(__FILE__))
15
+ ENV['RUBYLIB'] = File.expand_path('../lib', __dir__)
16
16
  end
17
17
 
18
18
  def teardown
@@ -29,7 +29,11 @@ class IDGXMLMakerCmdTest < Test::Unit::TestCase
29
29
  ruby_cmd = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name']) + RbConfig::CONFIG['EXEEXT']
30
30
  Dir.chdir(@tmpdir1) do
31
31
  _o, e, s = Open3.capture3("#{ruby_cmd} -S #{REVIEW_IDGXMLMAKER} #{option} #{configfile}")
32
- assert_equal '', e
32
+ if defined?(ReVIEW::TTYLogger)
33
+ assert_match(/SUCCESS/, e)
34
+ else
35
+ assert_equal '', e
36
+ end
33
37
  assert s.success?
34
38
  end
35
39
  assert File.exist?(File.join(@tmpdir1, targetfile))