review 3.0.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-win.yml +39 -0
  3. data/.github/workflows/ruby.yml +27 -0
  4. data/.rubocop.yml +50 -12
  5. data/.travis.yml +17 -8
  6. data/Dockerfile +21 -5
  7. data/NEWS.ja.md +358 -0
  8. data/NEWS.md +358 -1
  9. data/README.md +11 -8
  10. data/appveyor.yml +1 -3
  11. data/bin/review-catalog-converter +4 -4
  12. data/bin/review-check +8 -8
  13. data/bin/review-checkdep +1 -1
  14. data/bin/review-compile +12 -12
  15. data/bin/review-epubmaker +3 -35
  16. data/bin/review-idgxmlmaker +16 -0
  17. data/bin/review-index +2 -89
  18. data/bin/review-preproc +14 -19
  19. data/bin/review-validate +3 -3
  20. data/bin/review-vol +4 -78
  21. data/doc/LICENSE +1 -1
  22. data/doc/config.yml.sample +46 -12
  23. data/doc/config.yml.sample-simple +4 -2
  24. data/doc/format.ja.md +37 -13
  25. data/doc/format.md +35 -20
  26. data/doc/pdfmaker.ja.md +43 -1
  27. data/doc/pdfmaker.md +42 -1
  28. data/doc/quickstart.ja.md +46 -26
  29. data/doc/quickstart.md +38 -17
  30. data/lib/epubmaker/epubcommon.rb +10 -5
  31. data/lib/epubmaker/epubv2.rb +1 -1
  32. data/lib/epubmaker/epubv3.rb +1 -0
  33. data/lib/epubmaker/producer.rb +4 -2
  34. data/lib/review/book.rb +1 -1
  35. data/lib/review/book/base.rb +38 -79
  36. data/lib/review/book/chapter.rb +18 -3
  37. data/lib/review/book/compilable.rb +6 -5
  38. data/lib/review/book/index.rb +69 -101
  39. data/lib/review/book/index/item.rb +40 -0
  40. data/lib/review/book/page_metric.rb +7 -7
  41. data/lib/review/book/part.rb +28 -5
  42. data/lib/review/book/volume.rb +3 -4
  43. data/lib/review/builder.rb +105 -44
  44. data/lib/review/catalog.rb +13 -16
  45. data/lib/review/compiler.rb +84 -72
  46. data/lib/review/configure.rb +19 -8
  47. data/lib/review/epub2html.rb +37 -4
  48. data/lib/review/epubmaker.rb +62 -7
  49. data/lib/review/extentions/string.rb +0 -4
  50. data/lib/review/htmlbuilder.rb +102 -115
  51. data/lib/review/htmlutils.rb +2 -3
  52. data/lib/review/i18n.rb +2 -2
  53. data/lib/review/i18n.yml +9 -0
  54. data/lib/review/idgxmlbuilder.rb +153 -74
  55. data/lib/review/idgxmlmaker.rb +191 -0
  56. data/lib/review/init-web/finish.html +10 -0
  57. data/lib/review/init-web/index.html +190 -0
  58. data/lib/review/init-web/review-layout-design.js +691 -0
  59. data/lib/review/init.rb +125 -34
  60. data/lib/review/latexbuilder.rb +199 -88
  61. data/lib/review/lineinput.rb +1 -1
  62. data/lib/review/location.rb +32 -0
  63. data/lib/review/logger.rb +4 -8
  64. data/lib/review/makerhelper.rb +24 -5
  65. data/lib/review/markdownbuilder.rb +31 -37
  66. data/lib/review/md2inaobuilder.rb +3 -5
  67. data/lib/review/pdfmaker.rb +44 -22
  68. data/lib/review/plaintextbuilder.rb +106 -85
  69. data/lib/review/preprocessor.rb +32 -41
  70. data/lib/review/rstbuilder.rb +33 -33
  71. data/lib/review/textmaker.rb +19 -3
  72. data/lib/review/textutils.rb +76 -2
  73. data/lib/review/tocprinter.rb +231 -102
  74. data/lib/review/topbuilder.rb +114 -61
  75. data/lib/review/update.rb +19 -19
  76. data/lib/review/version.rb +1 -1
  77. data/lib/review/volumeprinter.rb +99 -0
  78. data/lib/review/webmaker.rb +11 -4
  79. data/lib/review/webtocprinter.rb +38 -35
  80. data/lib/review/yamlloader.rb +26 -16
  81. data/review.gemspec +6 -4
  82. data/samples/sample-book/README.md +7 -2
  83. data/samples/sample-book/src/.gitignore +154 -0
  84. data/samples/sample-book/src/config-ebook.yml +4 -0
  85. data/samples/sample-book/src/config-jlreq-ebook.yml +4 -0
  86. data/samples/sample-book/src/config-jlreq.yml +6 -0
  87. data/samples/sample-book/src/config.yml +2 -2
  88. data/samples/sample-book/src/lib/tasks/review.rake +29 -14
  89. data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +14 -8
  90. data/samples/syntax-book/ch01.re +4 -2
  91. data/samples/syntax-book/ch02.re +8 -16
  92. data/samples/syntax-book/ch03.re +3 -6
  93. data/samples/syntax-book/config-jlreq-lualatex.yml +4 -0
  94. data/samples/syntax-book/config-jlreq.yml +5 -0
  95. data/samples/syntax-book/config-print.yml +3 -0
  96. data/samples/syntax-book/config.yml +1 -1
  97. data/samples/syntax-book/lib/tasks/review.rake +30 -15
  98. data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +14 -8
  99. data/templates/latex/config.erb +16 -0
  100. data/templates/latex/layout.tex.erb +4 -0
  101. data/templates/latex/review-jlreq/review-base.sty +150 -61
  102. data/templates/latex/review-jlreq/review-jlreq.cls +74 -8
  103. data/templates/latex/review-jlreq/review-style.sty +4 -1
  104. data/templates/latex/review-jsbook/README.md +39 -0
  105. data/templates/latex/review-jsbook/review-base.sty +101 -23
  106. data/templates/latex/review-jsbook/review-jsbook.cls +28 -5
  107. data/templates/latex/review-jsbook/review-style.sty +5 -2
  108. data/templates/opf/epubv3.opf.erb +1 -0
  109. data/templates/web/html/layout-html5.html.erb +2 -2
  110. data/test/assets/test_template.tex +24 -3
  111. data/test/assets/test_template_backmatter.tex +24 -3
  112. data/test/test_book.rb +75 -21
  113. data/test/test_book_chapter.rb +4 -2
  114. data/test/test_book_part.rb +3 -3
  115. data/test/test_builder.rb +16 -0
  116. data/test/test_catalog.rb +24 -42
  117. data/test/test_catalog_converter_cmd.rb +1 -1
  118. data/test/test_epubmaker_cmd.rb +14 -7
  119. data/test/test_helper.rb +15 -7
  120. data/test/test_htmlbuilder.rb +909 -159
  121. data/test/test_i18n.rb +25 -25
  122. data/test/test_idgxmlbuilder.rb +395 -38
  123. data/test/test_idgxmlmaker_cmd.rb +46 -0
  124. data/test/test_image_finder.rb +52 -70
  125. data/test/test_index.rb +50 -10
  126. data/test/test_latexbuilder.rb +1194 -106
  127. data/test/test_latexbuilder_v2.rb +628 -97
  128. data/test/test_logger.rb +14 -1
  129. data/test/test_makerhelper.rb +3 -3
  130. data/test/test_markdownbuilder.rb +134 -16
  131. data/test/test_md2inaobuilder.rb +32 -9
  132. data/test/test_pdfmaker.rb +18 -1
  133. data/test/test_pdfmaker_cmd.rb +100 -6
  134. data/test/test_plaintextbuilder.rb +371 -25
  135. data/test/test_preprocessor.rb +2 -16
  136. data/test/test_rstbuilder.rb +249 -26
  137. data/test/test_textmaker_cmd.rb +54 -0
  138. data/test/test_textutils.rb +109 -2
  139. data/test/test_topbuilder.rb +546 -31
  140. data/test/test_update.rb +17 -8
  141. data/test/test_webtocprinter.rb +66 -34
  142. data/test/test_yamlloader.rb +13 -0
  143. data/vendor/jsclasses/LICENSE +1 -1
  144. data/vendor/jsclasses/jis/jsarticle.cls +53 -14
  145. data/vendor/jsclasses/jis/jsbook.cls +53 -14
  146. data/vendor/jsclasses/jis/jsclasses.dtx +84 -25
  147. data/vendor/jsclasses/jis/jslogo.dtx +4 -4
  148. data/vendor/jsclasses/jis/jslogo.sty +3 -3
  149. data/vendor/jsclasses/jis/jspf.cls +52 -13
  150. data/vendor/jsclasses/jis/jsreport.cls +53 -14
  151. data/vendor/jsclasses/jis/kiyou.cls +53 -14
  152. data/vendor/jsclasses/jis/okumacro.dtx +4 -5
  153. data/vendor/jsclasses/jis/okumacro.sty +3 -4
  154. data/vendor/jsclasses/jsarticle.cls +53 -14
  155. data/vendor/jsclasses/jsbook.cls +53 -14
  156. data/vendor/jsclasses/jsclasses.dtx +84 -25
  157. data/vendor/jsclasses/jsclasses.pdf +0 -0
  158. data/vendor/jsclasses/jslogo.dtx +4 -4
  159. data/vendor/jsclasses/jslogo.pdf +0 -0
  160. data/vendor/jsclasses/jslogo.sty +3 -3
  161. data/vendor/jsclasses/jspf.cls +52 -13
  162. data/vendor/jsclasses/jsreport.cls +53 -14
  163. data/vendor/jsclasses/kiyou.cls +53 -14
  164. data/vendor/jsclasses/okumacro.dtx +4 -5
  165. data/vendor/jsclasses/okumacro.pdf +0 -0
  166. data/vendor/jsclasses/okumacro.sty +3 -4
  167. metadata +55 -10
  168. data/lib/review/tocparser.rb +0 -271
  169. data/samples/syntax-book/review-ext.rb +0 -14
  170. data/test/test_tocparser.rb +0 -25
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (c) 2009-2017 Minero Aoki, Kenshi Muto
2
+ # Copyright (c) 2009-2019 Minero Aoki, Kenshi Muto
3
3
  # 2002-2008 Minero Aoki
