review 5.0.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +31 -0
  3. data/.github/workflows/ruby-win.yml +3 -3
  4. data/.github/workflows/ruby.yml +1 -1
  5. data/.rubocop.yml +15 -7
  6. data/NEWS.ja.md +108 -0
  7. data/NEWS.md +108 -0
  8. data/README.md +7 -6
  9. data/Rakefile +7 -2
  10. data/bin/review +2 -4
  11. data/bin/review-catalog-converter +3 -3
  12. data/bin/review-check +6 -8
  13. data/bin/review-checkdep +1 -4
  14. data/bin/review-compile +2 -5
  15. data/bin/review-epub2html +1 -4
  16. data/bin/review-epubmaker +3 -4
  17. data/bin/review-idgxmlmaker +1 -3
  18. data/bin/review-index +11 -5
  19. data/bin/review-init +1 -4
  20. data/bin/review-pdfmaker +1 -3
  21. data/bin/review-preproc +2 -4
  22. data/bin/review-textmaker +1 -3
  23. data/bin/review-update +1 -4
  24. data/bin/review-validate +3 -3
  25. data/bin/review-vol +1 -4
  26. data/bin/review-webmaker +1 -3
  27. data/doc/config.yml.sample +21 -5
  28. data/doc/config.yml.sample-simple +1 -1
  29. data/doc/format.ja.md +21 -10
  30. data/doc/format.md +21 -10
  31. data/doc/quickstart.ja.md +11 -1
  32. data/doc/quickstart.md +11 -2
  33. data/lib/review.rb +1 -1
  34. data/lib/review/book/base.rb +4 -0
  35. data/lib/review/book/book_unit.rb +3 -0
  36. data/lib/review/book/chapter.rb +3 -0
  37. data/lib/review/book/index.rb +1 -0
  38. data/lib/review/book/volume.rb +1 -0
  39. data/lib/review/builder.rb +8 -1
  40. data/lib/review/call_hook.rb +20 -0
  41. data/lib/review/catalog.rb +1 -0
  42. data/lib/review/compiler.rb +27 -10
  43. data/lib/review/configure.rb +64 -7
  44. data/lib/review/epubmaker.rb +93 -96
  45. data/lib/review/epubmaker/content.rb +113 -0
  46. data/lib/review/epubmaker/epubcommon.rb +372 -0
  47. data/lib/review/epubmaker/epubv2.rb +178 -0
  48. data/lib/review/epubmaker/epubv3.rb +231 -0
  49. data/lib/review/epubmaker/producer.rb +168 -0
  50. data/lib/review/epubmaker/reviewheaderlistener.rb +12 -2
  51. data/lib/review/epubmaker/zip_exporter.rb +84 -0
  52. data/lib/review/exception.rb +6 -0
  53. data/lib/review/htmlbuilder.rb +36 -49
  54. data/lib/review/htmlutils.rb +1 -1
  55. data/lib/review/i18n.rb +1 -0
  56. data/lib/review/idgxmlbuilder.rb +33 -30
  57. data/lib/review/idgxmlmaker.rb +3 -1
  58. data/lib/review/img_math.rb +245 -0
  59. data/lib/review/index_builder.rb +1 -0
  60. data/lib/review/init.rb +4 -4
  61. data/lib/review/latexbox.rb +58 -0
  62. data/lib/review/latexbuilder.rb +30 -19
  63. data/lib/review/latexutils.rb +9 -1
  64. data/lib/review/lineinput.rb +112 -2
  65. data/lib/review/logger.rb +41 -2
  66. data/lib/review/makerhelper.rb +2 -205
  67. data/lib/review/markdownbuilder.rb +32 -1
  68. data/lib/review/pdfmaker.rb +31 -29
  69. data/lib/review/plaintextbuilder.rb +9 -1
  70. data/lib/review/preprocessor.rb +12 -6
  71. data/lib/review/rstbuilder.rb +1 -1
  72. data/lib/review/sec_counter.rb +1 -0
  73. data/lib/review/template.rb +6 -0
  74. data/lib/review/textmaker.rb +11 -7
  75. data/lib/review/textutils.rb +2 -10
  76. data/lib/review/tocprinter.rb +85 -68
  77. data/lib/review/topbuilder.rb +18 -11
  78. data/lib/review/update.rb +5 -6
  79. data/lib/review/version.rb +1 -1
  80. data/lib/review/volumeprinter.rb +4 -5
  81. data/lib/review/webmaker.rb +18 -13
  82. data/lib/review/webtocprinter.rb +10 -9
  83. data/lib/review/yamlloader.rb +2 -1
  84. data/review.gemspec +5 -3
  85. data/samples/sample-book/src/config-epub2.yml +1 -1
  86. data/samples/sample-book/src/config.yml +1 -1
  87. data/samples/sample-book/src/lib/tasks/review.rake +17 -1
  88. data/samples/syntax-book/ch01.re +1 -1
  89. data/samples/syntax-book/ch02.re +21 -6
  90. data/samples/syntax-book/ch03.re +1 -1
  91. data/samples/syntax-book/images/img3-2.png +0 -0
  92. data/templates/html/_colophon.html.erb +23 -0
  93. data/templates/html/_colophon_history.html.erb +9 -0
  94. data/templates/html/_cover.html.erb +10 -0
  95. data/templates/html/_part_body.html.erb +6 -0
  96. data/templates/html/_titlepage.html.erb +20 -0
  97. data/templates/html/layout-html5.html.erb +6 -0
  98. data/templates/html/layout-xhtml1.html.erb +6 -0
  99. data/templates/latex/config.erb +8 -0
  100. data/templates/latex/review-jlreq/review-base.sty +4 -5
  101. data/templates/latex/review-jlreq/review-jlreq.cls +10 -2
  102. data/templates/latex/review-jlreq/review-style.sty +6 -1
  103. data/templates/latex/review-jlreq/review-tcbox.sty +348 -0
  104. data/templates/latex/review-jlreq/reviewmacro.sty +5 -0
  105. data/templates/latex/review-jsbook/review-base.sty +5 -7
  106. data/templates/latex/review-jsbook/review-jsbook.cls +10 -2
  107. data/templates/latex/review-jsbook/review-style.sty +6 -1
  108. data/templates/latex/review-jsbook/review-tcbox.sty +348 -0
  109. data/templates/latex/review-jsbook/reviewmacro.sty +5 -0
  110. data/templates/opf/epubv2.opf.erb +7 -7
  111. data/templates/opf/epubv3.opf.erb +7 -7
  112. data/templates/opf/opf_manifest_epubv2.opf.erb +10 -0
  113. data/templates/opf/opf_manifest_epubv3.opf.erb +10 -0
  114. data/templates/opf/opf_metainfo_epubv2.opf.erb +17 -0
  115. data/templates/opf/opf_metainfo_epubv3.opf.erb +49 -0
  116. data/templates/opf/opf_tocx_epubv2.opf.erb +9 -0
  117. data/templates/opf/opf_tocx_epubv3.opf.erb +17 -0
  118. data/templates/web/html/layout-html5.html.erb +6 -5
  119. data/templates/web/html/layout-xhtml1.html.erb +6 -0
  120. data/test/assets/header_listener.html +35 -0
  121. data/test/assets/img_math/img1.png +0 -0
  122. data/test/assets/img_math/img2.png +0 -0
  123. data/test/assets/img_math/img3.png +0 -0
  124. data/test/assets/syntax_book_index_detail.txt +58 -0
  125. data/test/assets/test_template.tex +4 -1
  126. data/test/assets/test_template_backmatter.tex +4 -1
  127. data/test/run_test.rb +1 -1
  128. data/test/test_book_chapter.rb +2 -2
  129. data/test/test_catalog_converter_cmd.rb +1 -1
  130. data/test/test_epub3maker.rb +168 -124
  131. data/test/test_epubmaker.rb +243 -131
  132. data/test/test_epubmaker_cmd.rb +2 -2
  133. data/test/test_helper.rb +5 -4
  134. data/test/test_htmlbuilder.rb +64 -6
  135. data/test/test_idgxmlbuilder.rb +13 -0
  136. data/test/test_idgxmlmaker_cmd.rb +7 -3
  137. data/test/test_img_math.rb +111 -0
  138. data/test/test_indexbuilder.rb +5 -5
  139. data/test/test_latexbuilder.rb +107 -4
  140. data/test/test_lineinput.rb +20 -93
  141. data/test/test_markdownbuilder.rb +29 -0
  142. data/test/test_pdfmaker.rb +71 -0
  143. data/test/test_pdfmaker_cmd.rb +2 -2
  144. data/test/test_plaintextbuilder.rb +10 -18
  145. data/test/test_reviewheaderlistener.rb +49 -0
  146. data/test/test_template.rb +12 -2
  147. data/test/test_textmaker_cmd.rb +5 -1
  148. data/test/test_tocprinter.rb +46 -0
  149. data/test/test_topbuilder.rb +6 -1
  150. data/test/test_update.rb +34 -34
  151. data/test/test_zip_exporter.rb +5 -6
  152. metadata +91 -17
  153. data/lib/epubmaker.rb +0 -23
  154. data/lib/epubmaker/content.rb +0 -111
  155. data/lib/epubmaker/epubcommon.rb +0 -449
  156. data/lib/epubmaker/epubv2.rb +0 -142
  157. data/lib/epubmaker/epubv3.rb +0 -235
  158. data/lib/epubmaker/producer.rb +0 -375
  159. data/lib/epubmaker/zip_exporter.rb +0 -81
  160. data/lib/lineinput.rb +0 -155
