lib/erbtex/runner.rb in erbtex-0.3.0 vs lib/erbtex/runner.rb in erbtex-0.4.1

- old
+ new

@@ -1,48 +1,56 @@ require 'tempfile' require 'pathname' +require 'English' +# Name space module for erbtex program. module ErbTeX - # When we are handed a command line, it will be one that was - # originally intended for the real tex processor, e.g., pdflatex. - # - # We want to find the intended input file and the intended output - # directory using the ErbTeX::CommandLine object. - # - # We want to process the intended input file with Erubis and save the - # output in a temporary file with an .etx extension. - # - # Write the .etx file to the current directory unless it is not - # writable, in which case write it to /tmp. - # - # Perhaps change the Erubis pattern to something other than the erbtex - # default '{: :}'. Erubis normally by uses '<%= %>' by default. Erubis -p - # commandline -p '\.{ }\.' + def self.run(cmd_line) + report_version && exit(0) if cmd_line.print_version + report_help && exit(0) if cmd_line.print_help - # If there are no Erubis patterns in the file, skip the Erubis phase - # and just pass the original command on to the system. - # - # But wait. What if there are \include{file} or \input file - # statements in the input and those have Erubis patterns in them? We - # have to invoke erbtex recursively on those, replacing the - # orginal with a processed temporary and patching up the - # \include{tmp-file}, and so on. - # - # If there is an error in the Erubis phase, we want the error message - # to make it clear what happened and exit without invoking the tex - # processor. - # - # We want to find the real tex processor with find_executable and run it - # on our processed .etx file and otherwise leave the commandline - # intact. - # - def self.run(cl) - tex_dir = input_dir(cl.input_file) - tex_file = erb_to_tex(cl.input_file, tex_dir) if cl.input_file - run_tex(cl.tex_command(tex_file), tex_dir) + tex_dir = input_dir(cmd_line.input_file) + tex_file = erb_to_tex(cmd_line.input_file, tex_dir) if cmd_line.input_file + run_tex(cmd_line.tex_command(tex_file), tex_dir) end + def self.report_version + puts "erbtex version: #{ErbTeX::VERSION}" + puts "Ruby version: #{RUBY_VERSION}" + begin + erubis_version = `erubis -v` + rescue Errno::ENOENT + warn 'Warning: erubis does not appear to be installed!' + exit(1) + end + puts "erubis version: #{erubis_version}" + true + end + + def self.report_help + puts <<~HELP + Usage: erbtex [erbtex_options] [tex_prog_args] [file] + + erbtex_options are: + --version - print the version of the erbtex gem, ruby and erubis + --help - print this help message + --invoke=<tex_prog> - after pre-processing, invoke <tex_prog> on the + resulting file, tex_prog is pdflatex by default + + All other arguments, except possibly the last, are passed unaltered to + the tex_prog for interpretation. If any of these arguments starts with a + '\\' or '&', then all remaining arguments are passed to tex-prog for + interpretation, even the final argument. + + The last argument is taken as the input file name unless it or any earlier + argument starts with a '\\' or '&', in which case it is also passed along + as an argument to the tex-prog. + + HELP + true + end + # Run the TeX program, adding add_dir to the front of TEXINPUTS, unless it is # already in TEXINPUTS. def self.run_tex(cmd, add_dir = nil) new_env = {} if add_dir @@ -52,164 +60,92 @@ .any? { |p| add_dir == File.absolute_path(File.expand_path(p)) } new_env['TEXINPUTS'] = "#{add_dir}:#{ENV['TEXINPUTS']}" end end unless system(cmd) - $stderr.puts "Call to '#{cmd}' failed." - exit $?.exitstatus + warn "Call to '#{cmd}' failed." + exit $CHILD_STATUS end - $? + $CHILD_STATUS end def self.input_dir(in_file) return nil unless in_file + in_file_absolute = File.absolute_path(File.expand_path(in_file)) - in_file_absolute[/\A(.*\/)([^\/.]+)(\.[\w.]+)\z/, 1] + in_file_absolute[%r{\A(.*/)([^/.]+)(\.[\w.]+)\z}, 1] end # Pre-process the input file with erubis, adding the add_dir to the front of # the ruby load path if its not already in the load path. Return the name of # the processed file. def self.erb_to_tex(in_file, add_dir = nil) - add_dir = File.absolute_path(File.expand_path(add_dir)) - unless $LOAD_PATH - .any? { |p| add_dir == File.absolute_path(File.expand_path(p)) } - $LOAD_PATH.unshift(add_dir) + if File.exist?(add_dir) + add_dir = File.absolute_path(File.expand_path(add_dir)) + unless $LOAD_PATH + .any? { |p| add_dir == File.absolute_path(File.expand_path(p)) } + $LOAD_PATH.unshift(add_dir) + end end in_contents = nil File.open(in_file) do |f| in_contents = f.read end # TODO: recurse through any \input or \include commands - pat = - if ENV['ERBTEX_PATTERN'] - ENV['ERBTEX_PATTERN'] - else - '{: :}' - end + pat = ENV['ERBTEX_PATTERN'] || '{: :}' - out_file = set_out_file(in_file) + out_file = out_file_name(in_file) File.open(out_file, 'w') do |f| er = ::Erubis::Eruby.new(in_contents, pattern: pat) f.write(er.result) end out_file - rescue SystemCallError => ex - $stderr.puts "Error: #{ex}" + rescue SystemCallError => e + warn "Error: #{e}" exit 1 - rescue ScriptError => ex - $stderr.puts "Erubis pre-processing failed: #{ex}" + rescue ScriptError => e + warn "Erubis pre-processing failed: #{e}" exit 1 end - def self.set_out_file(in_file) + def self.out_file_name(in_file) in_file_absolute = File.absolute_path(File.expand_path(in_file)) - in_dir = in_file_absolute[/\A(.*\/)([^\/.]+)(\.[\w.]+)\z/, 1] - in_base = in_file_absolute[/\A(.*\/)([^\/.]+)(\.[\w.]+)\z/, 2] - in_ext = in_file_absolute[/\A(.*\/)([^\/.]+)(\.[\w.]+)\z/, 3] + in_dir = File.dirname(in_file_absolute) + in_base = File.basename(in_file_absolute) + in_ext = File.extname(in_file_absolute) - if in_ext.empty? - if File.exists?("#{in_file}.tex.erb") - out_ext = '.tex' - elsif File.exists?("#{in_file}.tex") - out_ext = '.etx' - elsif File.exists?("#{in_file}.erb") - out_ext = '.tex' - else - out_ext = '.tex' - end - else - case in_ext - when '.tex.erb' - out_ext = '.tex' - when '.tex' - out_ext = '.etx' - when '.erb' - out_ext = '.tex' - else - out_ext = '.tex' - end - end + out_ext = if in_ext.empty? + if File.exist?("#{in_file}.tex.erb") + '.tex' + elsif File.exist?("#{in_file}.tex") + '.etx' + elsif File.exist?("#{in_file}.erb") + '.tex' + else + '.tex' + end + else + case in_ext + when '.tex.erb' + '.tex' + when '.tex' + '.etx' + when '.erb' + '.tex' + else + '.tex' + end + end # Find a writable directory, prefering the one the input file came # from, or the current directory, and a temp file as a last resort. if File.writable?(in_dir) - out_file = File.join(in_dir, "#{in_base}#{out_ext}") + File.join(in_dir, "#{in_base}#{out_ext}") elsif File.writable?('.') - out_file = File.join('.', "#{in_base}#{out_ext}") + File.join('.', "#{in_base}#{out_ext}") else - out_file = Tempfile.new([in_base, out_ext]).path + Tempfile.new([in_base, out_ext]).path end - out_file end end - # def ErbTeX.run(command) - # cl = CommandLine.new(command) - # Dir.chdir(cl.run_dir) do - # if cl.input_file - # new_infile = process(cl.input_file, cl.input_path) - # else - # new_infile = nil - # end - # if new_infile - # new_infile = Pathname.new(new_infile). - # relative_path_from(Pathname.new(cl.run_dir)) - # end - # new_progname = ErbTeX.find_executable(command.lstrip.split(' ')[0]) - # cmd = cl.new_command_line(new_progname, new_infile) - # cmd.sub!('\\', '\\\\\\') - # cmd.sub!('&', '\\\\&') - # puts "Executing: #{cmd}" - # system(cmd) - # end - # end - - # Run erbtex on the content of file_name, a String, and return the - # name of the file where the processed content can be found. This - # could be the orignal file name if no processing was needed, or a - # temporary file if the erubis pattern is found anywhere in the file. - # def ErbTeX.process(file_name, dir) - # puts "Input path: #{dir}" - # contents = nil - # File.open(file_name) do |f| - # contents = f.read - # end - # # TODO: recurse through any \input or \include commands - - # # Add current directory to LOAD_PATH - # $: << '.' unless $:.include?('.') - - # if ENV['ERBTEX_PATTERN'] - # pat = ENV['ERBTEX_PATTERN'] - # else - # pat = '{: :}' - # end - - # # Otherwise process the contents - # # Find a writable directory, prefering the one the input file came - # # from, or the current directory, and a temp file as a last resort. - # file_absolute = File.absolute_path(File.expand_path(file_name)) - # file_dir = File.dirname(file_absolute) - # if file_absolute =~ /\.tex\.erb$/ - # file_base = File.basename(file_absolute, '.tex.erb') - # else - # file_base = File.basename(file_absolute, '.tex') - # end - # of = nil - # if File.writable?(file_dir) - # out_file = file_dir + '/' + file_base + '.etx' - # elsif File.writable?('.') - # out_file = './' + file_base + '.etx' - # else - # of = Tempfile.new([File.basename(file_name), '.etx']) - # out_file = of.path - # end - # unless of - # of = File.open(out_file, 'w+') - # end - # er = Erubis::Eruby.new(contents, :pattern => pat) - # of.write(er.result) - # of.close - # out_file - # end