review 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +20 -5
  3. data/.travis.yml +2 -1
  4. data/NEWS.ja.md +93 -0
  5. data/NEWS.md +77 -0
  6. data/README.md +1 -1
  7. data/bin/review +38 -12
  8. data/bin/review-compile +106 -88
  9. data/bin/review-epubmaker +6 -1
  10. data/bin/review-init +21 -1
  11. data/bin/review-textmaker +16 -0
  12. data/doc/config.yml.sample +6 -1
  13. data/doc/format.ja.md +23 -0
  14. data/doc/format.md +20 -2
  15. data/doc/quickstart.ja.md +8 -4
  16. data/doc/quickstart.md +11 -8
  17. data/lib/review/book/base.rb +29 -18
  18. data/lib/review/book/index.rb +10 -5
  19. data/lib/review/builder.rb +58 -33
  20. data/lib/review/catalog.rb +30 -0
  21. data/lib/review/compiler.rb +53 -19
  22. data/lib/review/configure.rb +15 -14
  23. data/lib/review/epubmaker.rb +15 -4
  24. data/lib/review/htmlbuilder.rb +56 -24
  25. data/lib/review/idgxmlbuilder.rb +17 -7
  26. data/lib/review/latexbuilder.rb +113 -38
  27. data/lib/review/markdownbuilder.rb +12 -5
  28. data/lib/review/md2inaobuilder.rb +3 -1
  29. data/lib/review/pdfmaker.rb +23 -9
  30. data/lib/review/plaintextbuilder.rb +683 -0
  31. data/lib/review/rstbuilder.rb +30 -10
  32. data/lib/review/textmaker.rb +158 -0
  33. data/lib/review/textutils.rb +10 -1
  34. data/lib/review/topbuilder.rb +32 -417
  35. data/lib/review/version.rb +1 -1
  36. data/lib/review/webmaker.rb +29 -8
  37. data/review.gemspec +3 -4
  38. data/templates/html/layout-xhtml1.html.erb +0 -2
  39. data/templates/latex/layout.tex.erb +6 -4
  40. data/templates/web/html/layout-xhtml1.html.erb +0 -2
  41. data/test/book_test_helper.rb +1 -0
  42. data/test/run_test.rb +1 -1
  43. data/test/sample-book/src/Rakefile +19 -3
  44. data/test/syntax-book/Rakefile +19 -3
  45. data/test/test_catalog.rb +45 -0
  46. data/test/test_compiler.rb +8 -2
  47. data/test/test_htmlbuilder.rb +22 -0
  48. data/test/test_idgxmlbuilder.rb +22 -0
  49. data/test/test_index.rb +31 -0
  50. data/test/test_latexbuilder.rb +48 -16
  51. data/test/test_plaintextbuilder.rb +390 -0
  52. data/test/test_textutils.rb +2 -0
  53. data/test/test_topbuilder.rb +23 -1
  54. metadata +13 -7
@@ -1,3 +1,3 @@
1
1
  module ReVIEW
2
- VERSION = '2.4.0'.freeze
2
+ VERSION = '2.5.0'.freeze
3
3
  end
@@ -13,6 +13,7 @@ require 'review/converter'
13
13
  require 'review/configure'
14
14
  require 'review/book'
15
15
  require 'review/htmlbuilder'
16
+ require 'review/yamlloader'
16
17
  require 'review/template'
17
18
  require 'review/tocprinter'
18
19
  require 'review/version'
@@ -29,6 +30,15 @@ module ReVIEW
29
30
  @logger = ReVIEW.logger
30
31
  end
31
32
 
33
+ def error(msg)
34
+ @logger.error "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
35
+ exit 1
36
+ end
37
+
38
+ def warn(msg)
39
+ @logger.warn "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
40
+ end
41
+
32
42
  def self.execute(*args)
33
43
  self.new.execute(*args)
34
44
  end
@@ -68,13 +78,24 @@ module ReVIEW
68
78
  @config = ReVIEW::Configure.values
69
79
  @config.maker = 'webmaker'
70
80
  cmd_config, yamlfile = parse_opts(args)
81
+ error "#{yamlfile} not found." unless File.exist?(yamlfile)
71
82
 
