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
@@ -0,0 +1,40 @@
1
+ # Copyright (c) 2008-2019 Minero Aoki, Kenshi Muto
2
+ #
3
+ # This program is free software.
4
+ # You can distribute or modify this program under the terms of
5
+ # the GNU LGPL, Lesser General Public License version 2.1.
6
+ # For details of LGPL, see the file "COPYING".
7
+ #
8
+
9
+ require 'review/extentions'
10
+ require 'review/exception'
11
+ require 'review/book/image_finder'
12
+ require 'review/i18n'
13
+ require 'review/logger'
14
+
15
+ module ReVIEW
16
+ module Book
17
+ class Index
18
+ class Item
19
+ def initialize(id, number, caption = nil)
20
+ @id = id
21
+ @number = number
22
+ @caption = caption
23
+ @path = nil
24
+ @index = nil
25
+ end
26
+
27
+ attr_reader :id
28
+ attr_reader :number
29
+ attr_reader :caption
30
+ attr_accessor :index # internal use only
31
+
32
+ alias_method :content, :caption
33
+
34
+ def path
35
+ @path ||= @index.find_path(id)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2017 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2009-2020 Minero Aoki, Kenshi Muto
2
2
  # 2002-2008 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -11,21 +11,21 @@ module ReVIEW
11
11
  class PageMetric
12
12
  MetricData = Struct.new(:n_lines, :n_columns)
13
13
 
14
- def initialize(list_lines, list_columns, text_lines, text_columns, page_per_kbyte)
14
+ def initialize(list_lines, list_columns, text_lines, text_columns, _page_per_kbyte = 1)
15
+ # page_per_kbyte is obsolete. Just for backward compatibility
15
16
  @list = MetricData.new(list_lines, list_columns)
16
17
  @text = MetricData.new(text_lines, text_columns)
17
- @page_per_kbyte = page_per_kbyte
18
18
  end
19
19
 
20
- A5 = PageMetric.new(46, 80, 30, 74, 1)
21
- B5 = PageMetric.new(46, 80, 30, 74, 2)
20
+ # based on review-jsbook's default
21
+ A5 = PageMetric.new(40, 34, 29, 34)
22
+ B5 = PageMetric.new(50, 40, 36, 40)
22
23
 
23
24
  attr_reader :list
24
25
  attr_reader :text
25
- attr_reader :page_per_kbyte
26
26
 
27
27
  def ==(other)
28
- self.list == other.list && self.text == other.text && self.page_per_kbyte == other.page_per_kbyte
28
+ self.list == other.list && self.text == other.text
29
29
  end
30
30
  end
31
31
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2018 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2009-2019 Minero Aoki, Kenshi Muto
2
2
  # 2002-2008 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -13,6 +13,26 @@ module ReVIEW
13
13
  class Part
14
14
  include Compilable
15
15
 
16
+ def self.mkpart_from_namelistfile(book, path)
17
+ chaps = []
18
+ File.read(path, mode: 'rt:BOM|utf-8').split.each_with_index do |name, number|
19
+ if path =~ /PREDEF/
20
+ chaps << Chapter.mkchap(book, name)
21
+ else
22
+ chaps << Chapter.mkchap(book, name, number + 1)
23
+ end
24
+ end
25
+ Part.mkpart(chaps)
26
+ end
27
+
28
+ def self.mkpart_from_namelist(book, names)
29
+ Part.mkpart(names.map { |name| Chapter.mkchap_ifexist(book, name) }.compact)
30
+ end
31
+
32
+ def self.mkpart(chaps)
33
+ chaps.empty? ? nil : Part.new(self, nil, chaps)
34
+ end
35
+
16
36
  # if Part is dummy, `number` is nil.
17
37
  #
18
38
  def initialize(book, number, chapters, name = '', io = nil)
@@ -21,11 +41,11 @@ module ReVIEW
21
41
  @chapters = chapters
22
42
  @name = name
23
43
  @path = name
24
- @content = nil
44
+ @content = ''
25
45
  if io
26
46
  @content = io.read
27
47
  elsif @path.present? && File.exist?(File.join(@book.config['contentdir'], @path))
28
- @content = File.read(File.join(@book.config['contentdir'], @path), mode: 'r:BOM|utf-8')
48
+ @content = File.read(File.join(@book.config['contentdir'], @path), mode: 'rt:BOM|utf-8')
29
49
  @name = File.basename(@name, '.re')
