#!/usr/bin/env ruby # # $Id: review-compile 4326 2010-01-12 14:10:17Z kmuto $ # # Copyright (c) 2008-2014 Kenshi Muto, Masayoshi Takahashi, KADO Masanori, Minero Aoki # Copyright (c) 1999-2007 Minero Aoki # # This program is free software. # You can distribute or modify this program under the terms of # the GNU LGPL, Lesser General Public License version 2.1. # For details of the GNU LGPL, see the file "COPYING". # require 'pathname' bindir = Pathname.new(__FILE__).realpath.dirname $LOAD_PATH.unshift((bindir + '../lib').realpath) require 'review' require 'review/compiler' require 'review/book' require 'review/i18n' require 'fileutils' require 'optparse' def main Signal.trap(:INT) { exit 1 } if RUBY_PLATFORM !~ /mswin(?!ce)|mingw|cygwin|bccwin/ Signal.trap(:PIPE, 'IGNORE') end _main rescue Errno::EPIPE exit 0 end def _main mode = :files basedir = nil if /\Areview2/ =~ File.basename($0) target = File.basename($0, '.rb').sub(/review2/, '') else target = nil end check_only = false output_filename = nil config = ReVIEW::Configure.values config.merge!({ "secnolevel" => 2, # for IDGXML and HTML "tableopt" => nil, # for IDGXML "nolf" => nil, # for IDGXML "chapref" => nil, # for IDGXML "structuredxml" => nil, # for IDGXML "stylesheet" => [], # for HTML "mathml" => nil, # for HTML "language" => "ja", # for HTML "deprecated-blocklines" => nil, "footnotetext" => false, "htmlext" => "html", "htmlversion" => 4, }) opts = OptionParser.new opts.version = ReVIEW::VERSION opts.banner = "Usage: #{File.basename($0)} [--target=FMT]" opts.on('--yaml=YAML', 'Read configurations from YAML file.') do |yaml| require 'yaml' config = config.merge(YAML.load_file(yaml)) end opts.on('-c', '--check', 'Check manuscript') { check_only = true } opts.on('--level=LVL', 'Section level to append number.') {|lvl| config["secnolevel"] = lvl.to_i } opts.on('--toclevel=LVL', 'Section level to append number.') {|lvl| config["toclevel"] = lvl.to_i } opts.on('--nolfinxml', 'Do not insert LF in XML. (idgxml)') { config["nolf"] = true } opts.on('--structuredxml', 'Produce XML with structured sections. (idgxml)') { config["structuredxml"] = true } opts.on('--table=WIDTH', 'Default table width. (idgxml)') {|tbl| config["tableopt"] = tbl } opts.on('--listinfo', 'Append listinfo tag to lists to indicate begin/end. (idgxml)') { config["listinfo"] = true } opts.on('--chapref="before,middle,after"', 'Chapref decoration.') {|cdec| config["chapref"] = cdec } opts.on('--subdirmode', 'Use chapter/id.ext path style to find images. (deprecated)') do STDERR.puts "Warning: --subdirmode is deprecated. Images are automatically detected." end opts.on('--singledirmode', 'Use id.ext path style to find images. (deprecated)') do STDERR.puts "Warning: --singledirmode is deprecated. Images are automatically detected." end opts.on('--chapterlink', 'make chapref hyperlink') { config["chapterlink"] = true } opts.on('--stylesheet=file', 'Stylesheet file for HTML (comma separated)') {|files| config["stylesheet"] = files.split(/\s*,\s*/) } opts.on('--mathml', 'Use MathML for TeX equation in HTML') do config["mathml"] = true end opts.on('--htmlversion=VERSION', 'HTML version.') do |v| v = v.to_i config["htmlversion"] = v if v == 4 || v == 5 end opts.on('--epubversion=VERSION', 'EPUB version.') do |v| v = v.to_i config["epubversion"] = v if v == 2 || v == 3 end opts.on('--hdnumberingmode', 'Output numbering headlines. (deprecated)') { config["hdnumberingmode"] = true } opts.on('--deprecated-blocklines', 'Disable paragrahs in block tags. Treat physical line as a paragraph. (deprecated)') { config["deprecated-blocklines"] = true } opts.on('--target=FMT', 'Target format.') {|fmt| target = fmt } unless target opts.on('--footnotetext', 'Use footnotetext and footnotemark instead of footnote (latex)') { config["footnotetext"] = true } opts.on('--draft', 'use draft mode(inline comment)') { config["draft"] = true } opts.on('-a', '--all', 'Compile all chapters.') do mode = :dir basedir = nil end opts.on('--directory=DIR', 'Compile all chapters in DIR.') do |path| mode = :dir basedir = path end opts.on('--output-file=FILENAME', 'Write all results into file instead of stdout.') do |filename| output_filename = filename end opts.on('--tabwidth=WIDTH', 'tab width') {|width| config["tabwidth"] = width.to_i } opts.on('--catalogfile=FILENAME', 'Set catalog file') do |catalogfile| config["catalogfile"] = catalogfile end opts.on('--help', 'Prints this message and quit.') do puts opts.help exit 0 end begin opts.parse! unless target if check_only target = 'html' else raise OptionParser::ParseError, "no target given" end end rescue OptionParser::ParseError => err error err.message $stderr.puts opts.help exit 1 end begin config["builder"] = target ReVIEW::I18n.setup(config["language"]) case mode when :files if ARGV.empty? error 'no input' exit 1 end basedir = File.dirname(ARGV[0]) book = ReVIEW::Book::Base.load(basedir) book.config = config # needs only at the first time ARGV.each do |item| chap_name = File.basename(item, '.*') chap = book.chapter(chap_name) compiler = ReVIEW::Compiler.new(load_strategy_class(target, check_only)) result = compiler.compile(chap) if output_filename write output_filename, result else puts result unless check_only end end when :dir book = basedir ? ReVIEW::Book.load(basedir) : ReVIEW::Book::Base.load book.config = config compiler = ReVIEW::Compiler.new(load_strategy_class(target, check_only)) book.chapters.each do |chap| str = compiler.compile(chap) write "#{chap.name}#{compiler.strategy.extname}", str unless check_only end # PART book.parts_in_file.each do |part| str = compiler.compile(part) write "#{part.name}#{compiler.strategy.extname}", str unless check_only end else raise "must not happen: #{mode}" end rescue ReVIEW::ApplicationError => err raise if $DEBUG error err.message exit 1 end end def error(msg) $stderr.puts "#{File.basename($0, '.*')}: error: #{msg}" end def load_strategy_class(target, strict) require "review/#{target}builder" ReVIEW.const_get("#{target.upcase}Builder").new(strict) end def write(path, str) File.open(path, 'w') {|f| f.puts str } end main