diff --git a/.rubocop.yml b/.rubocop.yml index 6bac217ea..02cd220c9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -255,6 +255,8 @@ Style/MethodCallWithArgsParentheses: - 'write' - 'warn' - 'error' + - 'error!' + - 'app_error' - 'raise' - 'yield' - 'source' diff --git a/bin/review-compile b/bin/review-compile index 316eff105..9bf8cecec 100755 --- a/bin/review-compile +++ b/bin/review-compile @@ -16,6 +16,8 @@ require 'fileutils' require 'optparse' require 'yaml' +include ReVIEW::Loggable + DEFAULT_CONFIG_FILENAME = 'config.yml'.freeze def main @@ -47,17 +49,17 @@ def _main begin loader = ReVIEW::YAMLLoader.new if @config['yaml'] - error "#{@config['yaml']} not found." unless File.exist?(@config['yaml']) + error! "#{@config['yaml']} not found." unless File.exist?(@config['yaml']) begin @config.deep_merge!(loader.load_file(@config['yaml'])) rescue => e - error "yaml error #{e.message}" + error! "yaml error #{e.message}" end elsif File.exist?(DEFAULT_CONFIG_FILENAME) begin @config.deep_merge!(loader.load_file(DEFAULT_CONFIG_FILENAME)) rescue => e - error "yaml error #{e.message}" + error! "yaml error #{e.message}" end end @@ -73,12 +75,12 @@ def _main case @mode when :files - error('no input') if ARGV.empty? + error!('no input') if ARGV.empty? @basedir = File.dirname(ARGV[0]) book = ReVIEW::Book::Base.new(@basedir, config: @config) ARGV.each do |item| - error("file not found: #{item}") unless File.exist?(File.join(book.config['contentdir'], item)) + error!("file not found: #{item}") unless File.exist?(File.join(book.config['contentdir'], item)) chap_name = File.basename(item, '.*') chap = book.chapter(chap_name) compiler = ReVIEW::Compiler.new(load_builder_class(@target, @check_only)) @@ -105,7 +107,7 @@ def _main raise "must not happen: #{@mode}" end rescue ReVIEW::ApplicationError => e - error(e.message) + error! e.message end end @@ -164,15 +166,6 @@ def parse_opts end end -def error(msg) - @logger.error msg - exit 1 -end - -def warn(msg) - @logger.warn msg -end - def load_builder_class(target, strict) require "review/#{target}builder" ReVIEW.const_get("#{target.upcase}Builder").new(strict) diff --git a/lib/review/builder.rb b/lib/review/builder.rb index 8f0b2e91f..94be07c22 100644 --- a/lib/review/builder.rb +++ b/lib/review/builder.rb @@ -11,6 +11,7 @@ require 'review/compiler' require 'review/sec_counter' require 'review/img_math' +require 'review/loggable' require 'stringio' require 'fileutils' require 'tempfile' @@ -19,6 +20,7 @@ module ReVIEW class Builder include TextUtils + include Loggable CAPTION_TITLES = Compiler.minicolumn_names @@ -31,6 +33,7 @@ def post_paragraph end attr_accessor :doc_status, :previous_list_type + attr_reader :location def initialize(strict = false, *_args, img_math: nil) @strict = strict @@ -76,7 +79,7 @@ def bind(compiler, chapter, location) begin require 'unicode/eaw' rescue LoadError - warn 'not found unicode/eaw. disabled join_lines_by_lang feature.' + warn 'not found unicode/eaw. disabled join_lines_by_lang feature.', location: @location @book.config['join_lines_by_lang'] = nil end end @@ -101,7 +104,7 @@ def solve_nest(s) def check_nest if @children && !@children.empty? - error "//beginchild of #{@children.reverse.join(',')} misses //endchild" + app_error "//beginchild of #{@children.reverse.join(',')} misses //endchild" end end @@ -161,7 +164,7 @@ def list(lines, id, caption, lang = nil) list_body(id, lines, lang) list_header(id, caption, lang) unless caption_top?('list') rescue KeyError - error "no such list: #{id}" + app_error "no such list: #{id}" end end @@ -171,7 +174,7 @@ def listnum(lines, id, caption, lang = nil) listnum_body(lines, lang) list_header(id, caption, lang) unless caption_top?('list') rescue KeyError - error "no such list: #{id}" + app_error "no such list: #{id}" end end @@ -185,7 +188,7 @@ def image(lines, id, caption, metric = nil) if @chapter.image_bound?(id) image_image(id, caption, metric) else - warn "image not bound: #{id}" if @strict + warn "image not bound: #{id}", location: @location if @strict image_dummy(id, caption, lines) end end @@ -203,7 +206,7 @@ def table(lines, id = nil, caption = nil) table_header(id, caption) end rescue KeyError - error "no such table: #{id}" + app_error "no such table: #{id}" end end @@ -218,7 +221,7 @@ def table_row_separator_regexp when 'verticalbar' Regexp.new('\s*\\' + escape('|') + '\s*') else - error "Unknown value for 'table_row_separator', shold be: tabs, singletab, spaces, verticalbar" + app_error "Unknown value for 'table_row_separator', shold be: tabs, singletab, spaces, verticalbar" end end @@ -233,7 +236,7 @@ def parse_table_rows(lines) rows.push(line.strip.split(table_row_separator_regexp).map { |s| s.sub(/\A\./, '') }) end rows = adjust_n_cols(rows) - error 'no rows in the table' if rows.empty? + app_error 'no rows in the table' if rows.empty? [sepidx, rows] end @@ -294,19 +297,19 @@ def compile_inline(s) def inline_chapref(id) compile_inline(@book.chapter_index.display_string(id)) rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" end def inline_chap(id) @book.chapter_index.number(id) rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" end def inline_title(id) compile_inline(@book.chapter_index.title(id)) rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" end def inline_list(id) @@ -317,7 +320,7 @@ def inline_list(id) %Q(#{I18n.t('list')}#{I18n.t('format_number_without_chapter', [chapter.list(id).number])}) end rescue KeyError - error "unknown list: #{id}" + app_error "unknown list: #{id}" end def inline_img(id) @@ -328,7 +331,7 @@ def inline_img(id) %Q(#{I18n.t('image')}#{I18n.t('format_number_without_chapter', [chapter.image(id).number])}) end rescue KeyError - error "unknown image: #{id}" + app_error "unknown image: #{id}" end def inline_imgref(id) @@ -349,7 +352,7 @@ def inline_table(id) %Q(#{I18n.t('table')}#{I18n.t('format_number_without_chapter', [chapter.table(id).number])}) end rescue KeyError - error "unknown table: #{id}" + app_error "unknown table: #{id}" end def inline_eq(id) @@ -360,13 +363,13 @@ def inline_eq(id) %Q(#{I18n.t('equation')}#{I18n.t('format_number_without_chapter', [chapter.equation(id).number])}) end rescue KeyError - error "unknown equation: #{id}" + app_error "unknown equation: #{id}" end def inline_fn(id) @chapter.footnote(id).content rescue KeyError - error "unknown footnote: #{id}" + app_error "unknown footnote: #{id}" end def inline_bou(str) @@ -422,7 +425,7 @@ def inline_hd(id) inline_hd_chap(@chapter, id) end rescue KeyError - error "unknown headline: #{id}" + app_error "unknown headline: #{id}" end def inline_column(id) @@ -436,7 +439,7 @@ def inline_column(id) inline_column_chap(@chapter, id) end rescue KeyError - error "unknown column: #{id}" + app_error "unknown column: #{id}" end def inline_column_chap(chapter, id) @@ -460,7 +463,7 @@ def inline_w(s) if translated escape(translated) else - warn "word not bound: #{s}" + warn "word not bound: #{s}", location: @location escape("[missing word: #{s}]") end end @@ -496,18 +499,6 @@ def embed(lines, arg = nil) end end - def warn(msg) - @logger.warn "#{@location}: #{msg}" - end - - def error(msg) - if msg =~ /:\d+: error: / - raise ApplicationError, msg - else - raise ApplicationError, "#{@location}: error: #{msg}" - end - end - def handle_metric(str) str end @@ -582,7 +573,7 @@ def #{name}_end def check_nested_minicolumn if @doc_status[:minicolumn] - error "#{@location}: nested mini-column is not allowed" + app_error "#{@location}: nested mini-column is not allowed" end end @@ -735,7 +726,7 @@ def escape(str) def beginchild @children ||= [] unless @previous_list_type - error "//beginchild is shown, but previous element isn't ul, ol, or dl" + app_error "//beginchild is shown, but previous element isn't ul, ol, or dl" end puts "\x01→#{@previous_list_type}←\x01" @children.push(@previous_list_type) @@ -743,7 +734,7 @@ def beginchild def endchild if @children.nil? || @children.empty? - error "//endchild is shown, but any opened //beginchild doesn't exist" + app_error "//endchild is shown, but any opened //beginchild doesn't exist" else puts "\x01→/#{@children.pop}←\x01" end @@ -751,7 +742,7 @@ def endchild def caption_top?(type) unless %w[top bottom].include?(@book.config['caption_position'][type]) - warn("invalid caption_position/#{type} parameter. 'top' is assumed") + warn "invalid caption_position/#{type} parameter. 'top' is assumed", location: @location end @book.config['caption_position'][type] != 'bottom' end diff --git a/lib/review/compiler.rb b/lib/review/compiler.rb index 59c51971c..2568092fb 100644 --- a/lib/review/compiler.rb +++ b/lib/review/compiler.rb @@ -10,10 +10,13 @@ require 'review/preprocessor' require 'review/exception' require 'review/location' +require 'review/loggable' require 'strscan' module ReVIEW class Compiler + include Loggable + MAX_HEADLINE_LEVEL = 6 def initialize(builder) @@ -24,6 +27,12 @@ def initialize(builder) ## to decide escaping/non-escaping for text @command_name_stack = [] + + @logger = ReVIEW.logger + + @ignore_errors = builder.is_a?(ReVIEW::IndexBuilder) + + @compile_errors = nil end attr_reader :builder, :previous_list_type @@ -44,6 +53,10 @@ def non_escaped_commands def compile(chap) @chapter = chap do_compile + if @compile_errors + raise ApplicationError, "#{location.filename} cannot be compiled." + end + @builder.result end @@ -283,7 +296,7 @@ def do_compile compile_dlist(f) @builder.previous_list_type = 'dl' when /\A\s*:\s/ - warn 'Definition list starting with `:` is deprecated. It should start with ` : `.' + warn 'Definition list starting with `:` is deprecated. It should start with ` : `.', location: location compile_dlist(f) @builder.previous_list_type = 'dl' when %r{\A//\}} @@ -292,7 +305,7 @@ def do_compile compile_minicolumn_end else f.gets - error 'block end seen but not opened' + error 'block end seen but not opened', location: location end when %r{\A//[a-z]+} line = f.peek @@ -307,8 +320,7 @@ def do_compile name, args, lines = read_command(f) syntax = syntax_descriptor(name) unless syntax - error "unknown command: //#{name}" - compile_unknown_command(args, lines) + error "unknown command: //#{name}", location: location @command_name_stack.pop next end @@ -318,9 +330,9 @@ def do_compile @builder.previous_list_type = nil when %r{\A//} line = f.gets - warn "`//' seen but is not valid command: #{line.strip.inspect}" + warn "`//' seen but is not valid command: #{line.strip.inspect}", location: location if block_open?(line) - warn 'skipping block...' + warn 'skipping block...', location: location read_block(f, false) end @builder.previous_list_type = nil @@ -335,17 +347,17 @@ def do_compile end close_all_tagged_section rescue SyntaxError => e - error e + error e, location: location end def compile_minicolumn_begin(name, caption = nil) mid = "#{name}_begin" unless @builder.respond_to?(mid) - error "strategy does not support minicolumn: #{name}" + error "strategy does not support minicolumn: #{name}", location: location end if @minicolumn_name - error "minicolumn cannot be nested: #{name}" + error "minicolumn cannot be nested: #{name}", location: location return end @minicolumn_name = name @@ -355,7 +367,7 @@ def compile_minicolumn_begin(name, caption = nil) def compile_minicolumn_end unless @minicolumn_name - error "minicolumn is not used: #{name}" + error "minicolumn is not used: #{name}", location: location return end name = @minicolumn_name @@ -382,19 +394,19 @@ def compile_headline(line) open_tag = tag[1..-1] prev_tag_info = @tagged_section.pop if prev_tag_info.nil? || prev_tag_info.first != open_tag - error "#{open_tag} is not opened." + error "#{open_tag} is not opened.", location: location end close_tagged_section(*prev_tag_info) else if caption.empty? - warn 'headline is empty.' + warn 'headline is empty.', location: location end close_current_tagged_section(level) open_tagged_section(tag, level, label, caption) end else if caption.empty? - warn 'headline is empty.' + warn 'headline is empty.', location: location end if @headline_indexs.size > (index + 1) @headline_indexs = @headline_indexs[0..index] @@ -425,7 +437,7 @@ def tagged_section_init def open_tagged_section(tag, level, label, caption) mid = "#{tag}_begin" unless @builder.respond_to?(mid) - error "builder does not support tagged section: #{tag}" + error "builder does not support tagged section: #{tag}", location: location headline(level, label, caption) return end @@ -438,7 +450,7 @@ def close_tagged_section(tag, level) if @builder.respond_to?(mid) @builder.__send__(mid, level) else - error "builder does not support block op: #{mid}" + error "builder does not support block op: #{mid}", location: location end end @@ -467,7 +479,7 @@ def compile_ulist(f) elsif level < current_level # down level_diff = current_level - level if level_diff != 1 - error 'too many *.' + error 'too many *.', location: location end level = current_level @builder.ul_begin { level } @@ -561,7 +573,7 @@ def read_block(f, ignore_inline) end end unless f.peek.to_s.start_with?('//}') - error "unexpected EOF (block begins at: #{head})" + error "unexpected EOF (block begins at: #{head})", location: location return buf end f.gets # discard terminator @@ -581,7 +593,7 @@ def parse_args(str, _name = nil) words << w2 end unless scanner.eos? - error "argument syntax error: #{scanner.rest} in #{str.inspect}" + error "argument syntax error: #{scanner.rest} in #{str.inspect}", location: location return [] end words @@ -589,37 +601,32 @@ def parse_args(str, _name = nil) def compile_command(syntax, args, lines) unless @builder.respond_to?(syntax.name) - error "builder does not support command: //#{syntax.name}" - compile_unknown_command(args, lines) + error "builder does not support command: //#{syntax.name}", location: location return end begin syntax.check_args(args) rescue CompileError => e - error e.message + error e.message, location: location args = ['(NoArgument)'] * syntax.min_argc end if syntax.block_allowed? compile_block(syntax, args, lines) else if lines - error "block is not allowed for command //#{syntax.name}; ignore" + error "block is not allowed for command //#{syntax.name}; ignore", location: location end compile_single(syntax, args) end end - def compile_unknown_command(args, lines) - @builder.unknown_command(args, lines) - end - def compile_block(syntax, args, lines) @builder.__send__(syntax.name, (lines || default_block(syntax)), *args) end def default_block(syntax) if syntax.block_required? - error "block is required for //#{syntax.name}; use empty block" + error "block is required for //#{syntax.name}; use empty block", location: location end [] end @@ -633,7 +640,7 @@ def replace_fence(str) op = $1 arg = $3 if arg =~ /[\x01\x02\x03\x04]/ - error "invalid character in '#{str}'" + error "invalid character in '#{str}'", location: location end replaced = arg.tr('@', "\x01").tr('\\', "\x02").tr('{', "\x03").tr('}', "\x04") "@<#{op}>{#{replaced}}" @@ -655,7 +662,7 @@ def text(str, block_mode = false) words = replace_fence(str).split(/(@<\w+>\{(?:[^}\\]|\\.)*?\})/, -1) words.each do |w| if w.scan(/@<\w+>/).size > 1 && !/\A@/.match(w) - error "`@' seen but is not valid inline op: #{w}" + error "`@' seen but is not valid inline op: #{w}", location: location end end result = '' @@ -671,7 +678,7 @@ def text(str, block_mode = false) end result rescue => e - error e.message + error e.message, location: location end public :text # called from builder @@ -686,7 +693,7 @@ def compile_inline(str) @builder.__send__("inline_#{op}", arg) rescue => e - error e.message + error e.message, location: location @builder.nofunc_text(str) end @@ -698,12 +705,20 @@ def minicolumn_block_name?(name) @builder.minicolumn_block_name?(name) end - def warn(msg) - @builder.warn msg + def ignore_errors? + @ignore_errors end - def error(msg) - @builder.error msg + def location + @builder.location + end + + ## override + def error(msg, location: nil) + return if ignore_errors? # for IndexBuilder + + @compile_errors = true + super end end end # module ReVIEW diff --git a/lib/review/epubmaker.rb b/lib/review/epubmaker.rb index d851cfc9b..9336d8942 100644 --- a/lib/review/epubmaker.rb +++ b/lib/review/epubmaker.rb @@ -27,10 +27,12 @@ require 'review/epubmaker/epubv3' require 'review/epubmaker/reviewheaderlistener' require 'review/makerhelper' +require 'review/loggable' module ReVIEW class EPUBMaker include MakerHelper + include Loggable include ReVIEW::CallHook def initialize @@ -42,19 +44,6 @@ def initialize @basedir = nil end - def error(msg) - @logger.error msg - exit 1 - end - - def warn(msg) - @logger.warn msg - end - - def log(msg) - @logger.debug(msg) - end - def self.execute(*args) self.new.execute(*args) end @@ -84,14 +73,14 @@ def parse_opts(args) def execute(*args) cmd_config, yamlfile, exportfile = parse_opts(args) - error "#{yamlfile} not found." unless File.exist?(yamlfile) + error! "#{yamlfile} not found." unless File.exist?(yamlfile) @config = ReVIEW::Configure.create(maker: 'epubmaker', yamlfile: yamlfile, config: cmd_config) @producer = ReVIEW::EPUBMaker::Producer.new(@config) update_log_level - log("Loaded yaml file (#{yamlfile}).") + debug("Loaded yaml file (#{yamlfile}).") @basedir = File.absolute_path(File.dirname(yamlfile)) produce(yamlfile, exportfile) @@ -129,12 +118,10 @@ def produce(yamlfile, bookname = nil) booktmpname = "#{bookname}-epub" @img_math = ReVIEW::ImgMath.new(@config) - begin - @config.check_version(ReVIEW::VERSION) - rescue ReVIEW::ConfigError => e + unless @config.check_version(ReVIEW::VERSION, exception: false) warn e.message end - log("#{bookname}.epub will be created.") + debug("#{bookname}.epub will be created.") FileUtils.rm_f("#{bookname}.epub") if @config['debug'] @@ -145,7 +132,7 @@ def produce(yamlfile, bookname = nil) basetmpdir = build_path begin - log("Created first temporary directory as #{basetmpdir}.") + debug("Created first temporary directory as #{basetmpdir}.") call_hook('hook_beforeprocess', basetmpdir, base_dir: @basedir) @@ -192,14 +179,14 @@ def produce(yamlfile, bookname = nil) epubtmpdir = File.join(basetmpdir, booktmpname) Dir.mkdir(epubtmpdir) end - log('Call ePUB producer.') + debug('Call ePUB producer.') @producer.produce("#{bookname}.epub", basetmpdir, epubtmpdir, base_dir: @basedir) - log('Finished.') + debug('Finished.') @logger.success("built #{bookname}.epub") rescue ApplicationError => e raise if @config['debug'] - error(e.message) + error! e.message ensure FileUtils.remove_entry_secure(basetmpdir) unless @config['debug'] end @@ -245,7 +232,7 @@ def copy_images(resdir, destdir, allow_exts = nil) end basedir = File.dirname(file) FileUtils.mkdir_p(File.join(destdir, basedir)) - log("Copy #{file} to the temporary directory.") + debug("Copy #{file} to the temporary directory.") FileUtils.cp(file, File.join(destdir, basedir), preserve: true) end else @@ -270,7 +257,7 @@ def recursive_copy_files(resdir, destdir, allow_exts) recursive_copy_files(File.join(resdir, fname), File.join(destdir, fname), allow_exts) elsif fname =~ /\.(#{allow_exts.join('|')})\Z/i FileUtils.mkdir_p(destdir) - log("Copy #{resdir}/#{fname} to the temporary directory.") + debug("Copy #{resdir}/#{fname} to the temporary directory.") FileUtils.cp(File.join(resdir, fname), destdir, preserve: true) end end @@ -280,8 +267,7 @@ def recursive_copy_files(resdir, destdir, allow_exts) def check_compile_status return unless @compile_errors - $stderr.puts 'compile error, No EPUB file output.' - exit 1 + error! 'compile error, No EPUB file output.' end def build_body(basetmpdir, yamlfile) @@ -323,7 +309,7 @@ def build_body(basetmpdir, yamlfile) end def build_part(part, basetmpdir, htmlfile) - log("Create #{htmlfile} from a template.") + debug("Create #{htmlfile} from a template.") File.open(File.join(basetmpdir, htmlfile), 'w') do |f| @part_number = part.number @part_title = part.name.strip @@ -384,7 +370,7 @@ def build_chap(chap, base_path, basetmpdir, ispart) htmlfile = "#{id}.#{@config['htmlext']}" write_buildlogtxt(basetmpdir, htmlfile, filename) - log("Create #{htmlfile} from #{filename}.") + debug("Create #{htmlfile} from #{filename}.") if @config['params'].present? warn %Q('params:' in config.yml is obsoleted.) @@ -398,8 +384,8 @@ def build_chap(chap, base_path, basetmpdir, ispart) remove_hidden_title(basetmpdir, htmlfile) rescue => e @compile_errors = true - warn "compile error in #{filename} (#{e.class})" - warn e.message + error "compile error in #{filename} (#{e.class})" + error e.message end end @@ -480,7 +466,7 @@ def push_contents(_basetmpdir) @htmltoc.each_item do |level, file, title, args| next if level.to_i > @config['toclevel'] && args[:force_include].nil? - log("Push #{file} to ePUB contents.") + debug("Push #{file} to ePUB contents.") params = { file: file, level: level.to_i, @@ -504,7 +490,7 @@ def copy_stylesheet(basetmpdir) @config['stylesheet'].each do |sfile| unless File.exist?(sfile) - error "stylesheet: #{sfile} is not found." + error! "stylesheet: #{sfile} is not found." end FileUtils.cp(sfile, basetmpdir, preserve: true) @producer.contents.push(ReVIEW::EPUBMaker::Content.new(file: sfile)) @@ -514,7 +500,7 @@ def copy_stylesheet(basetmpdir) def copy_static_file(configname, destdir, destfilename: nil) destfilename ||= @config[configname] unless File.exist?(@config[configname]) - error "#{configname}: #{@config[configname]} is not found." + error! "#{configname}: #{@config[configname]} is not found." end FileUtils.cp(@config[configname], File.join(destdir, destfilename), preserve: true) diff --git a/lib/review/epubmaker/producer.rb b/lib/review/epubmaker/producer.rb index 3688f9e49..17ce891fd 100644 --- a/lib/review/epubmaker/producer.rb +++ b/lib/review/epubmaker/producer.rb @@ -25,11 +25,14 @@ require 'review/i18n' require 'review/configure' require 'review/extentions/hash' +require 'review/loggable' module ReVIEW class EPUBMaker # EPUBMaker produces EPUB file. class Producer + include Loggable + # Array of content objects. attr_accessor :contents # Parameter hash. @@ -37,10 +40,6 @@ class Producer # Message resource object. attr_reader :res - def warn(msg) - @logger.warn(msg) - end - # Construct producer object. # +config+ takes initial parameter hash. def initialize(config) diff --git a/lib/review/exception.rb b/lib/review/exception.rb index ca0d781c9..e53f5fd95 100644 --- a/lib/review/exception.rb +++ b/lib/review/exception.rb @@ -22,4 +22,11 @@ class SyntaxError < CompileError; end class FileNotFound < ApplicationError; end class KeyError < CompileError; end + + class BuildError < ApplicationError + def initialize(msg, location: nil) + @location = location + super(msg) + end + end end diff --git a/lib/review/htmlbuilder.rb b/lib/review/htmlbuilder.rb index 62d94007c..5dc8b4385 100644 --- a/lib/review/htmlbuilder.rb +++ b/lib/review/htmlbuilder.rb @@ -44,8 +44,6 @@ def extname def builder_init_file @noindent = nil @ol_num = nil - @warns = [] - @errors = [] @chapter.book.image_types = %w[.png .jpg .jpeg .gif .svg] @column = 0 @sec_counter = SecCounter.new(5, @chapter) @@ -78,7 +76,7 @@ def layoutfile if File.exist?(layout_file) if ENV['REVIEW_SAFE_MODE'].to_i & 4 > 0 - warn %Q(user's layout is prohibited in safe mode. ignored.) + warn %Q(user's layout is prohibited in safe mode. ignored.), location: location layout_file = File.expand_path(htmlfilename, ReVIEW::Template::TEMPLATE_DIR) end else @@ -618,7 +616,7 @@ def texequation_body(lines) require 'math_ml' require 'math_ml/symbol/character_reference' rescue LoadError - error 'not found math_ml' + app_error 'not found math_ml' end p = MathML::LaTeX::Parser.new(symbol: MathML::Symbol::CharacterReference) print p.parse(lines.join("\n") + "\n", true) @@ -676,7 +674,7 @@ def image_image(id, caption, metric) end def image_dummy(id, caption, lines) - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location puts %Q(
) image_header(id, caption) if caption_top?('image') puts %Q(
)
@@ -740,7 +738,7 @@ def table_end
 
     def imgtable(lines, id, caption = nil, metric = nil)
       unless @chapter.image_bound?(id)
