review 5.1.1 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-tex.yml +6 -2
  3. data/.github/workflows/ruby-win.yml +6 -2
  4. data/.github/workflows/ruby.yml +6 -2
  5. data/.rubocop.yml +5 -319
  6. data/NEWS.ja.md +149 -0
  7. data/NEWS.md +149 -1
  8. data/README.md +9 -8
  9. data/bin/review +1 -1
  10. data/bin/review-catalog-converter +15 -15
  11. data/bin/review-check +7 -7
  12. data/bin/review-compile +14 -23
  13. data/bin/review-index +1 -1
  14. data/bin/review-preproc +29 -35
  15. data/bin/review-validate +2 -2
  16. data/doc/config.yml.sample +9 -1
  17. data/doc/config.yml.sample-simple +1 -1
  18. data/doc/format.ja.md +29 -3
  19. data/doc/format.md +32 -3
  20. data/doc/writing_vertical.ja.md +6 -0
  21. data/lib/review/book/base.rb +3 -3
  22. data/lib/review/book/book_unit.rb +13 -3
  23. data/lib/review/book/chapter.rb +1 -1
  24. data/lib/review/book/index.rb +7 -4
  25. data/lib/review/book/part.rb +12 -13
  26. data/lib/review/book/volume.rb +1 -1
  27. data/lib/review/builder.rb +92 -65
  28. data/lib/review/catalog.rb +6 -5
  29. data/lib/review/compiler.rb +76 -57
  30. data/lib/review/configure.rb +5 -2
  31. data/lib/review/epub2html.rb +12 -12
  32. data/lib/review/epubmaker/content.rb +1 -1
  33. data/lib/review/epubmaker/epubcommon.rb +47 -45
  34. data/lib/review/epubmaker/epubv2.rb +2 -1
  35. data/lib/review/epubmaker/epubv3.rb +5 -4
  36. data/lib/review/epubmaker/producer.rb +6 -7
  37. data/lib/review/epubmaker/reviewheaderlistener.rb +1 -1
  38. data/lib/review/epubmaker.rb +56 -67
  39. data/lib/review/exception.rb +7 -0
  40. data/lib/review/extentions/string.rb +1 -1
  41. data/lib/review/htmlbuilder.rb +90 -34
  42. data/lib/review/htmlutils.rb +17 -17
  43. data/lib/review/i18n.rb +3 -3
  44. data/lib/review/i18n.yml +6 -0
  45. data/lib/review/idgxmlbuilder.rb +61 -39
  46. data/lib/review/idgxmlmaker.rb +27 -26
  47. data/lib/review/img_math.rb +12 -18
  48. data/lib/review/index_builder.rb +94 -53
  49. data/lib/review/init.rb +4 -4
  50. data/lib/review/latexbuilder.rb +84 -76
  51. data/lib/review/lineinput.rb +3 -3
  52. data/lib/review/location.rb +1 -1
  53. data/lib/review/loggable.rb +27 -0
  54. data/lib/review/logger.rb +69 -21
  55. data/lib/review/makerhelper.rb +8 -4
  56. data/lib/review/markdownbuilder.rb +21 -12
  57. data/lib/review/pdfmaker.rb +63 -42
  58. data/lib/review/plaintextbuilder.rb +16 -15
  59. data/lib/review/preprocessor/directive.rb +35 -0
  60. data/lib/review/preprocessor/line.rb +34 -0
  61. data/lib/review/preprocessor/repository.rb +177 -0
  62. data/lib/review/preprocessor.rb +94 -296
  63. data/lib/review/rstbuilder.rb +12 -3
  64. data/lib/review/template.rb +5 -1
  65. data/lib/review/textmaker.rb +32 -31
  66. data/lib/review/textutils.rb +5 -6
  67. data/lib/review/tocprinter.rb +12 -7
  68. data/lib/review/topbuilder.rb +96 -19
  69. data/lib/review/update.rb +16 -8
  70. data/lib/review/version.rb +1 -1
  71. data/lib/review/volumeprinter.rb +9 -9
  72. data/lib/review/webmaker.rb +45 -46
  73. data/lib/review/webtocprinter.rb +10 -10
  74. data/lib/review/yamlloader.rb +35 -2
  75. data/review.gemspec +2 -1
  76. data/samples/sample-book/src/config.yml +0 -1
  77. data/samples/sample-book/src/lib/tasks/review.rake +3 -1
  78. data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +2 -1
  79. data/samples/syntax-book/ch02.re +9 -0
  80. data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +2 -1
  81. data/templates/html/_titlepage.html.erb +9 -17
  82. data/templates/latex/config.erb +3 -0
  83. data/templates/latex/review-jlreq/review-base.sty +4 -5
  84. data/templates/latex/review-jlreq/review-jlreq.cls +39 -5
  85. data/templates/latex/review-jsbook/review-base.sty +9 -3
  86. data/templates/latex/review-jsbook/review-jsbook.cls +32 -5
  87. data/templates/opf/opf_manifest_epubv2.opf.erb +1 -1
  88. data/templates/opf/opf_manifest_epubv3.opf.erb +1 -1
  89. data/test/assets/syntax_book_index_detail.txt +10 -8
  90. data/test/assets/test_template.tex +4 -1
  91. data/test/assets/test_template_backmatter.tex +4 -1
  92. data/test/book_test_helper.rb +10 -10
  93. data/test/test_book_chapter.rb +25 -2
  94. data/test/test_builder.rb +10 -8
  95. data/test/test_epub3maker.rb +3 -3
  96. data/test/test_epubmaker.rb +27 -37
  97. data/test/test_epubmaker_cmd.rb +14 -3
  98. data/test/test_htmlbuilder.rb +111 -31
  99. data/test/test_idgxmlbuilder.rb +41 -33
  100. data/test/test_idgxmlmaker_cmd.rb +1 -1
  101. data/test/test_img_math.rb +11 -2
  102. data/test/test_index.rb +30 -4
  103. data/test/test_latexbuilder.rb +46 -25
  104. data/test/test_latexbuilder_v2.rb +18 -10
  105. data/test/test_markdownbuilder.rb +13 -0
  106. data/test/test_pdfmaker.rb +19 -0
  107. data/test/test_pdfmaker_cmd.rb +10 -10
  108. data/test/test_plaintextbuilder.rb +46 -22
  109. data/test/test_preprocessor.rb +188 -1
  110. data/test/test_rstbuilder.rb +13 -0
  111. data/test/test_textmaker_cmd.rb +1 -1
  112. data/test/test_topbuilder.rb +195 -29
  113. data/test/test_yamlloader.rb +28 -42
  114. metadata +11 -6
