review 5.2.0 → 5.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +1 -1
  3. data/.github/workflows/ruby-win.yml +1 -1
  4. data/.github/workflows/ruby.yml +1 -1
  5. data/.rubocop.yml +1 -319
  6. data/NEWS.ja.md +116 -0
  7. data/NEWS.md +117 -0
  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 +6 -8
  13. data/bin/review-index +1 -1
  14. data/bin/review-preproc +1 -1
  15. data/bin/review-validate +2 -2
  16. data/doc/config.yml.sample +7 -1
  17. data/doc/config.yml.sample-simple +1 -1
  18. data/doc/format.ja.md +34 -4
  19. data/doc/format.md +32 -3
  20. data/lib/review/book/base.rb +3 -3
  21. data/lib/review/book/book_unit.rb +13 -3
  22. data/lib/review/book/chapter.rb +1 -1
  23. data/lib/review/book/index.rb +7 -4
  24. data/lib/review/book/part.rb +12 -13
  25. data/lib/review/book/volume.rb +1 -1
  26. data/lib/review/builder.rb +82 -28
  27. data/lib/review/catalog.rb +6 -5
  28. data/lib/review/compiler.rb +20 -14
  29. data/lib/review/configure.rb +5 -2
  30. data/lib/review/epub2html.rb +12 -12
  31. data/lib/review/epubmaker/content.rb +1 -1
  32. data/lib/review/epubmaker/epubcommon.rb +47 -45
  33. data/lib/review/epubmaker/epubv2.rb +2 -1
  34. data/lib/review/epubmaker/epubv3.rb +5 -4
  35. data/lib/review/epubmaker/producer.rb +3 -3
  36. data/lib/review/epubmaker/reviewheaderlistener.rb +1 -1
  37. data/lib/review/epubmaker.rb +35 -32
  38. data/lib/review/extentions/string.rb +1 -1
  39. data/lib/review/htmlbuilder.rb +65 -15
  40. data/lib/review/htmlutils.rb +17 -17
  41. data/lib/review/i18n.rb +3 -3
  42. data/lib/review/i18n.yml +6 -0
  43. data/lib/review/idgxmlbuilder.rb +42 -21
  44. data/lib/review/idgxmlmaker.rb +15 -13
  45. data/lib/review/img_math.rb +1 -0
  46. data/lib/review/index_builder.rb +100 -38
  47. data/lib/review/init.rb +4 -4
  48. data/lib/review/latexbuilder.rb +69 -34
  49. data/lib/review/lineinput.rb +3 -3
  50. data/lib/review/location.rb +1 -1
  51. data/lib/review/logger.rb +21 -21
  52. data/lib/review/makerhelper.rb +3 -3
  53. data/lib/review/markdownbuilder.rb +16 -8
  54. data/lib/review/pdfmaker.rb +40 -21
  55. data/lib/review/plaintextbuilder.rb +8 -7
  56. data/lib/review/preprocessor/repository.rb +1 -1
  57. data/lib/review/preprocessor.rb +5 -5
  58. data/lib/review/rstbuilder.rb +11 -2
  59. data/lib/review/textmaker.rb +20 -18
  60. data/lib/review/textutils.rb +5 -6
  61. data/lib/review/tocprinter.rb +11 -6
  62. data/lib/review/topbuilder.rb +89 -12
  63. data/lib/review/update.rb +16 -8
  64. data/lib/review/version.rb +1 -1
  65. data/lib/review/volumeprinter.rb +9 -9
  66. data/lib/review/webmaker.rb +32 -32
  67. data/lib/review/webtocprinter.rb +10 -10
  68. data/lib/review/yamlloader.rb +36 -2
  69. data/review.gemspec +2 -0
  70. data/samples/sample-book/src/config.yml +0 -1
  71. data/samples/syntax-book/ch02.re +16 -1
  72. data/templates/html/_titlepage.html.erb +9 -17
  73. data/templates/latex/config.erb +3 -0
  74. data/templates/latex/review-jlreq/review-base.sty +2 -1
  75. data/templates/latex/review-jlreq/review-jlreq.cls +36 -3
  76. data/templates/latex/review-jsbook/review-base.sty +7 -1
  77. data/templates/latex/review-jsbook/review-jsbook.cls +31 -4
  78. data/templates/opf/opf_manifest_epubv2.opf.erb +1 -1
  79. data/templates/opf/opf_manifest_epubv3.opf.erb +1 -1
  80. data/test/assets/syntax_book_index_detail.txt +10 -8
  81. data/test/assets/test_template.tex +4 -1
  82. data/test/assets/test_template_backmatter.tex +4 -1
  83. data/test/book_test_helper.rb +10 -10
  84. data/test/test_book_chapter.rb +25 -2
  85. data/test/test_builder.rb +5 -3
  86. data/test/test_epub3maker.rb +3 -3
  87. data/test/test_epubmaker.rb +14 -29
  88. data/test/test_epubmaker_cmd.rb +2 -2
  89. data/test/test_htmlbuilder.rb +80 -8
  90. data/test/test_idgxmlbuilder.rb +13 -13
  91. data/test/test_idgxmlmaker_cmd.rb +1 -1
  92. data/test/test_img_math.rb +11 -2
  93. data/test/test_index.rb +30 -4
  94. data/test/test_latexbuilder.rb +53 -6
  95. data/test/test_markdownbuilder.rb +45 -0
  96. data/test/test_pdfmaker.rb +19 -0
  97. data/test/test_pdfmaker_cmd.rb +10 -10
  98. data/test/test_plaintextbuilder.rb +45 -4
  99. data/test/test_rstbuilder.rb +13 -0
  100. data/test/test_textmaker_cmd.rb +1 -1
  101. data/test/test_topbuilder.rb +169 -11
  102. data/test/test_yamlloader.rb +28 -42
  103. metadata +19 -4