72
- @config.merge!(YAML.load_file(yamlfile))
83
+ begin
84
+ loader = ReVIEW::YAMLLoader.new
85
+ @config.deep_merge!(loader.load_file(yamlfile))
86
+ rescue => e
87
+ error "yaml error #{e.message}"
88
+ end
73
89
  # YAML configs will be overridden by command line options.
74
- @config.merge!(cmd_config)
90
+ @config.deep_merge!(cmd_config)
75
91
  @config['htmlext'] = 'html'
76
92
  I18n.setup(@config['language'])
77
- generate_html_files(yamlfile)
93
+ begin
94
+ generate_html_files(yamlfile)
95
+ rescue ApplicationError => e
96
+ raise if @config['debug']
97
+ error(e.message)
98
+ end
78
99
  end
79
100
 
80
101
  def generate_html_files(yamlfile)
@@ -154,14 +175,14 @@ module ReVIEW
154
175
  htmlfile = "#{id}.#{@config['htmlext']}"
155
176
 
156
177
  if @config['params'].present?
157
- @logger.warn %Q('params:' in config.yml is obsoleted.)
178
+ warn %Q('params:' in config.yml is obsoleted.)
158
179
  end
159
180
 
160
181
  begin
161
182
  @converter.convert(filename, File.join(basetmpdir, htmlfile))
162
183
  rescue => e
163
- @logger.warn "compile error in #{filename} (#{e.class})"
164
- @logger.warn e.message
184
+ warn "compile error in #{filename} (#{e.class})"
185
+ warn e.message
165
186
  end
166
187
  end
167
188
 
@@ -240,7 +261,7 @@ module ReVIEW
240
261
  @body << %Q(<div class="titlepage">)
