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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +26 -4
  3. data/.travis.yml +1 -1
  4. data/NEWS.ja.md +97 -1
  5. data/NEWS.md +97 -1
  6. data/bin/review-catalog-converter +1 -1
  7. data/bin/review-check +5 -5
  8. data/bin/review-checkdep +1 -1
  9. data/bin/review-compile +5 -5
  10. data/bin/review-idgxmlmaker +16 -0
  11. data/bin/review-index +7 -7
  12. data/bin/review-preproc +9 -9
  13. data/bin/review-validate +2 -2
  14. data/bin/review-vol +5 -5
  15. data/doc/config.yml.sample +14 -6
  16. data/doc/config.yml.sample-simple +1 -1
  17. data/doc/format.ja.md +15 -5
  18. data/doc/format.md +30 -18
  19. data/doc/pdfmaker.ja.md +1 -1
  20. data/doc/pdfmaker.md +1 -1
  21. data/lib/review/book.rb +1 -1
  22. data/lib/review/book/base.rb +23 -63
  23. data/lib/review/book/chapter.rb +18 -3
  24. data/lib/review/book/compilable.rb +5 -0
  25. data/lib/review/book/index.rb +26 -65
  26. data/lib/review/book/index/item.rb +40 -0
  27. data/lib/review/book/part.rb +22 -2
  28. data/lib/review/builder.rb +60 -40
  29. data/lib/review/catalog.rb +12 -15
  30. data/lib/review/compiler.rb +68 -36
  31. data/lib/review/configure.rb +10 -7
  32. data/lib/review/epubmaker.rb +5 -2
  33. data/lib/review/htmlbuilder.rb +24 -71
  34. data/lib/review/htmlutils.rb +2 -3
  35. data/lib/review/i18n.rb +2 -2
  36. data/lib/review/idgxmlbuilder.rb +101 -55
  37. data/lib/review/idgxmlmaker.rb +184 -0
  38. data/lib/review/init-web/finish.html +10 -0
  39. data/lib/review/init-web/index.html +190 -0
  40. data/lib/review/init-web/review-layout-design.js +691 -0
  41. data/lib/review/init.rb +110 -26
  42. data/lib/review/latexbuilder.rb +76 -54
  43. data/lib/review/lineinput.rb +1 -1
  44. data/lib/review/logger.rb +4 -8
  45. data/lib/review/makerhelper.rb +6 -4
  46. data/lib/review/markdownbuilder.rb +25 -38
  47. data/lib/review/md2inaobuilder.rb +3 -5
  48. data/lib/review/pdfmaker.rb +15 -15
  49. data/lib/review/plaintextbuilder.rb +67 -76
  50. data/lib/review/preprocessor.rb +13 -13
  51. data/lib/review/rstbuilder.rb +31 -31
  52. data/lib/review/textmaker.rb +13 -3
  53. data/lib/review/textutils.rb +77 -2
  54. data/lib/review/tocparser.rb +17 -17
  55. data/lib/review/tocprinter.rb +8 -8
  56. data/lib/review/topbuilder.rb +76 -57
  57. data/lib/review/update.rb +16 -16
  58. data/lib/review/version.rb +1 -1
  59. data/lib/review/webmaker.rb +2 -2
  60. data/lib/review/yamlloader.rb +3 -0
  61. data/review.gemspec +4 -3
  62. data/samples/sample-book/README.md +7 -2
  63. data/samples/sample-book/src/.gitignore +153 -0
  64. data/samples/sample-book/src/config-jlreq.yml +6 -0
  65. data/samples/sample-book/src/lib/tasks/review.rake +20 -9
  66. data/samples/sample-book/src/lib/tasks/z01_copy_sty.rake +14 -8
  67. data/samples/syntax-book/ch03.re +3 -6
  68. data/samples/syntax-book/config-jlreq.yml +5 -0
  69. data/samples/syntax-book/lib/tasks/review.rake +7 -7
  70. data/samples/syntax-book/lib/tasks/z01_copy_sty.rake +14 -8
  71. data/templates/latex/config.erb +6 -0
  72. data/templates/latex/layout.tex.erb +1 -0
  73. data/templates/latex/review-jlreq/review-base.sty +93 -31
  74. data/templates/latex/review-jlreq/review-jlreq.cls +6 -0
  75. data/templates/latex/review-jlreq/review-style.sty +3 -0
  76. data/templates/latex/review-jsbook/README.md +39 -0
  77. data/templates/latex/review-jsbook/review-base.sty +65 -10
  78. data/templates/latex/review-jsbook/review-jsbook.cls +4 -0
  79. data/templates/latex/review-jsbook/review-style.sty +4 -1
  80. data/test/assets/test_template.tex +11 -3
  81. data/test/assets/test_template_backmatter.tex +11 -3
  82. data/test/test_book.rb +65 -19
  83. data/test/test_catalog.rb +18 -42
  84. data/test/test_catalog_converter_cmd.rb +1 -1
  85. data/test/test_epubmaker_cmd.rb +2 -2
  86. data/test/test_helper.rb +1 -1
  87. data/test/test_htmlbuilder.rb +144 -55
  88. data/test/test_i18n.rb +25 -25
  89. data/test/test_idgxmlbuilder.rb +60 -18
  90. data/test/test_image_finder.rb +6 -6
  91. data/test/test_latexbuilder.rb +128 -24
  92. data/test/test_latexbuilder_v2.rb +23 -23
  93. data/test/test_logger.rb +14 -1
  94. data/test/test_makerhelper.rb +3 -3
  95. data/test/test_markdownbuilder.rb +45 -4
  96. data/test/test_md2inaobuilder.rb +12 -2
  97. data/test/test_pdfmaker.rb +1 -1
  98. data/test/test_pdfmaker_cmd.rb +1 -1
  99. data/test/test_plaintextbuilder.rb +31 -6
  100. data/test/test_rstbuilder.rb +33 -4
  101. data/test/test_textutils.rb +109 -2
  102. data/test/test_topbuilder.rb +35 -7
  103. data/test/test_update.rb +17 -8
  104. data/test/test_yamlloader.rb +13 -0
  105. metadata +26 -2
