review 3.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|