4
4
  #
5
5
  # This program is free software.
@@ -18,6 +18,21 @@ module ReVIEW
18
18
 
19
19
  attr_reader :number, :book
20
20
 
21
+ def self.mkchap(book, name, number = nil)
22
+ name += book.ext if File.extname(name).empty?
23
+ path = File.join(book.contentdir, name)
24
+ raise FileNotFound, "file not exist: #{path}" unless File.file?(path)
25
+ Chapter.new(book, number, name, path)
26
+ end
27
+
28
+ def self.mkchap_ifexist(book, name, number = nil)
29
+ name += book.ext if File.extname(name).empty?
30
+ path = File.join(book.contentdir, name)
31
+ if File.file?(path)
32
+ Chapter.new(book, number, name, path)
33
+ end
34
+ end
35
+
21
36
  def initialize(book, number, name, path, io = nil)
22
37
  @book = book
23
38
  @number = number
@@ -35,7 +50,7 @@ module ReVIEW
35
50
  @content = nil
36
51
  end
37
52
  if !@content && @path && File.exist?(@path)
38
- @content = File.read(@path, mode: 'r:BOM|utf-8')
53
+ @content = File.read(@path, mode: 'rt:BOM|utf-8')
39
54
  @number = nil if %w[nonum nodisp notoc].include?(find_first_header_option)
