review 5.3.0 → 5.4.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/.github/workflows/ruby-tex.yml +1 -1
- data/.github/workflows/ruby.yml +1 -1
- data/.rubocop.yml +1 -322
- data/NEWS.ja.md +48 -0
- data/NEWS.md +48 -0
- data/README.md +9 -8
- data/bin/review +1 -1
- data/bin/review-catalog-converter +15 -15
- data/bin/review-check +7 -7
- data/bin/review-compile +6 -8
- data/bin/review-index +1 -1
- data/bin/review-preproc +1 -1
- data/bin/review-validate +2 -2
- data/doc/config.yml.sample +7 -1
- data/doc/config.yml.sample-simple +1 -1
- data/lib/review/book/base.rb +3 -3
- data/lib/review/book/book_unit.rb +1 -1
- data/lib/review/book/chapter.rb +1 -1
- data/lib/review/book/index.rb +3 -3
- data/lib/review/book/part.rb +12 -13
- data/lib/review/book/volume.rb +1 -1
- data/lib/review/builder.rb +10 -12
- data/lib/review/catalog.rb +5 -5
- data/lib/review/compiler.rb +13 -13
- data/lib/review/configure.rb +5 -2
- data/lib/review/epub2html.rb +12 -12
- data/lib/review/epubmaker/content.rb +1 -1
- data/lib/review/epubmaker/epubcommon.rb +44 -42
- data/lib/review/epubmaker/epubv2.rb +2 -1
- data/lib/review/epubmaker/epubv3.rb +5 -4
- data/lib/review/epubmaker/producer.rb +3 -3
- data/lib/review/epubmaker/reviewheaderlistener.rb +1 -1
- data/lib/review/epubmaker.rb +32 -31
- data/lib/review/extentions/string.rb +1 -1
- data/lib/review/htmlbuilder.rb +16 -15
- data/lib/review/htmlutils.rb +17 -17
- data/lib/review/i18n.rb +3 -3
- data/lib/review/idgxmlbuilder.rb +22 -21
- data/lib/review/idgxmlmaker.rb +15 -13
- data/lib/review/index_builder.rb +4 -20
- data/lib/review/init.rb +4 -4
- data/lib/review/latexbuilder.rb +30 -32
- data/lib/review/lineinput.rb +3 -3
- data/lib/review/location.rb +1 -1
- data/lib/review/logger.rb +21 -21
- data/lib/review/makerhelper.rb +3 -3
- data/lib/review/markdownbuilder.rb +6 -6
- data/lib/review/pdfmaker.rb +23 -19
- data/lib/review/plaintextbuilder.rb +5 -5
- data/lib/review/preprocessor/repository.rb +1 -1
- data/lib/review/preprocessor.rb +5 -5
- data/lib/review/textmaker.rb +20 -18
- data/lib/review/textutils.rb +3 -5
- data/lib/review/topbuilder.rb +71 -12
- data/lib/review/update.rb +16 -8
- data/lib/review/version.rb +1 -1
- data/lib/review/webmaker.rb +32 -32
- data/lib/review/webtocprinter.rb +10 -10
- data/lib/review/yamlloader.rb +35 -2
- data/review.gemspec +1 -0
- data/samples/sample-book/src/config.yml +0 -1
- data/templates/html/_titlepage.html.erb +9 -17
- data/templates/opf/opf_manifest_epubv2.opf.erb +1 -1
- data/templates/opf/opf_manifest_epubv3.opf.erb +1 -1
- data/test/book_test_helper.rb +10 -10
- data/test/test_epub3maker.rb +3 -3
- data/test/test_epubmaker.rb +14 -29
- data/test/test_epubmaker_cmd.rb +2 -2
- data/test/test_htmlbuilder.rb +4 -5
- data/test/test_idgxmlbuilder.rb +10 -10
- data/test/test_idgxmlmaker_cmd.rb +1 -1
- data/test/test_img_math.rb +11 -2
- data/test/test_latexbuilder.rb +2 -3
- data/test/test_pdfmaker_cmd.rb +10 -10
- data/test/test_textmaker_cmd.rb +1 -1
- data/test/test_topbuilder.rb +151 -11
- data/test/test_yamlloader.rb +28 -42
- metadata +8 -7
data/lib/review/preprocessor.rb
CHANGED
|
@@ -70,11 +70,11 @@ module ReVIEW
|
|
|
70
70
|
direc = parse_directive(line, 1, 'eval')
|
|
71
71
|
path = expand(direc.arg)
|
|
72
72
|
@leave_content = File.extname(path) == '.re'
|
|
73
|
-
if direc['eval']
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
ent = if direc['eval']
|
|
74
|
+
evaluate(path, ent)
|
|
75
|
+
else
|
|
76
|
+
@repository.fetch_file(path)
|
|
77
|
+
end
|
|
78
78
|
replace_block(f, line, ent, false) # FIXME: turn off lineno: tmp
|
|
79
79
|
|
|
80
80
|
when /\A\#@map(?:range)?/
|
data/lib/review/textmaker.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2018-
|
|
1
|
+
# Copyright (c) 2018-2022 Kenshi Muto
|
|
2
2
|
#
|
|
3
3
|
# This program is free software.
|
|
4
4
|
# You can distribute or modify this program under the terms of
|
|
@@ -74,9 +74,14 @@ module ReVIEW
|
|
|
74
74
|
cmd_config, yamlfile = parse_opts(args)
|
|
75
75
|
error! "#{yamlfile} not found." unless File.exist?(yamlfile)
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
begin
|
|
78
|
+
@config = ReVIEW::Configure.create(maker: 'textmaker',
|
|
79
|
+
yamlfile: yamlfile,
|
|
80
|
+
config: cmd_config)
|
|
81
|
+
rescue ReVIEW::ConfigError => e
|
|
82
|
+
error! e.message
|
|
83
|
+
end
|
|
84
|
+
|
|
80
85
|
@img_math = ReVIEW::ImgMath.new(@config, path_name: '_review_math_text')
|
|
81
86
|
|
|
82
87
|
I18n.setup(@config['language'])
|
|
@@ -111,12 +116,11 @@ module ReVIEW
|
|
|
111
116
|
|
|
112
117
|
def build_body(basetmpdir, _yamlfile)
|
|
113
118
|
base_path = Pathname.new(@basedir)
|
|
114
|
-
builder =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
end
|
|
119
|
+
builder = if @plaintext
|
|
120
|
+
ReVIEW::PLAINTEXTBuilder.new(img_math: @img_math)
|
|
121
|
+
else
|
|
122
|
+
ReVIEW::TOPBuilder.new(img_math: @img_math)
|
|
123
|
+
end
|
|
120
124
|
@converter = ReVIEW::Converter.new(@book, builder)
|
|
121
125
|
@book.parts.each do |part|
|
|
122
126
|
if part.name.present?
|
|
@@ -142,13 +146,11 @@ module ReVIEW
|
|
|
142
146
|
end
|
|
143
147
|
|
|
144
148
|
def build_chap(chap, base_path, basetmpdir, ispart)
|
|
145
|
-
filename =
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
|
|
151
|
-
end
|
|
149
|
+
filename = if ispart.present?
|
|
150
|
+
chap.path
|
|
151
|
+
else
|
|
152
|
+
Pathname.new(chap.path).relative_path_from(base_path).to_s
|
|
153
|
+
end
|
|
152
154
|
id = File.basename(filename).sub(/\.re\Z/, '')
|
|
153
155
|
if @buildonly && !@buildonly.include?(id)
|
|
154
156
|
warn "skip #{id}.re"
|
|
@@ -159,7 +161,7 @@ module ReVIEW
|
|
|
159
161
|
|
|
160
162
|
begin
|
|
161
163
|
@converter.convert(filename, File.join(basetmpdir, textfile))
|
|
162
|
-
rescue => e
|
|
164
|
+
rescue StandardError => e
|
|
163
165
|
@compile_errors = true
|
|
164
166
|
error "compile error in #{filename} (#{e.class})"
|
|
165
167
|
error e.message
|
data/lib/review/textutils.rb
CHANGED
|
@@ -72,13 +72,11 @@ module ReVIEW
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# lazy than rule 3, but it looks better
|
|
75
|
-
if lazy
|
|
76
|
-
if (%i[F W H].include?(Unicode::Eaw.property(tail)) &&
|
|
75
|
+
if lazy && ((%i[F W H].include?(Unicode::Eaw.property(tail)) &&
|
|
77
76
|
tail !~ /\p{Hangul}/) ||
|
|
78
77
|
(%i[F W H].include?(Unicode::Eaw.property(head)) &&
|
|
79
|
-
head !~ /\p{Hangul}/)
|
|
80
|
-
|
|
81
|
-
end
|
|
78
|
+
head !~ /\p{Hangul}/))
|
|
79
|
+
space = nil
|
|
82
80
|
end
|
|
83
81
|
end
|
|
84
82
|
space
|
data/lib/review/topbuilder.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2008-
|
|
1
|
+
# Copyright (c) 2008-2022 Minero Aoki, Kenshi Muto
|
|
2
2
|
# 2002-2006 Minero Aoki
|
|
3
3
|
#
|
|
4
4
|
# This program is free software.
|
|
@@ -262,13 +262,61 @@ module ReVIEW
|
|
|
262
262
|
blank
|
|
263
263
|
end
|
|
264
264
|
|
|
265
|
+
def table_rows(sepidx, rows)
|
|
266
|
+
if sepidx
|
|
267
|
+
sepidx.times do
|
|
268
|
+
tr(rows.shift.map { |s| th(s) })
|
|
269
|
+
end
|
|
270
|
+
if !@book.config['textmaker'] || !@book.config['textmaker']['th_bold']
|
|
271
|
+
puts '-' * 12
|
|
272
|
+
end
|
|
273
|
+
rows.each do |cols|
|
|
274
|
+
tr(cols.map { |s| td(s) })
|
|
275
|
+
end
|
|
276
|
+
else
|
|
277
|
+
rows.each do |cols|
|
|
278
|
+
h, *cs = *cols
|
|
279
|
+
tr([th(h)] + cs.map { |s| td(s) })
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
265
284
|
def th(str)
|
|
266
|
-
|
|
285
|
+
if @book.config['textmaker'] && @book.config['textmaker']['th_bold']
|
|
286
|
+
"★#{str}☆"
|
|
287
|
+
else
|
|
288
|
+
str
|
|
289
|
+
end
|
|
267
290
|
end
|
|
268
291
|
|
|
269
292
|
def table_end
|
|
270
293
|
end
|
|
271
294
|
|
|
295
|
+
def imgtable(lines, id, caption = nil, metric = nil)
|
|
296
|
+
metrics = parse_metric('top', metric)
|
|
297
|
+
metrics = " #{metrics}" if metrics.present?
|
|
298
|
+
blank
|
|
299
|
+
puts "◆→開始:#{@titles['table']}←◆"
|
|
300
|
+
if caption_top?('table') && caption.present?
|
|
301
|
+
table_header(id, caption)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
if @chapter.image_bound?(id)
|
|
305
|
+
puts "◆→#{@chapter.image(id).path}#{metrics}←◆"
|
|
306
|
+
else
|
|
307
|
+
warn "image not bound: #{id}", location: location
|
|
308
|
+
lines.each do |line|
|
|
309
|
+
puts line
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
if !caption_top?('table') && caption.present?
|
|
314
|
+
table_header(id, caption)
|
|
315
|
+
end
|
|
316
|
+
puts "◆→終了:#{@titles['table']}←◆"
|
|
317
|
+
blank
|
|
318
|
+
end
|
|
319
|
+
|
|
272
320
|
def comment(lines, comment = nil)
|
|
273
321
|
return unless @book.config['draft']
|
|
274
322
|
|
|
@@ -314,8 +362,9 @@ module ReVIEW
|
|
|
314
362
|
|
|
315
363
|
def compile_kw(word, alt)
|
|
316
364
|
if alt
|
|
317
|
-
|
|
318
|
-
else
|
|
365
|
+
"★#{word}☆(#{alt.strip})"
|
|
366
|
+
else
|
|
367
|
+
"★#{word}☆"
|
|
319
368
|
end
|
|
320
369
|
end
|
|
321
370
|
|
|
@@ -398,7 +447,7 @@ module ReVIEW
|
|
|
398
447
|
def inline_icon(id)
|
|
399
448
|
begin
|
|
400
449
|
"◆→画像 #{@chapter.image(id).path.sub(%r{\A\./}, '')}←◆"
|
|
401
|
-
rescue
|
|
450
|
+
rescue StandardError
|
|
402
451
|
warn "image not bound: #{id}", location: location
|
|
403
452
|
"◆→画像 #{id}←◆"
|
|
404
453
|
end
|
|
@@ -495,27 +544,37 @@ module ReVIEW
|
|
|
495
544
|
), __FILE__, __LINE__ - 11
|
|
496
545
|
end
|
|
497
546
|
|
|
498
|
-
def indepimage(
|
|
547
|
+
def indepimage(lines, id, caption = nil, metric = nil)
|
|
499
548
|
metrics = parse_metric('top', metric)
|
|
500
549
|
metrics = " #{metrics}" if metrics.present?
|
|
501
550
|
blank
|
|
551
|
+
puts "◆→開始:#{@titles['image']}←◆"
|
|
502
552
|
if caption_top?('image') && caption.present?
|
|
503
|
-
|
|
553
|
+
indepimage_header(id, caption)
|
|
554
|
+
blank
|
|
504
555
|
end
|
|
505
|
-
|
|
506
|
-
puts "
|
|
507
|
-
|
|
556
|
+
if @chapter.image_bound?(id)
|
|
557
|
+
puts "◆→#{@chapter.image(id).path}#{metrics}←◆"
|
|
558
|
+
else
|
|
508
559
|
warn "image not bound: #{id}", location: location
|
|
509
|
-
|
|
560
|
+
lines.each do |line|
|
|
561
|
+
puts line
|
|
562
|
+
end
|
|
510
563
|
end
|
|
511
564
|
if !caption_top?('image') && caption.present?
|
|
512
|
-
|
|
565
|
+
blank
|
|
566
|
+
indepimage_header(id, caption)
|
|
513
567
|
end
|
|
568
|
+
puts "◆→終了:#{@titles['image']}←◆"
|
|
514
569
|
blank
|
|
515
570
|
end
|
|
516
571
|
|
|
517
572
|
alias_method :numberlessimage, :indepimage
|
|
518
573
|
|
|
574
|
+
def indepimage_header(_id, caption)
|
|
575
|
+
puts "図#{I18n.t('caption_prefix_idgxml')}#{compile_inline(caption)}"
|
|
576
|
+
end
|
|
577
|
+
|
|
519
578
|
def inline_code(str)
|
|
520
579
|
"△#{str}☆"
|
|
521
580
|
end
|
data/lib/review/update.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#
|
|
2
|
-
# Copyright (c) 2018-
|
|
2
|
+
# Copyright (c) 2018-2022 Kenshi Muto
|
|
3
3
|
#
|
|
4
4
|
# This program is free software.
|
|
5
5
|
# You can distribute or modify this program under the terms of
|
|
@@ -165,7 +165,7 @@ module ReVIEW
|
|
|
165
165
|
|
|
166
166
|
Dir.glob(File.join(dir, '*.yml')).sort.each do |yml|
|
|
167
167
|
begin
|
|
168
|
-
config =
|
|
168
|
+
config = YAMLLoader.safe_load_file(yml)
|
|
169
169
|
if config['language'].present?
|
|
170
170
|
language = config['language']
|
|
171
171
|
end
|
|
@@ -226,9 +226,11 @@ module ReVIEW
|
|
|
226
226
|
|
|
227
227
|
def check_own_files(dir)
|
|
228
228
|
if File.exist?(File.join(dir, 'layouts/layout.tex.erb'))
|
|
229
|
+
# rubocop:disable Style/SoleNestedConditional
|
|
229
230
|
unless confirm('** There is custom layouts/layout.tex.erb file. Updating may break to make PDF until you fix layout.tex.erb. Do you really proceed to update? **', [], nil)
|
|
230
231
|
raise ApplicationError
|
|
231
232
|
end
|
|
233
|
+
# rubocop:enable Style/SoleNestedConditional
|
|
232
234
|
end
|
|
233
235
|
|
|
234
236
|
if File.exist?(File.join(dir, 'review-ext.rb'))
|
|
@@ -238,7 +240,7 @@ module ReVIEW
|
|
|
238
240
|
|
|
239
241
|
def update_version
|
|
240
242
|
@config_ymls.each do |yml|
|
|
241
|
-
config =
|
|
243
|
+
config = YAMLLoader.safe_load_file(yml)
|
|
242
244
|
if config['review_version'].to_f.round(1) == TARGET_VERSION.to_f.round(1)
|
|
243
245
|
next
|
|
244
246
|
end
|
|
@@ -265,10 +267,12 @@ module ReVIEW
|
|
|
265
267
|
target_rakefile = File.join(dir, 'Rakefile')
|
|
266
268
|
if File.exist?(target_rakefile)
|
|
267
269
|
if Digest::SHA256.hexdigest(File.read(target_rakefile)) != Digest::SHA256.hexdigest(File.read(master_rakefile))
|
|
270
|
+
# rubocop:disable Style/SoleNestedConditional
|
|
268
271
|
if confirm('%s will be overridden with Re:VIEW version (%s). Do you really proceed?', ['Rakefile', master_rakefile])
|
|
269
272
|
FileUtils.mv(target_rakefile, "#{target_rakefile}-old")
|
|
270
273
|
FileUtils.cp(master_rakefile, target_rakefile)
|
|
271
274
|
end
|
|
275
|
+
# rubocop:enable Style/SoleNestedConditional
|
|
272
276
|
end
|
|
273
277
|
else
|
|
274
278
|
@logger.info t('new file %s is created.', [target_rakefile]) unless @force
|
|
@@ -278,12 +282,14 @@ module ReVIEW
|
|
|
278
282
|
master_rakefile = File.join(@review_dir, 'samples/sample-book/src/lib/tasks/review.rake')
|
|
279
283
|
target_rakefile = File.join(taskdir, 'review.rake')
|
|
280
284
|
if File.exist?(target_rakefile)
|
|
285
|
+
# rubocop:disable Style/SoleNestedConditional
|
|
281
286
|
if Digest::SHA256.hexdigest(File.read(target_rakefile)) != Digest::SHA256.hexdigest(File.read(master_rakefile))
|
|
282
287
|
if confirm('%s will be overridden with Re:VIEW version (%s). Do you really proceed?', ['lib/tasks/review.rake', master_rakefile])
|
|
283
288
|
FileUtils.mv(target_rakefile, "#{target_rakefile}-old")
|
|
284
289
|
FileUtils.cp(master_rakefile, target_rakefile)
|
|
285
290
|
end
|
|
286
291
|
end
|
|
292
|
+
# rubocop:enable Style/SoleNestedConditional
|
|
287
293
|
else
|
|
288
294
|
@logger.info t('new file %s is created.', [target_rakefile]) unless @force
|
|
289
295
|
FileUtils.cp(master_rakefile, target_rakefile)
|
|
@@ -292,11 +298,13 @@ module ReVIEW
|
|
|
292
298
|
|
|
293
299
|
def update_epub_version
|
|
294
300
|
@epub_ymls.each do |yml|
|
|
295
|
-
config =
|
|
301
|
+
config = YAMLLoader.safe_load_file(yml)
|
|
296
302
|
if config['epubversion'].present? && config['epubversion'].to_f < EPUB_VERSION.to_f
|
|
303
|
+
# rubocop:disable Style/SoleNestedConditional
|
|
297
304
|
if confirm("%s: Update '%s' to '%s' from '%s'?", [File.basename(yml), 'epubversion', EPUB_VERSION, config['epubversion']])
|
|
298
305
|
rewrite_yml(yml, 'epubversion', EPUB_VERSION)
|
|
299
306
|
end
|
|
307
|
+
# rubocop:enable Style/SoleNestedConditional
|
|
300
308
|
end
|
|
301
309
|
if !config['htmlversion'].present? || config['htmlversion'].to_f >= HTML_VERSION.to_f
|
|
302
310
|
next
|
|
@@ -310,7 +318,7 @@ module ReVIEW
|
|
|
310
318
|
|
|
311
319
|
def update_locale
|
|
312
320
|
@locale_ymls.each do |yml|
|
|
313
|
-
config =
|
|
321
|
+
config = YAMLLoader.safe_load_file(yml)
|
|
314
322
|
if !config['chapter_quote'].present? || config['chapter_quote'].scan('%s').size != 1
|
|
315
323
|
next
|
|
316
324
|
end
|
|
@@ -324,7 +332,7 @@ module ReVIEW
|
|
|
324
332
|
|
|
325
333
|
def update_tex_parameters
|
|
326
334
|
@tex_ymls.each do |yml|
|
|
327
|
-
config =
|
|
335
|
+
config = YAMLLoader.safe_load_file(yml)
|
|
328
336
|
unless config['texdocumentclass']
|
|
329
337
|
next
|
|
330
338
|
end
|
|
@@ -510,7 +518,7 @@ module ReVIEW
|
|
|
510
518
|
|
|
511
519
|
def update_tex_command
|
|
512
520
|
@tex_ymls.each do |yml|
|
|
513
|
-
config =
|
|
521
|
+
config = YAMLLoader.safe_load_file(yml)
|
|
514
522
|
if !config['texcommand'] || config['texcommand'] !~ /\s+-/
|
|
515
523
|
next
|
|
516
524
|
end
|
|
@@ -535,7 +543,7 @@ module ReVIEW
|
|
|
535
543
|
|
|
536
544
|
def update_dvi_command
|
|
537
545
|
@tex_ymls.each do |yml|
|
|
538
|
-
config =
|
|
546
|
+
config = YAMLLoader.safe_load_file(yml)
|
|
539
547
|
if !config['dvicommand'] || config['dvicommand'] !~ /\s+-/
|
|
540
548
|
next
|
|
541
549
|
end
|
data/lib/review/version.rb
CHANGED
data/lib/review/webmaker.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright (c) 2016-
|
|
1
|
+
# Copyright (c) 2016-2022 Masayoshi Takahashi, Masanori Kado, Kenshi Muto
|
|
2
2
|
#
|
|
3
3
|
# This program is free software.
|
|
4
4
|
# You can distribute or modify this program under the terms of
|
|
@@ -78,9 +78,13 @@ module ReVIEW
|
|
|
78
78
|
cmd_config, yamlfile = parse_opts(args)
|
|
79
79
|
error! "#{yamlfile} not found." unless File.exist?(yamlfile)
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
begin
|
|
82
|
+
@config = ReVIEW::Configure.create(maker: 'webmaker',
|
|
83
|
+
yamlfile: yamlfile,
|
|
84
|
+
config: cmd_config)
|
|
85
|
+
rescue ReVIEW::ConfigError => e
|
|
86
|
+
error! e.message
|
|
87
|
+
end
|
|
84
88
|
|
|
85
89
|
@config['htmlext'] = 'html'
|
|
86
90
|
@img_math = ReVIEW::ImgMath.new(@config)
|
|
@@ -97,7 +101,7 @@ module ReVIEW
|
|
|
97
101
|
end
|
|
98
102
|
|
|
99
103
|
def generate_html_files(yamlfile)
|
|
100
|
-
@basedir = File.dirname(yamlfile)
|
|
104
|
+
@basedir = File.absolute_path(File.dirname(yamlfile))
|
|
101
105
|
@path = build_path
|
|
102
106
|
remove_old_files(@path)
|
|
103
107
|
Dir.mkdir(@path)
|
|
@@ -146,19 +150,27 @@ module ReVIEW
|
|
|
146
150
|
def build_part(part, basetmpdir, htmlfile)
|
|
147
151
|
@title = h("#{ReVIEW::I18n.t('part', part.number)} #{part.name.strip}")
|
|
148
152
|
File.open("#{basetmpdir}/#{htmlfile}", 'w') do |f|
|
|
149
|
-
@
|
|
150
|
-
@
|
|
151
|
-
@body
|
|
152
|
-
@body << %Q(<h2 class="part-title">#{part.name.strip}</h2>\n) if part.name.strip.present?
|
|
153
|
-
@body << "</div>\n"
|
|
154
|
-
|
|
153
|
+
@part_number = part.number
|
|
154
|
+
@part_title = part.name.strip
|
|
155
|
+
@body = ReVIEW::Template.generate(path: template_name(localfile: '_part_body.html.erb', systemfile: 'html/_part_body.html.erb'), binding: binding)
|
|
155
156
|
@language = @config['language']
|
|
156
157
|
@stylesheets = @config['stylesheet']
|
|
157
158
|
f.write ReVIEW::Template.generate(path: template_name, binding: binding)
|
|
158
159
|
end
|
|
159
160
|
end
|
|
160
161
|
|
|
161
|
-
def template_name
|
|
162
|
+
def template_name(localfile: 'layout-web.html.erb', systemfile: nil)
|
|
163
|
+
if @basedir
|
|
164
|
+
layoutfile = File.join(@basedir, 'layouts', localfile)
|
|
165
|
+
if File.exist?(layoutfile)
|
|
166
|
+
return layoutfile
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
if systemfile
|
|
171
|
+
return systemfile
|
|
172
|
+
end
|
|
173
|
+
|
|
162
174
|
if @config['htmlversion'].to_i == 5
|
|
163
175
|
'web/html/layout-html5.html.erb'
|
|
164
176
|
else
|
|
@@ -167,13 +179,11 @@ module ReVIEW
|
|
|
167
179
|
end
|
|
168
180
|
|
|
169
181
|
def build_chap(chap, base_path, basetmpdir, ispart)
|
|
170
|
-
filename =
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
filename = Pathname.new(chap.path).relative_path_from(base_path).to_s
|
|
176
|
-
end
|
|
182
|
+
filename = if ispart.present?
|
|
183
|
+
chap.path
|
|
184
|
+
else
|
|
185
|
+
Pathname.new(chap.path).relative_path_from(base_path).to_s
|
|
186
|
+
end
|
|
177
187
|
id = File.basename(filename).sub(/\.re\Z/, '')
|
|
178
188
|
|
|
179
189
|
if @buildonly && !@buildonly.include?(id)
|
|
@@ -219,7 +229,7 @@ module ReVIEW
|
|
|
219
229
|
|
|
220
230
|
if FileTest.directory?("#{resdir}/#{fname}")
|
|
221
231
|
recursive_copy_files("#{resdir}/#{fname}", "#{destdir}/#{fname}", allow_exts)
|
|
222
|
-
elsif
|
|
232
|
+
elsif /\.(#{allow_exts.join('|')})\Z/i.match?(fname)
|
|
223
233
|
FileUtils.mkdir_p(destdir)
|
|
224
234
|
FileUtils.cp("#{resdir}/#{fname}", destdir)
|
|
225
235
|
end
|
|
@@ -274,18 +284,8 @@ module ReVIEW
|
|
|
274
284
|
|
|
275
285
|
def build_titlepage(basetmpdir, htmlfile)
|
|
276
286
|
@title = h('titlepage')
|
|
277
|
-
File.open(
|
|
278
|
-
@body = ''
|
|
279
|
-
@body << %Q(<div class="titlepage">)
|
|
280
|
-
@body << %Q(<h1 class="tp-title">#{h(@config.name_of('booktitle'))}</h1>)
|
|
281
|
-
if @config['aut']
|
|
282
|
-
@body << %Q(<h2 class="tp-author">#{join_with_separator(@config.names_of('aut'), ReVIEW::I18n.t('names_splitter'))}</h2>)
|
|
283
|
-
end
|
|
284
|
-
if @config['pbl']
|
|
285
|
-
@body << %Q(<h3 class="tp-publisher">#{join_with_separator(@config.names_of('pbl'), ReVIEW::I18n.t('names_splitter'))}</h3>)
|
|
286
|
-
end
|
|
287
|
-
@body << '</div>'
|
|
288
|
-
|
|
287
|
+
File.open(File.join(basetmpdir, htmlfile), 'w') do |f|
|
|
288
|
+
@body = ReVIEW::Template.generate(path: template_name(localfile: '_titlepage.html.erb', systemfile: 'html/_titlepage.html.erb'), binding: binding)
|
|
289
289
|
@language = @config['language']
|
|
290
290
|
@stylesheets = @config['stylesheet']
|
|
291
291
|
f.write ReVIEW::Template.generate(path: template_name, binding: binding)
|
data/lib/review/webtocprinter.rb
CHANGED
|
@@ -41,16 +41,16 @@ EOT
|
|
|
41
41
|
next
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
if path.start_with?('.')
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if result.level == 0
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
content << if path.start_with?('.')
|
|
45
|
+
"<li>#{escape(result.headline)}"
|
|
46
|
+
else
|
|
47
|
+
%Q(<li><a href="#{path}">#{escape(result.headline)}</a>)
|
|
48
|
+
end
|
|
49
|
+
content << if result.level == 0
|
|
50
|
+
"\n<ul>" # part
|
|
51
|
+
else
|
|
52
|
+
"</li>\n"
|
|
53
|
+
end
|
|
54
54
|
end
|
|
55
55
|
content << "</ul>\n"
|
|
56
56
|
end
|
data/lib/review/yamlloader.rb
CHANGED
|
@@ -2,6 +2,39 @@ require 'yaml'
|
|
|
2
2
|
|
|
3
3
|
module ReVIEW
|
|
4
4
|
class YAMLLoader
|
|
5
|
+
def self.safe_load_file(file)
|
|
6
|
+
if YAML.respond_to?(:safe_load_file)
|
|
7
|
+
YAML.safe_load_file(file, aliases: true, permitted_classes: [Date])
|
|
8
|
+
else
|
|
9
|
+
File.open(file, 'rt:bom|utf-8') do |f|
|
|
10
|
+
begin
|
|
11
|
+
# < Ruby 3.1
|
|
12
|
+
YAML.safe_load(f, filename: file, aliases: true, permitted_classes: [Date])
|
|
13
|
+
rescue ArgumentError
|
|
14
|
+
# < Ruby 2.7
|
|
15
|
+
YAML.safe_load(f, [Date])
|
|
16
|
+
rescue Psych::DisallowedClass
|
|
17
|
+
# < Ruby 2.5
|
|
18
|
+
YAML.safe_load(File.read(file), [Date])
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.safe_load(s)
|
|
25
|
+
if YAML.respond_to?(:safe_load_file)
|
|
26
|
+
YAML.safe_load(s, aliases: true, permitted_classes: [Date])
|
|
27
|
+
else
|
|
28
|
+
begin
|
|
29
|
+
# < Ruby 3.1
|
|
30
|
+
YAML.safe_load(s, aliases: true, permitted_classes: [Date])
|
|
31
|
+
rescue ArgumentError, Psych::DisallowedClass
|
|
32
|
+
# < Ruby 2.7
|
|
33
|
+
YAML.safe_load(s, [Date])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
5
38
|
def initialize
|
|
6
39
|
end
|
|
7
40
|
|
|
@@ -17,8 +50,8 @@ module ReVIEW
|
|
|
17
50
|
|
|
18
51
|
while file_queue.present?
|
|
19
52
|
current_file = file_queue.shift
|
|
20
|
-
current_yaml =
|
|
21
|
-
if current_yaml.instance_of?(FalseClass)
|
|
53
|
+
current_yaml = YAMLLoader.safe_load_file(current_file)
|
|
54
|
+
if current_yaml.instance_of?(FalseClass) || current_yaml.nil?
|
|
22
55
|
raise "#{File.basename(current_file)} is malformed."
|
|
23
56
|
end
|
|
24
57
|
|
data/review.gemspec
CHANGED
|
@@ -12,6 +12,7 @@ Gem::Specification.new do |gem|
|
|
|
12
12
|
gem.summary = 'Re:VIEW: a easy-to-use digital publishing system'
|
|
13
13
|
gem.description = 'Re:VIEW is a digital publishing system for books and ebooks. It supports InDesign, EPUB and LaTeX.'
|
|
14
14
|
gem.required_rubygems_version = Gem::Requirement.new('>= 0') if gem.respond_to?(:required_rubygems_version=)
|
|
15
|
+
gem.metadata = { 'rubygems_mfa_required' => 'true' }
|
|
15
16
|
|
|
16
17
|
gem.files = `git ls-files`.split("\n")
|
|
17
18
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<div class="titlepage">
|
|
2
|
+
<h1 class="tp-title"><%= h(@config.name_of('booktitle')) %></h1>
|
|
3
|
+
<% if @config['subtitle'] %>
|
|
4
|
+
<h2 class="tp-subtitle"><%= h(@config.name_of('subtitle')) %></h2>
|
|
4
5
|
<% end %>
|
|
5
|
-
<% if @
|
|
6
|
-
|
|
7
|
-
<br />
|
|
8
|
-
<br />
|
|
9
|
-
</p>
|
|
10
|
-
<h2 class="tp-author"><%= h(@author_str) %></h2>
|
|
6
|
+
<% if @config['aut'] %>
|
|
7
|
+
<h2 class="tp-author"><%= h(@config.names_of('aut').join(ReVIEW::I18n.t('names_splitter'))) %></h2>
|
|
11
8
|
<% end %>
|
|
12
|
-
<% if @
|
|
13
|
-
|
|
14
|
-
<br />
|
|
15
|
-
<br />
|
|
16
|
-
<br />
|
|
17
|
-
<br />
|
|
18
|
-
</p>
|
|
19
|
-
<h3 class="tp-publisher"><%= h(@publisher_str) %></h3>
|
|
9
|
+
<% if @config['pbl'] %>
|
|
10
|
+
<h3 class="tp-publisher"><%= h(@config.names_of('pbl').join(ReVIEW::I18n.t('names_splitter'))) %></h3>
|
|
20
11
|
<% end %>
|
|
12
|
+
</div>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<% if @config['toc'] && @config['mytoc'] %>
|
|
5
5
|
<item id="toc" href="<%= @config['bookname'] %>-toc.<%= @config['htmlext'] %>" media-type="application/xhtml+xml"/>
|
|
6
6
|
<% end %>
|
|
7
|
-
<% @items.each do |item| %>
|
|
7
|
+
<% @items.sort_by { |x| x.id }.each do |item| %>
|
|
8
8
|
<item id="<%= item.id %>" href="<%= item.file %>" media-type="<%= item.media %>"/>
|
|
9
9
|
<% end %>
|
|
10
10
|
</manifest>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<% if @coverimage %>
|
|
5
5
|
<item properties="cover-image" id="cover-<%= @coverimage.id %>" href="<%= @coverimage.file %>" media-type="<%= @coverimage.media %>"/>
|
|
6
6
|
<% end %>
|
|
7
|
-
<% @items.each do |item| %>
|
|
7
|
+
<% @items.sort_by { |x| x.id }.each do |item| %>
|
|
8
8
|
<item id="<%= item.id %>" href="<%= item.file %>" media-type="<%= item.media %>"<%= item.properties_attribute %>/>
|
|
9
9
|
<% end %>
|
|
10
10
|
</manifest>
|
data/test/book_test_helper.rb
CHANGED
|
@@ -20,11 +20,11 @@ module BookTestHelper
|
|
|
20
20
|
created_files[filename] = path
|
|
21
21
|
end
|
|
22
22
|
conf_path = File.expand_path('config.yml', dir)
|
|
23
|
-
if File.exist?(conf_path)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
config = if File.exist?(conf_path)
|
|
24
|
+
ReVIEW::Configure.create(yamlfile: conf_path)
|
|
25
|
+
else
|
|
26
|
+
ReVIEW::Configure.values
|
|
27
|
+
end
|
|
28
28
|
book = Book::Base.new(dir, config: config)
|
|
29
29
|
yield(dir, book, created_files)
|
|
30
30
|
end
|
|
@@ -34,11 +34,11 @@ module BookTestHelper
|
|
|
34
34
|
def get_instance_variables(obj)
|
|
35
35
|
obj.instance_variables.each_with_object({}) do |name, memo|
|
|
36
36
|
value = obj.instance_variable_get(name)
|
|
37
|
-
if value.instance_variables.empty?
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
memo[name] = if value.instance_variables.empty?
|
|
38
|
+
value
|
|
39
|
+
else
|
|
40
|
+
get_instance_variables(value)
|
|
41
|
+
end
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
end
|