@@ -4,7 +4,7 @@ require 'fileutils'
4
4
  require 'yaml'
5
5
  require 'rbconfig'
6
6
 
7
- REVIEW_EPUBMAKER = File.expand_path('../bin/review-epubmaker', File.dirname(__FILE__))
7
+ REVIEW_EPUBMAKER = File.expand_path('../bin/review-epubmaker', __dir__)
8
8
 
9
9
  class EPUBMakerCmdTest < Test::Unit::TestCase
10
10
  def setup
@@ -12,7 +12,7 @@ class EPUBMakerCmdTest < Test::Unit::TestCase
12
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
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,14 @@ 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
+ @builder = HTMLBuilder.new(img_math: img_math)
19
20
  @compiler = ReVIEW::Compiler.new(@builder)
20
21
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
21
22
  location = Location.new(nil, nil)
22
23
  @builder.bind(@compiler, @chapter, location)
23
24
  I18n.setup('ja')
25
+ @skip_pygments = true # temporary suppress pygments test
24
26
  end
25
27
 
26
28
  def test_xmlns_ops_prefix_epub3
@@ -358,12 +360,26 @@ EOS
358
360
  rescue LoadError
359
361
  return true
360
362
  end
361
- @config['mathml'] = true
363
+ @config['math_format'] = 'mathml'
362
364
  actual = compile_inline('@<m>{\\frac{-b \\pm \\sqrt{b^2 - 4ac\\}\\}{2a\\}}')