@@ -3,8 +3,8 @@ require 'yaml'
3
3
  module ReVIEW
4
4
  class Catalog
5
5
  def initialize(file)
6
- if file.respond_to? :read
7
- @yaml = YAML.load(file.read)
6
+ if file.respond_to?(:read)
7
+ @yaml = YAML.safe_load(file.read, [Date])
8
8
  else ## as Object
9
9
  @yaml = file
10
10
  end
@@ -12,12 +12,11 @@ module ReVIEW
12
12
  end
13
13
 
14
14
  def predef
15
- return '' unless @yaml['PREDEF']
16
- @yaml['PREDEF'].join("\n")
15
+ @yaml['PREDEF'] || []
17
16
  end
18
17
 
19
18
  def chaps
20
- return '' unless @yaml['CHAPS']
19
+ return [] unless @yaml['CHAPS']
21
20
 
22
21
  @yaml['CHAPS'].map do |entry|
23
22
  if entry.is_a?(String)
@@ -25,11 +24,11 @@ module ReVIEW
25
24
  elsif entry.is_a?(Hash)
26
25
  entry.values # chaps in a part
27
26
  end
28
- end.flatten.join("\n")
27
+ end.flatten
29
28
  end
30
29
 
31
30
  def parts
32
- return '' unless @yaml['CHAPS']
31
+ return [] unless @yaml['CHAPS']
33
32
 
34
33
  part_list = @yaml['CHAPS'].map do |entry|
35
34
  if entry.is_a?(Hash)
@@ -37,7 +36,7 @@ module ReVIEW
37
36
  end
38
37
  end
39
38
 
40
- part_list.flatten.compact.join("\n")
39
+ part_list.flatten.compact
41
40
  end
42
41
 
43
42
  def replace_part(old_name, new_name)
@@ -55,13 +54,11 @@ module ReVIEW
55
54
  end
56
55
 
57
56
  def appendix
58
- return '' unless @yaml['APPENDIX']
59
- @yaml['APPENDIX'].join("\n")
57
+ @yaml['APPENDIX'] || []
60
58
  end
61
59
 
62
60
  def postdef
63
- return '' unless @yaml['POSTDEF']
64
- @yaml['POSTDEF'].join("\n")
61
+ @yaml['POSTDEF'] || []
65
62
  end
66
63
 
67
64
  def to_s
@@ -71,7 +68,7 @@ module ReVIEW
71
68
  def validate!(config, basedir)
72
69
  filenames = []
73
70
  if predef.present?