241
262
  @body << %Q(<h1 class="tp-title">#{CGI.escapeHTML(@config.name_of('booktitle'))}</h1>)
242
263
  @body << %Q(<h2 class="tp-author">#{join_with_separator(@config.names_of('aut'), ReVIEW::I18n.t('names_splitter'))}</h2>) if @config['aut']
243
- @body << %Q(<h3 class="tp-publisher">#{join_with_separator(@config.names_of('prt'), ReVIEW::I18n.t('names_splitter'))}</h3>) if @config['prt']
264
+ @body << %Q(<h3 class="tp-publisher">#{join_with_separator(@config.names_of('pbl'), ReVIEW::I18n.t('names_splitter'))}</h3>) if @config['pbl']
244
265
  @body << '</div>'
245
266
 
246
267
  @language = @config['language']
@@ -262,7 +283,7 @@ module ReVIEW
262
283
  def copy_file_with_param(name, target_file = nil)
263
284
  return if @config[name].nil? || !File.exist?(@config[name])
264
285
  target_file ||= File.basename(@config[name])
265
- FileUtils.cp(@config[name], File.join(basetmpdir, target_file))
286
+ FileUtils.cp(@config[name], File.join(@path, target_file))
266
287
  end
267
288
 
268
289
  def join_with_separator(value, sep)
@@ -12,13 +12,12 @@ Gem::Specification.new do |gem|
12
12
  gem.summary = 'Re:VIEW: a easy-to-use digital publishing system'
13
13
  gem.description = 'Re:VIEW is a digital publishing system for books and ebooks. It supports InDesign, EPUB and LaTeX.'
14
14
  gem.required_rubygems_version = Gem::Requirement.new('>= 0') if gem.respond_to? :required_rubygems_version=
15
- gem.date = '2017-06-29'
15
+ gem.date = '2018-03-01'
16
16
 
17
17
  gem.files = `git ls-files`.split("\n")
18
18
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
- gem.extra_rdoc_files = [
21
- ]
20
+ gem.extra_rdoc_files = []
22
21
  gem.require_paths = ['lib']
23
22
 
24
23
  gem.add_dependency('image_size')
@@ -26,6 +25,6 @@ Gem::Specification.new do |gem|
26
25
  gem.add_dependency('rubyzip')
27
26
  gem.add_development_dependency('pygments.rb')
28
27
  gem.add_development_dependency('rake')
29
- gem.add_development_dependency('rubocop')
28
+ gem.add_development_dependency('rubocop', '~> 0.52.0')
30
29
  gem.add_development_dependency('test-unit')
31
30
  end
@@ -13,8 +13,6 @@
13
13
  <title><%= @title %></title>
14
14
  </head>
15
15
  <body<%= @body_ext %>>
16
- <% if @error_messages %><%= @error_messages %><% end %>
17
- <% if @warning_messages %><%= @warning_messages %><% end %>
18
16
  <%= @body %>
19
17
  </body>
20
18
  </html>
@@ -249,8 +249,10 @@
249
249
  }
250
250
  \makeatother
251
251
 
252
- <%- if @config["usepackage"] -%>
253
- <%= @config["usepackage"] %>
252
+ <%- if @config["texstyle"] -%>
253
+ <%- [@config["texstyle"]].flatten.each do |x| -%>
254
+ \usepackage{<%= x %>}
255
+ <%- end -%>
254
256
  <%- end -%>
255
257
  <%- if @config["makeindex"] -%>
256
258
  \usepackage{makeidx}
@@ -360,7 +362,7 @@
360
362
  <%- if @config["subtitle"] -%>
361
363
  {\noindent\reviewtitlefont\large <%= escape_latex(@config.name_of("subtitle")) %>} \\
362
364
  <%- end -%>
363
- \rule[8pt]{14cm}{1pt} \\
365
+ \rule[8pt]{\textwidth}{1pt} \\
364
366
  {\noindent
365
367
  <%= @config["pubhistory"].to_s.gsub(/\n/){"\n\n\\noindent\n"} %>
366
368
  }
@@ -369,7 +371,7 @@
369
371
  <%= @okuduke %>
370
372
  \end{tabular}
371
373
   \\
372
- \rule[0pt]{14cm}{1pt} \\
374
+ \rule[0pt]{\textwidth}{1pt} \\
373
375
  <%- if @config["rights"] -%>
374
376
  <%= @config.names_of("rights").map{|s| escape_latex(s)}.join('\\' + '\\') %> \\
375
377
  <%- end -%>
@@ -13,8 +13,6 @@
13
13
  <title><%= @title %></title>
14
14
  </head>
15
15
  <body<%= @body_ext %>>
16
- <% if @error_messages %><%= @error_messages %><% end %>
17
- <% if @warning_messages %><%= @warning_messages %><% end %>
18
16
  <%= @body %>
19
17
  </body>
20
18
  </html>
@@ -1,4 +1,5 @@
1
1
  require 'test_helper'
2
+ require 'book_test_helper'
2
3
  require 'review/book'
3
4
 
4
5
  require 'stringio'
@@ -6,5 +6,5 @@ $LOAD_PATH.unshift(lib_dir)
6
6
 
7
7
  require 'test/unit'
8
8
 
9
- argv = ['--max-diff-target-string-size=10000']
9
+ argv = ARGV || ['--max-diff-target-string-size=10000']
10
10
  exit Test::Unit::AutoRunner.run(true, test_dir, argv)
@@ -6,10 +6,12 @@ BOOK_PDF = BOOK + '.pdf'
6
6
  BOOK_EPUB = BOOK + '.epub'
7
7
  CONFIG_FILE = 'config.yml'
8
8
  WEBROOT = 'webroot'
9
+ TEXTROOT = BOOK + '-text'
10
+ TOPROOT = BOOK + '-text'
9
11
 
10
12
  def build(mode, chapter)
11
13
  sh "review-compile --target=#{mode} --footnotetext --stylesheet=style.css #{chapter} > tmp"
12
- mode_ext = { 'html' => 'html', 'latex' => 'tex', 'idgxml' => 'xml' }
14
+ mode_ext = { 'html' => 'html', 'latex' => 'tex', 'idgxml' => 'xml', 'top' => 'txt', 'plaintext' => 'txt' }
13
15
  FileUtils.mv 'tmp', chapter.gsub(/re\z/, mode_ext[mode])
14
16
  end
15
17
 
@@ -46,9 +48,19 @@ task all: %i[pdf epub]
46
48
  desc 'generate PDF file'
47
49
  task pdf: BOOK_PDF
48
50
 
49
- desc 'generate stagic HTML file for web'
51
+ desc 'generate static HTML file for web'
50
52
  task web: WEBROOT
51
53
 
54
+ desc 'generate text file (without decoration)'
55
+ task plaintext: TEXTROOT do
56
+ sh "review-textmaker -n #{CONFIG_FILE}"
57
+ end
58
+
59
+ desc 'generate (decorated) text file'
60
+ task text: TOPROOT do
61
+ sh "review-textmaker #{CONFIG_FILE}"
62
+ end
63
+
52
64
  desc 'generate EPUB file'
53
65
  task epub: BOOK_EPUB
54
66
 
@@ -69,4 +81,8 @@ file WEBROOT => SRC do
69
81
  sh "review-webmaker #{CONFIG_FILE}"
70
82
  end
71
83
 
72
- CLEAN.include([BOOK, BOOK_PDF, BOOK_EPUB, BOOK + '-pdf', BOOK + '-epub', WEBROOT, 'images/_review_math'])
84
+ file TEXTROOT => SRC do
85
+ FileUtils.rm_rf [TEXTROOT]
86
+ end
87
+
88
+ CLEAN.include([BOOK, BOOK_PDF, BOOK_EPUB, BOOK + '-pdf', BOOK + '-epub', WEBROOT, 'images/_review_math', TEXTROOT])
@@ -6,10 +6,12 @@ BOOK_PDF = BOOK + '.pdf'
6
6
  BOOK_EPUB = BOOK + '.epub'
7
7
  CONFIG_FILE = 'config.yml'
8
8
  WEBROOT = 'webroot'
9
+ TEXTROOT = BOOK + '-text'
10
+ TOPROOT = BOOK + '-text'
9
11
 
10
12
  def build(mode, chapter)
11
13
  sh "review-compile --target=#{mode} --footnotetext --stylesheet=style.css #{chapter} > tmp"
12
- mode_ext = { 'html' => 'html', 'latex' => 'tex', 'idgxml' => 'xml' }
14
+ mode_ext = { 'html' => 'html', 'latex' => 'tex', 'idgxml' => 'xml', 'top' => 'txt', 'plaintext' => 'txt' }
13
15
  FileUtils.mv 'tmp', chapter.gsub(/re\z/, mode_ext[mode])
14
16
  end
15
17
 
@@ -46,9 +48,19 @@ task all: %i[pdf epub]
46
48
  desc 'generate PDF file'
47
49
  task pdf: BOOK_PDF
48
50
 
49
- desc 'generate stagic HTML file for web'
51
+ desc 'generate static HTML file for web'
50
52
  task web: WEBROOT
51
53
 
54
+ desc 'generate plaintext file'
55
+ task plaintext: TEXTROOT do
56
+ sh "review-textmaker -n #{CONFIG_FILE}"
57
+ end
58
+
59
+ desc 'generate decorated text file'
60
+ task text: TOPROOT do
61
+ sh "review-textmaker #{CONFIG_FILE}"
62
+ end
63
+
52
64
  desc 'generate EPUB file'
53
65
  task epub: BOOK_EPUB
54
66
 
@@ -69,4 +81,8 @@ file WEBROOT => SRC do
69
81
  sh "review-webmaker #{CONFIG_FILE}"
70
82
  end
71
83
 
72
- CLEAN.include([BOOK, BOOK_PDF, BOOK_EPUB, BOOK + '-pdf', BOOK + '-epub', WEBROOT])
84
+ file TEXTROOT => SRC do
85
+ FileUtils.rm_rf [TEXTROOT]
86
+ end
87
+
88
+ CLEAN.include([BOOK, BOOK_PDF, BOOK_EPUB, BOOK + '-pdf', BOOK + '-epub', WEBROOT, 'images/_review_math', TEXTROOT])
@@ -3,6 +3,7 @@ require 'review/catalog'
3
3
 
4
4
  class CatalogTest < Test::Unit::TestCase
5
5
  include ReVIEW
6
+ include BookTestHelper
6
7
 
7
8
  def test_predef
8
9
  sut = Catalog.new(yaml)
@@ -90,6 +91,50 @@ ch02.re
90
91
  assert_equal(exp.chomp, sut.chaps)
91
92
  end
92
93
 
94
+ def test_validate
95
+ mktmpbookdir do |dir, _book, _files|
96
+ %w[pre01.re pre02.re ch01.re ch02.re post01.re post02.re back01.re back02.re].each do |file|
97
+ FileUtils.touch(file)
98
+ end
99
+ cat = Catalog.new(yaml_hash)
100
+ cat.validate!(dir)
101
+ end
102
+ end
103
+
104
+ def test_validate_with_parts
105
+ mktmpbookdir do |dir, _book, _files|
106
+ %w[ch01.re part1.re ch02.re ch03.re part2.re ch04.re ch05.re].each do |file|
107
+ FileUtils.touch(file)
108
+ end
109
+ cat = Catalog.new(yaml_with_parts)
110
+ cat.validate!(dir)
111
+ end
112
+ end
113
+
114
+ def test_validate_fail_ch02
115
+ assert_raise FileNotFound do
116
+ mktmpbookdir do |dir, _book, _files|
117
+ %w[pre01.re pre02.re ch01.re].each do |file|
118
+ FileUtils.touch(file)
119
+ end
120
+ cat = Catalog.new(yaml_hash)
121
+ cat.validate!(dir)
122
+ end
123
+ end
124
+ end
125
+
126
+ def test_validate_fail_back02
127
+ assert_raise FileNotFound do
128
+ mktmpbookdir do |dir, _book, _files|
129
+ %w[pre01.re pre02.re ch01.re ch02.re post01.re post02.re back01.re back03.re].each do |file|
130
+ FileUtils.touch(file)
131
+ end
132
+ cat = Catalog.new(yaml_hash)
133
+ cat.validate!(dir)
134
+ end
135
+ end
136
+ end
137
+
93
138
  private
94
139
 
95
140
  def yaml
@@ -42,7 +42,13 @@ class CompilerTest < Test::Unit::TestCase
42
42
  end
43
43
 
44
44
  def test_replace_fence
45
- actual = @c.__send__(:replace_fence, '@<m>${}\\}|$, @<m>|{}\\}\\$|, @<m>|\\{\\a\\}|, @<tt>|}|, @<tt>|\\|, @<tt>|\\\\|, @<tt>|\\\\\\|')
46
- assert_equal '@<m>{{\\}\\\\\\}|}, @<m>{{\\}\\\\\\}\\$}, @<m>{\\{\\a\\\\\\}}, @<tt>{\\}}, @<tt>{\\\\}, @<tt>{\\\\\\\\}, @<tt>{\\\\\\\\\\\\}', actual
45
+ source_str = <<-'EOB'
46
+ @<m>${}\}|$, @<m>|{}\}\$|, @<m>|\{\a\}|, @<tt>|}|, @<tt>|\|, @<tt>|\\|, @<tt>|\\\|
47
+ EOB
48
+ expected = <<-'EOB'
49
+ @<m>{{\}\\\}|}, @<m>{{\}\\\}\$}, @<m>{\{\a\\\}}, @<tt>{\}}, @<tt>{\\}, @<tt>{\\\\}, @<tt>{\\\\\\}
50
+ EOB
51
+ actual = @c.__send__(:replace_fence, source_str)
52
+ assert_equal expected, actual
47
53
  end