363
- @config['mathml'] = nil
364
365
  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
366
  end
366
367
 
368
+ def test_inline_mathjax
369
+ @config['math_format'] = 'mathjax'
370
+ actual = compile_inline('@<m>{\\frac{-b \\pm \\sqrt{b^2 - 4ac\\}\\}{2a\\}}')
371
+ assert_equal %Q(<span class="equation">\\( \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a} \\)</span>), actual
372
+
373
+ content = <<-EOF
374
+ //texequation{
375
+ \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}
376
+ //}
377
+ EOF
378
+ actual = compile_block(content)
379
+ expected = %Q(<div class="equation">\n$$\\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}$$\n</div>\n)
380
+ assert_equal expected, actual
381
+ end
382
+
367
383
  def test_inline_img
368
384
  def @chapter.image(_id)
369
385
  item = Book::Index::Item.new('sampleimg', 1, 'sample photo')
@@ -614,6 +630,20 @@ EOS
614
630
  EOS
615
631
  assert_equal expected, actual
616
632
 
633
+ actual = compile_block("//image[sampleimg][]{\n//}\n")
634
+ expected = <<-EOS
635
+ <div id="sampleimg" class="image">
636
+ <img src="images/chap1-sampleimg.png" alt="" />
637
+ <p class="caption">
638
+ 図1.1:
639
+ </p>
640
+ </div>
641
+ EOS
642
+ assert_equal expected, actual
643
+
644
+ actual = compile_block("//image[sampleimg][][]{\n//}\n")
645
+ assert_equal expected, actual
646
+
617
647
  @config['caption_position']['image'] = 'top'
618
648
  actual = compile_block("//image[sampleimg][sample photo]{\n//}\n")
619
649
  expected = <<-EOS
@@ -730,6 +760,12 @@ EOS
730
760
  </div>
731
761
  EOS
732
762
  assert_equal expected, actual
763
+
764
+ actual = compile_block("//indepimage[sampleimg][]\n")
765
+ assert_equal expected, actual
766
+
767
+ actual = compile_block("//indepimage[sampleimg][][]\n")
768
+ assert_equal expected, actual
733
769
  end
734
770
 