@@ -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
+ 5796C 180L 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
+ 797C 22L 1.3P 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
@@ -85,15 +85,17 @@ class BuidlerTest < Test::Unit::TestCase
85
85
  chapter = ReVIEW::Book::Chapter.new(ReVIEW::Book::Base.new, 1, 'chap1', nil, StringIO.new)
86
86
  b.bind(nil, chapter, nil)
87
87
  e = assert_raises(ReVIEW::ApplicationError) { b.inline_list('unknown|list1') }
88
- assert_equal ': error: unknown list: unknown|list1', e.message
88
+ assert_equal 'unknown list: unknown|list1', e.message
89
89
  e = assert_raises(ReVIEW::ApplicationError) { b.inline_table('unknown|table1') }
90
- assert_equal ': error: unknown table: unknown|table1', e.message
90
+ assert_equal 'unknown table: unknown|table1', e.message
91
91
  e = assert_raises(ReVIEW::ApplicationError) { b.inline_img('unknown|img1') }
92
- assert_equal ': error: unknown image: unknown|img1', e.message
92
+ assert_equal 'unknown image: unknown|img1', e.message
93
93
  e = assert_raises(ReVIEW::ApplicationError) { b.inline_column('unknown|column1') }
94
- assert_equal ': error: unknown column: unknown|column1', e.message
94
+ assert_equal 'unknown column: unknown|column1', e.message
95
95
  e = assert_raises(ReVIEW::ApplicationError) { b.inline_fn('unknown|footnote1') }
96
- assert_equal ': error: unknown footnote: unknown|footnote1', e.message
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 ': error: //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 ': error: //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 ": error: //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/',
@@ -13,6 +14,8 @@ class EPUBMakerTest < Test::Unit::TestCase
13
14
  'language' => 'en',
14
15
  'titlepage' => nil
15
16
  )
17
+ @log_io = StringIO.new
18
+ ReVIEW.logger = ReVIEW::Logger.new(@log_io)
16
19
  @producer = ReVIEW::EPUBMaker::Producer.new(config)
17
20
  end
18
21
 