48
54
  end
@@ -430,6 +430,11 @@ EOS
430
430
  assert_equal %Q(<div class="memo">\n<p class="caption">this is <b>test</b>&lt;&amp;&gt;_</p>\n<p>test1</p>\n<p>test<i>2</i></p>\n</div>\n), actual
431
431
  end
432
432
 
433
+ def test_blankline
434
+ actual = compile_block("//blankline\nfoo\n")
435
+ assert_equal %Q(<p><br /></p>\n<p>foo</p>\n), actual
436
+ end
437
+
433
438
  def test_noindent
434
439
  @builder.noindent
435
440
  actual = compile_block("foo\nbar\n\nfoo2\nbar2\n")
@@ -1686,4 +1691,21 @@ EOS
1686
1691
  actual = compile_inline('test @<code>|@<code>{$サンプル$}|')
1687
1692
  assert_equal 'test <code class="inline-code tt">@&lt;code&gt;{$サンプル$}</code>', actual
1688
1693
  end
1694
+
1695
+ def test_inline_unknown
1696
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<img>{n}\n" }
1697
+ assert_equal ':1: error: unknown image: n', e.message
1698
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<fn>{n}\n" }
1699
+ assert_equal ':1: error: unknown footnote: n', e.message
1700
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<hd>{n}\n" }
1701
+ assert_equal ':1: error: unknown headline: n', e.message
1702
+ %w[list table column].each do |name|
1703
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<#{name}>{n}\n" }
1704
+ assert_equal ":1: error: unknown #{name}: n", e.message
1705
+ end
1706
+ %w[chap chapref title].each do |name|
1707
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<#{name}>{n}\n" }
1708
+ assert_equal ':1: error: key not found: "n"', e.message
1709
+ end
1710
+ end
1689
1711
  end