-        warn "image not bound: #{id}"
+        warn "image not bound: #{id}", location: location
         image_dummy(id, caption, lines)
         return
       end
@@ -757,7 +755,7 @@ def imgtable(lines, id, caption = nil, metric = nil)
           table_header(id, caption)
         end
       rescue KeyError
-        error "no such table: #{id}"
+        app_error "no such table: #{id}"
       end
 
       puts '
' @@ -813,7 +811,7 @@ def indepimage(lines, id, caption = '', metric = nil) begin puts %Q(#{escape(compile_inline(caption))}) rescue - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location if lines puts %Q(
)
           lines.each do |line|
@@ -866,7 +864,7 @@ def inline_labelref(idref)
     alias_method :inline_ref, :inline_labelref
 
     def inline_pageref(id)
-      error "pageref op is unsupported on this builder: #{id}"
+      app_error "pageref op is unsupported on this builder: #{id}"
     end
 
     def inline_chapref(id)
@@ -877,7 +875,7 @@ def inline_chapref(id)
         title
       end
     rescue KeyError
-      error "unknown chapter: #{id}"
+      app_error "unknown chapter: #{id}"
     end
 
     def inline_chap(id)
@@ -887,7 +885,7 @@ def inline_chap(id)
         @book.chapter_index.number(id)
       end
     rescue KeyError