@@ -316,12 +319,12 @@ EOT
316
319
  <item id="ch02-html" href="ch02.html" media-type="application/xhtml+xml"/>
317
320
  <item id="ch03-html" href="ch03.html" media-type="application/xhtml+xml"/>
318
321
  <item id="ch04-html" href="ch04.html" media-type="application/xhtml+xml"/>
319
- <item id="sample-png" href="sample.png" media-type="image/png"/>
320
- <item id="sample-jpg" href="sample.jpg" media-type="image/jpeg"/>
322
+ <item id="sample-GIF" href="sample.GIF" media-type="image/gif"/>
321
323
  <item id="sample-JPEG" href="sample.JPEG" media-type="image/jpeg"/>
322
324
  <item id="sample-SvG" href="sample.SvG" media-type="image/svg+xml"/>
323
- <item id="sample-GIF" href="sample.GIF" media-type="image/gif"/>
324
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"/>
325
328
  </manifest>
326
329
  <spine toc="ncx">
327
330
  <itemref idref="sample" linear="no"/>
@@ -804,19 +807,11 @@ EOT
804
807
  <title>Sample Book</title>
805
808
  </head>
806
809
  <body>
807
- <h1 class="tp-title">Sample Book</h1>
808
- <p>
809
- <br />
810
- <br />
811
- </p>
812
- <h2 class="tp-author">Mr.Smith</h2>
813
- <p>
814
- <br />
815
- <br />
816
- <br />
817
- <br />
818
- </p>
819
- <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>
820
815
  </body>
821
816
  </html>
822
817
  EOT
@@ -840,19 +835,11 @@ EOT
840
835
  <title>Sample Book</title>
841
836
  </head>
842
837
  <body>
843
- <h1 class="tp-title">Sample Book</h1>
844
- <p>
845
- <br />
846
- <br />
847
- </p>
848
- <h2 class="tp-author">Mr.Smith</h2>
849
- <p>
850
- <br />
851
- <br />
852
- <br />
853
- <br />
854
- </p>
855
- <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>
856
843
  </body>
857
844
  </html>
858
845
  EOT
@@ -901,8 +888,8 @@ EOT
901
888
  assert_nothing_raised { epubmaker.copy_stylesheet(tmpdir) }
902
889
 
903
890
  epubmaker.config['stylesheet'] = ['nothing.css']
904
- e = assert_raise(ApplicationError) { epubmaker.copy_stylesheet(tmpdir) }
905
- assert_equal 'stylesheet: nothing.css is not found.', e.message
891
+ assert_raise(SystemExit) { epubmaker.copy_stylesheet(tmpdir) }
892
+ assert_equal "ERROR --: stylesheet: nothing.css is not found.\n", @log_io.string
906
893
  end
907
894
 
908
895
  epubmaker_instance do |epubmaker, tmpdir|
@@ -911,8 +898,9 @@ EOT
911
898
  assert_nothing_raised { epubmaker.copy_frontmatter(tmpdir) }
912
899
 
913
900
  epubmaker.config['titlefile'] = 'nothing.html'
914
- e = assert_raise(ApplicationError) { epubmaker.copy_frontmatter(tmpdir) }
915
- assert_equal 'titlefile: nothing.html is not found.', e.message
901
+ @log_io.string = ''
902
+ assert_raise(SystemExit) { epubmaker.copy_frontmatter(tmpdir) }
903
+ assert_equal "ERROR --: titlefile: nothing.html is not found.\n", @log_io.string
916
904
  end
917
905
 
918
906
  # XXX: only `cover' is allowed to have invalid file name.
@@ -922,8 +910,9 @@ EOT
922
910
  assert_nothing_raised { epubmaker.copy_frontmatter(tmpdir) }
923
911
 
924
912
  epubmaker.config[name] = 'nothing.html'
925
- e = assert_raise(ApplicationError) { epubmaker.copy_frontmatter(tmpdir) }
926
- assert_equal "#{name}: nothing.html is not found.", e.message
913
+ @log_io.string = ''
914
+ assert_raise(SystemExit) { epubmaker.copy_frontmatter(tmpdir) }
915
+ assert_equal "ERROR --: #{name}: nothing.html is not found.\n", @log_io.string
927
916
  end
928
917
  end
929
918
 
@@ -933,8 +922,9 @@ EOT
933
922
  assert_nothing_raised { epubmaker.copy_backmatter(tmpdir) }
934
923
 