@@ -4,7 +4,7 @@
4
4
  <% if @coverimage %>
5
5
  <item properties="cover-image" id="cover-<%= @coverimage.id %>" href="<%= @coverimage.file %>" media-type="<%= @coverimage.media %>"/>
6
6
  <% end %>
7
- <% @items.each do |item| %>
7
+ <% @items.sort_by { |x| x.id }.each do |item| %>
8
8
  <item id="<%= item.id %>" href="<%= item.file %>" media-type="<%= item.media %>"<%= item.properties_attribute %>/>
9
9
  <% end %>
10
10
  </manifest>
@@ -26,7 +26,7 @@
26
26
  -----------------------------
27
27
  169C 2L 0.2P 第II部 部見出し■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□
28
28
  =============================
29
- 5652C 175L 10P ch02
29
+ 5858C 186L 11P ch02
30
30
  -----------------------------
31
31
  52C 1L 0.0P 第2章 長い章見出し■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□
32
32
  10C 1L 0.0P 2.1 ブロック命令
@@ -34,13 +34,15 @@
34
34
  338C 8L 0.5P 2.1.2 図
35
35
  709C 22L 1.3P 2.1.3 表
36
36
  1154C 56L 2.8P 2.1.4 囲み記事
37
- 523C 14L 0.8P 2.2 LaTeX式
38
- 11C 1L 0.0P 2.3 インライン命令
39
- 967C 17L 1.3P 2.3.1 書体
40
- 74C 1L 0.0P 2.3.2 見出し内 BOLD,ITALIC,TT,STRONG,EM,CODE,TTB,TTI,AMI,BOU,KW,UNDERLINE,INS、
41
- 797C 22L 1.3P 2.3.3 参照
42
- 39C 2L 0.1P 2.3.4 参考文献
43
- 194C 3L 0.3P 2.3.5 索引
37
+ 110C 2L 0.2P 2.2 後注
38
+ 523C 14L 0.8P 2.3 LaTeX式
39
+ 11C 1L 0.0P 2.4 インライン命令
40
+ 967C 17L 1.3P 2.4.1 書体
41
+ 74C 1L 0.0P 2.4.2 見出し内 BOLD,ITALIC,TT,STRONG,EM,CODE,TTB,TTI,AMI,BOU,KW,UNDERLINE,INS、
42
+ 859C 28L 1.6P 2.4.3 参照
43
+ 39C 2L 0.1P 2.4.4 参考文献
44
+ 194C 3L 0.3P 2.4.5 索引
45
+ 34C 3L 0.1P 2.4.5.1 後注
44
46
  =============================
45
47
  2255C 38L 4P ch03
46
48
  -----------------------------
@@ -1,6 +1,6 @@
1
1
  \documentclass[dvipdfmx]{review-jsbook}
2
2
  \makeatletter
3
- \def\review@reviewversion{5.1.0}
3
+ \def\review@reviewversion{5.3.0}
4
4
  \def\review@texcompiler{uplatex}
5
5
  \def\review@documentclass{review-jsbook}
6
6
 
@@ -61,6 +61,9 @@
61
61
  \ifdefined\reviewchapref\else% for 5.1.0 compatibility
