review 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +20 -5
  3. data/.travis.yml +2 -1
  4. data/NEWS.ja.md +93 -0
  5. data/NEWS.md +77 -0
  6. data/README.md +1 -1
  7. data/bin/review +38 -12
  8. data/bin/review-compile +106 -88
  9. data/bin/review-epubmaker +6 -1
  10. data/bin/review-init +21 -1
  11. data/bin/review-textmaker +16 -0
  12. data/doc/config.yml.sample +6 -1
  13. data/doc/format.ja.md +23 -0
  14. data/doc/format.md +20 -2
  15. data/doc/quickstart.ja.md +8 -4
  16. data/doc/quickstart.md +11 -8
  17. data/lib/review/book/base.rb +29 -18
  18. data/lib/review/book/index.rb +10 -5
  19. data/lib/review/builder.rb +58 -33
  20. data/lib/review/catalog.rb +30 -0
  21. data/lib/review/compiler.rb +53 -19
  22. data/lib/review/configure.rb +15 -14
  23. data/lib/review/epubmaker.rb +15 -4
  24. data/lib/review/htmlbuilder.rb +56 -24
  25. data/lib/review/idgxmlbuilder.rb +17 -7
  26. data/lib/review/latexbuilder.rb +113 -38
  27. data/lib/review/markdownbuilder.rb +12 -5
  28. data/lib/review/md2inaobuilder.rb +3 -1
  29. data/lib/review/pdfmaker.rb +23 -9
  30. data/lib/review/plaintextbuilder.rb +683 -0
  31. data/lib/review/rstbuilder.rb +30 -10
  32. data/lib/review/textmaker.rb +158 -0
  33. data/lib/review/textutils.rb +10 -1
  34. data/lib/review/topbuilder.rb +32 -417
  35. data/lib/review/version.rb +1 -1
  36. data/lib/review/webmaker.rb +29 -8
  37. data/review.gemspec +3 -4
  38. data/templates/html/layout-xhtml1.html.erb +0 -2
  39. data/templates/latex/layout.tex.erb +6 -4
  40. data/templates/web/html/layout-xhtml1.html.erb +0 -2
  41. data/test/book_test_helper.rb +1 -0
  42. data/test/run_test.rb +1 -1
  43. data/test/sample-book/src/Rakefile +19 -3
  44. data/test/syntax-book/Rakefile +19 -3
  45. data/test/test_catalog.rb +45 -0
  46. data/test/test_compiler.rb +8 -2
  47. data/test/test_htmlbuilder.rb +22 -0
  48. data/test/test_idgxmlbuilder.rb +22 -0
  49. data/test/test_index.rb +31 -0
  50. data/test/test_latexbuilder.rb +48 -16
  51. data/test/test_plaintextbuilder.rb +390 -0
  52. data/test/test_textutils.rb +2 -0
  53. data/test/test_topbuilder.rb +23 -1
  54. metadata +13 -7
@@ -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
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2009-2017 Minero Aoki, Kenshi Muto
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
- raise CompileError, "wrong # of parameters (block command //#{@name}, expect #{@argc_spec} but #{args.size})" unless @argc_spec === args.size
63
- @checker.call(*args) if @checker
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 :linebreak, 0
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
- warn 'headline is empty.' if caption.empty?
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
- error "#{open_tag} is not opened." if prev_tag_info.nil? || prev_tag_info.first != open_tag
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
- warn 'headline is empty.' if caption.empty?
300
- @headline_indexs = @headline_indexs[0..index] if @headline_indexs.size > (index + 1)
301
- @headline_indexs[index] = 0 if @headline_indexs[index].nil?
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
- close_tagged_section(* @tagged_section.pop) until @tagged_section.empty?
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/) { |cont| buf.push text(cont.strip) }
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/) { |cont| buf.push text(cont.strip) }
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
- @strategy.dd(f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) })
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
- error "block is not allowed for command //#{syntax.name}; ignore" if lines
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
- error "block is required for //#{syntax.name}; use empty block" if syntax.block_required?
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 { |w| error "`@<xxx>' seen but is not valid inline op: #{w}" if w.scan(/@<\w+>/).size > 1 && !/\A@<raw>/.match(w) }
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
- raise CompileError, "no such inline op: #{op}" unless inline_defined?(op)
534
- raise "strategy does not support inline op: @<#{op}>" unless @strategy.respond_to?("inline_#{op}")
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
@@ -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
- 'tableopt' => nil, # for IDGXML
61
- 'listinfo' => nil, # for IDGXML
62
- 'nolf' => true, # for IDGXML
63
- 'chapref' => nil, # for IDGXML
64
- 'structuredxml' => nil, # for IDGXML
65
- 'pt_to_mm_unit' => 0.3528, # for IDGXML (DTP: 1pt = 0.3528mm, JIS: 1pt = 0.3514mm)
66
-
67
- 'footnotetext' => nil, # for LaTeX
68
- 'texcommand' => 'uplatex', # for LaTeX
69
- 'texdocumentclass' => ['jsbook', 'uplatex,oneside'], # for LaTeX
70
- 'dvicommand' => 'dvipdfmx', # for LaTeX
71
- 'dvioptions' => '-d 5', # for LaTeX
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
@@ -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.deep_merge(loader.load_file(yamlfile))
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 basetmpdir unless @config['debug']
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
- Document.parse_stream(File.new(path), ReVIEWHeaderListener.new(headlines))
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('prt').join(ReVIEW::I18n.t('names_splitter')))}</h3>\n) if @config['prt']
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']
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2008-2017 Minero Aoki, Kenshi Muto, Masayoshi Takahashi,
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 { |e| Compiler.definline(e) }
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
- @toc = ReVIEW::WEBTOCPrinter.book_to_string(@book) if @book.config.maker == 'webmaker'
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
- prefix = %Q(<span class="secno">#{prefix}</span>) if prefix
123
+ if prefix
124
+ prefix = %Q(<span class="secno">#{prefix}</span>)
125
+ end
120
126
  puts '' if level > 1
121
127
  a_id = ''
122
- a_id = %Q(<a id="h#{anchor}"></a>) if anchor
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 { |line| puts detab(line) }
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 { |line, i| puts detab((i + first_line_num).to_s.rjust(2) + ': ' + line) }
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 { |line, i| puts detab((i + first_line_num).to_s.rjust(2) + ': ' + line) }
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 { |line| puts detab(line) }
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
- return { 'class' => sprintf('width-%03dper', ($1.to_f * 100).round) } if str =~ /\Ascale=([\d.]+)\Z/
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 { |line| puts detab(line) }
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 { tr(rows.shift.map { |s| th(s) }) }
619
- rows.each { |cols| tr(cols.map { |s| td(s) }) }
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 { |line| puts detab(line) }
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 linebreak
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 { |line| puts detab(line) }
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
- style = 'upright' if str.size == 1 && str.match(/[[:ascii:]]/)
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