935
924
  epubmaker.config[name] = 'nothing.html'
936
- e = assert_raise(ApplicationError) { epubmaker.copy_backmatter(tmpdir) }
937
- assert_equal "#{name}: nothing.html is not found.", e.message
925
+ @log_io.string = ''
926
+ assert_raise(SystemExit) { epubmaker.copy_backmatter(tmpdir) }
927
+ assert_equal "ERROR --: #{name}: nothing.html is not found.\n", @log_io.string
938
928
  end
939
929
  end
940
930
  end
@@ -3,13 +3,13 @@ require 'tmpdir'
3
3
  require 'fileutils'
4
4
  require 'yaml'
5
5
  require 'rbconfig'
6
+ require 'zip'
6
7
 
7
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
15
  ENV['RUBYLIB'] = File.expand_path('lib', __dir__)
@@ -17,12 +17,11 @@ class EPUBMakerCmdTest < Test::Unit::TestCase
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
 
24
23
  def common_buildepub(bookdir, configfile, targetepubfile)
25
- if /mswin|mingw|cygwin/ !~ RUBY_PLATFORM
24
+ unless /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
26
25
  config = prepare_samplebook(@tmpdir1, bookdir, nil, configfile)
27
26
  builddir = File.join(@tmpdir1, config['bookname'] + '-epub')
28
27
  assert !File.exist?(builddir)
@@ -35,11 +34,23 @@ class EPUBMakerCmdTest < Test::Unit::TestCase
35
34
  end
36
35
  end
37
36
 
37
+ def check_filesize(epubfile)
38
+ unless /mswin|mingw|cygwin/.match?(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
@@ -16,6 +16,8 @@ class HTMLBuidlerTest < Test::Unit::TestCase
16
16
  @book = Book::Base.new('.')
17
17
  @book.config = @config
18
18
  img_math = ReVIEW::ImgMath.new(@config)
19
+ @log_io = StringIO.new
20
+ ReVIEW.logger = ReVIEW::Logger.new(@log_io)
19
21
  @builder = HTMLBuilder.new(img_math: img_math)
20
22
  @compiler = ReVIEW::Compiler.new(@builder)
21
23
  @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new)
@@ -133,6 +135,48 @@ class HTMLBuidlerTest < Test::Unit::TestCase
133
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
134
136
  end
135
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
+
136
180
  def test_label
137
181
  actual = compile_block("//label[label_test]\n")
138
182
  assert_equal %Q(<a id="label_test"></a>\n), actual
@@ -1664,7 +1708,7 @@ EOS
1664
1708
  end
1665
1709
 
1666
1710
  def test_texequation
1667
- return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1711
+ return true if /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
1668
1712
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1669
1713
 
1670
1714
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
@@ -1697,7 +1741,7 @@ EOS
1697
1741
 
1698
1742
  def test_texequation_fail
1699
1743
  # Re:VIEW 3 never fail on defer mode. This test is only for Re:VIEW 2.
1700
- return true if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
1744
+ return true if /mswin|mingw|cygwin/.match?(RUBY_PLATFORM)
1701
1745
  return true unless system('latex -version 1>/dev/null 2>/dev/null')
1702
1746
 
1703
1747
  mktmpbookdir('catalog.yml' => "CHAPS:\n - ch01.re\n",
@@ -2029,8 +2073,8 @@ EOS
2029
2073
  * AA
2030
2074
  EOS
2031
2075
 
2032
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2033
- assert_equal ':1: error: too many *.', e.message
2076
+ assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2077
+ assert_match(/too many \*\./, @log_io.string)
2034
2078
  end
2035
2079
 
2036
2080
  def test_ul_nest4
@@ -2278,6 +2322,43 @@ EOS
2278
2322
  assert_equal expected, fn
2279
2323
  end
2280
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
+
2281
2362
  def test_inline_hd
2282
2363
  book = ReVIEW::Book::Base.new
2283
2364
  book.catalog = ReVIEW::Catalog.new('CHAPS' => %w[ch1.re ch2.re])
@@ -2378,10 +2459,10 @@ EOS
2378
2459
 
2379
2460
  def test_empty_table
2380
2461
  e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") }
2381
- assert_equal ':2: error: no rows in the table', e.message
2462
+ assert_equal 'no rows in the table', e.message
2382
2463
 
2383
2464
  e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") }
2384
- assert_equal ':3: error: no rows in the table', e.message
2465
+ assert_equal 'no rows in the table', e.message
2385
2466
  end
2386
2467
 
2387
2468
  def test_inline_table
@@ -2736,8 +2817,8 @@ EOS
2736
2817
 
2737
2818
  //}
2738
2819
  EOS
2739
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2740
- 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)
2741
2822
  end