735
771
  def test_indepimage_with_metric
@@ -944,6 +980,8 @@ EOS
944
980
  end
945
981
 
946
982
  def test_list_pygments
983
+ return true if @skip_pygments
984
+
947
985
  def @chapter.list(_id)
948
986
  Book::Index::Item.new('samplelist', 1)
949
987
  end
@@ -971,6 +1009,8 @@ test&lt;i&gt;2&lt;/i&gt;
971
1009
  end
972
1010
 
973
1011
  def test_list_pygments_lang
1012
+ return true if @skip_pygments
1013
+
974
1014
  def @chapter.list(_id)
975
1015
  Book::Index::Item.new('samplelist', 1)
976
1016
  end
@@ -999,6 +1039,8 @@ EOS
999
1039
  end
1000
1040
 
1001
1041
  def test_list_pygments_nulllang
1042
+ return true if @skip_pygments
1043
+
1002
1044
  def @chapter.list(_id)
1003
1045
  Book::Index::Item.new('samplelist', 1)
1004
1046
  end
@@ -1191,6 +1233,8 @@ EOS
1191
1233
  end
1192
1234
 
1193
1235
  def test_listnum_pygments_lang
1236
+ return true if @skip_pygments
1237
+
1194
1238
  def @chapter.list(_id)
1195
1239
  Book::Index::Item.new('samplelist', 1)
1196
1240
  end
@@ -1218,6 +1262,8 @@ EOS
1218
1262
  end
1219
1263
 
1220
1264
  def test_listnum_pygments_lang_linenum
1265
+ return true if @skip_pygments
1266
+
1221
1267
  def @chapter.list(_id)
1222
1268
  Book::Index::Item.new('samplelist', 1)
1223
1269
  end
@@ -1246,6 +1292,8 @@ EOS
1246
1292
  end
1247
1293
 
1248
1294
  def test_listnum_pygments_lang_without_lang
1295
+ return true if @skip_pygments
1296
+
1249
1297
  def @chapter.list(_id)
1250
1298
  Book::Index::Item.new('samplelist', 1)
1251
1299
  end
@@ -1432,6 +1480,8 @@ EOS
1432
1480
  end
1433
1481
 
1434
1482
  def test_emlist_pygments_lang
1483
+ return true if @skip_pygments
1484
+
1435
1485
  begin
1436
1486
  require 'pygments'
1437
1487
  rescue LoadError
@@ -1568,6 +1618,8 @@ EOS
1568
1618
  end
1569
1619
 
1570
1620
  def test_cmd_pygments
1621
+ return true if @skip_pygments
1622
+
1571
1623
  begin
1572
1624
  require 'pygments'
1573
1625
  rescue LoadError
@@ -1614,13 +1666,16 @@ EOS
1614
1666
  def test_texequation
1615
1667
  return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1616
1668
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1669
+
1617
1670
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
1618
1671
  'ch01.re' => "= test\n\n//texequation{\np \\land \\bm{P} q\n//}\n") do |dir, book, _files|
1619
1672
  @book = book
1620
1673
  @book.config = @config
1621
- @config['imgmath'] = true
1674
+ @config['math_format'] = 'imgmath'
1622
1675
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
1623
1676
  location = Location.new(nil, nil)
1677
+ img_math = ReVIEW::ImgMath.new(@config)
1678
+ @builder = HTMLBuilder.new(img_math: img_math)
1624
1679
  @builder.bind(@compiler, @chapter, location)
1625
1680
  FileUtils.mkdir_p(File.join(dir, 'images'))
1626
1681
  expected = <<-EOB
@@ -1644,14 +1699,17 @@ EOS
1644
1699
  # Re:VIEW 3 never fail on defer mode. This test is only for Re:VIEW 2.
1645
1700
  return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1646
1701
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1702
+
1647
1703
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
1648
1704
  'ch01.re' => "= test\n\n//texequation{\np \\land \\bm{P}} q\n//}\n") do |dir, book, _files|
1649
1705
  @book = book
1650
1706
  @book.config = @config
1651
1707
  @config['review_version'] = 2
1652
- @config['imgmath'] = true
1708
+ @config['math_format'] = 'imgmath'
1653
1709
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
1654
1710
  location = Location.new(nil, nil)
1711
+ img_math = ReVIEW::ImgMath.new(@config)
1712
+ @builder = HTMLBuilder.new(img_math: img_math)
1655
1713
  @builder.bind(@compiler, @chapter, location)