40
55
  end
41
56
  @list_index = nil
@@ -125,7 +140,7 @@ module ReVIEW
125
140
  private
126
141
 
127
142
  def on_file?(contents)
128
- contents.lines.map(&:strip).include?("#{id}#{@book.ext}")
143
+ contents.map(&:strip).include?("#{id}#{@book.ext}")
129
144
  end
130
145
 
131
146
  # backward compatibility
@@ -52,11 +52,7 @@ module ReVIEW
52
52
  end
53
53
 
54
54
  def volume
55
- unless @volume
56
- @volume = Volume.count_file(path)
57
- @volume.page_per_kbyte = @book.page_metric.page_per_kbyte
58
- end
59
- @volume
55
+ @volume ||= Volume.count_file(path)
60
56
  end
61
57
 
62
58
  def lines
@@ -168,6 +164,11 @@ module ReVIEW
168
164
  def prev_chapter
169
165
  book.prev_chapter(self)
170
166
  end
167
+
168
+ def image_bound?(item_id)
169
+ item = self.image(item_id)
170
+ item.path
171
+ end
171
172
  end
172
173
  end
173
174
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2008-2018 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2008-2019 Minero Aoki, Kenshi Muto
2
2
  # 2002-2007 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -12,29 +12,24 @@ require 'review/exception'
12
12
  require 'review/book/image_finder'
13
13
  require 'review/i18n'
14
14
  require 'review/logger'
15
+ require 'review/book/index/item'
15
16
 