-      error "unknown chapter: #{id}"
+      app_error "unknown chapter: #{id}"
     end
 
     def inline_title(id)
@@ -898,7 +896,7 @@ def inline_title(id)
         title
       end
     rescue KeyError
-      error "unknown chapter: #{id}"
+      app_error "unknown chapter: #{id}"
     end
 
     def inline_fn(id)
@@ -908,7 +906,7 @@ def inline_fn(id)
         %Q(*#{@chapter.footnote(id).number})
       end
     rescue KeyError
-      error "unknown footnote: #{id}"
+      app_error "unknown footnote: #{id}"
     end
 
     def compile_ruby(base, ruby)
@@ -990,7 +988,7 @@ def inline_m(str)
           require 'math_ml'
           require 'math_ml/symbol/character_reference'
         rescue LoadError
-          error 'not found math_ml'
+          app_error 'not found math_ml'
         end
         parser = MathML::LaTeX::Parser.new(symbol: MathML::Symbol::CharacterReference)
         %Q(#{parser.parse(str, nil)})
@@ -1036,7 +1034,7 @@ def bibpaper_bibpaper(_id, _caption, lines)
     def inline_bib(id)
       %Q([#{@chapter.bibpaper(id).number}])
     rescue KeyError
-      error "unknown bib: #{id}"
+      app_error "unknown bib: #{id}"
     end
 
     def inline_hd_chap(chap, id)
@@ -1053,7 +1051,7 @@ def inline_hd_chap(chap, id)
         str
       end
     rescue KeyError
-      error "unknown headline: #{id}"
+      app_error "unknown headline: #{id}"
     end
 
     def column_label(id, chapter = @chapter)
@@ -1069,7 +1067,7 @@ def inline_column_chap(chapter, id)
         I18n.t('column', compile_inline(chapter.column(id).caption))
       end
     rescue KeyError
-      error "unknown column: #{id}"
+      app_error "unknown column: #{id}"
     end
 
     def inline_list(id)
@@ -1196,7 +1194,7 @@ def inline_icon(id)
       begin
         %Q([#{id}])
       rescue
-        warn "image not bound: #{id}"
+        warn "image not bound: #{id}", location: location
         %Q(
missing image: #{id}
) end end diff --git a/lib/review/idgxmlbuilder.rb b/lib/review/idgxmlbuilder.rb index 626ebac3d..2638b073a 100644 --- a/lib/review/idgxmlbuilder.rb +++ b/lib/review/idgxmlbuilder.rb @@ -265,7 +265,7 @@ def inline_column_chap(chapter, id) I18n.t('column', compile_inline(chapter.column(id).caption)) end rescue KeyError - error "unknown column: #{id}" + app_error "unknown column: #{id}" end def inline_list(id) @@ -436,7 +436,7 @@ def image_dummy(id, caption, lines) print '
' image_header(id, caption) unless caption_top?('image') puts '' - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location end def image_header(id, caption) @@ -502,7 +502,7 @@ def table(lines, id = nil, caption = nil) table_header(id, caption) end rescue KeyError - error "no such table: #{id}" + app_error "no such table: #{id}" end puts '' @tsize = nil @@ -524,7 +524,7 @@ def parse_table_rows(lines) col2 = rows[rows.length - 1].split(table_row_separator_regexp).length @col = col2 if col2 > @col end - error 'no rows in the table' if rows.empty? + app_error 'no rows in the table' if rows.empty? [sepidx, rows] end @@ -539,11 +539,11 @@ def table_rows(sepidx, rows) cellwidth.size.times do |n| cellwidth[n] = cellwidth[n].to_f / @book.config['pt_to_mm_unit'].to_f totallength += cellwidth[n] - warn "total length exceeds limit for table: #{@table_id}" if totallength > @tablewidth + warn "total length exceeds limit for table: #{@table_id}", location: location if totallength > @tablewidth end if cellwidth.size < @col cw = (@tablewidth - totallength) / (@col - cellwidth.size) - warn "auto cell sizing exceeds limit for table: #{@table_id}" if cw <= 0 + warn "auto cell sizing exceeds limit for table: #{@table_id}", location: location if cw <= 0 (cellwidth.size..(@col - 1)).each { |i| cellwidth[i] = cw } end end @@ -627,7 +627,7 @@ def imgtable(lines, id, caption = nil, metric = nil) end puts '' else - warn "image not bound: #{id}" if @strict + warn "image not bound: #{id}", location: location if @strict image_dummy(id, caption, lines) end end @@ -656,7 +656,7 @@ def footnote(id, str) def inline_fn(id) %Q(#{compile_inline(@chapter.footnote(id).content.strip)}) rescue KeyError - error "unknown footnote: #{id}" + app_error "unknown footnote: #{id}" end def compile_ruby(base, ruby) @@ -718,7 +718,7 @@ def inline_maru(str) sprintf('&#x%x;', 9392 + str[0] - 65) end else - error "can't parse maru: #{str}" + app_error "can't parse maru: #{str}" end end @@ -780,7 +780,7 @@ def inline_icon(id) begin %Q() rescue - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location '' end end @@ -1127,7 +1127,7 @@ def indepimage(_lines, id, caption = nil, metric = nil) begin puts %Q() rescue - warn %Q(image not bound: #{id}) + warn %Q(image not bound: #{id}), location: location end unless caption_top?('image') puts %Q(#{compile_inline(caption)}) if caption.present? @@ -1188,7 +1188,7 @@ def inline_chapref(id) if chs2.size == 3 chs = chs2 else - error '--chapsplitter must have exactly 3 parameters with comma.' + app_error '--chapsplitter must have exactly 3 parameters with comma.' end end s = "#{chs[0]}#{@book.chapter_index.number(id)}#{chs[1]}#{@book.chapter_index.title(id)}#{chs[2]}" @@ -1206,7 +1206,7 @@ def inline_chapref(id) end end rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" end def inline_chap(id) @@ -1216,7 +1216,7 @@ def inline_chap(id) @book.chapter_index.number(id) end rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" end def inline_title(id) @@ -1227,7 +1227,7 @@ def inline_title(id) title end rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" end def source(lines, caption = nil, lang = nil) @@ -1270,7 +1270,7 @@ def bibpaper_bibpaper(_id, _caption, lines) def inline_bib(id) %Q([#{@chapter.bibpaper(id).number}]) rescue KeyError - error "unknown bib: #{id}" + app_error "unknown bib: #{id}" end def inline_hd_chap(chap, id) @@ -1281,7 +1281,7 @@ def inline_hd_chap(chap, id) I18n.t('hd_quote_without_number', compile_inline(chap.headline(id).caption)) end rescue KeyError - error "unknown headline: #{id}" + app_error "unknown headline: #{id}" end def inline_recipe(id) diff --git a/lib/review/idgxmlmaker.rb b/lib/review/idgxmlmaker.rb index 6cb6cf0ae..b9c0817d5 100644 --- a/lib/review/idgxmlmaker.rb +++ b/lib/review/idgxmlmaker.rb @@ -16,10 +16,12 @@ require 'review/idgxmlbuilder' require 'review/version' require 'review/makerhelper' +require 'review/loggable' module ReVIEW class IDGXMLMaker include MakerHelper + include Loggable attr_accessor :config, :basedir @@ -27,15 +29,7 @@ def initialize @basedir = nil @logger = ReVIEW.logger @plaintext = nil - end - - def error(msg) - @logger.error "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}" - exit 1 - end - - def warn(msg) - @logger.warn "#{File.basename($PROGRAM_NAME, '.*')}: #{msg}" + @compile_errors = nil end def self.execute(*args) @@ -78,7 +72,7 @@ def remove_old_files(path) def execute(*args) cmd_config, yamlfile = parse_opts(args) - error "#{yamlfile} not found." unless File.exist?(yamlfile) + error! "#{yamlfile} not found." unless File.exist?(yamlfile) @config = ReVIEW::Configure.create(maker: 'idgxmlmaker', yamlfile: yamlfile, @@ -90,7 +84,7 @@ def execute(*args) rescue ApplicationError => e raise if @config['debug'] - error(e.message) + error! e.message end end @@ -106,6 +100,10 @@ def generate_idgxml_files(yamlfile) end build_body(@path, yamlfile) + + if @compile_errors + app_error 'compile error, No IDGXML file output.' + end end def apply_filter(xmlfile) @@ -180,8 +178,9 @@ def build_chap(chap, base_path, basetmpdir, ispart) @converter.convert(filename, File.join(basetmpdir, xmlfile)) apply_filter(File.join(basetmpdir, xmlfile)) rescue => e - warn "compile error in #{filename} (#{e.class})" - warn e.message + @compile_errors = true + error "compile error in #{filename} (#{e.class})" + error e.message end end end diff --git a/lib/review/img_math.rb b/lib/review/img_math.rb index 0179cbed1..8281c3ded 100644 --- a/lib/review/img_math.rb +++ b/lib/review/img_math.rb @@ -1,8 +1,11 @@ require 'fileutils' require 'shellwords' +require 'review/loggable' module ReVIEW class ImgMath + include Loggable + def initialize(config, path_name: '_review_math') @config = config @logger = ReVIEW.logger @@ -50,7 +53,7 @@ def make_math_image(str, key, fontsize = 12) cmd = "latex --interaction=nonstopmode --output-directory=#{tmpdir} #{tex_path} && dvipng -T tight -z9 -o #{img_path} #{dvi_path}" out, status = Open3.capture2e(cmd) unless status.success? - raise ApplicationError, "latex compile error\n\nError log:\n" + out + raise ApplicationError, "latex compile error\n\nError log:\n#{out}" end img_path @@ -97,15 +100,13 @@ def make_math_images when 'dvipng' make_math_images_dvipng(tmpdir, tex_path, math_real_dir) else - error "unknown math converter error. imgmath_options/converter parameter should be 'pdfcrop' or 'dvipng'." - exit 1 + error! "unknown math converter error. imgmath_options/converter parameter should be 'pdfcrop' or 'dvipng'." end rescue CompileError FileUtils.cp([tex_path, File.join(File.dirname(tex_path), '__IMGMATH__.log')], math_real_dir) - error "LaTeX math compile error. See #{math_real_dir}/__IMGMATH__.log for details." - exit 1 + error! "LaTeX math compile error. See #{math_real_dir}/__IMGMATH__.log for details." end end @math_maps.clear @@ -113,14 +114,6 @@ def make_math_images private - def error(msg) - @logger.error msg - end - - def warn(msg) - @logger.warn msg - end - def default_imgmath_preamble <<-EOB \\documentclass[uplatex,a3paper,landscape]{jsarticle} @@ -156,7 +149,7 @@ def make_math_images_pdfcrop(dir, tex_path, math_real_dir) if File.exist?(dvi_path) out, status = Open3.capture2e(*[@config['dvicommand'], @config['dvioptions'].shellsplit, dvi_path].flatten.compact) if !status.success? || !File.exist?(pdf_path) - warn "error in #{@config['dvicommand']}. Error log:\n#{out}" + @logger.error "error in #{@config['dvicommand']}. Error log:\n#{out}" raise CompileError end end @@ -167,7 +160,7 @@ def make_math_images_pdfcrop(dir, tex_path, math_real_dir) end out, status = Open3.capture2e(*args) unless status.success? - warn "error in pdfcrop. Error log:\n#{out}" + @logger.error "error in pdfcrop. Error log:\n#{out}" raise CompileError end pdf_path = '__IMGMATH__pdfcrop.pdf' @@ -192,7 +185,7 @@ def make_math_images_pdfcrop(dir, tex_path, math_real_dir) end out, status = Open3.capture2e(*args) unless status.success? - warn "error in pdf extracting. Error log:\n#{out}" + @logger.error "error in pdf extracting. Error log:\n#{out}" raise CompileError end @@ -209,7 +202,7 @@ def make_math_images_pdfcrop(dir, tex_path, math_real_dir) end out, status = Open3.capture2e(*args) unless status.success? - warn "error in pdf pixelizing. Error log:\n#{out}" + @logger.error "error in pdf pixelizing. Error log:\n#{out}" raise CompileError end end @@ -235,7 +228,7 @@ def make_math_images_dvipng(dir, tex_path, math_real_dir) end out, status = Open3.capture2e(*args) unless status.success? - warn "error in dvipng. Error log:\n#{out}" + @logger.error "error in dvipng. Error log:\n#{out}" raise CompileError end end diff --git a/lib/review/index_builder.rb b/lib/review/index_builder.rb index 523b83f30..2d362eccb 100644 --- a/lib/review/index_builder.rb +++ b/lib/review/index_builder.rb @@ -24,9 +24,9 @@ def initialize(strict = false, *args) def check_id(id) if id if id =~ %r![#%\\{}\[\]~/$'"|*?&<>`\s]! - warn "deprecated ID: `#{$&}` in `#{id}`" + warn "deprecated ID: `#{$&}` in `#{id}`", location: location elsif id.start_with?('.') - warn "deprecated ID: `#{id}` begins from `.`" + warn "deprecated ID: `#{id}` begins from `.`", location: location end end end @@ -598,17 +598,9 @@ def embed(_lines, _arg = nil) '' end - def warn(msg) - @logger.warn "#{@location}: #{msg}" - end - - def error(msg = '(no message)') - if msg =~ /builder does not support command/ - # ignore - return - end - - super + ## override + def error(msg = nil) + # ignore in indexing end def texequation(_lines, id = nil, _caption = '') diff --git a/lib/review/latexbuilder.rb b/lib/review/latexbuilder.rb index beb096199..462ddf271 100644 --- a/lib/review/latexbuilder.rb +++ b/lib/review/latexbuilder.rb @@ -61,7 +61,7 @@ def setup_index require 'nkf' @index_mecab = MeCab::Tagger.new(@book.config['pdfmaker']['makeindex_mecab_opts']) rescue LoadError - warn 'not found MeCab' + warn 'not found MeCab', location: location end end @@ -156,7 +156,7 @@ def headline(level, label, caption) puts macro('label', label) if label end rescue - error "unknown level: #{level}" + app_error "unknown level: #{level}" end def nonum_begin(level, _label, caption) @@ -480,7 +480,7 @@ def common_code_block(id, lines, command, caption, _lang) captionstr = macro('reviewlistcaption', "#{I18n.t('list')}#{I18n.t('format_number_header', [get_chap, @chapter.list(id).number])}#{I18n.t('caption_prefix')}#{compile_inline(caption)}") end rescue KeyError - error "no such list: #{id}" + app_error "no such list: #{id}" end end end @@ -613,7 +613,7 @@ def image_image(id, caption = '', metric = nil) end def image_dummy(id, caption, lines) - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location puts '\begin{reviewdummyimage}' # path = @chapter.image(id).path puts "--[[path = #{id} (#{existence(id)})]]--" @@ -700,7 +700,7 @@ def indepimage(lines, id, caption = nil, metric = nil) puts "\\#{command}[width=\\maxwidth]{#{@chapter.image(id).path}}" end else - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location puts '\begin{reviewdummyimage}' puts "--[[path = #{escape(id)} (#{existence(id)})]]--" lines.each do |line| @@ -736,7 +736,7 @@ def table(lines, id = nil, caption = nil) table_header(id, caption) end rescue KeyError - error "no such table: #{id}" + app_error "no such table: #{id}" end table_begin(rows.first.size) table_rows(sepidx, rows) @@ -902,7 +902,7 @@ def emtable(lines, caption = nil) def imgtable(lines, id, caption = nil, metric = nil) unless @chapter.image_bound?(id) - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location image_dummy(id, caption, lines) return end @@ -920,7 +920,7 @@ def imgtable(lines, id, caption = nil, metric = nil) end puts macro('label', table_label(id)) rescue ReVIEW::KeyError - error "no such table: #{id}" + app_error "no such table: #{id}" end imgtable_image(id, caption, metric) @@ -1056,7 +1056,7 @@ def inline_chapref(id) title end rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" nofunc_text("[UnknownChapter:#{id}]") end @@ -1067,7 +1067,7 @@ def inline_chap(id) @book.chapter_index.number(id) end rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" nofunc_text("[UnknownChapter:#{id}]") end @@ -1079,7 +1079,7 @@ def inline_title(id) title end rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" nofunc_text("[UnknownChapter:#{id}]") end @@ -1096,7 +1096,7 @@ def inline_list(id) macro('reviewlistref', I18n.t('format_number', [get_chap(chapter), chapter.list(id).number])) end rescue KeyError - error "unknown list: #{id}" + app_error "unknown list: #{id}" end def inline_table(id) @@ -1107,7 +1107,7 @@ def inline_table(id) macro('reviewtableref', I18n.t('format_number', [get_chap(chapter), chapter.table(id).number]), table_label(id, chapter)) end rescue KeyError - error "unknown table: #{id}" + app_error "unknown table: #{id}" end def inline_img(id) @@ -1118,7 +1118,7 @@ def inline_img(id) macro('reviewimageref', I18n.t('format_number', [get_chap(chapter), chapter.image(id).number]), image_label(id, chapter)) end rescue KeyError - error "unknown image: #{id}" + app_error "unknown image: #{id}" end def inline_eq(id) @@ -1129,13 +1129,13 @@ def inline_eq(id) macro('reviewequationref', I18n.t('format_number', [get_chap(chapter), chapter.equation(id).number])) end rescue KeyError - error "unknown equation: #{id}" + app_error "unknown equation: #{id}" end def footnote(id, content) if @book.config['footnotetext'] || @foottext[id] if @doc_status[:column] - warn "//footnote[#{id}] is in the column block. It is recommended to move out of the column block." + warn "//footnote[#{id}] is in the column block. It is recommended to move out of the column block.", location: location end puts macro("footnotetext[#{@chapter.footnote(id).number}]", compile_inline(content.strip)) end @@ -1151,7 +1151,7 @@ def inline_fn(id) macro('footnote', compile_inline(@chapter.footnote(id).content.strip)) end rescue KeyError - error "unknown footnote: #{id}" + app_error "unknown footnote: #{id}" end BOUTEN = '・'.freeze @@ -1285,7 +1285,7 @@ def inline_column_chap(chapter, id) I18n.t('column', compile_inline(chapter.column(id).caption)), column_label(id, chapter)) rescue KeyError - error "unknown column: #{id}" + app_error "unknown column: #{id}" end def inline_raw(str) # rubocop:disable Lint/UselessMethodDefinition @@ -1324,7 +1324,7 @@ def inline_icon(id) end macro(command, @chapter.image(id).path) else - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location "\\verb|--[[path = #{id} (#{existence(id)})]]--|" end end diff --git a/lib/review/loggable.rb b/lib/review/loggable.rb new file mode 100644 index 000000000..df2abdcba --- /dev/null +++ b/lib/review/loggable.rb @@ -0,0 +1,27 @@ +module ReVIEW + module Loggable + attr_reader :logger + + def error(msg, location: nil) + logger.error(msg, location: location) + end + + def app_error(msg) + raise ApplicationError, msg + end + + def error!(msg, location: nil) + logger.error(msg, location: location) + + exit 1 + end + + def warn(msg, location: nil) + logger.warn(msg, location: location) + end + + def debug(msg, location: nil) + logger.debug(msg, location: location) + end + end +end diff --git a/lib/review/logger.rb b/lib/review/logger.rb index 08b1df79b..ea0dcc698 100644 --- a/lib/review/logger.rb +++ b/lib/review/logger.rb @@ -7,6 +7,30 @@ def initialize(io = $stderr, progname: '--') self.formatter = ->(severity, _datetime, name, msg) { "#{severity} #{name}: #{msg}\n" } end + def warn(msg, location: nil) + if location + super("#{location}: #{msg}") + else + super(msg) + end + end + + def error(msg, location: nil) + if location + super("#{location}: #{msg}") + else + super(msg) + end + end + + def debug(msg, location: nil) + if location + super("#{location}: #{msg}") + else + super(msg) + end + end + def ttylogger? nil end @@ -19,6 +43,30 @@ def success(_log) begin require 'tty-logger' class TTYLogger < ::TTY::Logger + def warn(msg, location: nil) + if location + super("#{location}: #{msg}") + else + super(msg) + end + end + + def error(msg, location: nil) + if location + super("#{location}: #{msg}") + else + super(msg) + end + end + + def debug(msg, location: nil) + if location + super("#{location}: #{msg}") + else + super(msg) + end + end + def ttylogger? true end diff --git a/lib/review/markdownbuilder.rb b/lib/review/markdownbuilder.rb index a0acd722b..eea3c3fbc 100644 --- a/lib/review/markdownbuilder.rb +++ b/lib/review/markdownbuilder.rb @@ -245,7 +245,7 @@ def image_dummy(_id, _caption, lines) def inline_img(id) "#{I18n.t('image')}#{@chapter.image(id).number}" rescue KeyError - error "unknown image: #{id}" + app_error "unknown image: #{id}" end def inline_dtp(str) @@ -264,14 +264,14 @@ def inline_hd_chap(chap, id) anchor = 'h' + n.tr('.', '-') %Q(#{str}) else - warn 'MARKDOWNBuilder does not support links to other chapters' + warn 'MARKDOWNBuilder does not support links to other chapters', location: location str end else str end rescue KeyError - error "unknown headline: #{id}" + app_error "unknown headline: #{id}" end def indepimage(_lines, id, caption = '', _metric = nil) @@ -401,7 +401,7 @@ def inline_icon(id) begin "![](#{@chapter.image(id).path.sub(%r{\A\./}, '')})" rescue - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location %Q(
missing image: #{id}
) end end diff --git a/lib/review/pdfmaker.rb b/lib/review/pdfmaker.rb index ba8a001bd..0697bb58d 100644 --- a/lib/review/pdfmaker.rb +++ b/lib/review/pdfmaker.rb @@ -24,11 +24,13 @@ require 'review/template' require 'review/latexbox' require 'review/call_hook' +require 'review/loggable' module ReVIEW class PDFMaker include FileUtils include ReVIEW::LaTeXUtils + include Loggable include ReVIEW::CallHook attr_accessor :config, :basedir @@ -38,13 +40,14 @@ def initialize @logger = ReVIEW.logger @input_files = Hash.new { |h, key| h[key] = '' } @mastertex = '__REVIEW_BOOK__' + @compile_errors = nil end def system_with_info(*args) @logger.info args.join(' ') out, status = Open3.capture2e(*args) unless status.success? - @logger.error "execution error\n\nError log:\n" + out + error "execution error\n\nError log:\n#{out}" end end @@ -52,19 +55,10 @@ def system_or_raise(*args) @logger.info args.join(' ') out, status = Open3.capture2e(*args) unless status.success? - error "failed to run command: #{args.join(' ')}\n\nError log:\n" + out + error! "failed to run command: #{args.join(' ')}\n\nError log:\n#{out}" end end - def error(msg) - @logger.error msg - exit 1 - end - - def warn(msg) - @logger.warn msg - end - def pdf_filepath File.join(@basedir, @config['bookname'] + '.pdf') end @@ -92,7 +86,7 @@ def check_compile_status(ignore_errors) if ignore_errors @logger.info 'compile error, but try to generate PDF file' else - error 'compile error, No PDF file output.' + error! 'compile error, No PDF file output.' end end @@ -126,7 +120,7 @@ def parse_opts(args) def execute(*args) cmd_config, yamlfile = parse_opts(args) - error "#{yamlfile} not found." unless File.exist?(yamlfile) + error! "#{yamlfile} not found." unless File.exist?(yamlfile) @config = ReVIEW::Configure.create(maker: 'pdfmaker', yamlfile: yamlfile, @@ -155,7 +149,7 @@ def execute(*args) rescue ApplicationError => e raise if @config['debug'] - error(e.message) + error! e.message end end @@ -217,7 +211,7 @@ def build_pdf makeindex_dic = ReVIEW::Configure.values['pdfmaker']['makeindex_dic'] else unless @config['texcommand'].present? - error "texcommand isn't defined." + error! "texcommand isn't defined." end texcommand = @config['texcommand'] dvicommand = @config['dvicommand'] @@ -303,8 +297,8 @@ def output_chaps(filename) @converter.convert(filename + '.re', File.join(@path, filename + '.tex')) rescue => e @compile_errors = true - warn "compile error in #{filename}.tex (#{e.class})" - warn e.message + error "compile error in #{filename}.tex (#{e.class})" + error e.message end end @@ -457,7 +451,7 @@ def erb_config begin @boxsetting = ReVIEW::LaTeXBox.new.tcbox(@config) rescue ReVIEW::ConfigError => e - error e + error! e end end end diff --git a/lib/review/plaintextbuilder.rb b/lib/review/plaintextbuilder.rb index 767bcc27d..d6dc50890 100644 --- a/lib/review/plaintextbuilder.rb +++ b/lib/review/plaintextbuilder.rb @@ -169,7 +169,7 @@ def list(lines, id, caption, lang = nil) list_header(id, caption, lang) end rescue KeyError - error "no such list: #{id}" + app_error "no such list: #{id}" end blank end @@ -238,7 +238,7 @@ def listnum(lines, id, caption, lang = nil) list_header(id, caption, lang) end rescue KeyError - error "no such list: #{id}" + app_error "no such list: #{id}" end blank end @@ -337,7 +337,7 @@ def footnote(id, str) def inline_fn(id) " 注#{@chapter.footnote(id).number} " rescue KeyError - error "unknown footnote: #{id}" + app_error "unknown footnote: #{id}" end def compile_ruby(base, _ruby) @@ -401,7 +401,7 @@ def bibpaper_bibpaper(_id, _caption, lines) def inline_bib(id) %Q(#{@chapter.bibpaper(id).number} ) rescue KeyError - error "unknown bib: #{id}" + app_error "unknown bib: #{id}" end def inline_hd_chap(chap, id) @@ -412,7 +412,7 @@ def inline_hd_chap(chap, id) I18n.t('hd_quote_without_number', compile_inline(chap.headline(id).caption)) end rescue KeyError - error "unknown headline: #{id}" + app_error "unknown headline: #{id}" end def noindent @@ -680,7 +680,7 @@ def inline_chapref(id) if @book.config['chapref'] chs2 = @book.config['chapref'].split(',') if chs2.size != 3 - error '--chapsplitter must have exactly 3 parameters with comma.' + app_error '--chapsplitter must have exactly 3 parameters with comma.' end chs = chs2 end @@ -694,7 +694,7 @@ def inline_chapref(id) end end rescue KeyError - error "unknown chapter: #{id}" + app_error "unknown chapter: #{id}" end def source(lines, caption = nil, _lang = nil) diff --git a/lib/review/textmaker.rb b/lib/review/textmaker.rb index 5062abd70..6b262d578 100644 --- a/lib/review/textmaker.rb +++ b/lib/review/textmaker.rb @@ -17,10 +17,12 @@ require 'review/version' require 'review/makerhelper' require 'review/img_math' +require 'review/loggable' module ReVIEW class TEXTMaker include MakerHelper + include Loggable attr_accessor :config, :basedir @@ -29,15 +31,7 @@ def initialize @logger = ReVIEW.logger @plaintext = nil @img_math = nil - end - - def error(msg) - @logger.error msg - exit 1 - end - - def warn(msg) - @logger.warn msg + @compile_errors = nil end def self.execute(*args) @@ -78,7 +72,7 @@ def remove_old_files(path) def execute(*args) cmd_config, yamlfile = parse_opts(args) - error "#{yamlfile} not found." unless File.exist?(yamlfile) + error! "#{yamlfile} not found." unless File.exist?(yamlfile) @config = ReVIEW::Configure.create(maker: 'textmaker', yamlfile: yamlfile, @@ -92,7 +86,7 @@ def execute(*args) rescue ApplicationError => e raise if @config['debug'] - error(e.message) + error! e.message end if @config['math_format'] == 'imgmath' @@ -109,6 +103,10 @@ def generate_text_files(yamlfile) @book = ReVIEW::Book::Base.new(@basedir, config: @config) build_body(@path, yamlfile) + + if @compile_errors + app_error 'compile error, No TEXT file output.' + end end def build_body(basetmpdir, _yamlfile) @@ -162,8 +160,9 @@ def build_chap(chap, base_path, basetmpdir, ispart) begin @converter.convert(filename, File.join(basetmpdir, textfile)) rescue => e - warn "compile error in #{filename} (#{e.class})" - warn e.message + @compile_errors = true + error "compile error in #{filename} (#{e.class})" + error e.message end end end diff --git a/lib/review/tocprinter.rb b/lib/review/tocprinter.rb index bdce50acc..f9439ce91 100644 --- a/lib/review/tocprinter.rb +++ b/lib/review/tocprinter.rb @@ -257,7 +257,7 @@ def build_chap(chap) compiler.compile(@book.chapter(chap.name)) rescue ReVIEW::ApplicationError => e @logger.error e.message - exit 1 + '' end end diff --git a/lib/review/topbuilder.rb b/lib/review/topbuilder.rb index 56b202088..00ea5efd0 100644 --- a/lib/review/topbuilder.rb +++ b/lib/review/topbuilder.rb @@ -105,7 +105,7 @@ def list(lines, id, caption, lang = nil) list_header(id, caption, lang) end rescue KeyError - error "no such list: #{id}" + app_error "no such list: #{id}" end puts "◆→終了:#{@titles['list']}←◆" blank @@ -178,7 +178,7 @@ def listnum(lines, id, caption, lang = nil) list_header(id, caption, lang) end rescue KeyError - error "no such list: #{id}" + app_error "no such list: #{id}" end puts "◆→終了:#{@titles['list']}←◆" blank @@ -202,7 +202,7 @@ def image(lines, id, caption, metric = nil) if @chapter.image_bound?(id) puts "◆→#{@chapter.image(id).path}#{metrics}←◆" else - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location lines.each do |line| puts line end @@ -287,7 +287,7 @@ def footnote(id, str) def inline_fn(id) "【注#{@chapter.footnote(id).number}】" rescue KeyError - error "unknown footnote: #{id}" + app_error "unknown footnote: #{id}" end def compile_ruby(base, ruby) @@ -381,7 +381,7 @@ def inline_icon(id) begin "◆→画像 #{@chapter.image(id).path.sub(%r{\A\./}, '')}←◆" rescue - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location "◆→画像 #{id}←◆" end end @@ -425,7 +425,7 @@ def bibpaper_header(id, caption) def inline_bib(id) %Q([#{@chapter.bibpaper(id).number}]) rescue KeyError - error "unknown bib: #{id}" + app_error "unknown bib: #{id}" end def noindent @@ -487,7 +487,7 @@ def indepimage(_lines, id, caption = nil, metric = nil) begin puts "◆→画像 #{@chapter.image(id).path.sub(%r{\A\./}, '')}#{metrics}←◆" rescue - warn "image not bound: #{id}" + warn "image not bound: #{id}", location: location puts "◆→画像 #{id}←◆" end if !caption_top?('image') && caption.present? diff --git a/lib/review/webmaker.rb b/lib/review/webmaker.rb index 37d4aa7cd..0ea500dbd 100644 --- a/lib/review/webmaker.rb +++ b/lib/review/webmaker.rb @@ -21,11 +21,13 @@ require 'review/version' require 'review/makerhelper' require 'review/img_math' +require 'review/loggable' module ReVIEW class WEBMaker include ERB::Util include MakerHelper + include Loggable attr_accessor :config, :basedir @@ -33,15 +35,7 @@ def initialize @basedir = nil @logger = ReVIEW.logger @img_math = nil - end - - def error(msg) - @logger.error msg - exit 1 - end - - def warn(msg) - @logger.warn msg + @compile_errors = nil end def self.execute(*args) @@ -82,7 +76,7 @@ def remove_old_files(path) def execute(*args) cmd_config, yamlfile = parse_opts(args) - error "#{yamlfile} not found." unless File.exist?(yamlfile) + error! "#{yamlfile} not found." unless File.exist?(yamlfile) @config = ReVIEW::Configure.create(maker: 'webmaker', yamlfile: yamlfile, @@ -98,7 +92,7 @@ def execute(*args) rescue ApplicationError => e raise if @config['debug'] - error(e.message) + error! e.message end end @@ -129,6 +123,7 @@ def generate_html_files(yamlfile) def build_body(basetmpdir, _yamlfile) base_path = Pathname.new(@basedir) + @compile_errors = nil @book.parts.each do |part| if part.name.present? if part.file? @@ -143,6 +138,9 @@ def build_body(basetmpdir, _yamlfile) part.chapters.each { |chap| build_chap(chap, base_path, basetmpdir, false) } end + if @compile_errors + app_error 'compile error, No web files output.' + end end def build_part(part, basetmpdir, htmlfile) @@ -191,9 +189,10 @@ def build_chap(chap, base_path, basetmpdir, ispart) begin @converter.convert(filename, File.join(basetmpdir, htmlfile)) - rescue => e - warn "compile error in #{filename} (#{e.class})" - warn e.message + rescue ApplicationError => e + @compile_errors = true + error "compile error in #{filename} (#{e.class})" + error e.message end end diff --git a/test/test_builder.rb b/test/test_builder.rb index 3f306fcf6..a6ebe7380 100644 --- a/test/test_builder.rb +++ b/test/test_builder.rb @@ -85,15 +85,15 @@ def test_inline_missing_ref chapter = ReVIEW::Book::Chapter.new(ReVIEW::Book::Base.new, 1, 'chap1', nil, StringIO.new) b.bind(nil, chapter, nil) e = assert_raises(ReVIEW::ApplicationError) { b.inline_list('unknown|list1') } - assert_equal ': error: unknown list: unknown|list1', e.message + assert_equal 'unknown list: unknown|list1', e.message e = assert_raises(ReVIEW::ApplicationError) { b.inline_table('unknown|table1') } - assert_equal ': error: unknown table: unknown|table1', e.message + assert_equal 'unknown table: unknown|table1', e.message e = assert_raises(ReVIEW::ApplicationError) { b.inline_img('unknown|img1') } - assert_equal ': error: unknown image: unknown|img1', e.message + assert_equal 'unknown image: unknown|img1', e.message e = assert_raises(ReVIEW::ApplicationError) { b.inline_column('unknown|column1') } - assert_equal ': error: unknown column: unknown|column1', e.message + assert_equal 'unknown column: unknown|column1', e.message e = assert_raises(ReVIEW::ApplicationError) { b.inline_fn('unknown|footnote1') } - assert_equal ': error: unknown footnote: unknown|footnote1', e.message + assert_equal 'unknown footnote: unknown|footnote1', e.message end def test_nest_error @@ -102,16 +102,16 @@ def test_nest_error assert_equal '', b.solve_nest('') b.children = ['dl'] e = assert_raises(ReVIEW::ApplicationError) { b.solve_nest('') } - assert_equal ': error: //beginchild of dl misses //endchild', e.message + assert_equal '//beginchild of dl misses //endchild', e.message b.children = ['ul', 'dl', 'ol'] e = assert_raises(ReVIEW::ApplicationError) { b.solve_nest('') } - assert_equal ': error: //beginchild of ol,dl,ul misses //endchild', e.message + assert_equal '//beginchild of ol,dl,ul misses //endchild', e.message assert_equal "\u0001→/ol←\u0001", b.endchild assert_equal "\u0001→/dl←\u0001", b.endchild assert_equal "\u0001→/ul←\u0001", b.endchild e = assert_raises(ReVIEW::ApplicationError) { b.endchild } - assert_equal ": error: //endchild is shown, but any opened //beginchild doesn't exist", e.message + assert_equal "//endchild is shown, but any opened //beginchild doesn't exist", e.message end class XBuilder < Builder diff --git a/test/test_epubmaker.rb b/test/test_epubmaker.rb index 76de59e0d..ae383f238 100644 --- a/test/test_epubmaker.rb +++ b/test/test_epubmaker.rb @@ -13,6 +13,8 @@ def setup 'language' => 'en', 'titlepage' => nil ) + @log_io = StringIO.new + ReVIEW.logger = ReVIEW::Logger.new(@log_io) @producer = ReVIEW::EPUBMaker::Producer.new(config) end @@ -901,8 +903,8 @@ def test_copy_static_file assert_nothing_raised { epubmaker.copy_stylesheet(tmpdir) } epubmaker.config['stylesheet'] = ['nothing.css'] - e = assert_raise(ApplicationError) { epubmaker.copy_stylesheet(tmpdir) } - assert_equal 'stylesheet: nothing.css is not found.', e.message + assert_raise(SystemExit) { epubmaker.copy_stylesheet(tmpdir) } + assert_equal "ERROR --: stylesheet: nothing.css is not found.\n", @log_io.string end epubmaker_instance do |epubmaker, tmpdir| @@ -911,8 +913,9 @@ def test_copy_static_file assert_nothing_raised { epubmaker.copy_frontmatter(tmpdir) } epubmaker.config['titlefile'] = 'nothing.html' - e = assert_raise(ApplicationError) { epubmaker.copy_frontmatter(tmpdir) } - assert_equal 'titlefile: nothing.html is not found.', e.message + @log_io.string = '' + assert_raise(SystemExit) { epubmaker.copy_frontmatter(tmpdir) } + assert_equal "ERROR --: titlefile: nothing.html is not found.\n", @log_io.string end # XXX: only `cover' is allowed to have invalid file name. @@ -922,8 +925,9 @@ def test_copy_static_file assert_nothing_raised { epubmaker.copy_frontmatter(tmpdir) } epubmaker.config[name] = 'nothing.html' - e = assert_raise(ApplicationError) { epubmaker.copy_frontmatter(tmpdir) } - assert_equal "#{name}: nothing.html is not found.", e.message + @log_io.string = '' + assert_raise(SystemExit) { epubmaker.copy_frontmatter(tmpdir) } + assert_equal "ERROR --: #{name}: nothing.html is not found.\n", @log_io.string end end @@ -933,8 +937,9 @@ def test_copy_static_file assert_nothing_raised { epubmaker.copy_backmatter(tmpdir) } epubmaker.config[name] = 'nothing.html' - e = assert_raise(ApplicationError) { epubmaker.copy_backmatter(tmpdir) } - assert_equal "#{name}: nothing.html is not found.", e.message + @log_io.string = '' + assert_raise(SystemExit) { epubmaker.copy_backmatter(tmpdir) } + assert_equal "ERROR --: #{name}: nothing.html is not found.\n", @log_io.string end end end diff --git a/test/test_htmlbuilder.rb b/test/test_htmlbuilder.rb index 1e04c072c..01ac7c52a 100644 --- a/test/test_htmlbuilder.rb +++ b/test/test_htmlbuilder.rb @@ -16,6 +16,8 @@ def setup @book = Book::Base.new('.') @book.config = @config img_math = ReVIEW::ImgMath.new(@config) + @log_io = StringIO.new + ReVIEW.logger = ReVIEW::Logger.new(@log_io) @builder = HTMLBuilder.new(img_math: img_math) @compiler = ReVIEW::Compiler.new(@builder) @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new) @@ -2029,8 +2031,8 @@ def test_ul_nest3 * AA EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':1: error: too many *.', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/too many \*\./, @log_io.string) end def test_ul_nest4 @@ -2378,10 +2380,10 @@ def test_table def test_empty_table e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") } - assert_equal ':2: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") } - assert_equal ':3: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message end def test_inline_table @@ -2736,8 +2738,8 @@ def test_minicolumn_blocks_nest_error1 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -2753,8 +2755,8 @@ def test_minicolumn_blocks_nest_error2 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -2770,8 +2772,8 @@ def test_minicolumn_blocks_nest_error3 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -2813,28 +2815,26 @@ def test_inline_w EOB end @book.config['words_file'] = File.join(dir, 'words.csv') - io = StringIO.new - @builder.instance_eval { @logger = ReVIEW::Logger.new(io) } actual = compile_block('@{F} @{B} @{B} @{N}') assert_equal %Q(

foo bar"\\<>_@<b>{BAZ} bar"\\<>_@<b>{BAZ} [missing word: N]

\n), actual - assert_match(/WARN --: :1: word not bound: N/, io.string) + assert_match(/WARN --: :1: word not bound: N/, @log_io.string) end end def test_inline_unknown - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown image: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown footnote: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown headline: n', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown image: n/, @log_io.string) + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown footnote: n/, @log_io.string) + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown headline: n/, @log_io.string) %w[list table column].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ":1: error: unknown #{name}: n", e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/unknown #{name}: n/, @log_io.string) end %w[chap chapref title].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ':1: error: key not found: "n"', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/key not found: "n"/, @log_io.string) end end @@ -2909,7 +2909,7 @@ def test_nest_error_close1 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ":1: error: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message + assert_equal "//beginchild is shown, but previous element isn't ul, ol, or dl", e.message end def test_nest_error_close2 @@ -2927,7 +2927,7 @@ def test_nest_error_close2 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':12: error: //beginchild of dl,ol,ul misses //endchild', e.message + assert_equal '//beginchild of dl,ol,ul misses //endchild', e.message end def test_nest_error_close3 @@ -2947,7 +2947,7 @@ def test_nest_error_close3 //endchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':14: error: //beginchild of ol,ul misses //endchild', e.message + assert_equal '//beginchild of ol,ul misses //endchild', e.message end def test_nest_ul diff --git a/test/test_idgxmlbuilder.rb b/test/test_idgxmlbuilder.rb index 3fb82f935..0f872ac70 100644 --- a/test/test_idgxmlbuilder.rb +++ b/test/test_idgxmlbuilder.rb @@ -14,6 +14,8 @@ def setup @config['tableopt'] = '10' @book = Book::Base.new @book.config = @config + @log_io = StringIO.new + ReVIEW.logger = ReVIEW::Logger.new(@log_io) @compiler = ReVIEW::Compiler.new(@builder) @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new) location = Location.new(nil, nil) @@ -169,10 +171,10 @@ def test_customize_mmtopt def test_empty_table e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") } - assert_equal ':2: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") } - assert_equal ':3: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message end def test_emtable @@ -436,8 +438,8 @@ def test_minicolumn_blocks_nest_error1 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -453,8 +455,8 @@ def test_minicolumn_blocks_nest_error2 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -469,8 +471,8 @@ def test_minicolumn_blocks_nest_error3 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -1095,8 +1097,8 @@ def test_ul_nest3 * AA EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':1: error: too many *.', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/too many \*\./, @log_io.string) end def test_ul_nest4 @@ -1131,19 +1133,25 @@ def test_ol end def test_inline_unknown - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown image: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown footnote: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown headline: n', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown image: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown footnote: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown headline: n/, @log_io.string) %w[list table column].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ":1: error: unknown #{name}: n", e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/unknown #{name}: n/, @log_io.string) end %w[chap chapref title].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ':1: error: key not found: "n"', e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/key not found: "n"/, @log_io.string) end end @@ -1283,7 +1291,7 @@ def test_nest_error_close1 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ":1: error: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message + assert_equal "//beginchild is shown, but previous element isn't ul, ol, or dl", e.message end def test_nest_error_close2 @@ -1301,7 +1309,7 @@ def test_nest_error_close2 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':12: error: //beginchild of dl,ol,ul misses //endchild', e.message + assert_equal '//beginchild of dl,ol,ul misses //endchild', e.message end def test_nest_error_close3 @@ -1321,7 +1329,7 @@ def test_nest_error_close3 //endchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':14: error: //beginchild of ol,ul misses //endchild', e.message + assert_equal '//beginchild of ol,ul misses //endchild', e.message end def test_nest_ul diff --git a/test/test_latexbuilder.rb b/test/test_latexbuilder.rb index 18fb75483..c6b8da72f 100644 --- a/test/test_latexbuilder.rb +++ b/test/test_latexbuilder.rb @@ -20,6 +20,8 @@ def setup @config['pdfmaker']['image_scale2width'] = nil @book = Book::Base.new @book.config = @config + @log_io = StringIO.new + ReVIEW.logger = ReVIEW::Logger.new(@log_io) @compiler = ReVIEW::Compiler.new(@builder) @chapter = Book::Chapter.new(@book, 1, 'chap1', nil, StringIO.new) location = Location.new(nil, nil) @@ -1433,10 +1435,10 @@ def test_table def test_empty_table e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") } - assert_equal ':2: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") } - assert_equal ':3: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message end def test_customize_cellwidth @@ -2252,8 +2254,8 @@ def test_minicolumn_blocks_nest_error1 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -2269,8 +2271,8 @@ def test_minicolumn_blocks_nest_error2 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -2285,8 +2287,8 @@ def test_minicolumn_blocks_nest_error3 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -2427,19 +2429,25 @@ def test_inline_w end def test_inline_unknown - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown image: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown footnote: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown headline: n', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown image: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown footnote: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown headline: n/, @log_io.string) %w[list table column].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ":1: error: unknown #{name}: n", e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/unknown #{name}: n/, @log_io.string) end %w[chap chapref title].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ':1: error: key not found: "n"', e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/key not found: "n"/, @log_io.string) end end @@ -2588,7 +2596,7 @@ def test_nest_error_close1 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ":1: error: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message + assert_equal "//beginchild is shown, but previous element isn't ul, ol, or dl", e.message end def test_nest_error_close2 @@ -2606,7 +2614,7 @@ def test_nest_error_close2 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':12: error: //beginchild of dl,ol,ul misses //endchild', e.message + assert_equal '//beginchild of dl,ol,ul misses //endchild', e.message end def test_nest_error_close3 @@ -2626,7 +2634,7 @@ def test_nest_error_close3 //endchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':14: error: //beginchild of ol,ul misses //endchild', e.message + assert_equal '//beginchild of ol,ul misses //endchild', e.message end def test_nest_ul diff --git a/test/test_latexbuilder_v2.rb b/test/test_latexbuilder_v2.rb index a71dccf7a..ab6f3b39f 100644 --- a/test/test_latexbuilder_v2.rb +++ b/test/test_latexbuilder_v2.rb @@ -20,6 +20,8 @@ def setup @config['pdfmaker']['image_scale2width'] = nil @book = Book::Base.new @book.config = @config + @log_io = StringIO.new + ReVIEW.logger = ReVIEW::Logger.new(@log_io) @compiler = ReVIEW::Compiler.new(@builder) @chapter = Book::Chapter.new(@book, 1, 'chap1', nil, StringIO.new) location = Location.new(nil, nil) @@ -1544,19 +1546,25 @@ def test_inline_fence end def test_inline_unknown - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown image: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown footnote: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown headline: n', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown image: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown footnote: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown headline: n/, @log_io.string) %w[list table column].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ":1: error: unknown #{name}: n", e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/unknown #{name}: n/, @log_io.string) end %w[chap chapref title].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ':1: error: key not found: "n"', e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/key not found: "n"/, @log_io.string) end end diff --git a/test/test_plaintextbuilder.rb b/test/test_plaintextbuilder.rb index 54597b649..aaa489ed4 100644 --- a/test/test_plaintextbuilder.rb +++ b/test/test_plaintextbuilder.rb @@ -14,6 +14,8 @@ def setup @config['language'] = 'ja' @book = Book::Base.new @book.config = @config + @log_io = StringIO.new + ReVIEW.logger = ReVIEW::Logger.new(@log_io) @compiler = ReVIEW::Compiler.new(@builder) @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new) location = Location.new(nil, nil) @@ -469,10 +471,10 @@ def test_table def test_empty_table e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") } - assert_equal ':2: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") } - assert_equal ':3: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message end def test_inline_table @@ -691,8 +693,8 @@ def test_minicolumn_blocks_nest_error1 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -708,8 +710,8 @@ def test_minicolumn_blocks_nest_error2 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -724,8 +726,8 @@ def test_minicolumn_blocks_nest_error3 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -761,19 +763,25 @@ def test_texequation end def test_inline_unknown - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown image: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown footnote: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown headline: n', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown image: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown footnote: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown headline: n/, @log_io.string) %w[list table column].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ":1: error: unknown #{name}: n", e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/unknown #{name}: n/, @log_io.string) end %w[chap chapref title].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ':1: error: key not found: "n"', e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/key not found: "n"/, @log_io.string) end end @@ -891,7 +899,7 @@ def test_nest_error_open //endchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ":1: error: //endchild is shown, but any opened //beginchild doesn't exist", e.message + assert_equal "//endchild is shown, but any opened //beginchild doesn't exist", e.message end def test_nest_error_close1 @@ -899,7 +907,7 @@ def test_nest_error_close1 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ":1: error: //beginchild is shown, but previous element isn't ul, ol, or dl", e.message + assert_equal "//beginchild is shown, but previous element isn't ul, ol, or dl", e.message end def test_nest_error_close2 @@ -917,7 +925,7 @@ def test_nest_error_close2 //beginchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':12: error: //beginchild of dl,ol,ul misses //endchild', e.message + assert_equal '//beginchild of dl,ol,ul misses //endchild', e.message end def test_nest_error_close3 @@ -937,7 +945,7 @@ def test_nest_error_close3 //endchild EOS e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_equal ':14: error: //beginchild of ol,ul misses //endchild', e.message + assert_equal '//beginchild of ol,ul misses //endchild', e.message end def test_nest_ul diff --git a/test/test_topbuilder.rb b/test/test_topbuilder.rb index e09de5bed..0af665b7b 100644 --- a/test/test_topbuilder.rb +++ b/test/test_topbuilder.rb @@ -14,6 +14,8 @@ def setup @config['language'] = 'ja' @book = Book::Base.new @book.config = @config + @log_io = StringIO.new + ReVIEW.logger = ReVIEW::Logger.new(@log_io) @compiler = ReVIEW::Compiler.new(@builder) @chapter = Book::Chapter.new(@book, 1, '-', nil, StringIO.new) location = Location.new(nil, nil) @@ -539,10 +541,10 @@ def test_table def test_empty_table e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n//}\n") } - assert_equal ':2: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message e = assert_raises(ReVIEW::ApplicationError) { compile_block("//table{\n------------\n//}\n") } - assert_equal ':3: error: no rows in the table', e.message + assert_equal 'no rows in the table', e.message end def test_inline_table @@ -879,8 +881,8 @@ def test_minicolumn_blocks_nest_error1 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -896,8 +898,8 @@ def test_minicolumn_blocks_nest_error2 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -912,8 +914,8 @@ def test_minicolumn_blocks_nest_error3 //} EOS - e = assert_raises(ReVIEW::ApplicationError) { compile_block(src) } - assert_match(/minicolumn cannot be nested:/, e.message) + assert_raises(ReVIEW::ApplicationError) { compile_block(src) } + assert_match(/minicolumn cannot be nested:/, @log_io.string) end end @@ -998,19 +1000,25 @@ def test_inline_w end def test_inline_unknown - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown image: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown footnote: n', e.message - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } - assert_equal ':1: error: unknown headline: n', e.message + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown image: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown footnote: n/, @log_io.string) + + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@{n}\n") } + assert_match(/unknown headline: n/, @log_io.string) %w[list table column].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ":1: error: unknown #{name}: n", e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/unknown #{name}: n/, @log_io.string) end %w[chap chapref title].each do |name| - e = assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } - assert_equal ':1: error: key not found: "n"', e.message + @log_io.string = '' + assert_raises(ReVIEW::ApplicationError) { compile_block("@<#{name}>{n}\n") } + assert_match(/key not found: "n"/, @log_io.string) end end