1656
1714
  FileUtils.mkdir_p(File.join(dir, 'images'))
1657
1715
  tmpio = $stderr
@@ -2756,7 +2814,7 @@ EOB
2756
2814
  end
2757
2815
  @book.config['words_file'] = File.join(dir, 'words.csv')
2758
2816
  io = StringIO.new
2759
- @builder.instance_eval{ @logger = ReVIEW::Logger.new(io) }
2817
+ @builder.instance_eval { @logger = ReVIEW::Logger.new(io) }
2760
2818
  actual = compile_block('@<w>{F} @<w>{B} @<wb>{B} @<w>{N}')
2761
2819
  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
2820
  assert_match(/WARN --: :1: word not bound: N/, io.string)
@@ -48,6 +48,19 @@ class IDGXMLBuidlerTest < Test::Unit::TestCase
48
48
  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
49
  end
50
50
 
51
+ def test_headline_secttags
52
+ @config['structuredxml'] = true
53
+ 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")
54
+ expected = '<chapter id="chap:1"><title aid:pstyle="h1">第1章 HEAD1</title><?dtp level="1" section="第1章 HEAD1"?>' +
55
+ '<sect id="sect:1.1"><title aid:pstyle="h2">1.1 HEAD1-1</title><?dtp level="2" section="1.1 HEAD1-1"?>' +
56
+ '<sect2 id="sect:1.1.1"><title aid:pstyle="h3">HEAD1-1-1</title><?dtp level="3" section="HEAD1-1-1"?></sect2></sect>' +
57
+ '<sect id="sect:1.2"><title aid:pstyle="h2">1.2 HEAD1-2</title><?dtp level="2" section="1.2 HEAD1-2"?>' +
58
+ '<sect3 id="sect:1.2.0.1"><title aid:pstyle="h4">HEAD1-2-0-1</title><?dtp level="4" section="HEAD1-2-0-1"?>' +
59
+ '<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>' +
60
+ '<sect id="sect:1.3"><title aid:pstyle="h2">1.3 HEAD1-3</title><?dtp level="2" section="1.3 HEAD1-3"?></sect></chapter>'
61
+ assert_equal expected, actual
62
+ end
63
+
51
64
  def test_label
52
65
  actual = compile_block("//label[label_test]\n")
53
66
  assert_equal %Q(<label id='label_test' />), actual