30
50
  end
31
51
  if file?
@@ -45,8 +65,11 @@ module ReVIEW
45
65
  end
46
66
 
47
67
  def volume
48
- vol = Volume.sum(@chapters.map(&:volume))
49
- vol.page_per_kbyte = @book.page_metric.page_per_kbyte
68
+ if @number && file?
69
+ vol = Volume.count_file(File.join(@book.config['contentdir'], @path))
70
+ else
71
+ vol = Volume.new(0, 0, 0)
72
+ end
50
73
  vol
51
74
  end
52
75
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2007-2017 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2007-2020 Minero Aoki, Kenshi Muto
2
2
  # 2002-2007 Minero Aoki
3
3
  #
4
4
  # This program is free software.
@@ -33,20 +33,19 @@ module ReVIEW
33
33
  @bytes = bytes
34
34
  @chars = chars
35
35
  @lines = lines
36
- @page_per_kbyte = nil
37
36
  end
38
37
 
39
38
  attr_reader :bytes
40
39
  attr_reader :chars
41
40
  attr_accessor :lines
42
- attr_accessor :page_per_kbyte
43
41
 
44
42
  def kbytes
45
43
  (@bytes.to_f / 1024).ceil
46
44
  end
47
45
 
48
46
  def page
49
- (kbytes.to_f / @page_per_kbyte).ceil
47
+ # XXX:unrelibable
48
+ kbytes.to_f.ceil
50
49
  end
51
50
 
52
51
  def to_s
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2002-2018 Minero Aoki, Kenshi Muto
1
+ # Copyright (c) 2002-2020 Minero Aoki, Kenshi Muto
2
2
  #
3
3
  # This program is free software.
4
4
  # You can distribute or modify this program under the terms of
@@ -56,12 +56,28 @@ module ReVIEW
56
56
  @tabwidth = nil
57
57
  @tsize = nil
58
58
  if @book && @book.config
59
- if @book.config['words_file']
60
- load_words(@book.config['words_file'])
59
+ if words_file_path = @book.config['words_file']
60
+ if words_file_path.is_a?(String)
61
+ words_files = [words_file_path]
62
+ else
63
+ words_files = words_file_path
64
+ end
65
+ words_files.each do |f|
66
+ load_words(f)
67
+ end
61
68
  end
62
69
  if @book.config['tabwidth']
63
70
  @tabwidth = @book.config['tabwidth']
64
71
  end
72
+
73
+ if @book.config['join_lines_by_lang']
74
+ begin
75
+ require 'unicode/eaw'
76
+ rescue LoadError
77
+ warn 'not found unicode/eaw. disabled join_lines_by_lang feature.'
78
+ @book.config['join_lines_by_lang'] = nil
79
+ end
80
+ end
65
81
  end
66
82
  builder_init_file
67
83
  end
@@ -71,6 +87,10 @@ module ReVIEW
71
87
  end
72
88
  private :builder_init_file
73
89
 
90
+ def highlight?
91
+ false
92
+ end
93
+
74
94
  def result
75
95
  @output.string
76
96
  end
@@ -122,59 +142,87 @@ module ReVIEW
122
142
 
123
143
  def list(lines, id, caption, lang = nil)
124
144
  begin
125
- list_header id, caption, lang
145
+ list_header(id, caption, lang) if caption_top?('list')
146
+ list_body(id, lines, lang)
147
+ list_header(id, caption, lang) unless caption_top?('list')
126
148
  rescue KeyError
127
149
  error "no such list: #{id}"
128
150
  end
129
- list_body id, lines, lang
130
151
  end
131
152
 
132
153
  def listnum(lines, id, caption, lang = nil)
133
154
  begin
134
- list_header id, caption, lang
155
+ list_header(id, caption, lang) if caption_top?('list')
156
+ listnum_body(lines, lang)
157
+ list_header(id, caption, lang) unless caption_top?('list')
135
158
  rescue KeyError
136
159
  error "no such list: #{id}"
137
160
  end
138
- listnum_body lines, lang
139
161
  end
140
162
 
141
- def source(lines, caption, lang = nil)
142
- source_header caption
143
- source_body lines, lang
163
+ def source(lines, caption = nil, lang = nil)
164
+ source_header(caption) if caption_top?('list')
165
+ source_body(lines, lang)
166
+ source_header(caption) unless caption_top?('list')
144
167
  end