74
- filenames.concat(predef.split(/\n/))
71
+ filenames.concat(predef)
75
72
  end
76
73
  parts_with_chaps.each do |chap|
77
74
  if chap.is_a?(Hash)
@@ -86,10 +83,10 @@ module ReVIEW
86
83
  end
87
84
  end
88
85
  if appendix.present?
89
- filenames.concat(appendix.split(/\n/))
86
+ filenames.concat(appendix)
90
87
  end
91
88
  if postdef.present?
92
- filenames.concat(postdef.split(/\n/))
89
+ filenames.concat(postdef)
93
90
  end
94
91
  filenames.each do |filename|
95
92
  refile = File.join(basedir, config['contentdir'], filename)
@@ -16,6 +16,12 @@ module ReVIEW
16
16
  class Compiler
17
17
  def initialize(strategy)
18
18
  @strategy = strategy
19
+
20
+ ## commands which do not parse block lines in compiler
21
+ @non_parsed_commands = %i[embed texequation graph]
22
+
23
+ ## to decide escaping/non-escaping for text
24
+ @command_name_stack = []
19
25
  end
20
26
 
21
27
  attr_reader :strategy
@@ -66,11 +72,11 @@ module ReVIEW
66
72
  SYNTAX = {}
67
73
 
68
74
  def self.defblock(name, argc, optional = false, &block)
69
- defsyntax name, (optional ? :optional : :block), argc, &block
75
+ defsyntax(name, (optional ? :optional : :block), argc, &block)
70
76
  end
71
77
 
72
78
  def self.defsingle(name, argc, &block)
73
- defsyntax name, :line, argc, &block
79
+ defsyntax(name, :line, argc, &block)
74
80
  end
75
81
 
76
82
  def self.defsyntax(name, type, argc, &block)
@@ -217,32 +223,47 @@ module ReVIEW
217
223
 
218
224
  def do_compile
219
225
  f = LineInput.new(StringIO.new(@chapter.content))
220
- @strategy.bind self, @chapter, Location.new(@chapter.basename, f)
226
+ @strategy.bind(self, @chapter, Location.new(@chapter.basename, f))
227
+
228
+ @non_parsed_commands = %i[embed texequation graph]
229
+ if @strategy.highlight?
230
+ @non_escaped_commands = %i[list emlist listnum emlistnum cmd]
231
+ else
232
+ @non_escaped_commands = []
233
+ end
234
+ @command_name_stack = []
235
+
221
236
  tagged_section_init
222
237
  while f.next?
223
238
  case f.peek
224
239
  when /\A\#@/
225
240
  f.gets # Nothing to do