@@ -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))
@@ -0,0 +1,111 @@
1
+ require 'test_helper'
2
+ require 'review/htmlbuilder'
3
+ require 'review/img_math'
4
+ require 'mini_magick'
5
+
6
+ class ImgMathTest < Test::Unit::TestCase
7
+ def setup
8
+ @config = ReVIEW::Configure.values
9
+ @tmpdir = Dir.mktmpdir
10
+ @config.merge!(
11
+ 'math_format' => 'imgmath',
12
+ 'texcommand' => 'uplatex',
13
+ 'imagedir' => @tmpdir
14
+ )
15
+ @config['imgmath_options']['fontsize'] = 24
16
+ @img_math = ReVIEW::ImgMath.new(@config)
17
+ end
18
+
19
+ def teardown
20
+ @img_math.cleanup_mathimg
21
+ FileUtils.rm_rf(@tmpdir)
22
+ end
23
+
24
+ def test_defer_math_image_pathname
25
+ str1 = '$A > B \\gg C$'
26
+ key1 = Digest::SHA256.hexdigest(str1)
27
+ img_path1 = @img_math.defer_math_image(str1, key1)
28
+
29
+ assert_equal "_gen_#{key1}.png", File.basename(img_path1)
30
+ end
31
+
32
+ def test_defer_math_image
33
+ unless support_latex_in_tests?
34
+ $stderr.puts 'skip test_defer_math_image'
35
+ return true
36
+ end
37
+
38
+ str1 = '$\\sum_{i=1}^nf_n(x) \\in \\mathbb{R}$'
39
+ key1 = Digest::SHA256.hexdigest(str1)
40
+ img_path1 = @img_math.defer_math_image(str1, key1)
41
+ str2 = '$\\sum_{i=1}^nf_n(X) \\in \\mathbb{R}$'
42
+ key2 = Digest::SHA256.hexdigest(str2)
43
+ img_path2 = @img_math.defer_math_image(str2, key2)
44
+ @img_math.make_math_images
45
+
46
+ assert File.exist?(img_path1)
47
+ assert File.exist?(img_path2)
48
+
49
+ val1 = compare_images(img_path1, File.join(assets_dir, 'img_math/img1.png'))
50
+ assert_equal 0, val1
51
+
52
+ val2 = compare_images(img_path2, File.join(assets_dir, 'img_math/img2.png'))
53
+ assert_equal 0, val2
54
+
55
+ val3 = compare_images(img_path1, img_path2)
56
+ assert val3 > 100
57
+ end
58
+
59
+ def test_make_math_image_pathname
60
+ unless support_latex_in_tests?
61
+ $stderr.puts 'skip test_make_math_image_pathname'
62
+ return true
63
+ end
64
+
65
+ str1 = '$A > B \\gg C$'
66
+ key1 = Digest::SHA256.hexdigest(str1)
67
+ img_path1 = @img_math.make_math_image(str1, key1)
68
+
69
+ assert_equal "_gen_#{key1}.png", File.basename(img_path1)
70
+ end
71
+
72
+ def test_make_math_image
73
+ unless support_latex_in_tests?
74
+ $stderr.puts 'skip test_make_math_image'
75
+ return true
76
+ end
77
+ str1 = '$A > B \\gg C$'
78
+ key1 = Digest::SHA256.hexdigest(str1)
79
+ img_path1 = @img_math.make_math_image(str1, key1)
80
+
81
+ assert File.exist?(img_path1)
82
+
83
+ val1 = compare_images(img_path1, File.join(assets_dir, 'img_math/img3.png'))
84
+ assert val1 < 10
85
+ end
86
+
87
+ private
88
+
89
+ def compare_images(image1, image2)
90
+ compare = MiniMagick::Tool::Compare.new(whiny: false)
91
+ compare << '-fuzz'
92
+ compare << '10%'
93
+ compare.metric('AE')
94
+ compare << image1
95
+ compare << image2
96
+ compare << File.join(@tmpdir, 'diff.jpg')
97
+
98
+ compare.call do |_, dist, _|
99
+ return dist.to_i
100
+ end
101
+ end
102
+
103
+ def support_latex_in_tests?
104
+ begin
105
+ `uplatex -v`
106
+ true
107
+ rescue
108
+ false
109
+ end
110
+ end
111
+ end
@@ -24,28 +24,28 @@ class IndexBuidlerTest < Test::Unit::TestCase
24
24
 
25
25
  def test_check_id
26
26
  io = StringIO.new
27
- @b.instance_eval{ @logger = ReVIEW::Logger.new(io) }
27
+ @b.instance_eval { @logger = ReVIEW::Logger.new(io) }
28
28
  @b.check_id('ABC')
29
29
  assert_match('', io.string)
30
30
 