16
17
  module ReVIEW
17
18
  module Book
18
19
  class Index
19
20
  def self.parse(src, *args)
20
- items = []
21
+ index = self.new(*args)
21
22
  seq = 1
22
23
  src.grep(%r{\A//#{item_type}}) do |line|
23
24
  if id = line.slice(/\[(.*?)\]/, 1)
24
- items.push item_class.new(id, seq)
25
+ index.add_item(ReVIEW::Book::Index::Item.new(id, seq))
25
26
  seq += 1
26
27
  if id.empty?
27
28
  ReVIEW.logger.warn "warning: no ID of #{item_type} in #{line}"
28
29
  end
29
30
  end
30
31
  end
31
- new(items, *args)
32
- end
33
-
34
- Item = Struct.new(:id, :number)
35
-
36
- def self.item_class
37
- self::Item
32
+ index
38
33
  end
39
34
 
40
35
  include Enumerable
@@ -43,19 +38,22 @@ module ReVIEW
43
38
  self.class.item_type
44
39
  end
45
40
 
46
- def initialize(items)
47
- @items = items
41
+ def initialize
48
42
  @index = {}
49
43
  @logger = ReVIEW.logger
50
- items.each do |i|
51
- if @index[i.id]
52
- @logger.warn "warning: duplicate ID: #{i.id} (#{i})"
53
- end
54
- @index[i.id] = i
55
- end
56
44
  @image_finder = nil
57
45
  end
58
46
 
47
+ def add_item(item)
48
+ if @index[item.id]
49
+ @logger.warn "warning: duplicate ID: #{item.id} (#{item})"
50
+ end
51
+ @index[item.id] = item
52
+ if item.class != ReVIEW::Book::Chapter
53
+ item.index = self
54
+ end
55
+ end
56
+
59
57
  def [](id)
60
58
  @index.fetch(id)
61
59
  rescue
@@ -65,9 +63,9 @@ module ReVIEW
65
63
  raise KeyError, "key '#{id}' is ambiguous for #{self.class}"
66
64
  end
67
65
 
68
- @items.each do |i|
69
- if i.id.split('|').include?(id)
70
- return i
66
+ @index.values.each do |item|
67
+ if item.id.split('|').include?(id)
68
+ return item
71
69
  end
72
70
  end
73
71
  raise KeyError, "not found key '#{id}' for #{self.class}"
@@ -78,7 +76,7 @@ module ReVIEW
78
76
  end
79
77
 
80
78
  def each(&block)
81
- @items.each(&block)
79
+ @index.values.each(&block)
82
80
  end
83
81
 
84
82
  def key?(id)
@@ -93,8 +91,9 @@ module ReVIEW
93
91
  end
94
92
 
95
93
  def number(id)
96
- chapter = @index.fetch(id)
94
+ chapter_item = @index.fetch(id)
97
95
  begin
96
+ chapter = chapter_item.content
98
97
  chapter.format_number
99
98
  rescue # part
100
99
  I18n.t('part', chapter.number)
@@ -102,9 +101,9 @@ module ReVIEW
102
101
  end
103
102
 
104
103
  def title(id)
105
- @index.fetch(id).title
104
+ @index.fetch(id).content.title
106
105
  rescue # non-file part
107
- @index.fetch(id).name
106
+ @index.fetch(id).content.name
108
107
  end
109
108
 
110
109
  def display_string(id)
@@ -135,35 +134,33 @@ module ReVIEW
135
134
  end
136
135
 
137
136
  class FootnoteIndex < Index
138
- Item = Struct.new(:id, :number, :content)
139
-
140
137
  def self.parse(src)
141
- items = []
138
+ index = self.new
142
139
  seq = 1
143
140
  src.grep(%r{\A//footnote}) do |line|
144
141
  if m = /\[(.*?)\]\[(.*)\]/.match(line)
145
142
  m1 = m[1].gsub(/\\(\])/) { $1 }
146
143
  m2 = m[2].gsub(/\\(\])/) { $1 }
147
- items.push Item.new(m1, seq, m2)
144
+ index.add_item(Item.new(m1, seq, m2))
148
145
  end
149
146
  seq += 1
150
147
  end
151
- new(items)
148
+ index
152
149
  end
153
150
  end
154
151
 
155
152
  class ImageIndex < Index
156
153
  def self.parse(src, *args)
157
- items = []
154
+ index = self.new(*args)
158
155
  seq = 1
159
156
  src.grep(%r{\A//#{item_type}}) do |line|
160
157
  # ex. ["//image", "id", "", "caption"]
161
158
  elements = line.split(/\[(.*?)\]/)
162
159
  if elements[1].present?
163
- if line =~ %r{\A//imgtable}
164
- items.push item_class.new(elements[1], 0, elements[3])
160
+ if line.start_with?('//imgtable')
161
+ index.add_item(ReVIEW::Book::Index::Item.new(elements[1], 0, elements[3]))
165
162
  else ## %r<\A//(image|graph)>
166
- items.push item_class.new(elements[1], seq, elements[3])
163
+ index.add_item(ReVIEW::Book::Index::Item.new(elements[1], seq, elements[3]))
167
164
  seq += 1
168
165
  end
169
166
  if elements[1] == ''
@@ -171,45 +168,21 @@ module ReVIEW
171
168
  end
172
169
  end
173
170
  end
174
- new(items, *args)
171
+ index
175
172
  end
176
173
 
177
174
  def self.item_type
178
175
  '(image|graph|imgtable)'
179
176
  end
180
177
 
181
- class Item
182
- def initialize(id, number, caption = nil)
183
- @id = id
184
- @number = number
185
- @caption = caption
186
- @path = nil
187
- end
188
-
189
- attr_reader :id
190
- attr_reader :number
191
- attr_reader :caption
192
- attr_writer :index # internal use only
193
-
194
- def bound?
195
- path
196
- end
197
-
198
- def path
199
- @path ||= @index.find_path(id)
200
- end
201
- end
202
-
203
178
  attr_reader :image_finder
204
179
 
205
- def initialize(items, chapid, basedir, types, builder)
206
- super items
207
- items.each do |i|
208
- i.index = self
209
- end
180
+ def initialize(chapid, basedir, types, builder)
181
+ super()
210
182
  @chapid = chapid
211
183
  @basedir = basedir
212
184
  @types = types
185
+ @logger = ReVIEW.logger
213
186
 
214
187
  @image_finder = ReVIEW::Book::ImageFinder.new(basedir, chapid, builder, types)
215
188
  end
@@ -220,46 +193,42 @@ module ReVIEW
220
193
  end
221
194
 
222
195
  class IconIndex < ImageIndex
223
- def initialize(items, chapid, basedir, types, builder)
224
- @items = items
196
+ def initialize(chapid, basedir, types, builder)
225
197
  @index = {}
226
- items.each { |i| @index[i.id] = i }
227
- items.each { |i| i.index = self }
228
198
  @chapid = chapid
229
199
  @basedir = basedir
230
200
  @types = types
201
+ @logger = ReVIEW.logger
231
202
 
232
203
  @image_finder = ImageFinder.new(basedir, chapid, builder, types)
233
204
  end
234
205
 
235
206
  def self.parse(src, *args)
236
- items = []
207
+ index = self.new(*args)
237
208
  seq = 1
238
209
  src.grep(/@<icon>/) do |line|
239
210
  line.gsub(/@<icon>\{(.+?)\}/) do
240
- items.push item_class.new($1, seq)
211
+ index.add_item(ReVIEW::Book::Index::Item.new($1, seq))
241
212
  seq += 1
242
213
  end
243
214
  end
244
- new(items, *args)
215
+ index
245
216
  end
246
217
  end
247
218
 
248
219
  class BibpaperIndex < Index
249
- Item = Struct.new(:id, :number, :caption)
250
-
251
220
  def self.parse(src)
252
- items = []
221
+ index = self.new
253
222
  seq = 1
254
223
  src.grep(%r{\A//bibpaper}) do |line|
255
224
  if m = /\[(.*?)\]\[(.*)\]/.match(line)
256
225
  m1 = m[1].gsub(/\\(.)/) { $1 }
257
226
  m2 = m[2].gsub(/\\(.)/) { $1 }
258
- items.push Item.new(m1, seq, m2)
227
+ index.add_item(Item.new(m1, seq, m2))
259
228
  end
260
229
  seq += 1
261
230
  end
262
- new(items)
231
+ index
263
232
  end
264
233
  end
265
234
 
@@ -268,18 +237,12 @@ module ReVIEW
268
237
  'numberlessimage'
269
238
  end
270
239
 
271
- class Item < ImageIndex::Item
272
- end
273
-
274
240
  def number(_id)
275
241
  ''
276
242
  end
277
243
  end
278
244
 
279
245
  class IndepImageIndex < ImageIndex
280
- class Item < ImageIndex::Item
281
- end
282
-
283
246
  def self.item_type
284
247
  '(indepimage|imgtable)'
285
248
  end
@@ -291,11 +254,9 @@ module ReVIEW
291
254
 
292
255
  class HeadlineIndex < Index
293
256
  HEADLINE_PATTERN = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/
294
- Item = Struct.new(:id, :number, :caption)
295
- attr_reader :items
296
257
 
297
258
  def self.parse(src, chap)
298
- items = []
259
+ headline_index = self.new(chap)
299
260
  indexs = []
300
261
  headlines = []
301
262
  inside_column = false
@@ -305,7 +266,7 @@ module ReVIEW
305
266
  if line =~ %r{\A//[a-z]+.*\{\Z}
306
267
  inside_block = true
307
268
  next
308
- elsif line =~ %r{\A//\}}
269
+ elsif line.start_with?('//}')
309
270
  inside_block = nil
310
271
  next
311
272
  elsif inside_block
@@ -316,6 +277,7 @@ module ReVIEW
316
277
  if m.nil? || m[1].size > 10 # Ignore too deep index
317
278
  next
318
279
  end
280
+
319
281
  index = m[1].size - 2
320
282
 
321
283
  # column
@@ -335,7 +297,9 @@ module ReVIEW
335
297
 
336
298
  next unless index >= 0
337
299
  if indexs.size > (index + 1)
338
- indexs = indexs.take(index + 1)
300
+ unless %w[nonum notoc nodisp].include?(m[2])
301
+ indexs = indexs.take(index + 1)
302
+ end
339
303
  headlines = headlines.take(index + 1)
340
304
  end
341
305
  if indexs[index].nil?
@@ -343,27 +307,32 @@ module ReVIEW
343
307
  indexs[i] ||= 0
344
308
  end
345
309
  end
346
- indexs[index] += 1
347
- headlines[index] = m[3].present? ? m[3].strip : m[4].strip
348
- items.push Item.new(headlines.join('|'), indexs.dup, m[4].strip)
310
+
311
+ if %w[nonum notoc nodisp].include?(m[2])
312
+ headlines[index] = m[3].present? ? m[3].strip : m[4].strip
313
+ item_id = headlines.join('|')
314
+ headline_index.add_item(Item.new(item_id, nil, m[4].strip))
315
+ else
316
+ indexs[index] += 1
317
+ headlines[index] = m[3].present? ? m[3].strip : m[4].strip
318
+ item_id = headlines.join('|')
319
+ headline_index.add_item(Item.new(item_id, indexs.dup, m[4].strip))
320
+ end
349
321
  end
350
- new(items, chap)
322
+ headline_index
351
323
  end
352
324
 
353
- def initialize(items, chap)
354
- @items = items
325
+ def initialize(chap)
355
326
  @chap = chap
356
327
  @index = {}
357
328
  @logger = ReVIEW.logger
358
- items.each do |i|
359
- if @index[i.id]
360
- @logger.warn "warning: duplicate ID: #{i.id}"
361
- end
362
- @index[i.id] = i
363
- end
364
329
  end
365
330
 
366
331
  def number(id)
332
+ unless self[id].number
333
+ # when notoc
334
+ return ''
335
+ end
367
336
  n = @chap.number
368
337
  # XXX: remove magic number (move to lib/review/book/chapter.rb)
369
338
  if @chap.on_appendix? && @chap.number > 0 && @chap.number < 28
@@ -375,10 +344,9 @@ module ReVIEW
375
344
 
376
345
  class ColumnIndex < Index
377
346
  COLUMN_PATTERN = /\A(=+)\[column\](?:\{(.+?)\})?(.*)/
378
- Item = Struct.new(:id, :number, :caption)
379
347
 
380
348
  def self.parse(src, *_args)
381
- items = []
349
+ index = self.new
382
350
  seq = 1
383
351
  src.each do |line|
384
352
  m = COLUMN_PATTERN.match(line)
@@ -388,10 +356,10 @@ module ReVIEW
388
356
  caption = m[3].strip
389
357
  id = caption if id.nil? || id.empty?
390
358
 
391
- items.push item_class.new(id, seq, caption)
359
+ index.add_item(ReVIEW::Book::Index::Item.new(id, seq, caption))
392
360
  seq += 1
393
361
  end
394
- new(items)
362
+ index
395
363
  end
396
364
  end
397
365
  end