@@ -341,6 +341,11 @@ class IDGXMLBuidlerTest < Test::Unit::TestCase
341
341
  assert_equal %Q(<p align='center'>foobar</p><p align='center'>buz</p>), actual
342
342
  end
343
343
 
344
+ def test_blankline
345
+ actual = compile_block("//blankline\nfoo\n")
346
+ assert_equal %Q(<p/><p>foo</p>), actual
347
+ end
348
+
344
349
  def test_noindent
345
350
  actual = compile_block("//noindent\nfoo\nbar\n\nfoo2\nbar2\n")
346
351
  assert_equal %Q(<p aid:pstyle="noindent" noindent='1'>foobar</p><p>foo2bar2</p>), actual
@@ -614,6 +619,23 @@ EOS
614
619
  assert_equal expected, actual
615
620
  end
616
621
 
622
+ def test_inline_unknown
623
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<img>{n}\n" }
624
+ assert_equal ':1: error: unknown image: n', e.message
625
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<fn>{n}\n" }
626
+ assert_equal ':1: error: unknown footnote: n', e.message
627
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<hd>{n}\n" }
628
+ assert_equal ':1: error: unknown headline: n', e.message
629
+ %w[list table column].each do |name|
630
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<#{name}>{n}\n" }
631
+ assert_equal ":1: error: unknown #{name}: n", e.message
632
+ end
633
+ %w[chap chapref title].each do |name|
634
+ e = assert_raises(ReVIEW::ApplicationError) { compile_block "@<#{name}>{n}\n" }
635
+ assert_equal ':1: error: key not found: "n"', e.message
636
+ end
637
+ end
638
+
617
639
  def test_inline_raw0