145
168
 
146
169
  def image(lines, id, caption, metric = nil)
147
- if @chapter.image(id).bound?
148
- image_image id, caption, metric
170
+ if @chapter.image_bound?(id)
171
+ image_image(id, caption, metric)
149
172
  else
150
173
  warn "image not bound: #{id}" if @strict
151
- image_dummy id, caption, lines
174
+ image_dummy(id, caption, lines)
152
175
  end
153
176
  end
154
177
 
155
178
  def table(lines, id = nil, caption = nil)
156
- rows = []
179
+ sepidx, rows = parse_table_rows(lines)
180
+ begin
181
+ if caption_top?('table') && caption.present?
182
+ table_header(id, caption)
183
+ end
184
+ table_begin(rows.first.size)
185
+ table_rows(sepidx, rows)
186
+ table_end
187
+ if !caption_top?('table') && caption.present?
188
+ table_header(id, caption)
189
+ end
190
+ rescue KeyError
191
+ error "no such table: #{id}"
192
+ end
193
+ end
194
+
195
+ def table_row_separator_regexp
196
+ case @book.config['table_row_separator']
197
+ when 'tabs'
198
+ Regexp.new('\t+')
199
+ when 'singletab'
200
+ Regexp.new('\t')
201
+ when 'spaces'
202
+ Regexp.new('\s+')
203
+ when 'verticalbar'
204
+ Regexp.new('\s*\\' + escape('|') + '\s*')
205
+ else
206
+ error "Unknown value for 'table_row_separator', shold be: tabs, singletab, spaces, verticalbar"
207
+ end
208
+ end
209
+
210
+ def parse_table_rows(lines)
157
211
  sepidx = nil
212
+ rows = []
158
213
  lines.each_with_index do |line, idx|
159
- if /\A[\=\-]{12}/ =~ line
160
- # just ignore
161
- # error "too many table separator" if sepidx
214
+ if /\A[\=\-]{12}/ =~ line || /\A[\=\{\-\}]{12}/ =~ line
162
215
  sepidx ||= idx
163
216
  next
164
217
  end
165
- rows.push(line.strip.split(/\t+/).map { |s| s.sub(/\A\./, '') })
218
+ rows.push(line.strip.split(table_row_separator_regexp).map { |s| s.sub(/\A\./, '') })
166
219
  end
167
220
  rows = adjust_n_cols(rows)
221
+ error 'no rows in the table' if rows.empty?
222
+ [sepidx, rows]
223
+ end
168
224
 
169
- begin
170
- if caption.present?
171
- table_header id, caption
172
- end
173
- rescue KeyError
174
- error "no such table: #{id}"
175
- end
176
- return if rows.empty?
177
- table_begin rows.first.size
225
+ def table_rows(sepidx, rows)
178
226
  if sepidx
179
227
  sepidx.times do
180
228
  tr(rows.shift.map { |s| th(s) })
@@ -188,7 +236,6 @@ module ReVIEW
188
236
  tr([th(h)] + cs.map { |s| td(s) })
189
237
  end
190
238
  end
191
- table_end
192
239
  end
193
240
 
194
241
  def adjust_n_cols(rows)
@@ -199,7 +246,7 @@ module ReVIEW
199
246
  end
200
247
  n_maxcols = rows.map(&:size).max
201
248
  rows.each do |cols|
202
- cols.concat [''] * (n_maxcols - cols.size)
249
+ cols.concat([''] * (n_maxcols - cols.size))
203
250
  end
204
251
  rows
205
252
  end
@@ -230,7 +277,7 @@ module ReVIEW
230
277
  end
231
278
 
232
279
  def inline_chapref(id)
233
- compile_inline @book.chapter_index.display_string(id)
280
+ compile_inline(@book.chapter_index.display_string(id))
234
281
  rescue KeyError
235
282
  error "unknown chapter: #{id}"
236
283
  end
@@ -242,7 +289,7 @@ module ReVIEW
242
289
  end
243
290
 
244
291
  def inline_title(id)
245
- compile_inline @book.chapter_index.title(id)
292
+ compile_inline(@book.chapter_index.title(id))
246
293
  rescue KeyError
247
294
  error "unknown chapter: #{id}"
248
295
  end
@@ -341,10 +388,10 @@ module ReVIEW
341
388
  end
342
389
 