2742
2823
  end
2743
2824
 
@@ -2753,8 +2834,8 @@ EOS
2753
2834
 
2754
2835
  //}
2755
2836
  EOS
2756
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2757
- 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)
2758
2839
  end
2759
2840
  end
2760
2841
 
@@ -2770,8 +2851,8 @@ EOS
2770
2851
 
2771
2852
  //}
2772
2853
  EOS
2773
- e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2774
- 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)
2775
2856
  end
2776
2857
  end
2777
2858
 
@@ -2806,35 +2887,34 @@ EOS
2806
2887
 
2807
2888
  def test_inline_w
2808
2889
  Dir.mktmpdir do |dir|
2809
- File.open(File.join(dir, 'words.csv'), 'w') do |f|
2810
- f.write <<EOB
2890
+ File.write(File.join(dir, 'words.csv'), <<EOB
2811
2891
  "F","foo"
2812
2892
  "B","bar""\\<>_@<b>{BAZ}"
2813
2893
  EOB
2814
- end
2894
+ )
2815
2895
  @book.config['words_file'] = File.join(dir, 'words.csv')
2816
- io = StringIO.new
2817
- @builder.instance_eval { @logger = ReVIEW::Logger.new(io) }
2818
2896
  actual = compile_block('@<w>{F} @<w>{B} @<wb>{B} @<w>{N}')
2819
2897
  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
2820
- assert_match(/WARN --: :1: word not bound: N/, io.string)
2898
+ assert_match(/WARN --: :1: word not bound: N/, @log_io.string)
2821
2899
  end
2822
2900
  end
2823
2901
 
2824
2902
  def test_inline_unknown
2825
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<img>{n}\n") }
2826
- assert_equal ':1: error: unknown image: n', e.message
2827
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<fn>{n}\n") }
2828
- assert_equal ':1: error: unknown footnote: n', e.message
2829
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<hd>{n}\n") }
2830
- assert_equal ':1: error: unknown headline: n', e.message
2903
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<img>{n}\n") }
2904
+ assert_match(/unknown image: n/, @log_io.string)
2905
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<fn>{n}\n") }
2906
+ assert_match(/unknown footnote: n/, @log_io.string)
2907
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<endnote>{n}\n") }
2908
+ assert_match(/unknown endnote: n/, @log_io.string)
2909
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<hd>{n}\n") }
2910
+ assert_match(/unknown headline: n/, @log_io.string)
2831
2911
  %w[list table column].each do |name|
2832
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2833
- assert_equal ":1: error: unknown #{name}: n", e.message
2912
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2913
+ assert_match(/unknown #{name}: n/, @log_io.string)
2834
2914
  end
2835
2915
  %w[chap chapref title].each do |name|
2836
- e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2837
- assert_equal ':1: error: key not found: "n"', e.message
2916
+ assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") }
2917
+ assert_match(/key not found: "n"/, @log_io.string)
2838
2918
  end
2839
2919
  end
2840
2920
 
@@ -2909,7 +2989,7 @@ EOS
2909
2989
  //beginchild
2910
2990
  EOS
2911
2991
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2912
- assert_equal ":1: error: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message
2992
+ assert_equal ":1: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message
2913
2993
  end
2914
2994
 
2915
2995
  def test_nest_error_close2
@@ -2927,7 +3007,7 @@ EOS
2927
3007
  //beginchild
2928
3008
  EOS
2929
3009
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2930
- assert_equal ':12: error: //beginchild of dl,ol,ul misses //endchild', e.message
3010
+ assert_equal ':12: //beginchild of dl,ol,ul misses //endchild', e.message
2931
3011
  end
2932
3012
 
2933
3013
  def test_nest_error_close3
@@ -2947,7 +3027,7 @@ EOS
2947
3027
  //endchild
2948
3028
  EOS
2949
3029
  e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) }
2950
- assert_equal ':14: error: //beginchild of ol,ul misses //endchild', e.message
3030
+ assert_equal ':14: //beginchild of ol,ul misses //endchild', e.message
2951
3031
  end
2952
3032
 
2953
3033
  def test_nest_ul