review 2.4.0 → 2.5.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 +5 -5
- data/.rubocop.yml +20 -5
- data/.travis.yml +2 -1
- data/NEWS.ja.md +93 -0
- data/NEWS.md +77 -0
- data/README.md +1 -1
- data/bin/review +38 -12
- data/bin/review-compile +106 -88
- data/bin/review-epubmaker +6 -1
- data/bin/review-init +21 -1
- data/bin/review-textmaker +16 -0
- data/doc/config.yml.sample +6 -1
- data/doc/format.ja.md +23 -0
- data/doc/format.md +20 -2
- data/doc/quickstart.ja.md +8 -4
- data/doc/quickstart.md +11 -8
- data/lib/review/book/base.rb +29 -18
- data/lib/review/book/index.rb +10 -5
- data/lib/review/builder.rb +58 -33
- data/lib/review/catalog.rb +30 -0
- data/lib/review/compiler.rb +53 -19
- data/lib/review/configure.rb +15 -14
- data/lib/review/epubmaker.rb +15 -4
- data/lib/review/htmlbuilder.rb +56 -24
- data/lib/review/idgxmlbuilder.rb +17 -7
- data/lib/review/latexbuilder.rb +113 -38
- data/lib/review/markdownbuilder.rb +12 -5
- data/lib/review/md2inaobuilder.rb +3 -1
- data/lib/review/pdfmaker.rb +23 -9
- data/lib/review/plaintextbuilder.rb +683 -0
- data/lib/review/rstbuilder.rb +30 -10
- data/lib/review/textmaker.rb +158 -0
- data/lib/review/textutils.rb +10 -1
- data/lib/review/topbuilder.rb +32 -417
- data/lib/review/version.rb +1 -1
- data/lib/review/webmaker.rb +29 -8
- data/review.gemspec +3 -4
- data/templates/html/layout-xhtml1.html.erb +0 -2
- data/templates/latex/layout.tex.erb +6 -4
- data/templates/web/html/layout-xhtml1.html.erb +0 -2
- data/test/book_test_helper.rb +1 -0
- data/test/run_test.rb +1 -1
- data/test/sample-book/src/Rakefile +19 -3
- data/test/syntax-book/Rakefile +19 -3
- data/test/test_catalog.rb +45 -0
- data/test/test_compiler.rb +8 -2
- data/test/test_htmlbuilder.rb +22 -0
- data/test/test_idgxmlbuilder.rb +22 -0
- data/test/test_index.rb +31 -0
- data/test/test_latexbuilder.rb +48 -16
- data/test/test_plaintextbuilder.rb +390 -0
- data/test/test_textutils.rb +2 -0
- data/test/test_topbuilder.rb +23 -1
- metadata +13 -7
data/lib/review/catalog.rb
CHANGED
@@ -48,5 +48,35 @@ module ReVIEW
|
|
48
48
|
return '' unless @yaml['POSTDEF']
|
49
49
|
@yaml['POSTDEF'].join("\n")
|
50
50
|
end
|
51
|
+
|
52
|
+
def validate!(basedir)
|
53
|
+
filenames = []
|
54
|
+
if predef.present?
|
55
|
+
filenames.concat(predef.split(/\n/))
|
56
|
+
end
|
57
|
+
parts_with_chaps.each do |chap|
|
58
|
+
if chap.is_a?(Hash)
|
59
|
+
chap.each_key do |part|
|
60
|
+
if File.extname(part) == '.re'
|
61
|
+
filenames.push(part)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
filenames.concat(chap.values.flatten)
|
65
|
+
else
|
66
|
+
filenames.push(chap)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
if appendix.present?
|
70
|
+
filenames.concat(appendix.split(/\n/))
|
71
|
+
end
|
72
|
+
if postdef.present?
|
73
|
+
filenames.concat(postdef.split(/\n/))
|
74
|
+
end
|
75
|
+
filenames.each do |filename|
|
76
|
+
unless File.exist?(File.join(basedir, filename))
|
77
|
+
raise FileNotFound, "file not found in catalog.yml: #{basedir}/#{filename}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
51
81
|
end
|
52
82
|
end
|
data/lib/review/compiler.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2009-
|
1
|
+
# Copyright (c) 2009-2018 Minero Aoki, Kenshi Muto
|
2
2
|
# Copyright (c) 2002-2007 Minero Aoki
|
3
3
|
#
|
4
4
|
# This program is free software.
|
@@ -59,8 +59,12 @@ module ReVIEW
|
|
59
59
|
attr_reader :name
|
60
60
|
|
61
61
|
def check_args(args)
|
62
|
-
|
63
|
-
|
62
|
+
unless @argc_spec === args.size
|
63
|
+
raise CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})"
|
64
|
+
end
|
65
|
+
if @checker
|
66
|
+
@checker.call(*args)
|
67
|
+
end
|
64
68
|
end
|
65
69
|
|
66
70
|
def min_argc
|
@@ -161,7 +165,7 @@ module ReVIEW
|
|
161
165
|
|
162
166
|
defsingle :footnote, 2
|
163
167
|
defsingle :noindent, 0
|
164
|
-
defsingle :
|
168
|
+
defsingle :blankline, 0
|
165
169
|
defsingle :pagebreak, 0
|
166
170
|
defsingle :hr, 0
|
167
171
|
defsingle :parasep, 0
|
@@ -286,19 +290,29 @@ module ReVIEW
|
|
286
290
|
index = level - 1
|
287
291
|
if tag
|
288
292
|
if tag !~ %r{\A/}
|
289
|
-
|
293
|
+
if caption.empty?
|
294
|
+
warn 'headline is empty.'
|
295
|
+
end
|
290
296
|
close_current_tagged_section(level)
|
291
297
|
open_tagged_section(tag, level, label, caption)
|
292
298
|
else
|
293
299
|
open_tag = tag[1..-1]
|
294
300
|
prev_tag_info = @tagged_section.pop
|
295
|
-
|
301
|
+
if prev_tag_info.nil? || prev_tag_info.first != open_tag
|
302
|
+
error "#{open_tag} is not opened."
|
303
|
+
end
|
296
304
|
close_tagged_section(*prev_tag_info)
|
297
305
|
end
|
298
306
|
else
|
299
|
-
|
300
|
-
|
301
|
-
|
307
|
+
if caption.empty?
|
308
|
+
warn 'headline is empty.'
|
309
|
+
end
|
310
|
+
if @headline_indexs.size > (index + 1)
|
311
|
+
@headline_indexs = @headline_indexs[0..index]
|
312
|
+
end
|
313
|
+
if @headline_indexs[index].nil?
|
314
|
+
@headline_indexs[index] = 0
|
315
|
+
end
|
302
316
|
@headline_indexs[index] += 1
|
303
317
|
close_current_tagged_section(level)
|
304
318
|
@strategy.headline level, label, caption
|
@@ -340,7 +354,9 @@ module ReVIEW
|
|
340
354
|
end
|
341
355
|
|
342
356
|
def close_all_tagged_section
|
343
|
-
|
357
|
+
until @tagged_section.empty?
|
358
|
+
close_tagged_section(* @tagged_section.pop)
|
359
|
+
end
|
344
360
|
end
|
345
361
|
|
346
362
|
def compile_ulist(f)
|
@@ -349,7 +365,9 @@ module ReVIEW
|
|
349
365
|
next if line =~ /\A\#@/
|
350
366
|
|
351
367
|
buf = [text(line.sub(/\*+/, '').strip)]
|
352
|
-
f.while_match(/\A\s+(?!\*)\S/)
|
368
|
+
f.while_match(/\A\s+(?!\*)\S/) do |cont|
|
369
|
+
buf.push text(cont.strip)
|
370
|
+
end
|
353
371
|
|
354
372
|
line =~ /\A\s+(\*+)/
|
355
373
|
current_level = $1.size
|
@@ -392,7 +410,9 @@ module ReVIEW
|
|
392
410
|
|
393
411
|
num = line.match(/(\d+)\./)[1]
|
394
412
|
buf = [text(line.sub(/\d+\./, '').strip)]
|
395
|
-
f.while_match(/\A\s+(?!\d+\.)\S/)
|
413
|
+
f.while_match(/\A\s+(?!\d+\.)\S/) do |cont|
|
414
|
+
buf.push text(cont.strip)
|
415
|
+
end
|
396
416
|
@strategy.ol_item buf, num
|
397
417
|
end
|
398
418
|
@strategy.ol_end
|
@@ -402,7 +422,8 @@ module ReVIEW
|
|
402
422
|
@strategy.dl_begin
|
403
423
|
while /\A\s*:/ =~ f.peek
|
404
424
|
@strategy.dt text(f.gets.sub(/\A\s*:/, '').strip)
|
405
|
-
|
425
|
+
desc = f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) }
|
426
|
+
@strategy.dd(desc)
|
406
427
|
f.skip_blank_lines
|
407
428
|
f.skip_comment_lines
|
408
429
|
end
|
@@ -423,8 +444,9 @@ module ReVIEW
|
|
423
444
|
name = line.slice(/[a-z]+/).to_sym
|
424
445
|
ignore_inline = (name == :embed)
|
425
446
|
args = parse_args(line.sub(%r{\A//[a-z]+}, '').rstrip.chomp('{'), name)
|
447
|
+
@strategy.doc_status[name] = true
|
426
448
|
lines = block_open?(line) ? read_block(f, ignore_inline) : nil
|
427
|
-
|
449
|
+
@strategy.doc_status[name] = nil
|
428
450
|
[name, args, lines]
|
429
451
|
end
|
430
452
|
|
@@ -483,7 +505,9 @@ module ReVIEW
|
|
483
505
|
if syntax.block_allowed?
|
484
506
|
compile_block syntax, args, lines
|
485
507
|
else
|
486
|
-
|
508
|
+
if lines
|
509
|
+
error "block is not allowed for command //#{syntax.name}; ignore"
|
510
|
+
end
|
487
511
|
compile_single syntax, args
|
488
512
|
end
|
489
513
|
end
|
@@ -497,7 +521,9 @@ module ReVIEW
|
|
497
521
|
end
|
498
522
|
|
499
523
|
def default_block(syntax)
|
500
|
-
|
524
|
+
if syntax.block_required?
|
525
|
+
error "block is required for //#{syntax.name}; use empty block"
|
526
|
+
end
|
501
527
|
[]
|
502
528
|
end
|
503
529
|
|
@@ -516,7 +542,11 @@ module ReVIEW
|
|
516
542
|
def text(str)
|
517
543
|
return '' if str.empty?
|
518
544
|
words = replace_fence(str).split(/(@<\w+>\{(?:[^\}\\]|\\.)*?\})/, -1)
|
519
|
-
words.each
|
545
|
+
words.each do |w|
|
546
|
+
if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w)
|
547
|
+
error "`@<xxx>' seen but is not valid inline op: #{w}"
|
548
|
+
end
|
549
|
+
end
|
520
550
|
result = @strategy.nofunc_text(words.shift)
|
521
551
|
until words.empty?
|
522
552
|
result << compile_inline(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\'))
|
@@ -530,8 +560,12 @@ module ReVIEW
|
|
530
560
|
|
531
561
|
def compile_inline(str)
|
532
562
|
op, arg = /\A@<(\w+)>\{(.*?)\}\z/.match(str).captures
|
533
|
-
|
534
|
-
|
563
|
+
unless inline_defined?(op)
|
564
|
+
raise CompileError, "no such inline op: #{op}"
|
565
|
+
end
|
566
|
+
unless @strategy.respond_to?("inline_#{op}")
|
567
|
+
raise "strategy does not support inline op: @<#{op}>"
|
568
|
+
end
|
535
569
|
@strategy.__send__("inline_#{op}", arg)
|
536
570
|
rescue => err
|
537
571
|
error err.message
|
data/lib/review/configure.rb
CHANGED
@@ -53,23 +53,24 @@ module ReVIEW
|
|
53
53
|
'ext' => '.re',
|
54
54
|
'image_dir' => 'images',
|
55
55
|
'image_types' => %w[.ai .psd .eps .pdf .tif .tiff .png .bmp .jpg .jpeg .gif .svg],
|
56
|
-
'image_scale2width' => true, # for LaTeX
|
57
56
|
'bib_file' => 'bib.re',
|
58
57
|
'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt],
|
59
58
|
'externallink' => true,
|
60
|
-
|
61
|
-
'
|
62
|
-
'
|
63
|
-
'
|
64
|
-
'
|
65
|
-
'
|
66
|
-
|
67
|
-
|
68
|
-
'
|
69
|
-
'
|
70
|
-
'
|
71
|
-
'
|
72
|
-
|
59
|
+
# for IDGXML
|
60
|
+
'tableopt' => nil,
|
61
|
+
'listinfo' => nil,
|
62
|
+
'nolf' => true,
|
63
|
+
'chapref' => nil,
|
64
|
+
'structuredxml' => nil,
|
65
|
+
'pt_to_mm_unit' => 0.3528, # DTP: 1pt = 0.3528mm, JIS: 1pt = 0.3514mm
|
66
|
+
# for LaTeX
|
67
|
+
'image_scale2width' => true,
|
68
|
+
'footnotetext' => nil,
|
69
|
+
'texcommand' => 'uplatex',
|
70
|
+
'texdocumentclass' => ['jsbook', 'uplatex,oneside'],
|
71
|
+
'dvicommand' => 'dvipdfmx',
|
72
|
+
'dvioptions' => '-d 5',
|
73
|
+
# for PDFMaker
|
73
74
|
'pdfmaker' => {
|
74
75
|
'makeindex' => nil, # Make index page
|
75
76
|
'makeindex_command' => 'mendex', # works only when makeindex is true
|
data/lib/review/epubmaker.rb
CHANGED
@@ -50,7 +50,13 @@ module ReVIEW
|
|
50
50
|
|
51
51
|
def load_yaml(yamlfile)
|
52
52
|
loader = ReVIEW::YAMLLoader.new
|
53
|
-
@config = ReVIEW::Configure.values
|
53
|
+
@config = ReVIEW::Configure.values
|
54
|
+
begin
|
55
|
+
@config.deep_merge!(loader.load_file(yamlfile))
|
56
|
+
rescue => e
|
57
|
+
error "yaml error #{e.message}"
|
58
|
+
end
|
59
|
+
|
54
60
|
@producer = Producer.new(@config)
|
55
61
|
@producer.load(yamlfile)
|
56
62
|
@config = @producer.config
|
@@ -134,8 +140,11 @@ module ReVIEW
|
|
134
140
|
log('Call ePUB producer.')
|
135
141
|
@producer.produce("#{bookname}.epub", basetmpdir, epubtmpdir)
|
136
142
|
log('Finished.')
|
143
|
+
rescue ApplicationError => e
|
144
|
+
raise if @config['debug']
|
145
|
+
error(e.message)
|
137
146
|
ensure
|
138
|
-
FileUtils.remove_entry_secure
|
147
|
+
FileUtils.remove_entry_secure(basetmpdir) unless @config['debug']
|
139
148
|
end
|
140
149
|
end
|
141
150
|
|
@@ -364,7 +373,8 @@ module ReVIEW
|
|
364
373
|
def write_info_body(basetmpdir, _id, filename, ispart = nil, chaptype = nil)
|
365
374
|
headlines = []
|
366
375
|
path = File.join(basetmpdir, filename)
|
367
|
-
|
376
|
+
htmlio = File.new(path)
|
377
|
+
Document.parse_stream(htmlio, ReVIEWHeaderListener.new(headlines))
|
368
378
|
properties = detect_properties(path)
|
369
379
|
prop_str = ''
|
370
380
|
prop_str = ',properties=' + properties.join(' ') if properties.present?
|
@@ -378,6 +388,7 @@ module ReVIEW
|
|
378
388
|
first = nil
|
379
389
|
end
|
380
390
|
end
|
391
|
+
htmlio.close
|
381
392
|
end
|
382
393
|
|
383
394
|
def push_contents(_basetmpdir)
|
@@ -435,7 +446,7 @@ module ReVIEW
|
|
435
446
|
@body << %Q(<h1 class="tp-title">#{CGI.escapeHTML(@config.name_of('booktitle'))}</h1>\n)
|
436
447
|
@body << %Q(<h2 class="tp-subtitle">#{CGI.escapeHTML(@config.name_of('subtitle'))}</h2>\n) if @config['subtitle']
|
437
448
|
@body << %Q(<h2 class="tp-author">#{CGI.escapeHTML(@config.names_of('aut').join(ReVIEW::I18n.t('names_splitter')))}</h2>\n) if @config['aut']
|
438
|
-
@body << %Q(<h3 class="tp-publisher">#{CGI.escapeHTML(@config.names_of('
|
449
|
+
@body << %Q(<h3 class="tp-publisher">#{CGI.escapeHTML(@config.names_of('pbl').join(ReVIEW::I18n.t('names_splitter')))}</h3>\n) if @config['pbl']
|
439
450
|
@body << '</div>'
|
440
451
|
|
441
452
|
@language = @producer.config['language']
|
data/lib/review/htmlbuilder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2008-
|
1
|
+
# Copyright (c) 2008-2018 Minero Aoki, Kenshi Muto, Masayoshi Takahashi,
|
2
2
|
# KADO Masanori
|
3
3
|
# 2002-2007 Minero Aoki
|
4
4
|
#
|
@@ -20,7 +20,9 @@ module ReVIEW
|
|
20
20
|
include TextUtils
|
21
21
|
include HTMLUtils
|
22
22
|
|
23
|
-
[:ref].each
|
23
|
+
[:ref].each do |e|
|
24
|
+
Compiler.definline(e)
|
25
|
+
end
|
24
26
|
Compiler.defblock(:planning, 0..1)
|
25
27
|
Compiler.defblock(:best, 0..1)
|
26
28
|
Compiler.defblock(:security, 0..1)
|
@@ -101,7 +103,9 @@ module ReVIEW
|
|
101
103
|
@next_title = @next ? compile_inline(@next.title) : ''
|
102
104
|
@prev_title = @prev ? compile_inline(@prev.title) : ''
|
103
105
|
|
104
|
-
|
106
|
+
if @book.config.maker == 'webmaker'
|
107
|
+
@toc = ReVIEW::WEBTOCPrinter.book_to_string(@book)
|
108
|
+
end
|
105
109
|
|
106
110
|
ReVIEW::Template.load(layoutfile).result(binding)
|
107
111
|
end
|
@@ -116,10 +120,14 @@ module ReVIEW
|
|
116
120
|
|
117
121
|
def headline(level, label, caption)
|
118
122
|
prefix, anchor = headline_prefix(level)
|
119
|
-
|
123
|
+
if prefix
|
124
|
+
prefix = %Q(<span class="secno">#{prefix}</span>)
|
125
|
+
end
|
120
126
|
puts '' if level > 1
|
121
127
|
a_id = ''
|
122
|
-
|
128
|
+
if anchor
|
129
|
+
a_id = %Q(<a id="h#{anchor}"></a>)
|
130
|
+
end
|
123
131
|
|
124
132
|
if caption.empty?
|
125
133
|
puts a_id if label
|
@@ -282,7 +290,9 @@ module ReVIEW
|
|
282
290
|
puts %Q(<div class="syntax">)
|
283
291
|
puts %Q(<p class="caption">#{compile_inline(caption)}</p>) if caption.present?
|
284
292
|
print %Q(<pre class="syntax">)
|
285
|
-
lines.each
|
293
|
+
lines.each do |line|
|
294
|
+
puts detab(line)
|
295
|
+
end
|
286
296
|
puts '</pre>'
|
287
297
|
puts '</div>'
|
288
298
|
end
|
@@ -435,7 +445,9 @@ module ReVIEW
|
|
435
445
|
class_names.push('highlight') if highlight?
|
436
446
|
print %Q(<pre class="#{class_names.join(' ')}">)
|
437
447
|
first_line_num = line_num
|
438
|
-
lines.each_with_index
|
448
|
+
lines.each_with_index do |line, i|
|
449
|
+
puts detab((i + first_line_num).to_s.rjust(2) + ': ' + line)
|
450
|
+
end
|
439
451
|
puts '</pre>'
|
440
452
|
end
|
441
453
|
end
|
@@ -470,7 +482,9 @@ module ReVIEW
|
|
470
482
|
class_names.push('highlight') if highlight?
|
471
483
|
print %Q(<pre class="#{class_names.join(' ')}">)
|
472
484
|
first_line_num = line_num
|
473
|
-
lines.each_with_index
|
485
|
+
lines.each_with_index do |line, i|
|
486
|
+
puts detab((i + first_line_num).to_s.rjust(2) + ': ' + line)
|
487
|
+
end
|
474
488
|
puts '</pre>'
|
475
489
|
end
|
476
490
|
|
@@ -490,7 +504,9 @@ module ReVIEW
|
|
490
504
|
|
491
505
|
def quotedlist(lines, css_class)
|
492
506
|
print %Q(<blockquote><pre class="#{css_class}">)
|
493
|
-
lines.each
|
507
|
+
lines.each do |line|
|
508
|
+
puts detab(line)
|
509
|
+
end
|
494
510
|
puts '</pre></blockquote>'
|
495
511
|
end
|
496
512
|
private :quotedlist
|
@@ -541,7 +557,9 @@ module ReVIEW
|
|
541
557
|
end
|
542
558
|
|
543
559
|
def handle_metric(str)
|
544
|
-
|
560
|
+
if str =~ /\Ascale=([\d.]+)\Z/
|
561
|
+
return { 'class' => sprintf('width-%03dper', ($1.to_f * 100).round) }
|
562
|
+
end
|
545
563
|
|
546
564
|
k, v = str.split('=', 2)
|
547
565
|
{ k => v.sub(/\A["']/, '').sub(/["']\Z/, '') }
|
@@ -572,7 +590,9 @@ module ReVIEW
|
|
572
590
|
warn "image not bound: #{id}"
|
573
591
|
puts %Q(<div id="#{normalize_id(id)}" class="image">)
|
574
592
|
puts %Q(<pre class="dummyimage">)
|
575
|
-
lines.each
|
593
|
+
lines.each do |line|
|
594
|
+
puts detab(line)
|
595
|
+
end
|
576
596
|
puts '</pre>'
|
577
597
|
image_header id, caption
|
578
598
|
puts '</div>'
|
@@ -615,8 +635,12 @@ module ReVIEW
|
|
615
635
|
table_begin rows.first.size
|
616
636
|
return if rows.empty?
|
617
637
|
if sepidx
|
618
|
-
sepidx.times
|
619
|
-
|
638
|
+
sepidx.times do
|
639
|
+
tr(rows.shift.map { |s| th(s) })
|
640
|
+
end
|
641
|
+
rows.each do |cols|
|
642
|
+
tr(cols.map { |s| td(s) })
|
643
|
+
end
|
620
644
|
else
|
621
645
|
rows.each do |cols|
|
622
646
|
h, *cs = *cols
|
@@ -711,7 +735,9 @@ module ReVIEW
|
|
711
735
|
warn "image not bound: #{id}"
|
712
736
|
if lines
|
713
737
|
puts %Q(<pre class="dummyimage">)
|
714
|
-
lines.each
|
738
|
+
lines.each do |line|
|
739
|
+
puts detab(line)
|
740
|
+
end
|
715
741
|
puts '</pre>'
|
716
742
|
end
|
717
743
|
end
|
@@ -734,8 +760,8 @@ module ReVIEW
|
|
734
760
|
puts %Q(<a id="#{normalize_id(id)}"></a>)
|
735
761
|
end
|
736
762
|
|
737
|
-
def
|
738
|
-
puts '<br
|
763
|
+
def blankline
|
764
|
+
puts '<p><br /></p>'
|
739
765
|
end
|
740
766
|
|
741
767
|
def pagebreak
|
@@ -744,7 +770,9 @@ module ReVIEW
|
|
744
770
|
|
745
771
|
def bpo(lines)
|
746
772
|
puts '<bpo>'
|
747
|
-
lines.each
|
773
|
+
lines.each do |line|
|
774
|
+
puts detab(line)
|
775
|
+
end
|
748
776
|
puts '</bpo>'
|
749
777
|
end
|
750
778
|
|
@@ -771,7 +799,6 @@ module ReVIEW
|
|
771
799
|
end
|
772
800
|
rescue KeyError
|
773
801
|
error "unknown chapter: #{id}"
|
774
|
-
nofunc_text("[UnknownChapter:#{id}]")
|
775
802
|
end
|
776
803
|
|
777
804
|
def inline_chap(id)
|
@@ -782,7 +809,6 @@ module ReVIEW
|
|
782
809
|
end
|
783
810
|
rescue KeyError
|
784
811
|
error "unknown chapter: #{id}"
|
785
|
-
nofunc_text("[UnknownChapter:#{id}]")
|
786
812
|
end
|
787
813
|
|
788
814
|
def inline_title(id)
|
@@ -794,7 +820,6 @@ module ReVIEW
|
|
794
820
|
end
|
795
821
|
rescue KeyError
|
796
822
|
error "unknown chapter: #{id}"
|
797
|
-
nofunc_text("[UnknownChapter:#{id}]")
|
798
823
|
end
|
799
824
|
|
800
825
|
def inline_fn(id)
|
@@ -803,6 +828,8 @@ module ReVIEW
|
|
803
828
|
else
|
804
829
|
%Q(<a id="fnb-#{normalize_id(id)}" href="#fn-#{normalize_id(id)}" class="noteref">*#{@chapter.footnote(id).number}</a>)
|
805
830
|
end
|
831
|
+
rescue KeyError
|
832
|
+
error "unknown footnote: #{id}"
|
806
833
|
end
|
807
834
|
|
808
835
|
def compile_ruby(base, ruby)
|
@@ -921,6 +948,8 @@ module ReVIEW
|
|
921
948
|
|
922
949
|
def inline_bib(id)
|
923
950
|
%Q(<a href="#{@book.bib_file.gsub(/\.re\Z/, ".#{@book.config['htmlext']}")}#bib-#{normalize_id(id)}">[#{@chapter.bibpaper(id).number}]</a>)
|
951
|
+
rescue KeyError
|
952
|
+
error "unknown bib: #{id}"
|
924
953
|
end
|
925
954
|
|
926
955
|
def inline_hd_chap(chap, id)
|
@@ -936,6 +965,8 @@ module ReVIEW
|
|
936
965
|
else
|
937
966
|
str
|
938
967
|
end
|
968
|
+
rescue KeyError
|
969
|
+
error "unknown headline: #{id}"
|
939
970
|
end
|
940
971
|
|
941
972
|
def column_label(id, chapter = @chapter)
|
@@ -950,6 +981,8 @@ module ReVIEW
|
|
950
981
|
else
|
951
982
|
I18n.t('column', compile_inline(chapter.column(id).caption))
|
952
983
|
end
|
984
|
+
rescue KeyError
|
985
|
+
error "unknown column: #{id}"
|
953
986
|
end
|
954
987
|
|
955
988
|
def inline_list(id)
|
@@ -967,7 +1000,6 @@ module ReVIEW
|
|
967
1000
|
end
|
968
1001
|
rescue KeyError
|
969
1002
|
error "unknown list: #{id}"
|
970
|
-
nofunc_text("[UnknownList:#{id}]")
|
971
1003
|
end
|
972
1004
|
|
973
1005
|
def inline_table(id)
|
@@ -985,7 +1017,6 @@ module ReVIEW
|
|
985
1017
|
end
|
986
1018
|
rescue KeyError
|
987
1019
|
error "unknown table: #{id}"
|
988
|
-
nofunc_text("[UnknownTable:#{id}]")
|
989
1020
|
end
|
990
1021
|
|
991
1022
|
def inline_img(id)
|
@@ -1003,7 +1034,6 @@ module ReVIEW
|
|
1003
1034
|
end
|
1004
1035
|
rescue KeyError
|
1005
1036
|
error "unknown image: #{id}"
|
1006
|
-
nofunc_text("[UnknownImage:#{id}]")
|
1007
1037
|
end
|
1008
1038
|
|
1009
1039
|
def inline_asis(str, tag)
|
@@ -1110,7 +1140,9 @@ module ReVIEW
|
|
1110
1140
|
def inline_tcy(str)
|
1111
1141
|
# 縦中横用のtcy、uprightのCSSスタイルについては電書協ガイドラインを参照
|
1112
1142
|
style = 'tcy'
|
1113
|
-
|
1143
|
+
if str.size == 1 && str.match(/[[:ascii:]]/)
|
1144
|
+
style = 'upright'
|
1145
|
+
end
|
1114
1146
|
%Q(<span class="#{style}">#{escape_html(str)}</span>)
|
1115
1147
|
end
|
1116
1148
|
|