343
390
  def bibpaper(lines, id, caption)
344
- bibpaper_header id, caption
391
+ bibpaper_header(id, caption)
345
392
  unless lines.empty?
346
393
  puts
347
- bibpaper_bibpaper id, caption, lines
394
+ bibpaper_bibpaper(id, caption, lines)
348
395
  end
349
396
  puts
350
397
  end
@@ -404,7 +451,12 @@ module ReVIEW
404
451
  end
405
452
 
406
453
  def inline_wb(s)
407
- inline_b(unescape(inline_w(s)))
454
+ translated = @dictionary[s]
455
+ if translated
456
+ inline_b(translated)
457
+ else
458
+ inline_b("[missing word: #{s}]")
459
+ end
408
460
  end
409
461
 
410
462
  def raw(str)
@@ -423,9 +475,9 @@ module ReVIEW
423
475
  if arg
424
476
  builders = arg.gsub(/^\s*\|/, '').gsub(/\|\s*$/, '').gsub(/\s/, '').split(',')
425
477
  c = target_name
426
- print lines.join if builders.include?(c)
478
+ print lines.join("\n") + "\n" if builders.include?(c)
427
479
  else
428
- print lines.join
480
+ print lines.join("\n") + "\n"
429
481
  end
430
482
  end
431
483
 
@@ -478,7 +530,9 @@ module ReVIEW
478
530
  def extract_chapter_id(chap_ref)
479
531
  m = /\A([\w+-]+)\|(.+)/.match(chap_ref)
480
532
  if m
481
- return [@book.contents.detect { |chap| chap.id == m[1] }, m[2]]
533
+ ch = @book.contents.detect { |chap| chap.id == m[1] }
534
+ raise KeyError unless ch
535
+ return [ch, m[2]]
482
536
  end
483
537
  [@chapter, chap_ref]
484
538
  end
@@ -502,13 +556,13 @@ module ReVIEW
502
556
  file = "#{id}.#{image_ext}"
503
557
  file_path = File.join(dir, file)
504
558
 
505
- line = self.unescape(lines.join("\n"))
559
+ content = lines.join("\n") + "\n"
506
560
 
507
561
  tf = Tempfile.new('review_graph')
508
- tf.puts line
562
+ tf.puts content
509
563
  tf.close
510
564
  begin
511
- file_path = send("graph_#{command}".to_sym, id, file_path, line, tf.path)
565
+ file_path = send("graph_#{command}".to_sym, id, file_path, content, tf.path)
512
566
  ensure
513
567
  tf.unlink
514
568
  end
@@ -556,7 +610,7 @@ EOTGNUPLOT
556
610
  file_path.sub!(/\.pdf\Z/, '.eps')
557
611
  end
558
612
  system_graph(id, 'java', '-jar', 'plantuml.jar', "-t#{ext}", '-charset', 'UTF-8', tf_path)
559
- FileUtils.mv "#{tf_path}.#{ext}", file_path
613
+ FileUtils.mv("#{tf_path}.#{ext}", file_path)
560
614
  file_path
561
615
  end
562
616
 
@@ -565,7 +619,7 @@ EOTGNUPLOT
565
619
  end
566
620
 
567
621
  def inline_include(file_name)
568
- compile_inline File.read(file_name, mode: 'rt:BOM|utf-8').chomp
622
+ compile_inline(File.read(file_name, mode: 'rt:BOM|utf-8').chomp)
569
623
  end
570
624
 
571
625
  def ul_item_begin(lines)
@@ -614,6 +668,10 @@ EOTGNUPLOT
614
668
  end
615
669
  end
616
670
 
671
+ def over_secnolevel?(n)
672
+ @book.config['secnolevel'] >= n.to_s.split('.').size
673
+ end
674
+
617
675
  ## override TextUtils::detab
618
676
  def detab(str, num = nil)
619
677
  if num
@@ -629,8 +687,11 @@ EOTGNUPLOT
629
687
  str
630
688
  end
631
689
 
632
- def unescape(str)
633
- str
690
+ def caption_top?(type)
691
+ unless %w[top bottom].include?(@book.config['caption_position'][type])
692
+ warn("invalid caption_position/#{type} parameter. 'top' is assumed")
693
+ end
694
+ @book.config['caption_position'][type] != 'bottom'
634
695
  end
635
696
  end
636
697
  end # module ReVIEW