review 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby-win.yml +39 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.rubocop.yml +10 -7
- data/Dockerfile +21 -5
- data/NEWS.ja.md +101 -1
- data/NEWS.md +102 -2
- data/README.md +10 -7
- data/appveyor.yml +0 -20
- data/bin/review-compile +1 -1
- data/bin/review-validate +1 -1
- data/doc/config.yml.sample +12 -1
- data/doc/config.yml.sample-simple +1 -0
- data/doc/format.ja.md +16 -4
- data/doc/format.md +2 -1
- data/doc/quickstart.ja.md +40 -23
- data/doc/quickstart.md +33 -15
- data/lib/review/book/base.rb +8 -7
- data/lib/review/book/index.rb +50 -56
- data/lib/review/book/index/item.rb +1 -1
- data/lib/review/builder.rb +26 -4
- data/lib/review/compiler.rb +6 -3
- data/lib/review/configure.rb +5 -3
- data/lib/review/epubmaker.rb +15 -2
- data/lib/review/extentions/string.rb +0 -4
- data/lib/review/htmlbuilder.rb +4 -15
- data/lib/review/idgxmlbuilder.rb +10 -19
- data/lib/review/idgxmlmaker.rb +10 -3
- data/lib/review/init.rb +8 -1
- data/lib/review/latexbuilder.rb +13 -6
- data/lib/review/pdfmaker.rb +24 -9
- data/lib/review/rstbuilder.rb +2 -2
- data/lib/review/textmaker.rb +7 -1
- data/lib/review/tocparser.rb +6 -2
- data/lib/review/version.rb +1 -1
- data/lib/review/webmaker.rb +8 -1
- data/review.gemspec +2 -2
- data/samples/sample-book/src/.gitignore +1 -0
- data/samples/sample-book/src/config-ebook.yml +4 -0
- data/samples/sample-book/src/config-jlreq-ebook.yml +4 -0
- data/samples/sample-book/src/config.yml +1 -1
- data/samples/sample-book/src/lib/tasks/review.rake +10 -6
- data/samples/syntax-book/ch01.re +4 -2
- data/samples/syntax-book/ch02.re +8 -16
- data/samples/syntax-book/config-jlreq-lualatex.yml +4 -0
- data/samples/syntax-book/config-print.yml +3 -0
- data/samples/syntax-book/config.yml +1 -1
- data/samples/syntax-book/lib/tasks/review.rake +23 -8
- data/templates/latex/config.erb +6 -6
- data/templates/latex/review-jlreq/review-base.sty +14 -4
- data/templates/latex/review-jlreq/review-jlreq.cls +10 -1
- data/templates/latex/review-jlreq/review-style.sty +1 -1
- data/templates/latex/review-jsbook/review-base.sty +10 -0
- data/templates/latex/review-jsbook/review-jsbook.cls +1 -1
- data/templates/latex/review-jsbook/review-style.sty +1 -1
- data/test/assets/test_template.tex +6 -6
- data/test/assets/test_template_backmatter.tex +6 -6
- data/test/test_book.rb +8 -0
- data/test/test_book_chapter.rb +4 -2
- data/test/test_catalog.rb +1 -0
- data/test/test_epubmaker_cmd.rb +12 -5
- data/test/test_helper.rb +11 -6
- data/test/test_htmlbuilder.rb +80 -8
- data/test/test_idgxmlbuilder.rb +57 -2
- data/test/test_idgxmlmaker_cmd.rb +46 -0
- data/test/test_image_finder.rb +52 -70
- data/test/test_index.rb +12 -12
- data/test/test_latexbuilder.rb +171 -8
- data/test/test_latexbuilder_v2.rb +9 -7
- data/test/test_pdfmaker_cmd.rb +99 -5
- data/test/test_textmaker_cmd.rb +54 -0
- data/test/test_topbuilder.rb +59 -0
- data/vendor/jsclasses/LICENSE +1 -1
- data/vendor/jsclasses/jis/jsarticle.cls +53 -14
- data/vendor/jsclasses/jis/jsbook.cls +53 -14
- data/vendor/jsclasses/jis/jsclasses.dtx +84 -25
- data/vendor/jsclasses/jis/jslogo.dtx +4 -4
- data/vendor/jsclasses/jis/jslogo.sty +3 -3
- data/vendor/jsclasses/jis/jspf.cls +52 -13
- data/vendor/jsclasses/jis/jsreport.cls +53 -14
- data/vendor/jsclasses/jis/kiyou.cls +53 -14
- data/vendor/jsclasses/jis/okumacro.dtx +4 -5
- data/vendor/jsclasses/jis/okumacro.sty +3 -4
- data/vendor/jsclasses/jsarticle.cls +53 -14
- data/vendor/jsclasses/jsbook.cls +53 -14
- data/vendor/jsclasses/jsclasses.dtx +84 -25
- data/vendor/jsclasses/jsclasses.pdf +0 -0
- data/vendor/jsclasses/jslogo.dtx +4 -4
- data/vendor/jsclasses/jslogo.pdf +0 -0
- data/vendor/jsclasses/jslogo.sty +3 -3
- data/vendor/jsclasses/jspf.cls +52 -13
- data/vendor/jsclasses/jsreport.cls +53 -14
- data/vendor/jsclasses/kiyou.cls +53 -14
- data/vendor/jsclasses/okumacro.dtx +4 -5
- data/vendor/jsclasses/okumacro.pdf +0 -0
- data/vendor/jsclasses/okumacro.sty +3 -4
- metadata +15 -6
- data/samples/syntax-book/review-ext.rb +0 -14
data/lib/review/book/index.rb
CHANGED
@@ -18,18 +18,18 @@ module ReVIEW
|
|
18
18
|
module Book
|
19
19
|
class Index
|
20
20
|
def self.parse(src, *args)
|
21
|
-
|
21
|
+
index = self.new(*args)
|
22
22
|
seq = 1
|
23
23
|
src.grep(%r{\A//#{item_type}}) do |line|
|
24
24
|
if id = line.slice(/\[(.*?)\]/, 1)
|
25
|
-
|
25
|
+
index.add_item(ReVIEW::Book::Index::Item.new(id, seq))
|
26
26
|
seq += 1
|
27
27
|
if id.empty?
|
28
28
|
ReVIEW.logger.warn "warning: no ID of #{item_type} in #{line}"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
32
|
+
index
|
33
33
|
end
|
34
34
|
|
35
35
|
include Enumerable
|
@@ -38,19 +38,22 @@ module ReVIEW
|
|
38
38
|
self.class.item_type
|
39
39
|
end
|
40
40
|
|
41
|
-
def initialize
|
42
|
-
@items = items
|
41
|
+
def initialize
|
43
42
|
@index = {}
|
44
43
|
@logger = ReVIEW.logger
|
45
|
-
items.each do |item|
|
46
|
-
if @index[item.id]
|
47
|
-
@logger.warn "warning: duplicate ID: #{item.id} (#{item})"
|
48
|
-
end
|
49
|
-
@index[item.id] = item
|
50
|
-
end
|
51
44
|
@image_finder = nil
|
52
45
|
end
|
53
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
|
+
|
54
57
|
def [](id)
|
55
58
|
@index.fetch(id)
|
56
59
|
rescue
|
@@ -60,7 +63,7 @@ module ReVIEW
|
|
60
63
|
raise KeyError, "key '#{id}' is ambiguous for #{self.class}"
|
61
64
|
end
|
62
65
|
|
63
|
-
@
|
66
|
+
@index.values.each do |item|
|
64
67
|
if item.id.split('|').include?(id)
|
65
68
|
return item
|
66
69
|
end
|
@@ -73,7 +76,7 @@ module ReVIEW
|
|
73
76
|
end
|
74
77
|
|
75
78
|
def each(&block)
|
76
|
-
@
|
79
|
+
@index.values.each(&block)
|
77
80
|
end
|
78
81
|
|
79
82
|
def key?(id)
|
@@ -88,8 +91,9 @@ module ReVIEW
|
|
88
91
|
end
|
89
92
|
|
90
93
|
def number(id)
|
91
|
-
|
94
|
+
chapter_item = @index.fetch(id)
|
92
95
|
begin
|
96
|
+
chapter = chapter_item.content
|
93
97
|
chapter.format_number
|
94
98
|
rescue # part
|
95
99
|
I18n.t('part', chapter.number)
|
@@ -97,9 +101,9 @@ module ReVIEW
|
|
97
101
|
end
|
98
102
|
|
99
103
|
def title(id)
|
100
|
-
@index.fetch(id).title
|
104
|
+
@index.fetch(id).content.title
|
101
105
|
rescue # non-file part
|
102
|
-
@index.fetch(id).name
|
106
|
+
@index.fetch(id).content.name
|
103
107
|
end
|
104
108
|
|
105
109
|
def display_string(id)
|
@@ -131,32 +135,32 @@ module ReVIEW
|
|
131
135
|
|
132
136
|
class FootnoteIndex < Index
|
133
137
|
def self.parse(src)
|
134
|
-
|
138
|
+
index = self.new
|
135
139
|
seq = 1
|
136
140
|
src.grep(%r{\A//footnote}) do |line|
|
137
141
|
if m = /\[(.*?)\]\[(.*)\]/.match(line)
|
138
142
|
m1 = m[1].gsub(/\\(\])/) { $1 }
|
139
143
|
m2 = m[2].gsub(/\\(\])/) { $1 }
|
140
|
-
|
144
|
+
index.add_item(Item.new(m1, seq, m2))
|
141
145
|
end
|
142
146
|
seq += 1
|
143
147
|
end
|
144
|
-
|
148
|
+
index
|
145
149
|
end
|
146
150
|
end
|
147
151
|
|
148
152
|
class ImageIndex < Index
|
149
153
|
def self.parse(src, *args)
|
150
|
-
|
154
|
+
index = self.new(*args)
|
151
155
|
seq = 1
|
152
156
|
src.grep(%r{\A//#{item_type}}) do |line|
|
153
157
|
# ex. ["//image", "id", "", "caption"]
|
154
158
|
elements = line.split(/\[(.*?)\]/)
|
155
159
|
if elements[1].present?
|
156
|
-
if line
|
157
|
-
|
160
|
+
if line.start_with?('//imgtable')
|
161
|
+
index.add_item(ReVIEW::Book::Index::Item.new(elements[1], 0, elements[3]))
|
158
162
|
else ## %r<\A//(image|graph)>
|
159
|
-
|
163
|
+
index.add_item(ReVIEW::Book::Index::Item.new(elements[1], seq, elements[3]))
|
160
164
|
seq += 1
|
161
165
|
end
|
162
166
|
if elements[1] == ''
|
@@ -164,7 +168,7 @@ module ReVIEW
|
|
164
168
|
end
|
165
169
|
end
|
166
170
|
end
|
167
|
-
|
171
|
+
index
|
168
172
|
end
|
169
173
|
|
170
174
|
def self.item_type
|
@@ -173,14 +177,12 @@ module ReVIEW
|
|
173
177
|
|
174
178
|
attr_reader :image_finder
|
175
179
|
|
176
|
-
def initialize(
|
177
|
-
super(
|
178
|
-
items.each do |item|
|
179
|
-
item.index = self
|
180
|
-
end
|
180
|
+
def initialize(chapid, basedir, types, builder)
|
181
|
+
super()
|
181
182
|
@chapid = chapid
|
182
183
|
@basedir = basedir
|
183
184
|
@types = types
|
185
|
+
@logger = ReVIEW.logger
|
184
186
|
|
185
187
|
@image_finder = ReVIEW::Book::ImageFinder.new(basedir, chapid, builder, types)
|
186
188
|
end
|
@@ -191,44 +193,42 @@ module ReVIEW
|
|
191
193
|
end
|
192
194
|
|
193
195
|
class IconIndex < ImageIndex
|
194
|
-
def initialize(
|
195
|
-
@items = items
|
196
|
+
def initialize(chapid, basedir, types, builder)
|
196
197
|
@index = {}
|
197
|
-
items.each { |item| @index[item.id] = item }
|
198
|
-
items.each { |item| item.index = self }
|
199
198
|
@chapid = chapid
|
200
199
|
@basedir = basedir
|
201
200
|
@types = types
|
201
|
+
@logger = ReVIEW.logger
|
202
202
|
|
203
203
|
@image_finder = ImageFinder.new(basedir, chapid, builder, types)
|
204
204
|
end
|
205
205
|
|
206
206
|
def self.parse(src, *args)
|
207
|
-
|
207
|
+
index = self.new(*args)
|
208
208
|
seq = 1
|
209
209
|
src.grep(/@<icon>/) do |line|
|
210
210
|
line.gsub(/@<icon>\{(.+?)\}/) do
|
211
|
-
|
211
|
+
index.add_item(ReVIEW::Book::Index::Item.new($1, seq))
|
212
212
|
seq += 1
|
213
213
|
end
|
214
214
|
end
|
215
|
-
|
215
|
+
index
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
219
|
class BibpaperIndex < Index
|
220
220
|
def self.parse(src)
|
221
|
-
|
221
|
+
index = self.new
|
222
222
|
seq = 1
|
223
223
|
src.grep(%r{\A//bibpaper}) do |line|
|
224
224
|
if m = /\[(.*?)\]\[(.*)\]/.match(line)
|
225
225
|
m1 = m[1].gsub(/\\(.)/) { $1 }
|
226
226
|
m2 = m[2].gsub(/\\(.)/) { $1 }
|
227
|
-
|
227
|
+
index.add_item(Item.new(m1, seq, m2))
|
228
228
|
end
|
229
229
|
seq += 1
|
230
230
|
end
|
231
|
-
|
231
|
+
index
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
@@ -254,10 +254,9 @@ module ReVIEW
|
|
254
254
|
|
255
255
|
class HeadlineIndex < Index
|
256
256
|
HEADLINE_PATTERN = /\A(=+)(?:\[(.+?)\])?(?:\{(.+?)\})?(.*)/
|
257
|
-
attr_reader :items
|
258
257
|
|
259
258
|
def self.parse(src, chap)
|
260
|
-
|
259
|
+
headline_index = self.new(chap)
|
261
260
|
indexs = []
|
262
261
|
headlines = []
|
263
262
|
inside_column = false
|
@@ -267,7 +266,7 @@ module ReVIEW
|
|
267
266
|
if line =~ %r{\A//[a-z]+.*\{\Z}
|
268
267
|
inside_block = true
|
269
268
|
next
|
270
|
-
elsif line
|
269
|
+
elsif line.start_with?('//}')
|
271
270
|
inside_block = nil
|
272
271
|
next
|
273
272
|
elsif inside_block
|
@@ -311,27 +310,22 @@ module ReVIEW
|
|
311
310
|
|
312
311
|
if %w[nonum notoc nodisp].include?(m[2])
|
313
312
|
headlines[index] = m[3].present? ? m[3].strip : m[4].strip
|
314
|
-
|
313
|
+
item_id = headlines.join('|')
|
314
|
+
headline_index.add_item(Item.new(item_id, nil, m[4].strip))
|
315
315
|
else
|
316
316
|
indexs[index] += 1
|
317
317
|
headlines[index] = m[3].present? ? m[3].strip : m[4].strip
|
318
|
-
|
318
|
+
item_id = headlines.join('|')
|
319
|
+
headline_index.add_item(Item.new(item_id, indexs.dup, m[4].strip))
|
319
320
|
end
|
320
321
|
end
|
321
|
-
|
322
|
+
headline_index
|
322
323
|
end
|
323
324
|
|
324
|
-
def initialize(
|
325
|
-
@items = items
|
325
|
+
def initialize(chap)
|
326
326
|
@chap = chap
|
327
327
|
@index = {}
|
328
328
|
@logger = ReVIEW.logger
|
329
|
-
items.each do |item|
|
330
|
-
if @index[item.id]
|
331
|
-
@logger.warn "warning: duplicate ID: #{item.id}"
|
332
|
-
end
|
333
|
-
@index[item.id] = item
|
334
|
-
end
|
335
329
|
end
|
336
330
|
|
337
331
|
def number(id)
|
@@ -352,7 +346,7 @@ module ReVIEW
|
|
352
346
|
COLUMN_PATTERN = /\A(=+)\[column\](?:\{(.+?)\})?(.*)/
|
353
347
|
|
354
348
|
def self.parse(src, *_args)
|
355
|
-
|
349
|
+
index = self.new
|
356
350
|
seq = 1
|
357
351
|
src.each do |line|
|
358
352
|
m = COLUMN_PATTERN.match(line)
|
@@ -362,10 +356,10 @@ module ReVIEW
|
|
362
356
|
caption = m[3].strip
|
363
357
|
id = caption if id.nil? || id.empty?
|
364
358
|
|
365
|
-
|
359
|
+
index.add_item(ReVIEW::Book::Index::Item.new(id, seq, caption))
|
366
360
|
seq += 1
|
367
361
|
end
|
368
|
-
|
362
|
+
index
|
369
363
|
end
|
370
364
|
end
|
371
365
|
end
|
data/lib/review/builder.rb
CHANGED
@@ -56,8 +56,15 @@ module ReVIEW
|
|
56
56
|
@tabwidth = nil
|
57
57
|
@tsize = nil
|
58
58
|
if @book && @book.config
|
59
|
-
if @book.config['words_file']
|
60
|
-
|
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']
|
@@ -151,7 +158,7 @@ module ReVIEW
|
|
151
158
|
listnum_body(lines, lang)
|
152
159
|
end
|
153
160
|
|
154
|
-
def source(lines, caption, lang = nil)
|
161
|
+
def source(lines, caption = nil, lang = nil)
|
155
162
|
source_header(caption)
|
156
163
|
source_body(lines, lang)
|
157
164
|
end
|
@@ -179,6 +186,21 @@ module ReVIEW
|
|
179
186
|
table_end
|
180
187
|
end
|
181
188
|
|
189
|
+
def table_row_separator_regexp
|
190
|
+
case @book.config['table_row_separator']
|
191
|
+
when 'tabs'
|
192
|
+
Regexp.new('\t+')
|
193
|
+
when 'singletab'
|
194
|
+
Regexp.new('\t')
|
195
|
+
when 'spaces'
|
196
|
+
Regexp.new('\s+')
|
197
|
+
when 'verticalbar'
|
198
|
+
Regexp.new('\s*\\' + escape('|') + '\s*')
|
199
|
+
else
|
200
|
+
error "Unknown value for 'table_row_separator', shold be: tabs, singletab, spaces, verticalbar"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
182
204
|
def parse_table_rows(lines)
|
183
205
|
sepidx = nil
|
184
206
|
rows = []
|
@@ -187,7 +209,7 @@ module ReVIEW
|
|
187
209
|
sepidx ||= idx
|
188
210
|
next
|
189
211
|
end
|
190
|
-
rows.push(line.strip.split(
|
212
|
+
rows.push(line.strip.split(table_row_separator_regexp).map { |s| s.sub(/\A\./, '') })
|
191
213
|
end
|
192
214
|
rows = adjust_n_cols(rows)
|
193
215
|
error 'no rows in the table' if rows.empty?
|
data/lib/review/compiler.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2009-
|
1
|
+
# Copyright (c) 2009-2020 Minero Aoki, Kenshi Muto
|
2
2
|
# Copyright (c) 2002-2007 Minero Aoki
|
3
3
|
#
|
4
4
|
# This program is free software.
|
@@ -115,7 +115,7 @@ module ReVIEW
|
|
115
115
|
defblock :emlist, 0..2
|
116
116
|
defblock :cmd, 0..1
|
117
117
|
defblock :table, 0..2
|
118
|
-
defblock :imgtable, 0..
|
118
|
+
defblock :imgtable, 0..3
|
119
119
|
defblock :emtable, 0..1
|
120
120
|
defblock :quote, 0
|
121
121
|
defblock :image, 2..3, true
|
@@ -422,7 +422,10 @@ module ReVIEW
|
|
422
422
|
def compile_dlist(f)
|
423
423
|
@strategy.dl_begin
|
424
424
|
while /\A\s*:/ =~ f.peek
|
425
|
+
# defer compile_inline to handle footnotes
|
426
|
+
@strategy.doc_status[:dt] = true
|
425
427
|
@strategy.dt(text(f.gets.sub(/\A\s*:/, '').strip))
|
428
|
+
@strategy.doc_status[:dt] = nil
|
426
429
|
desc = f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) }
|
427
430
|
@strategy.dd(desc)
|
428
431
|
f.skip_blank_lines
|
@@ -466,7 +469,7 @@ module ReVIEW
|
|
466
469
|
buf.push(text(line.rstrip, true))
|
467
470
|
end
|
468
471
|
end
|
469
|
-
unless
|
472
|
+
unless f.peek.to_s.start_with?('//}')
|
470
473
|
error "unexpected EOF (block begins at: #{head})"
|
471
474
|
return buf
|
472
475
|
end
|
data/lib/review/configure.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2012-
|
2
|
+
# Copyright (c) 2012-2020 Masanori Kado, Masayoshi Takahashi, Kenshi Muto
|
3
3
|
#
|
4
4
|
# This program is free software.
|
5
5
|
# You can distribute or modify this program under the terms of
|
@@ -66,6 +66,7 @@ module ReVIEW
|
|
66
66
|
'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt],
|
67
67
|
'externallink' => true,
|
68
68
|
'join_lines_by_lang' => nil, # experimental. default should be nil
|
69
|
+
'table_row_separator' => 'tabs',
|
69
70
|
# for IDGXML
|
70
71
|
'tableopt' => nil,
|
71
72
|
'listinfo' => nil,
|
@@ -74,7 +75,6 @@ module ReVIEW
|
|
74
75
|
'structuredxml' => nil,
|
75
76
|
'pt_to_mm_unit' => 0.3528, # DTP: 1pt = 0.3528mm, JIS: 1pt = 0.3514mm
|
76
77
|
# for LaTeX
|
77
|
-
'image_scale2width' => true,
|
78
78
|
'footnotetext' => nil,
|
79
79
|
'texcommand' => 'uplatex',
|
80
80
|
'texoptions' => '-interaction=nonstopmode -file-line-error -halt-on-error',
|
@@ -84,6 +84,7 @@ module ReVIEW
|
|
84
84
|
'dvioptions' => '-d 5 -z 9',
|
85
85
|
# for PDFMaker
|
86
86
|
'pdfmaker' => {
|
87
|
+
'image_scale2width' => true,
|
87
88
|
'makeindex' => nil, # Make index page
|
88
89
|
'makeindex_command' => 'mendex', # works only when makeindex is true
|
89
90
|
'makeindex_options' => '-f -r -I utf8',
|
@@ -91,7 +92,8 @@ module ReVIEW
|
|
91
92
|
'makeindex_dic' => nil,
|
92
93
|
'makeindex_mecab' => true,
|
93
94
|
'makeindex_mecab_opts' => '-Oyomi',
|
94
|
-
'use_cover_nombre' => true
|
95
|
+
'use_cover_nombre' => true,
|
96
|
+
'use_original_image_size' => nil
|
95
97
|
},
|
96
98
|
'imgmath_options' => {
|
97
99
|
'format' => 'png',
|
data/lib/review/epubmaker.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2010-
|
1
|
+
# Copyright (c) 2010-2020 Kenshi Muto and Masayoshi Takahashi
|
2
2
|
#
|
3
3
|
# This program is free software.
|
4
4
|
# You can distribute or modify this program under the terms of
|
@@ -73,6 +73,7 @@ module ReVIEW
|
|
73
73
|
def parse_opts(args)
|
74
74
|
cmd_config = {}
|
75
75
|
opts = OptionParser.new
|
76
|
+
@buildonly = nil
|
76
77
|
|
77
78
|
opts.banner = 'Usage: review-epubmaker [options] configfile [export_filename]'
|
78
79
|
opts.version = ReVIEW::VERSION
|
@@ -81,6 +82,7 @@ module ReVIEW
|
|
81
82
|
exit 0
|
82
83
|
end
|
83
84
|
opts.on('--[no-]debug', 'Keep temporary files.') { |debug| cmd_config['debug'] = debug }
|
85
|
+
opts.on('-y', '--only file1,file2,...', 'Build only specified files.') { |v| @buildonly = v.split(/\s*,\s*/).map { |m| m.strip.sub(/\.re\Z/, '') } }
|
84
86
|
|
85
87
|
opts.parse!(args)
|
86
88
|
if args.size < 1 || args.size > 2
|
@@ -394,6 +396,11 @@ module ReVIEW
|
|
394
396
|
end
|
395
397
|
end
|
396
398
|
|
399
|
+
if @buildonly && !@buildonly.include?(id)
|
400
|
+
warn "skip #{id}.re"
|
401
|
+
return
|
402
|
+
end
|
403
|
+
|
397
404
|
htmlfile = "#{id}.#{@config['htmlext']}"
|
398
405
|
write_buildlogtxt(basetmpdir, htmlfile, filename)
|
399
406
|
log("Create #{htmlfile} from #{filename}.")
|
@@ -445,6 +452,13 @@ module ReVIEW
|
|
445
452
|
path = File.join(basetmpdir, filename)
|
446
453
|
htmlio = File.new(path)
|
447
454
|
Document.parse_stream(htmlio, ReVIEWHeaderListener.new(headlines))
|
455
|
+
htmlio.close
|
456
|
+
|
457
|
+
if headlines.empty?
|
458
|
+
warn "#{filename} is discarded because there is no heading. Use `=[notoc]' or `=[nodisp]' to exclude headlines from the table of contents."
|
459
|
+
return
|
460
|
+
end
|
461
|
+
|
448
462
|
properties = detect_properties(path)
|
449
463
|
if properties.present?
|
450
464
|
prop_str = ',properties=' + properties.join(' ')
|
@@ -472,7 +486,6 @@ module ReVIEW
|
|
472
486
|
first = nil
|
473
487
|
end
|
474
488
|
end
|
475
|
-
htmlio.close
|
476
489
|
end
|
477
490
|
|
478
491
|
def push_contents(_basetmpdir)
|