618
640
  assert_equal 'normal', compile_inline('@<raw>{normal}')
619
641
  end
@@ -177,4 +177,35 @@ class IndexTest < Test::Unit::TestCase
177
177
  index = Book::HeadlineIndex.parse(src, chap)
178
178
  assert_equal '1.1.1', index.number('sec1-1')
179
179
  end
180
+
181
+ def test_headeline_index9
182
+ src = <<-EOB
183
+ = chap1
184
+ == sec1
185
+ === sec1-1
186
+ ===[column] column1
187
+ ===[/column]
188
+ ==== sec1-1-1
189
+ === sec1-2
190
+ EOB
191
+ book = Book::Base.load
192
+ chap = Book::Chapter.new(book, 1, '-', nil)
193
+ index = Book::HeadlineIndex.parse(src, chap)
194
+ assert_equal [1, 1, 1], index['sec1-1-1'].number
195
+ end
196
+
197
+ def test_headeline_index10
198
+ src = <<-EOB
199
+ = chap1
200
+ == sec1
201
+ === sec1-1
202
+ ====[column] column1
203
+ ==== sec1-1-1
204
+ === sec1-2
205
+ EOB
206
+ book = Book::Base.load
207
+ chap = Book::Chapter.new(book, 1, '-', nil)
208
+ index = Book::HeadlineIndex.parse(src, chap)
209
+ assert_equal [1, 1, 1], index['sec1-1-1'].number
210
+ end
180
211
  end