62
62
  \newcommand{\reviewchapref}[2]{\hyperref[##2]{##1}}
63
63
  \fi
64
+ \ifdefined\reviewtcy\else% for 5.3.0 compatibility
65
+ \DeclareRobustCommand{\reviewtcy}[1]{\rensuji{##1}}
66
+ \fi
64
67
  }
65
68
 
66
69
  \makeatother
@@ -1,6 +1,6 @@
1
1
  \documentclass[dvipdfmx]{review-jsbook}
2
2
  \makeatletter
3
- \def\review@reviewversion{5.1.0}
3
+ \def\review@reviewversion{5.3.0}
4
4
  \def\review@texcompiler{uplatex}
5
5
  \def\review@documentclass{review-jsbook}
6
6
 
@@ -72,6 +72,9 @@ some ad content
72
72
  \ifdefined\reviewchapref\else% for 5.1.0 compatibility
73
73
  \newcommand{\reviewchapref}[2]{\hyperref[##2]{##1}}
74
74
  \fi
75
+ \ifdefined\reviewtcy\else% for 5.3.0 compatibility
76
+ \DeclareRobustCommand{\reviewtcy}[1]{\rensuji{##1}}
77
+ \fi
75
78
  }
76
79
 
77
80
  \makeatother
@@ -20,11 +20,11 @@ module BookTestHelper
20
20
  created_files[filename] = path
21
21
  end
22
22
  conf_path = File.expand_path('config.yml', dir)
23
- if File.exist?(conf_path)
24
- config = ReVIEW::Configure.create(yamlfile: conf_path)
25
- else
26
- config = ReVIEW::Configure.values
27
- end
23
+ config = if File.exist?(conf_path)
24
+ ReVIEW::Configure.create(yamlfile: conf_path)
25
+ else
26
+ ReVIEW::Configure.values
27
+ end
28
28
  book = Book::Base.new(dir, config: config)
29
29
  yield(dir, book, created_files)
30
30
  end
@@ -34,11 +34,11 @@ module BookTestHelper
34
34
  def get_instance_variables(obj)
35
35
  obj.instance_variables.each_with_object({}) do |name, memo|
36
36
  value = obj.instance_variable_get(name)
37
- if value.instance_variables.empty?
38
- memo[name] = value
39
- else
40
- memo[name] = get_instance_variables(value)
41
- end
37
+ memo[name] = if value.instance_variables.empty?
38
+ value
39
+ else
40
+ get_instance_variables(value)
41
+ end
42
42
  end
43
43
  end
44
44
  end
@@ -1,4 +1,5 @@
1
1
  require 'book_test_helper'
2
+
2
3
  class ChapterTest < Test::Unit::TestCase
3
4
  include BookTestHelper
4
5
 
@@ -41,12 +42,12 @@ class ChapterTest < Test::Unit::TestCase
41
42
 
42
43
  def test_size
43
44
  ch = Book::Chapter.new(nil, nil, nil, __FILE__, :io)
44
- filesize = IO.read(__FILE__, mode: 'rt:BOM|utf-8').size
45
+ filesize = File.read(__FILE__, mode: 'rt:BOM|utf-8').size
45
46
  assert_equal filesize, ch.size
46
47
 
47
48
  File.open(__FILE__, 'r') do |i|
48
49
  ch = Book::Chapter.new(nil, nil, nil, nil, i)
49
- filesize = IO.read(__FILE__, mode: 'rt:BOM|utf-8').size
50
+ filesize = File.read(__FILE__, mode: 'rt:BOM|utf-8').size
50
51
  assert_equal filesize, ch.size
51
52
  end
52
53
  end
@@ -174,6 +175,7 @@ E
174
175
 
175
176
  def test_footnote_index
176
177
  content = <<E
178
+ @<fn>{abc}@<fn>{def}@<fn>{xyz}
177
179
  //footnote[abc][textabc...]
178
180
  //footnote[def][textdef...]
179
181
  //footnote[xyz][textxyz...]
@@ -189,6 +191,27 @@ E
189
191
  end
190
192
  end
191
193
 
194
+ def test_endnote_index
195
+ content = <<E
196
+ @<fn>{abc}@<fn>{def}@<fn>{xyz}@<endnote>{abc}@<endnote>{def}@<endnote>{xyz}
197
+ //footnote[abc][textabc...]
198
+ //footnote[def][textdef...]
199
+ //footnote[xyz][textxyz...]
200
+ //endnote[abc][textabc...]
201
+ //endnote[def][textdef...]
202
+ //endnote[xyz][textxyz...]
203
+ //list[def][def-list]{
204
+ //}
205
+ //list[others][others-list]{
206
+ //}
207
+ E
208
+ do_test_index(content, Book::EndnoteIndex, :endnote_index, :endnote) do |ch|
209
+ assert_raises ReVIEW::KeyError do
210
+ ch.endnote('xyz2')
211
+ end
212
+ end
213
+ end
214
+
192
215
  def test_bibpaper
193
216
  do_test_index(<<E, Book::BibpaperIndex, :bibpaper_index, :bibpaper, filename: 'bib.re')
194
217
  //bibpaper[abc][text...]
data/test/test_builder.rb CHANGED
@@ -94,6 +94,8 @@ class BuidlerTest < Test::Unit::TestCase
94
94
  assert_equal 'unknown column: unknown|column1', e.message
95
95
  e = assert_raises(ReVIEW::ApplicationError) { b.inline_fn('unknown|footnote1') }
96
96
  assert_equal 'unknown footnote: unknown|footnote1', e.message
97
+ e = assert_raises(ReVIEW::ApplicationError) { b.inline_endnote('endnote1') }
98
+ assert_equal 'unknown endnote: endnote1', e.message
97
99
  end
98
100
 
99
101
  def test_nest_error
@@ -102,16 +104,16 @@ class BuidlerTest < Test::Unit::TestCase
102
104
  assert_equal '', b.solve_nest('')
103
105
  b.children = ['dl']
104
106
  e = assert_raises(ReVIEW::ApplicationError) { b.solve_nest('') }
105
- assert_equal '//beginchild of dl misses //endchild', e.message
107
+ assert_equal ': //beginchild of dl misses //endchild', e.message
106
108
  b.children = ['ul', 'dl', 'ol']
107
109
  e = assert_raises(ReVIEW::ApplicationError) { b.solve_nest('') }
108
- assert_equal '//beginchild of ol,dl,ul misses //endchild', e.message
110
+ assert_equal ': //beginchild of ol,dl,ul misses //endchild', e.message
109
111
 
110
112
  assert_equal "\u0001→/ol←\u0001", b.endchild
111
113
  assert_equal "\u0001→/dl←\u0001", b.endchild
112
114
  assert_equal "\u0001→/ul←\u0001", b.endchild
113
115
  e = assert_raises(ReVIEW::ApplicationError) { b.endchild }
114
- assert_equal "//endchild is shown, but any opened //beginchild doesn't exist", e.message
116
+ assert_equal ": //endchild is shown, but any opened //beginchild doesn't exist", e.message
115
117
  end
116
118
 
117
119
  class XBuilder < Builder
@@ -321,12 +321,12 @@ EOT
321
321
  <item id="ch02-html" href="ch02.html" media-type="application/xhtml+xml"/>
322
322
  <item id="ch03-html" href="ch03.html" media-type="application/xhtml+xml" properties="mathml"/>
323
323
  <item id="ch04-html" href="ch04.html" media-type="application/xhtml+xml"/>
324
- <item id="sample-png" href="sample.png" media-type="image/png"/>
325
- <item id="sample-jpg" href="sample.jpg" media-type="image/jpeg"/>
324
+ <item id="sample-GIF" href="sample.GIF" media-type="image/gif"/>
326
325
  <item id="sample-JPEG" href="sample.JPEG" media-type="image/jpeg"/>
327
326
  <item id="sample-SvG" href="sample.SvG" media-type="image/svg+xml"/>
328
- <item id="sample-GIF" href="sample.GIF" media-type="image/gif"/>
329
327
  <item id="sample-css" href="sample.css" media-type="text/css"/>
328
+ <item id="sample-jpg" href="sample.jpg" media-type="image/jpeg"/>
329
+ <item id="sample-png" href="sample.png" media-type="image/png"/>
330
330
  </manifest>
331
331
  <spine page-progression-direction="ltr">
332
332
  <itemref idref="sample" linear="no"/>
@@ -6,6 +6,7 @@ class EPUBMakerTest < Test::Unit::TestCase
6
6
  config = ReVIEW::Configure.values
7
7
  config.merge!(
8
8
  'bookname' => 'sample',
9
+ 'booktitle' => 'Sample Book',
9
10
  'title' => 'Sample Book',
10
11
  'epubversion' => 2,
11
12
  'urnid' => 'http://example.jp/',
@@ -318,12 +319,12 @@ EOT
318
319
  <item id="ch02-html" href="ch02.html" media-type="application/xhtml+xml"/>
319
320
  <item id="ch03-html" href="ch03.html" media-type="application/xhtml+xml"/>
320
321
  <item id="ch04-html" href="ch04.html" media-type="application/xhtml+xml"/>
321
- <item id="sample-png" href="sample.png" media-type="image/png"/>
322
- <item id="sample-jpg" href="sample.jpg" media-type="image/jpeg"/>
322
+ <item id="sample-GIF" href="sample.GIF" media-type="image/gif"/>
323
323
  <item id="sample-JPEG" href="sample.JPEG" media-type="image/jpeg"/>
324
324
  <item id="sample-SvG" href="sample.SvG" media-type="image/svg+xml"/>
325
- <item id="sample-GIF" href="sample.GIF" media-type="image/gif"/>
326
325
  <item id="sample-css" href="sample.css" media-type="text/css"/>
326
+ <item id="sample-jpg" href="sample.jpg" media-type="image/jpeg"/>
327
+ <item id="sample-png" href="sample.png" media-type="image/png"/>
327
328
  </manifest>
328
329
  <spine toc="ncx">
329
330
  <itemref idref="sample" linear="no"/>
@@ -806,19 +807,11 @@ EOT
806
807
  <title>Sample Book</title>
807
808
  </head>
808
809
  <body>
809
- <h1 class="tp-title">Sample Book</h1>
810
- <p>
811
- <br />
812
- <br />
813
- </p>
814
- <h2 class="tp-author">Mr.Smith</h2>
815
- <p>
816
- <br />
817
- <br />
818
- <br />
819
- <br />
820
- </p>
821
- <h3 class="tp-publisher">BLUEPRINT</h3>
810
+ <div class="titlepage">
811
+ <h1 class="tp-title">Sample Book</h1>
812
+ <h2 class="tp-author">Mr.Smith</h2>
813
+ <h3 class="tp-publisher">BLUEPRINT</h3>
814
+ </div>
822
815
  </body>
823
816
  </html>
824
817
  EOT
@@ -842,19 +835,11 @@ EOT
842
835
  <title>Sample Book</title>
843
836
  </head>
844
837
  <body>
845
- <h1 class="tp-title">Sample Book</h1>
846
- <p>
847
- <br />
848
- <br />
849
- </p>
850
- <h2 class="tp-author">Mr.Smith</h2>
851
- <p>
852
- <br />
853
- <br />
854
- <br />
855
- <br />
856
- </p>
857
- <h3 class="tp-publisher">BLUEPRINT</h3>
838
+ <div class="titlepage">
839
+ <h1 class="tp-title">Sample Book</h1>
840
+ <h2 class="tp-author">Mr.Smith</h2>
841
+ <h3 class="tp-publisher">BLUEPRINT</h3>
842
+ </div>
858
843
  </body>
859
844
  </html>
860
845
  EOT
@@ -21,7 +21,7 @@ class EPUBMakerCmdTest < Test::Unit::TestCase
21
21
  end
22
22
 
23
23
  def common_buildepub(bookdir, configfile, targetepubfile)
24
- if /mswin|mingw|cygwin/ !~ RUBY_PLATFORM
24
+ unless /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
25
25
  config = prepare_samplebook(@tmpdir1, bookdir, nil, configfile)
26
26
  builddir = File.join(@tmpdir1, config['bookname'] + '-epub')
27
27
  assert !File.exist?(builddir)
@@ -35,7 +35,7 @@ class EPUBMakerCmdTest < Test::Unit::TestCase
35
35
  end
36
36
 
37
37
  def check_filesize(epubfile)
38
- if /mswin|mingw|cygwin/ !~ RUBY_PLATFORM
38
+ unless /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
39
39
  Zip::File.open(epubfile) do |zio|
40
40
  zio.each do |entry|
41
41
  assert_not_equal(0, entry.size, "#{entry.name} is 0 byte.")
@@ -372,6 +372,40 @@ EOS
372
372
  end
373
373
  end
374
374
 
375
+ def test_inline_sec
376
+ def @chapter.headline_index
377
+ item = Book::Index::Item.new('chap1|test', [1, 1], 'te_st<>')
378
+ idx = Book::HeadlineIndex.new(self)
379
+ idx.add_item(item)
380
+ idx
381
+ end
382
+
383
+ @config['secnolevel'] = 3
384
+ actual = compile_inline('test @<secref>{test}')
385
+ assert_equal 'test <a href="-.html#h1-1-1">「1.1.1 te_st&lt;&gt;」</a>', actual
386
+ actual = compile_inline('test @<sectitle>{test}')
387
+ assert_equal 'test <a href="-.html#h1-1-1">te_st&lt;&gt;</a>', actual
388
+ actual = compile_inline('test @<sec>{test}')
389
+ assert_equal 'test <a href="-.html#h1-1-1">1.1.1</a>', actual
390
+
391
+ @config['secnolevel'] = 2
392
+ actual = compile_inline('test @<secref>{test}')
393
+ assert_equal 'test <a href="-.html#h1-1-1">「te_st&lt;&gt;」</a>', actual
394
+ actual = compile_inline('test @<sectitle>{test}')
395
+ assert_equal 'test <a href="-.html#h1-1-1">te_st&lt;&gt;</a>', actual
396
+ assert_raises(ReVIEW::ApplicationError) { compile_block('test @<sec>{test}') }
397
+ assert_match(/the target headline doesn't have a number/, @log_io.string)
398
+
399
+ @config['chapterlink'] = nil
400
+ @config['secnolevel'] = 3
401
+ actual = compile_inline('test @<secref>{test}')
402
+ assert_equal 'test 「1.1.1 te_st&lt;&gt;」', actual
403
+ actual = compile_inline('test @<sectitle>{test}')
404
+ assert_equal 'test te_st&lt;&gt;', actual
405
+ actual = compile_inline('test @<sec>{test}')
406
+ assert_equal 'test 1.1.1', actual
407
+ end
408
+
375
409
  def test_inline_uchar
376
410
  actual = compile_inline('test @<uchar>{2460} test2')
377
411
  assert_equal 'test &#x2460; test2', actual
@@ -1708,7 +1742,7 @@ EOS
1708
1742
  end
1709
1743
 
1710
1744
  def test_texequation
1711
- return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1745
+ return true if /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
1712
1746
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1713
1747
 
1714
1748
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
@@ -1741,7 +1775,7 @@ EOS
1741
1775
 
1742
1776
  def test_texequation_fail
1743
1777
  # Re:VIEW 3 never fail on defer mode. This test is only for Re:VIEW 2.
1744
- return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1778
+ return true if /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
1745
1779
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1746
1780
 
1747
1781
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
@@ -2322,6 +2356,43 @@ EOS
2322
2356
  assert_equal expected, fn
2323
2357
  end
2324
2358
 
2359
+ def test_endnote
2360
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block("//endnote[foo][bar]\n\n@<endnote>{foo}\n") }
2361
+ assert_equal ':4: //endnote is found but //printendnotes is not found.', e.message
2362
+
2363
+ actual = compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n//printendnotes\n")
2364
+ expected = <<-'EOS'
2365
+ <p><a id="endnoteb-foo" href="#endnote-foo" class="noteref" epub:type="noteref">(1)</a></p>
2366
+ <div class="endnotes">
2367
+ <div class="endnote" id="endnote-foo"><p class="endnote">(1) bar</p></div>
2368
+ </div>
2369
+ EOS
2370
+ assert_equal expected, actual
2371
+
2372
+ @book.config['epubmaker'] ||= {}
2373
+ @book.config['epubmaker']['back_footnote'] = true
2374
+ actual = compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n//printendnotes\n")
2375
+ expected = <<-'EOS'
2376
+ <p><a id="endnoteb-foo" href="#endnote-foo" class="noteref" epub:type="noteref">(1)</a></p>
2377
+ <div class="endnotes">
2378
+ <div class="endnote" id="endnote-foo"><p class="endnote"><a href="#endnoteb-foo">⏎</a>(1) bar</p></div>
2379
+ </div>
2380
+ EOS
2381
+ assert_equal expected, actual
2382
+
2383
+ I18n.set('html_endnote_textmark', '+%s:')
2384
+ I18n.set('html_endnote_refmark', '+%s:')
2385
+ I18n.set('html_footnote_backmark', '←')
2386
+ actual = compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n//printendnotes\n")
2387
+ expected = <<-'EOS'
2388
+ <p><a id="endnoteb-foo" href="#endnote-foo" class="noteref" epub:type="noteref">+1:</a></p>
2389
+ <div class="endnotes">
2390
+ <div class="endnote" id="endnote-foo"><p class="endnote"><a href="#endnoteb-foo">←</a>+1:bar</p></div>
2391
+ </div>
2392
+ EOS
2393
+ assert_equal expected, actual
2394
+ end
2395
+
2325
2396
  def test_inline_hd
2326
2397
  book = ReVIEW::Book::Base.new
2327
2398
  book.catalog = ReVIEW::Catalog.new('CHAPS' => %w[ch1.re ch2.re])
@@ -2850,12 +2921,11 @@ EOS
2850
2921
 
2851
2922
  def test_inline_w
2852
2923
  Dir.mktmpdir do |dir|
2853
- File.open(File.join(dir, 'words.csv'), 'w') do |f|
2854
- f.write <<EOB
2924
+ File.write(File.join(dir, 'words.csv'), <<EOB
2855
2925
  "F","foo"
2856
2926
  "B","bar""\\<>_@<b>{BAZ}"
2857
2927
  EOB
2858
- end
2928
+ )
2859
2929
  @book.config['words_file'] = File.join(dir, 'words.csv')
2860
2930
  actual = compile_block('@<w>{F} @<w>{B} @<wb>{B} @<w>{N}')
2861
2931
  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
@@ -2868,6 +2938,8 @@ EOB
2868
2938
  assert_match(/unknown image: n/, @log_io.string)
2869
2939
  assert_raises(ReVIEW::ApplicationError) { compile_block("@<fn>{n}\n") }
2870
2940
  assert_match(/unknown footnote: n/, @log_io.string)
2941
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<endnote>{n}\n") }
2942
+ assert_match(/unknown endnote: n/, @log_io.string)
2871
2943
  assert_raises(ReVIEW::ApplicationError) { compile_block("@<hd>{n}\n") }
2872
2944
  assert_match(/unknown headline: n/, @log_io.string)
2873
2945
  %w[list table column].each do |name|
@@ -2951,7 +3023,7 @@ EOS
2951
3023
  //beginchild
2952
3024
  EOS
2953
3025
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2954
- assert_equal "//beginchild is shown, but previous element isn't ul, ol, or dl", e.message
3026
+ assert_equal ":1: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message
2955
3027
  end
2956
3028
 
2957
3029
  def test_nest_error_close2
@@ -2969,7 +3041,7 @@ EOS
2969
3041
  //beginchild
2970
3042
  EOS
2971
3043
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2972
- assert_equal '//beginchild of dl,ol,ul misses //endchild', e.message
3044
+ assert_equal ':12: //beginchild of dl,ol,ul misses //endchild', e.message
2973
3045
  end
2974
3046
 
2975
3047
  def test_nest_error_close3
@@ -2989,7 +3061,7 @@ EOS
2989
3061
  //endchild
2990
3062
  EOS
2991
3063
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2992
- assert_equal '//beginchild of ol,ul misses //endchild', e.message
3064
+ assert_equal ':14: //beginchild of ol,ul misses //endchild', e.message
2993
3065
  end
2994
3066
 
2995
3067
  def test_nest_ul
@@ -348,15 +348,15 @@ EOS
348
348
  //}
349
349
  EOS
350
350
 
351
- if type == 'notice' # exception pattern
352
- expected = <<-EOS.chomp
351
+ expected = if type == 'notice' # exception pattern
352
+ <<-EOS.chomp
353
353
  <#{type}-t><title aid:pstyle='#{type}-title'>#{type}1</title></#{type}-t><#{type}-t><title aid:pstyle='#{type}-title'>#{type}2</title></#{type}-t>
354
354
  EOS
355
- else
356
- expected = <<-EOS.chomp
355
+ else
356
+ <<-EOS.chomp
357
357
  <#{type}><title aid:pstyle='#{type}-title'>#{type}1</title></#{type}><#{type}><title aid:pstyle='#{type}-title'>#{type}2</title></#{type}>
358
358
  EOS
359
- end
359
+ end
360
360
  assert_equal expected, compile_block(src)
361
361
 
362
362
  src = <<-EOS
@@ -412,17 +412,17 @@ LIST
412
412
  //}
413
413
  EOS
414
414
 
415
- if type == 'notice' # exception pattern
416
- expected = <<-EOS.chomp
415
+ expected = if type == 'notice' # exception pattern
416
+ <<-EOS.chomp
417
417
  <#{type}><ul><li aid:pstyle="ul-item">A</li></ul><ol><li aid:pstyle="ol-item" olnum="1" num="1">B</li></ol></#{type}><#{type}-t><title aid:pstyle='#{type}-title'>OMITEND1</title><list type='emlist'><pre>LIST
418
418
  </pre></list></#{type}-t><#{type}-t><title aid:pstyle='#{type}-title'>OMITEND2</title></#{type}-t>
419
419
  EOS
420
- else
421
- expected = <<-EOS.chomp
420
+ else
421
+ <<-EOS.chomp
422
422
  <#{type}><ul><li aid:pstyle="ul-item">A</li></ul><ol><li aid:pstyle="ol-item" olnum="1" num="1">B</li></ol></#{type}><#{type}><title aid:pstyle='#{type}-title'>OMITEND1</title><list type='emlist'><pre>LIST
423
423
  </pre></list></#{type}><#{type}><title aid:pstyle='#{type}-title'>OMITEND2</title></#{type}>
424
424
  EOS
425
- end
425
+ end
426
426
  assert_equal expected, compile_block(src)
427
427
  end
428
428
  end
@@ -1291,7 +1291,7 @@ EOS
1291
1291
  //beginchild
1292
1292
  EOS
1293
1293
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1294
- assert_equal "//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
1295
1295
  end
1296
1296
 
1297
1297
  def test_nest_error_close2
@@ -1309,7 +1309,7 @@ EOS
1309
1309
  //beginchild
1310
1310
  EOS
1311
1311
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1312
- assert_equal '//beginchild of dl,ol,ul misses //endchild', e.message
1312
+ assert_equal ':12: //beginchild of dl,ol,ul misses //endchild', e.message
1313
1313
  end
1314
1314
 
1315
1315
  def test_nest_error_close3
@@ -1329,7 +1329,7 @@ EOS
1329
1329
  //endchild
1330
1330
  EOS
1331
1331
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
1332
- assert_equal '//beginchild of ol,ul misses //endchild', e.message
1332
+ assert_equal ':14: //beginchild of ol,ul misses //endchild', e.message
1333
1333
  end
1334
1334
 
1335
1335
  def test_nest_ul
@@ -21,7 +21,7 @@ class IDGXMLMakerCmdTest < Test::Unit::TestCase
21
21
  end
22
22
 
23
23
  def common_buildidgxml(bookdir, configfile, targetfile, option)
24
- if /mswin|mingw|cygwin/ !~ RUBY_PLATFORM
24
+ unless /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
25
25
  config = prepare_samplebook(@tmpdir1, bookdir, nil, configfile)
26
26
  builddir = File.join(@tmpdir1, config['bookname'] + '-idgxml')
27
27
  assert !File.exist?(builddir)
@@ -30,7 +30,7 @@ class ImgMathTest < Test::Unit::TestCase
30
30
  end
31
31
 
32
32
  def test_defer_math_image
33
- unless support_latex_in_tests?
33
+ unless support_latex_in_tests? && support_pdftocairo_in_tests?
34
34
  $stderr.puts 'skip test_defer_math_image'
35
35
  return true
36
36
  end
@@ -104,7 +104,16 @@ class ImgMathTest < Test::Unit::TestCase
104
104
  begin
105
105
  `uplatex -v`
106
106
  true
107
- rescue
107
+ rescue StandardError
108
+ false
109
+ end
110
+ end
111
+
112
+ def support_pdftocairo_in_tests?
113
+ begin
114
+ `pdftocairo -v`
115
+ true
116
+ rescue StandardError
108
117
  false
109
118
  end
110
119
  end
data/test/test_index.rb CHANGED
@@ -12,6 +12,8 @@ class IndexTest < Test::Unit::TestCase
12
12
  @builder = TOPBuilder.new
13
13
  @config = ReVIEW::Configure.create(config: { 'secnolevel' => 2, 'language' => 'ja' })
14
14
  @book = Book::Base.new(config: @config)
15
+ @log_io = StringIO.new
16
+ ReVIEW.logger = ReVIEW::Logger.new(@log_io)
15
17
  @compiler = ReVIEW::Compiler.new(@builder)
16
18
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
17
19
  location = Location.new(nil, nil)
@@ -21,16 +23,19 @@ class IndexTest < Test::Unit::TestCase
21
23
  end
22
24
 
23
25
  def test_footnote_index
24
- compile_block("//footnote[foo][bar]\n")
26
+ compile_block("@<fn>{foo}\n//footnote[foo][bar]\n")
25
27
  fn = @chapter.footnote_index
26
28
  items = fn.to_a
27
29
  item = items[0]
28
30
  assert_equal 'foo', item.id
29
31
  assert_equal 'bar', item.content
32
+
33
+ compile_block("//footnote[foo][bar]\n")
34
+ assert_match(/ID foo is not referred/, @log_io.string)
30
35
  end
31
36
 
32
37
  def test_footnote_index_with_escape
33
- compile_block('//footnote[foo][bar[\]buz]' + "\n")
38
+ compile_block("@<fn>{foo}\n" + '//footnote[foo][bar[\]buz]' + "\n")
34
39
  fn = @chapter.footnote_index
35
40
  items = fn.to_a
36
41
  item = items[0]
@@ -39,7 +44,7 @@ class IndexTest < Test::Unit::TestCase
39
44
  end
40
45
 
41
46
  def test_footnote_index_with_escape2
42
- compile_block('//footnote[foo][bar\\a\\$buz]' + "\n")
47
+ compile_block("@<fn>{foo}\n" + '//footnote[foo][bar\\a\\$buz]' + "\n")
43
48
  fn = @chapter.footnote_index
44
49
  items = fn.to_a
45
50
  item = items[0]
@@ -48,7 +53,7 @@ class IndexTest < Test::Unit::TestCase
48
53
  end
49
54
 
50
55
  def test_footnote_index_key?
51
- compile_block('//footnote[foo][bar]' + "\n")
56
+ compile_block("@<fn>{foo}\n" + '//footnote[foo][bar]' + "\n")
52
57
  fn = @chapter.footnote_index
53
58
  assert_equal true, fn.key?('foo')
54
59
 
@@ -58,6 +63,27 @@ class IndexTest < Test::Unit::TestCase
58
63
  # rubocop:enable Style/PreferredHashMethods
59
64
  end
60
65
 
66
+ def test_endnote_index
67
+ compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n//printendnotes\n")
68
+ endnote = @chapter.endnote_index
69
+ items = endnote.to_a
70
+ item = items[0]
71
+ assert_equal 'foo', item.id
72
+ assert_equal 'bar', item.content
73
+ assert_equal true, endnote.key?('foo')
74
+ # rubocop:disable Style/PreferredHashMethods
75
+ assert_equal true, endnote.has_key?('foo')
76
+ # rubocop:enable Style/PreferredHashMethods
77
+
78
+ e = assert_raises(ReVIEW::ApplicationError) do
79
+ compile_block("@<endnote>{foo}\n//endnote[foo][bar]\n")
80
+ end
81
+ assert_equal ':3: //endnote is found but //printendnotes is not found.', e.message
82
+
83
+ compile_block("//endnote[foo][bar]\n//printendnotes\n")
84
+ assert_match(/ID foo is not referred/, @log_io.string)
85
+ end
86
+
61
87
  def test_headline_index
62
88
  src = <<-EOB
63
89
  = chap1