review 3.2.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +26 -4
- data/.travis.yml +1 -1
- data/NEWS.ja.md +97 -1
- data/NEWS.md +97 -1
- data/bin/review-catalog-converter +1 -1
- data/bin/review-check +5 -5
- data/bin/review-checkdep +1 -1
- data/bin/review-compile +5 -5
- data/bin/review-idgxmlmaker +16 -0
- data/bin/review-index +7 -7
- data/bin/review-preproc +9 -9
- data/bin/review-validate +2 -2
- data/bin/review-vol +5 -5
- data/doc/config.yml.sample +14 -6
- data/doc/config.yml.sample-simple +1 -1
- data/doc/format.ja.md +15 -5
- data/doc/format.md +30 -18
- data/doc/pdfmaker.ja.md +1 -1
- data/doc/pdfmaker.md +1 -1
- data/lib/review/book.rb +1 -1
- data/lib/review/book/base.rb +23 -63
- data/lib/review/book/chapter.rb +18 -3
- data/lib/review/book/compilable.rb +5 -0
- data/lib/review/book/index.rb +26 -65
- data/lib/review/book/index/item.rb +40 -0
- data/lib/review/book/part.rb +22 -2
- data/lib/review/builder.rb +60 -40
- data/lib/review/catalog.rb +12 -15
- data/lib/review/compiler.rb +68 -36
- data/lib/review/configure.rb +10 -7
- data/lib/review/epubmaker.rb +5 -2
- data/lib/review/htmlbuilder.rb +24 -71
- data/lib/review/htmlutils.rb +2 -3
- data/lib/review/i18n.rb +2 -2
- data/lib/review/idgxmlbuilder.rb +101 -55
- data/lib/review/idgxmlmaker.rb +184 -0
- data/lib/review/init-web/finish.html +10 -0
- data/lib/review/init-web/index.html +190 -0
- data/lib/review/init-web/review-layout-design.js +691 -0
- data/lib/review/init.rb +110 -26
- data/lib/review/latexbuilder.rb +76 -54
- data/lib/review/lineinput.rb +1 -1
- data/lib/review/logger.rb +4 -8
- data/lib/review/makerhelper.rb +6 -4
- data/lib/review/markdownbuilder.rb +25 -38
- data/lib/review/md2inaobuilder.rb +3 -5
- data/lib/review/pdfmaker.rb +15 -15
- data/lib/review/plaintextbuilder.rb +67 -76
- data/lib/review/preprocessor.rb +13 -13
- data/lib/review/rstbuilder.rb +31 -31
- data/lib/review/textmaker.rb +13 -3
- data/lib/review/textutils.rb +77 -2
- data/lib/review/tocparser.rb +17 -17
- data/lib/review/tocprinter.rb +8 -8
- data/lib/review/topbuilder.rb +76 -57
- data/lib/review/update.rb +16 -16
- data/lib/review/version.rb +1 -1
- data/lib/review/webmaker.rb +2 -2
- data/lib/review/yamlloader.rb +3 -0
- data/review.gemspec +4 -3
- data/samples/sample-book/README.md +7 -2
- data/samples/sample-book/src/.gitignore +153 -0
- data/samples/sample-book/src/config-jlreq.yml +6 -0
- data/samples/sample-book/src/lib/tasks/review.rake +20 -9
- data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +14 -8
- data/samples/syntax-book/ch03.re +3 -6
- data/samples/syntax-book/config-jlreq.yml +5 -0
- data/samples/syntax-book/lib/tasks/review.rake +7 -7
- data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +14 -8
- data/templates/latex/config.erb +6 -0
- data/templates/latex/layout.tex.erb +1 -0
- data/templates/latex/review-jlreq/review-base.sty +93 -31
- data/templates/latex/review-jlreq/review-jlreq.cls +6 -0
- data/templates/latex/review-jlreq/review-style.sty +3 -0
- data/templates/latex/review-jsbook/README.md +39 -0
- data/templates/latex/review-jsbook/review-base.sty +65 -10
- data/templates/latex/review-jsbook/review-jsbook.cls +4 -0
- data/templates/latex/review-jsbook/review-style.sty +4 -1
- data/test/assets/test_template.tex +11 -3
- data/test/assets/test_template_backmatter.tex +11 -3
- data/test/test_book.rb +65 -19
- data/test/test_catalog.rb +18 -42
- data/test/test_catalog_converter_cmd.rb +1 -1
- data/test/test_epubmaker_cmd.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/test/test_htmlbuilder.rb +144 -55
- data/test/test_i18n.rb +25 -25
- data/test/test_idgxmlbuilder.rb +60 -18
- data/test/test_image_finder.rb +6 -6
- data/test/test_latexbuilder.rb +128 -24
- data/test/test_latexbuilder_v2.rb +23 -23
- data/test/test_logger.rb +14 -1
- data/test/test_makerhelper.rb +3 -3
- data/test/test_markdownbuilder.rb +45 -4
- data/test/test_md2inaobuilder.rb +12 -2
- data/test/test_pdfmaker.rb +1 -1
- data/test/test_pdfmaker_cmd.rb +1 -1
- data/test/test_plaintextbuilder.rb +31 -6
- data/test/test_rstbuilder.rb +33 -4
- data/test/test_textutils.rb +109 -2
- data/test/test_topbuilder.rb +35 -7
- data/test/test_update.rb +17 -8
- data/test/test_yamlloader.rb +13 -0
- metadata +26 -2
data/lib/review/book/chapter.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2009-
|
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: '
|
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.
|
143
|
+
contents.map(&:strip).include?("#{id}#{@book.ext}")
|
129
144
|
end
|
130
145
|
|
131
146
|
# backward compatibility
|
data/lib/review/book/index.rb
CHANGED
@@ -12,6 +12,7 @@ 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
|
@@ -21,7 +22,7 @@ module ReVIEW
|
|
21
22
|
seq = 1
|
22
23
|
src.grep(%r{\A//#{item_type}}) do |line|
|
23
24
|
if id = line.slice(/\[(.*?)\]/, 1)
|
24
|
-
items.push
|
25
|
+
items.push(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}"
|
@@ -31,12 +32,6 @@ module ReVIEW
|
|
31
32
|
new(items, *args)
|
32
33
|
end
|
33
34
|
|
34
|
-
Item = Struct.new(:id, :number)
|
35
|
-
|
36
|
-
def self.item_class
|
37
|
-
self::Item
|
38
|
-
end
|
39
|
-
|
40
35
|
include Enumerable
|
41
36
|
|
42
37
|
def item_type
|
@@ -47,11 +42,11 @@ module ReVIEW
|
|
47
42
|
@items = items
|
48
43
|
@index = {}
|
49
44
|
@logger = ReVIEW.logger
|
50
|
-
items.each do |
|
51
|
-
if @index[
|
52
|
-
@logger.warn "warning: duplicate ID: #{
|
45
|
+
items.each do |item|
|
46
|
+
if @index[item.id]
|
47
|
+
@logger.warn "warning: duplicate ID: #{item.id} (#{item})"
|
53
48
|
end
|
54
|
-
@index[
|
49
|
+
@index[item.id] = item
|
55
50
|
end
|
56
51
|
@image_finder = nil
|
57
52
|
end
|
@@ -65,9 +60,9 @@ module ReVIEW
|
|
65
60
|
raise KeyError, "key '#{id}' is ambiguous for #{self.class}"
|
66
61
|
end
|
67
62
|
|
68
|
-
@items.each do |
|
69
|
-
if
|
70
|
-
return
|
63
|
+
@items.each do |item|
|
64
|
+
if item.id.split('|').include?(id)
|
65
|
+
return item
|
71
66
|
end
|
72
67
|
end
|
73
68
|
raise KeyError, "not found key '#{id}' for #{self.class}"
|
@@ -135,8 +130,6 @@ module ReVIEW
|
|
135
130
|
end
|
136
131
|
|
137
132
|
class FootnoteIndex < Index
|
138
|
-
Item = Struct.new(:id, :number, :content)
|
139
|
-
|
140
133
|
def self.parse(src)
|
141
134
|
items = []
|
142
135
|
seq = 1
|
@@ -144,7 +137,7 @@ module ReVIEW
|
|
144
137
|
if m = /\[(.*?)\]\[(.*)\]/.match(line)
|
145
138
|
m1 = m[1].gsub(/\\(\])/) { $1 }
|
146
139
|
m2 = m[2].gsub(/\\(\])/) { $1 }
|
147
|
-
items.push
|
140
|
+
items.push(Item.new(m1, seq, m2))
|
148
141
|
end
|
149
142
|
seq += 1
|
150
143
|
end
|
@@ -161,9 +154,9 @@ module ReVIEW
|
|
161
154
|
elements = line.split(/\[(.*?)\]/)
|
162
155
|
if elements[1].present?
|
163
156
|
if line =~ %r{\A//imgtable}
|
164
|
-
items.push
|
157
|
+
items.push(ReVIEW::Book::Index::Item.new(elements[1], 0, elements[3]))
|
165
158
|
else ## %r<\A//(image|graph)>
|
166
|
-
items.push
|
159
|
+
items.push(ReVIEW::Book::Index::Item.new(elements[1], seq, elements[3]))
|
167
160
|
seq += 1
|
168
161
|
end
|
169
162
|
if elements[1] == ''
|
@@ -178,34 +171,12 @@ module ReVIEW
|
|
178
171
|
'(image|graph|imgtable)'
|
179
172
|
end
|
180
173
|
|
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
174
|
attr_reader :image_finder
|
204
175
|
|
205
176
|
def initialize(items, chapid, basedir, types, builder)
|
206
|
-
super
|
207
|
-
items.each do |
|
208
|
-
|
177
|
+
super(items)
|
178
|
+
items.each do |item|
|
179
|
+
item.index = self
|
209
180
|
end
|
210
181
|
@chapid = chapid
|
211
182
|
@basedir = basedir
|
@@ -223,8 +194,8 @@ module ReVIEW
|
|
223
194
|
def initialize(items, chapid, basedir, types, builder)
|
224
195
|
@items = items
|
225
196
|
@index = {}
|
226
|
-
items.each { |
|
227
|
-
items.each { |
|
197
|
+
items.each { |item| @index[item.id] = item }
|
198
|
+
items.each { |item| item.index = self }
|
228
199
|
@chapid = chapid
|
229
200
|
@basedir = basedir
|
230
201
|
@types = types
|
@@ -237,7 +208,7 @@ module ReVIEW
|
|
237
208
|
seq = 1
|
238
209
|
src.grep(/@<icon>/) do |line|
|
239
210
|
line.gsub(/@<icon>\{(.+?)\}/) do
|
240
|
-
items.push
|
211
|
+
items.push(ReVIEW::Book::Index::Item.new($1, seq))
|
241
212
|
seq += 1
|
242
213
|
end
|
243
214
|
end
|
@@ -246,8 +217,6 @@ module ReVIEW
|
|
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
221
|
items = []
|
253
222
|
seq = 1
|
@@ -255,7 +224,7 @@ module ReVIEW
|
|
255
224
|
if m = /\[(.*?)\]\[(.*)\]/.match(line)
|
256
225
|
m1 = m[1].gsub(/\\(.)/) { $1 }
|
257
226
|
m2 = m[2].gsub(/\\(.)/) { $1 }
|
258
|
-
items.push
|
227
|
+
items.push(Item.new(m1, seq, m2))
|
259
228
|
end
|
260
229
|
seq += 1
|
261
230
|
end
|
@@ -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,7 +254,6 @@ module ReVIEW
|
|
291
254
|
|
292
255
|
class HeadlineIndex < Index
|
293
256
|
HEADLINE_PATTERN = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/
|
294
|
-
Item = Struct.new(:id, :number, :caption)
|
295
257
|
attr_reader :items
|
296
258
|
|
297
259
|
def self.parse(src, chap)
|
@@ -349,11 +311,11 @@ module ReVIEW
|
|
349
311
|
|
350
312
|
if %w[nonum notoc nodisp].include?(m[2])
|
351
313
|
headlines[index] = m[3].present? ? m[3].strip : m[4].strip
|
352
|
-
items.push
|
314
|
+
items.push(Item.new(headlines.join('|'), nil, m[4].strip))
|
353
315
|
else
|
354
316
|
indexs[index] += 1
|
355
317
|
headlines[index] = m[3].present? ? m[3].strip : m[4].strip
|
356
|
-
items.push
|
318
|
+
items.push(Item.new(headlines.join('|'), indexs.dup, m[4].strip))
|
357
319
|
end
|
358
320
|
end
|
359
321
|
new(items, chap)
|
@@ -364,11 +326,11 @@ module ReVIEW
|
|
364
326
|
@chap = chap
|
365
327
|
@index = {}
|
366
328
|
@logger = ReVIEW.logger
|
367
|
-
items.each do |
|
368
|
-
if @index[
|
369
|
-
@logger.warn "warning: duplicate ID: #{
|
329
|
+
items.each do |item|
|
330
|
+
if @index[item.id]
|
331
|
+
@logger.warn "warning: duplicate ID: #{item.id}"
|
370
332
|
end
|
371
|
-
@index[
|
333
|
+
@index[item.id] = item
|
372
334
|
end
|
373
335
|
end
|
374
336
|
|
@@ -388,7 +350,6 @@ module ReVIEW
|
|
388
350
|
|
389
351
|
class ColumnIndex < Index
|
390
352
|
COLUMN_PATTERN = /\A(=+)\[column\](?:\{(.+?)\})?(.*)/
|
391
|
-
Item = Struct.new(:id, :number, :caption)
|
392
353
|
|
393
354
|
def self.parse(src, *_args)
|
394
355
|
items = []
|
@@ -401,7 +362,7 @@ module ReVIEW
|
|
401
362
|
caption = m[3].strip
|
402
363
|
id = caption if id.nil? || id.empty?
|
403
364
|
|
404
|
-
items.push
|
365
|
+
items.push(ReVIEW::Book::Index::Item.new(id, seq, caption))
|
405
366
|
seq += 1
|
406
367
|
end
|
407
368
|
new(items)
|
@@ -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_writer :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
|
data/lib/review/book/part.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2009-
|
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)
|
@@ -25,7 +45,7 @@ module ReVIEW
|
|
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: '
|
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?
|
data/lib/review/builder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2002-
|
1
|
+
# Copyright (c) 2002-2019 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
|
@@ -62,6 +62,15 @@ module ReVIEW
|
|
62
62
|
if @book.config['tabwidth']
|
63
63
|
@tabwidth = @book.config['tabwidth']
|
64
64
|
end
|
65
|
+
|
66
|
+
if @book.config['join_lines_by_lang']
|
67
|
+
begin
|
68
|
+
require 'unicode/eaw'
|
69
|
+
rescue LoadError
|
70
|
+
warn 'not found unicode/eaw. disabled join_lines_by_lang feature.'
|
71
|
+
@book.config['join_lines_by_lang'] = nil
|
72
|
+
end
|
73
|
+
end
|
65
74
|
end
|
66
75
|
builder_init_file
|
67
76
|
end
|
@@ -71,6 +80,10 @@ module ReVIEW
|
|
71
80
|
end
|
72
81
|
private :builder_init_file
|
73
82
|
|
83
|
+
def highlight?
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
74
87
|
def result
|
75
88
|
@output.string
|
76
89
|
end
|
@@ -122,43 +135,55 @@ module ReVIEW
|
|
122
135
|
|
123
136
|
def list(lines, id, caption, lang = nil)
|
124
137
|
begin
|
125
|
-
list_header
|
138
|
+
list_header(id, caption, lang)
|
126
139
|
rescue KeyError
|
127
140
|
error "no such list: #{id}"
|
128
141
|
end
|
129
|
-
list_body
|
142
|
+
list_body(id, lines, lang)
|
130
143
|
end
|
131
144
|
|
132
145
|
def listnum(lines, id, caption, lang = nil)
|
133
146
|
begin
|
134
|
-
list_header
|
147
|
+
list_header(id, caption, lang)
|
135
148
|
rescue KeyError
|
136
149
|
error "no such list: #{id}"
|
137
150
|
end
|
138
|
-
listnum_body
|
151
|
+
listnum_body(lines, lang)
|
139
152
|
end
|
140
153
|
|
141
154
|
def source(lines, caption, lang = nil)
|
142
|
-
source_header
|
143
|
-
source_body
|
155
|
+
source_header(caption)
|
156
|
+
source_body(lines, lang)
|
144
157
|
end
|
145
158
|
|
146
159
|
def image(lines, id, caption, metric = nil)
|
147
|
-
if @chapter.
|
148
|
-
image_image
|
160
|
+
if @chapter.image_bound?(id)
|
161
|
+
image_image(id, caption, metric)
|
149
162
|
else
|
150
163
|
warn "image not bound: #{id}" if @strict
|
151
|
-
image_dummy
|
164
|
+
image_dummy(id, caption, lines)
|
152
165
|
end
|
153
166
|
end
|
154
167
|
|
155
168
|
def table(lines, id = nil, caption = nil)
|
156
|
-
rows =
|
169
|
+
sepidx, rows = parse_table_rows(lines)
|
170
|
+
begin
|
171
|
+
if caption.present?
|
172
|
+
table_header(id, caption)
|
173
|
+
end
|
174
|
+
rescue KeyError
|
175
|
+
error "no such table: #{id}"
|
176
|
+
end
|
177
|
+
table_begin(rows.first.size)
|
178
|
+
table_rows(sepidx, rows)
|
179
|
+
table_end
|
180
|
+
end
|
181
|
+
|
182
|
+
def parse_table_rows(lines)
|
157
183
|
sepidx = nil
|
184
|
+
rows = []
|
158
185
|
lines.each_with_index do |line, idx|
|
159
|
-
if /\A[\=\-]{12}/ =~ line
|
160
|
-
# just ignore
|
161
|
-
# error "too many table separator" if sepidx
|
186
|
+
if /\A[\=\-]{12}/ =~ line || /\A[\=\{\-\}]{12}/ =~ line
|
162
187
|
sepidx ||= idx
|
163
188
|
next
|
164
189
|
end
|
@@ -166,15 +191,10 @@ module ReVIEW
|
|
166
191
|
end
|
167
192
|
rows = adjust_n_cols(rows)
|
168
193
|
error 'no rows in the table' if rows.empty?
|
194
|
+
[sepidx, rows]
|
195
|
+
end
|
169
196
|
|
170
|
-
|
171
|
-
if caption.present?
|
172
|
-
table_header id, caption
|
173
|
-
end
|
174
|
-
rescue KeyError
|
175
|
-
error "no such table: #{id}"
|
176
|
-
end
|
177
|
-
table_begin rows.first.size
|
197
|
+
def table_rows(sepidx, rows)
|
178
198
|
if sepidx
|
179
199
|
sepidx.times do
|
180
200
|
tr(rows.shift.map { |s| th(s) })
|
@@ -188,7 +208,6 @@ module ReVIEW
|
|
188
208
|
tr([th(h)] + cs.map { |s| td(s) })
|
189
209
|
end
|
190
210
|
end
|
191
|
-
table_end
|
192
211
|
end
|
193
212
|
|
194
213
|
def adjust_n_cols(rows)
|
@@ -199,7 +218,7 @@ module ReVIEW
|
|
199
218
|
end
|
200
219
|
n_maxcols = rows.map(&:size).max
|
201
220
|
rows.each do |cols|
|
202
|
-
cols.concat
|
221
|
+
cols.concat([''] * (n_maxcols - cols.size))
|
203
222
|
end
|
204
223
|
rows
|
205
224
|
end
|
@@ -230,7 +249,7 @@ module ReVIEW
|
|
230
249
|
end
|
231
250
|
|
232
251
|
def inline_chapref(id)
|
233
|
-
compile_inline
|
252
|
+
compile_inline(@book.chapter_index.display_string(id))
|
234
253
|
rescue KeyError
|
235
254
|
error "unknown chapter: #{id}"
|
236
255
|
end
|
@@ -242,7 +261,7 @@ module ReVIEW
|
|
242
261
|
end
|
243
262
|
|
244
263
|
def inline_title(id)
|
245
|
-
compile_inline
|
264
|
+
compile_inline(@book.chapter_index.title(id))
|
246
265
|
rescue KeyError
|
247
266
|
error "unknown chapter: #{id}"
|
248
267
|
end
|
@@ -341,10 +360,10 @@ module ReVIEW
|
|
341
360
|
end
|
342
361
|
|
343
362
|
def bibpaper(lines, id, caption)
|
344
|
-
bibpaper_header
|
363
|
+
bibpaper_header(id, caption)
|
345
364
|
unless lines.empty?
|
346
365
|
puts
|
347
|
-
bibpaper_bibpaper
|
366
|
+
bibpaper_bibpaper(id, caption, lines)
|
348
367
|
end
|
349
368
|
puts
|
350
369
|
end
|
@@ -404,7 +423,12 @@ module ReVIEW
|
|
404
423
|
end
|
405
424
|
|
406
425
|
def inline_wb(s)
|
407
|
-
|
426
|
+
translated = @dictionary[s]
|
427
|
+
if translated
|
428
|
+
inline_b(translated)
|
429
|
+
else
|
430
|
+
inline_b("[missing word: #{s}]")
|
431
|
+
end
|
408
432
|
end
|
409
433
|
|
410
434
|
def raw(str)
|
@@ -423,9 +447,9 @@ module ReVIEW
|
|
423
447
|
if arg
|
424
448
|
builders = arg.gsub(/^\s*\|/, '').gsub(/\|\s*$/, '').gsub(/\s/, '').split(',')
|
425
449
|
c = target_name
|
426
|
-
print lines.join if builders.include?(c)
|
450
|
+
print lines.join("\n") + "\n" if builders.include?(c)
|
427
451
|
else
|
428
|
-
print lines.join
|
452
|
+
print lines.join("\n") + "\n"
|
429
453
|
end
|
430
454
|
end
|
431
455
|
|
@@ -504,13 +528,13 @@ module ReVIEW
|
|
504
528
|
file = "#{id}.#{image_ext}"
|
505
529
|
file_path = File.join(dir, file)
|
506
530
|
|
507
|
-
|
531
|
+
content = lines.join("\n") + "\n"
|
508
532
|
|
509
533
|
tf = Tempfile.new('review_graph')
|
510
|
-
tf.puts
|
534
|
+
tf.puts content
|
511
535
|
tf.close
|
512
536
|
begin
|
513
|
-
file_path = send("graph_#{command}".to_sym, id, file_path,
|
537
|
+
file_path = send("graph_#{command}".to_sym, id, file_path, content, tf.path)
|
514
538
|
ensure
|
515
539
|
tf.unlink
|
516
540
|
end
|
@@ -558,7 +582,7 @@ EOTGNUPLOT
|
|
558
582
|
file_path.sub!(/\.pdf\Z/, '.eps')
|
559
583
|
end
|
560
584
|
system_graph(id, 'java', '-jar', 'plantuml.jar', "-t#{ext}", '-charset', 'UTF-8', tf_path)
|
561
|
-
FileUtils.mv
|
585
|
+
FileUtils.mv("#{tf_path}.#{ext}", file_path)
|
562
586
|
file_path
|
563
587
|
end
|
564
588
|
|
@@ -567,7 +591,7 @@ EOTGNUPLOT
|
|
567
591
|
end
|
568
592
|
|
569
593
|
def inline_include(file_name)
|
570
|
-
compile_inline
|
594
|
+
compile_inline(File.read(file_name, mode: 'rt:BOM|utf-8').chomp)
|
571
595
|
end
|
572
596
|
|
573
597
|
def ul_item_begin(lines)
|
@@ -634,9 +658,5 @@ EOTGNUPLOT
|
|
634
658
|
def escape(str)
|
635
659
|
str
|
636
660
|
end
|
637
|
-
|
638
|
-
def unescape(str)
|
639
|
-
str
|
640
|
-
end
|
641
661
|
end
|
642
662
|
end # module ReVIEW
|