31
31
  %w(# % \\ { } [ ] ~ / $ ' " | * ? & < > `).each do |c|
32
32
  io = StringIO.new
33
- @b.instance_eval{ @logger = ReVIEW::Logger.new(io) }
33
+ @b.instance_eval { @logger = ReVIEW::Logger.new(io) }
34
34
  @b.check_id("id#{c}")
35
35
  assert_match(/deprecated ID: `#{Regexp.escape(c)}` in `id#{Regexp.escape(c)}`/, io.string)
36
36
  end
37
37
  io = StringIO.new
38
- @b.instance_eval{ @logger = ReVIEW::Logger.new(io) }
38
+ @b.instance_eval { @logger = ReVIEW::Logger.new(io) }
39
39
  @b.check_id('A B C#')
40
40
  assert_match(/deprecated ID: ` ` in `A B C#`/, io.string)
41
41
 
42
42
  io = StringIO.new
43
- @b.instance_eval{ @logger = ReVIEW::Logger.new(io) }
43
+ @b.instance_eval { @logger = ReVIEW::Logger.new(io) }
44
44
  @b.check_id("A\tB")
45
45
  assert_match(/deprecated ID: `\t` in `A\tB`/, io.string)
46
46
 
47
47
  io = StringIO.new
48
- @b.instance_eval{ @logger = ReVIEW::Logger.new(io) }
48
+ @b.instance_eval { @logger = ReVIEW::Logger.new(io) }
49
49
  @b.check_id('.ABC')
50
50
  assert_match(/deprecated ID: `.ABC` begins from `.`/, io.string)
51
51
  end
@@ -197,6 +197,16 @@ EOS
197
197
  assert_equal 'abc\\reviewunderline{def}ghi', actual
198
198
  end
199
199
 
200
+ def test_inline_ins
201
+ actual = compile_inline('abc@<ins>{def}ghi')
202
+ assert_equal 'abc\\reviewinsert{def}ghi', actual
203
+ end
204
+
205
+ def test_inline_del
206
+ actual = compile_inline('abc@<del>{def}ghi')
207
+ assert_equal 'abc\\reviewstrike{def}ghi', actual
208
+ end
209
+
200
210
  def test_inline_bou
201
211
  actual = compile_inline('傍点の@<bou>{テスト}です。')
202
212
  assert_equal '傍点の\\reviewbou{テスト}です。', actual
@@ -296,13 +306,65 @@ EOS
296
306
  return true
297
307
  end
298
308
  tmpdir = Dir.mktmpdir
299
- File.write(File.join(tmpdir, 'sample.dic'), "強運\tはーどらっく\n")
309
+ File.write(File.join(tmpdir, 'sample.dic'), "強運\tはーどらっく\nmain(ブロック)\tmain{|}\n")
300
310
  @book.config['pdfmaker']['makeindex'] = true
301
311
  @book.config['pdfmaker']['makeindex_dic'] = "#{tmpdir}/sample.dic"
302
312
  @builder.setup_index
303
313
  actual = compile_inline('@<hidx>{漢字}@<hidx>{強運}@<hidx>{項目@1<<>>項目@2}')
304
- FileUtils.remove_entry_secure(tmpdir)
305
314
  assert_equal %Q(\\index{かんじ@漢字}\\index{はーどらっく@強運}\\index{こうもく"@1@項目"@1!こうもく"@2@項目"@2}), actual
315
+ actual = compile_inline('@<hidx>{main(ブロック)}@<hidx>{あいうえお{\}}')
316
+ FileUtils.remove_entry_secure(tmpdir)
317
+ assert_equal %Q(\\index{main{|}@main(ブロック)}\\index{あいうえお{}@あいうえお\\reviewleftcurlybrace{}\\reviewrightcurlybrace{}}), actual
318
+ end
319
+
320
+ def test_inline_idx_escape
321
+ # as is
322
+ %w[a あ ' ( ) = ` + ; * : , . ? /].each do |c|
323
+ actual = @builder.index(c)
324
+ assert_equal %Q(\\index{#{c}}), actual
325
+ end
326
+ actual = @builder.index('[')
327
+ assert_equal %Q(\\index{[}), actual
328
+ actual = @builder.index(']')
329
+ assert_equal %Q(\\index{]}), actual
330
+
331
+ # escape display string by "
332
+ %w[! " @].each do |c|
333
+ actual = @builder.index(c)
334
+ assert_equal %Q(\\index{"#{c}@"#{c}}), actual
335
+ end
336
+
337
+ # escape display string by \
338
+ %w[# % &].each do |c|
339
+ actual = @builder.index(c)
340
+ assert_equal %Q(\\index{#{c}@\\#{c}}), actual
341
+ end
342
+
343
+ # escape display string by macro
344
+ actual = @builder.index('$')
345
+ assert_equal %Q(\\index{$@\\textdollar{}}), actual
346
+ actual = @builder.index('-')
347
+ assert_equal %Q(\\index{-@{-}}), actual
348
+ actual = @builder.index('~')
349
+ assert_equal %Q(\\index{~@\\textasciitilde{}}), actual
350
+ actual = @builder.index('^')
351
+ assert_equal %Q(\\index{^@\\textasciicircum{}}), actual
352
+ actual = @builder.index('\\')
353
+ assert_equal %Q(\\index{\\@\\reviewbackslash{}}), actual
354
+ actual = @builder.index('<')
355
+ assert_equal %Q(\\index{<@\\textless{}}), actual
356
+ actual = @builder.index('>')
357
+ assert_equal %Q(\\index{>@\\textgreater{}}), actual
358
+ actual = @builder.index('_')
359
+ assert_equal %Q(\\index{_@\\textunderscore{}}), actual
360
+
361
+ # escape both sort key and display string
362
+ actual = @builder.index('{')
363
+ assert_equal %Q(\\index{{@\\reviewleftcurlybrace{}}), actual
364
+ actual = @builder.index('|')
365
+ assert_equal %Q(\\index{|@\\textbar{}}), actual
366
+ actual = @builder.index('}')
367
+ assert_equal %Q(\\index{}@\\reviewrightcurlybrace{}}), actual
306
368
  end
307
369
 
308
370
  def test_jis_x_0201_kana
@@ -1039,6 +1101,19 @@ EOS
1039
1101
  \\end{reviewimage}
1040
1102
  EOS
1041
1103
  assert_equal expected, actual
1104
+
1105
+ actual = compile_block("//image[sampleimg][]{\n//}\n")
1106
+ expected = <<-EOS
1107
+ \\begin{reviewimage}%%sampleimg
1108
+ \\reviewimagecaption{}
1109
+ \\label{image:chap1:sampleimg}
1110
+ \\reviewincludegraphics[width=\\maxwidth]{./images/chap1-sampleimg.png}
1111
+ \\end{reviewimage}
1112
+ EOS
1113
+ assert_equal expected, actual
1114
+
1115
+ actual = compile_block("//image[sampleimg][][]{\n//}\n")
1116
+ assert_equal expected, actual
1042
1117
  end
1043
1118
 
1044
1119
  def test_image_with_metric
@@ -1187,6 +1262,12 @@ EOS
1187
1262
  \\end{reviewimage}
1188
1263
  EOS
1189
1264
  assert_equal expected, actual
1265
+
1266
+ actual = compile_block("//indepimage[sampleimg][]\n")
1267
+ assert_equal expected, actual
1268
+
1269
+ actual = compile_block("//indepimage[sampleimg][][]\n")
1270
+ assert_equal expected, actual
1190
1271
  end
1191
1272
 
1192
1273
  def test_indepimage_with_metric
@@ -1286,7 +1367,7 @@ EOS
1286
1367
  end
1287
1368
 
1288
1369
  io = StringIO.new
1289
- @builder.instance_eval{ @logger = ReVIEW::Logger.new(io) }
1370
+ @builder.instance_eval { @logger = ReVIEW::Logger.new(io) }
1290
1371
 
1291
1372
  actual = compile_block("//indepimage[sample_img_nofile_][sample photo]\n")
1292
1373
  expected = <<-EOS
@@ -1324,6 +1405,16 @@ ccc & ddd\\textless{}\\textgreater{}\\& \\\\ \\hline
1324
1405
  EOS
1325
1406
  assert_equal expected, actual
1326
1407
 
1408
+ actual = compile_block("//table[foo][]{\naaa\tbbb\n------------\nccc\tddd<>&\n//}\n")
1409
+ expected = <<-EOS
1410
+ \\begin{reviewtable}{|l|l|}
1411
+ \\hline
1412
+ \\reviewth{aaa} & \\reviewth{bbb} \\\\ \\hline
1413
+ ccc & ddd\\textless{}\\textgreater{}\\& \\\\ \\hline
1414
+ \\end{reviewtable}
1415
+ EOS
1416
+ assert_equal expected, actual
1417
+
1327
1418
  @config['caption_position']['table'] = 'bottom'
1328
1419
  actual = compile_block("//table[foo][FOO]{\naaa\tbbb\n------------\nccc\tddd<>&\n//}\n")
1329
1420
  expected = <<-EOS
@@ -1491,6 +1582,18 @@ EOS
1491
1582
  EOS
1492
1583
  assert_equal expected, actual
1493
1584
 
1585
+ actual = compile_block("//imgtable[sampleimg][]{\n//}\n")
1586
+ expected = <<-EOS
1587
+ \\label{table:chap1:sampleimg}
1588
+ \\begin{reviewimage}%%sampleimg
1589
+ \\reviewincludegraphics[width=\\maxwidth]{./images/chap1-sampleimg.png}
1590
+ \\end{reviewimage}
1591
+ EOS
1592
+ assert_equal expected, actual
1593
+
1594
+ actual = compile_block("//imgtable[sampleimg][][]{\n//}\n")
1595
+ assert_equal expected, actual
1596
+
1494
1597
  @book.config['pdfmaker']['use_original_image_size'] = true
1495
1598
  actual = compile_block("//imgtable[sampleimg][test for imgtable]{\n//}\n")
1496
1599
 
@@ -2312,7 +2415,7 @@ EOB
2312
2415
  @book.config['words_file'] = File.join(dir, 'words.csv')
2313
2416
 
2314
2417
  io = StringIO.new
2315
- @builder.instance_eval{ @logger = ReVIEW::Logger.new(io) }
2418
+ @builder.instance_eval { @logger = ReVIEW::Logger.new(io) }
2316
2419
  actual = compile_block('@<w>{F} @<w>{B} @<wb>{B} @<w>{N}')
2317
2420
  expected = <<-EOS
2318
2421