226
241
  when /\A=+[\[\s\{]/
227
- compile_headline f.gets
242
+ compile_headline(f.gets)
228
243
  when /\A\s+\*/
229
- compile_ulist f
244
+ compile_ulist(f)
230
245
  when /\A\s+\d+\./
231
- compile_olist f
246
+ compile_olist(f)
247
+ when /\A\s+:\s/
248
+ compile_dlist(f)
232
249
  when /\A\s*:\s/
233
- compile_dlist f
250
+ warn 'Definition list starting with `:` is deprecated. It should start with ` : `.'
251
+ compile_dlist(f)
234
252
  when %r{\A//\}}
235
253
  f.gets
236
254
  error 'block end seen but not opened'
237
255
  when %r{\A//[a-z]+}
256
+ # @command_name_stack.push(name) ## <- move into read_command() to use name
238
257
  name, args, lines = read_command(f)
239
258
  syntax = syntax_descriptor(name)
240
259
  unless syntax
241
260
  error "unknown command: //#{name}"
242
- compile_unknown_command args, lines
261
+ compile_unknown_command(args, lines)
262
+ @command_name_stack.pop
243
263
  next
244
264
  end
245
- compile_command syntax, args, lines
265
+ compile_command(syntax, args, lines)
266
+ @command_name_stack.pop
246
267
  when %r{\A//}
247
268
  line = f.gets
248
269
  warn "`//' seen but is not valid command: #{line.strip.inspect}"
@@ -255,7 +276,7 @@ module ReVIEW
255
276
  f.gets
256
277
  next
257
278
  end
258
- compile_paragraph f
279
+ compile_paragraph(f)
259
280
  end
260
281
  end
261
282
  close_all_tagged_section
@@ -296,7 +317,7 @@ module ReVIEW
296
317
  end
297
318
  @headline_indexs[index] += 1
298
319
  close_current_tagged_section(level)
299
- @strategy.headline level, label, caption
320
+ @strategy.headline(level, label, caption)
300
321
  end
301
322
  end
302
323
 
@@ -307,7 +328,7 @@ module ReVIEW
307
328
  end
308
329
 
309
330
  def headline(level, label, caption)
310
- @strategy.headline level, label, caption
331
+ @strategy.headline(level, label, caption)
311
332
  end
312
333
 
313
334
  def tagged_section_init
@@ -318,17 +339,17 @@ module ReVIEW
318
339
  mid = "#{tag}_begin"
319
340
  unless @strategy.respond_to?(mid)
320
341
  error "strategy does not support tagged section: #{tag}"
321
- headline level, label, caption
342
+ headline(level, label, caption)
322
343
  return
323
344
  end
324
- @tagged_section.push [tag, level]
325
- @strategy.__send__ mid, level, label, caption
345
+ @tagged_section.push([tag, level])
346
+ @strategy.__send__(mid, level, label, caption)
326
347
  end
327
348
 
328
349
  def close_tagged_section(tag, level)
329
350
  mid = "#{tag}_end"
330
351
  if @strategy.respond_to?(mid)
331
- @strategy.__send__ mid, level
352
+ @strategy.__send__(mid, level)
332
353
  else
333
354
  error "strategy does not support block op: #{mid}"
334
355
  end
@@ -347,7 +368,7 @@ module ReVIEW
347
368
 
348
369
  buf = [text(line.sub(/\*+/, '').strip)]
349
370
  f.while_match(/\A\s+(?!\*)\S/) do |cont|
350
- buf.push text(cont.strip)
371
+ buf.push(text(cont.strip))
351
372
  end
352
373
 
353
374
  line =~ /\A\s+(\*+)/
@@ -355,7 +376,7 @@ module ReVIEW
355
376
  if level == current_level
356
377
  @strategy.ul_item_end
357
378
  # body
358
- @strategy.ul_item_begin buf
379
+ @strategy.ul_item_begin(buf)
359
380
  elsif level < current_level # down
360
381
  level_diff = current_level - level
361
382
  if level_diff != 1
@@ -363,7 +384,7 @@ module ReVIEW
363
384
  end
364
385
  level = current_level
365
386
  @strategy.ul_begin { level }
366
- @strategy.ul_item_begin buf
387
+ @strategy.ul_item_begin(buf)
367
388
  elsif level > current_level # up
368
389
  level_diff = level - current_level
369
390
  level = current_level
@@ -373,7 +394,7 @@ module ReVIEW
373
394
  end
374
395
  @strategy.ul_item_end
375
396
  # body
376
- @strategy.ul_item_begin buf
397
+ @strategy.ul_item_begin(buf)
377
398
  end
378
399
  end
379
400
 
@@ -391,9 +412,9 @@ module ReVIEW
391
412
  num = line.match(/(\d+)\./)[1]
392
413
  buf = [text(line.sub(/\d+\./, '').strip)]
393
414
  f.while_match(/\A\s+(?!\d+\.)\S/) do |cont|
394
- buf.push text(cont.strip)
415
+ buf.push(text(cont.strip))
395
416
  end
396
- @strategy.ol_item buf, num
417
+ @strategy.ol_item(buf, num)
397
418
  end
398
419
  @strategy.ol_end
399
420
  end
@@ -401,7 +422,7 @@ module ReVIEW
401
422
  def compile_dlist(f)
402
423
  @strategy.dl_begin
403
424
  while /\A\s*:/ =~ f.peek
404
- @strategy.dt text(f.gets.sub(/\A\s*:/, '').strip)
425
+ @strategy.dt(text(f.gets.sub(/\A\s*:/, '').strip))
405
426
  desc = f.break(/\A(\S|\s*:|\s+\d+\.\s|\s+\*\s)/).map { |line| text(line.strip) }
406
427
  @strategy.dd(desc)
407
428
  f.skip_blank_lines
@@ -414,15 +435,16 @@ module ReVIEW
414
435
  buf = []
415
436
  f.until_match(%r{\A//|\A\#@}) do |line|
416
437
  break if line.strip.empty?
417
- buf.push text(line.sub(/^(\t+)\s*/) { |m| '<!ESCAPETAB!>' * m.size }.strip.gsub('<!ESCAPETAB!>', "\t"))
438
+ buf.push(text(line.sub(/^(\t+)\s*/) { |m| '<!ESCAPETAB!>' * m.size }.strip.gsub('<!ESCAPETAB!>', "\t")))
418
439
  end
419
- @strategy.paragraph buf
440
+ @strategy.paragraph(buf)
420
441
  end
421
442
 
422
443
  def read_command(f)
423
444
  line = f.gets
424
445
  name = line.slice(/[a-z]+/).to_sym
425
- ignore_inline = (name == :embed)
446
+ ignore_inline = @non_parsed_commands.include?(name)
447
+ @command_name_stack.push(name)
426
448
  args = parse_args(line.sub(%r{\A//[a-z]+}, '').rstrip.chomp('{'), name)
427
449
  @strategy.doc_status[name] = true
428
450
  lines = block_open?(line) ? read_block(f, ignore_inline) : nil
@@ -439,9 +461,9 @@ module ReVIEW
439
461
  buf = []
440
462
  f.until_match(%r{\A//\}}) do |line|
441
463
  if ignore_inline
442
- buf.push line
464
+ buf.push(line.chomp)
443
465
  elsif line !~ /\A\#@/
444
- buf.push text(line.rstrip)
466
+ buf.push(text(line.rstrip, true))
445
467
  end
446
468
  end
447
469
  unless %r{\A//\}} =~ f.peek
@@ -473,27 +495,27 @@ module ReVIEW
473
495
  def compile_command(syntax, args, lines)
474
496
  unless @strategy.respond_to?(syntax.name)
475
497
  error "strategy does not support command: //#{syntax.name}"
476
- compile_unknown_command args, lines
498
+ compile_unknown_command(args, lines)
477
499
  return
478
500
  end
479
501
  begin
480
- syntax.check_args args
502
+ syntax.check_args(args)
481
503
  rescue CompileError => e
482
504
  error e.message
483
505
  args = ['(NoArgument)'] * syntax.min_argc
484
506
  end
485
507
  if syntax.block_allowed?
486
- compile_block syntax, args, lines
508
+ compile_block(syntax, args, lines)
487
509
  else
488
510
  if lines
489
511
  error "block is not allowed for command //#{syntax.name}; ignore"
490
512
  end
491
- compile_single syntax, args
513
+ compile_single(syntax, args)
492
514
  end
493
515
  end
494
516
 
495
517
  def compile_unknown_command(args, lines)
496
- @strategy.unknown_command args, lines
518
+ @strategy.unknown_command(args, lines)
497
519
  end
498
520
 
499
521
  def compile_block(syntax, args, lines)
@@ -527,7 +549,12 @@ module ReVIEW
527
549
  str.gsub("\x01", '@').gsub("\x02", '\\').gsub("\x03", '{').gsub("\x04", '}')
528
550
  end
529
551
 
530
- def text(str)
552
+ def in_non_escaped_command?
553
+ current_command = @command_name_stack.last
554
+ current_command && @non_escaped_commands.include?(current_command)
555
+ end
556
+
557
+ def text(str, block_mode = false)
531
558
  return '' if str.empty?
532
559
  words = replace_fence(str).split(/(@<\w+>\{(?:[^\}\\]|\\.)*?\})/, -1)
533
560
  words.each do |w|
@@ -535,10 +562,15 @@ module ReVIEW
535
562
  error "`@<xxx>' seen but is not valid inline op: #{w}"
536
563
  end
537
564
  end
538
- result = @strategy.nofunc_text(revert_replace_fence(words.shift))
565
+ result = ''
539
566
  until words.empty?
567
+ if in_non_escaped_command? && block_mode
568
+ result << revert_replace_fence(words.shift)
569
+ else
570
+ result << @strategy.nofunc_text(revert_replace_fence(words.shift))
571
+ end
572
+ break if words.empty?
540
573
  result << compile_inline(revert_replace_fence(words.shift.gsub(/\\\}/, '}').gsub(/\\\\/, '\\')))
541
- result << @strategy.nofunc_text(revert_replace_fence(words.shift))
542
574
  end
543
575
  result
544
576
  rescue => e
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (c) 2012-2018 Masanori Kado, Masayoshi Takahashi, Kenshi Muto
2
+ # Copyright (c) 2012-2019 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
@@ -15,10 +15,10 @@ module ReVIEW
15
15
  def self.values
16
16
  conf = Configure[
17
17
  # These parameters can be overridden by YAML file.
18
- 'bookname' => 'example', # it defines epub file name also
18
+ 'bookname' => 'book', # it defines epub file name also
19
19
  'booktitle' => 'Re:VIEW Sample Book',
20
20
  'title' => nil,
21
- 'aut' => nil, # author
21
+ 'aut' => ['anonymous'], # author
22
22
  'prt' => nil, # printer(publisher)
23
23
  'asn' => nil, # associated name
24
24
  'ant' => nil, # bibliographic antecedent
@@ -32,7 +32,7 @@ module ReVIEW
32
32
  'rights' => nil, # Copyright messages
33
33
  'description' => nil, # Description
34
34
  'urnid' => "urn:uid:#{SecureRandom.uuid}", # Identifier
35
- 'stylesheet' => 'stylesheet.css', # stylesheet file
35
+ 'stylesheet' => [], # stylesheet file
36
36
  'coverfile' => nil, # content file of body of cover page
37
37
  'mytoc' => nil, # whether make own table of contents or not
38
38
  'params' => '', # specify review2html parameters
@@ -65,6 +65,7 @@ module ReVIEW
65
65
  'words_file' => nil,
66
66
  'colophon_order' => %w[aut csl trl dsr ill cov edt pbl contact prt],
67
67
  'externallink' => true,
68
+ 'join_lines_by_lang' => nil, # experimental. default should be nil
68
69
  # for IDGXML
69
70
  'tableopt' => nil,
70
71
  'listinfo' => nil,
@@ -76,8 +77,9 @@ module ReVIEW
76
77
  'image_scale2width' => true,
77
78
  'footnotetext' => nil,
78
79
  'texcommand' => 'uplatex',
79
- 'texoptions' => '-interaction=nonstopmode -file-line-error',
80
+ 'texoptions' => '-interaction=nonstopmode -file-line-error -halt-on-error',
80
81
  '_texdocumentclass' => ['review-jsbook', ''],
82
+ 'texstyle' => ['reviewmacro'],
81
83
  'dvicommand' => 'dvipdfmx',
82
84
  'dvioptions' => '-d 5 -z 9',
83
85
  # for PDFMaker
@@ -88,7 +90,8 @@ module ReVIEW
88
90
  'makeindex_sty' => nil,
89
91
  'makeindex_dic' => nil,
90
92
  'makeindex_mecab' => true,
91
- 'makeindex_mecab_opts' => '-Oyomi'
93
+ 'makeindex_mecab_opts' => '-Oyomi',
94
+ 'use_cover_nombre' => true
92
95
  },
93
96
  'imgmath_options' => {
94
97
  'format' => 'png',
@@ -99,7 +102,7 @@ module ReVIEW
99
102
  'preamble_file' => nil,
100
103
  'fontsize' => 10,
101
104
  'lineheight' => 10 * 1.2,
102
- 'pdfcrop_pixelize_cmd' => 'pdftocairo -png -r 90 -f %p -l %p -singlefile %i %O',
105
+ 'pdfcrop_pixelize_cmd' => 'pdftocairo -%t -r 90 -f %p -l %p -singlefile %i %O',
103
106
  'dvipng_cmd' => 'dvipng -T tight -z 9 -p %p -l %p -o %o %i'
104
107
  }
105
108
  ]
@@ -39,12 +39,12 @@ module ReVIEW
39
39
  end
40
40
 
41
41
  def error(msg)
42
- @logger.error "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
42
+ @logger.error msg
43
43
  exit 1
44
44
  end
45
45
 
46
46
  def warn(msg)
47
- @logger.warn "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}"
47
+ @logger.warn msg
48
48
  end
49
49
 
50
50
  def log(msg)
@@ -500,6 +500,9 @@ module ReVIEW
500
500
  def copy_stylesheet(basetmpdir)
501
501
  return if @config['stylesheet'].empty?
502
502
  @config['stylesheet'].each do |sfile|
503
+ unless File.exist?(sfile)
504
+ error "#{sfile} is not found."
505
+ end
503
506
  FileUtils.cp(sfile, basetmpdir)
504
507
  @producer.contents.push(Content.new('file' => sfile))
505
508
  end