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

- old
+ new

@@ -12,16 +12,14 @@ # 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 like .{ }. so that - # AucTeX does not get confused with the comment character used in - # Erubis by default (<%= %>). Erubis -p commandline would use the - # switch -p '\.{ }\.' But adapt if old pattern style is found in the - # input. - # + # Perhaps change the Erubis pattern to something other than the erbtex + # default '{: :}'. Erubis normally by uses '<%= %>' by default. Erubis -p + # commandline -p '\.{ }\.' + # 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 @@ -35,74 +33,183 @@ # # 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 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 + 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) + 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 + add_dir = File.absolute_path(File.expand_path(add_dir)) + unless ENV['TEXINPUTS'].split(File::PATH_SEPARATOR) + .reject { |p| p.strip.empty? } + .any? { |p| add_dir == File.absolute_path(File.expand_path(p)) } + new_env['TEXINPUTS'] = "#{add_dir}:#{ENV['TEXINPUTS']}" end - if new_infile - new_infile = Pathname.new(new_infile). - relative_path_from(Pathname.new(cl.run_dir)) - new_progname = ErbTeX.find_executable(command.lstrip.split(' ')[0]) - cmd = cl.new_command_line(new_progname, new_infile) - cmd.sub!('\\', '\\\\\\') - puts "Executing: #{cmd}" - system(cmd) - end end + unless system(cmd) + $stderr.puts "Call to '#{cmd}' failed." + exit $?.exitstatus + 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 + 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] + 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) end + + in_contents = nil + File.open(in_file) do |f| + in_contents = f.read + end # TODO: recurse through any \input or \include commands - # Add current directory to LOAD_PATH - $: << '.' unless $:.include?('.') + pat = + if ENV['ERBTEX_PATTERN'] + ENV['ERBTEX_PATTERN'] + else + '{: :}' + end - if ENV['ERBTEX_PATTERN'] - pat = ENV['ERBTEX_PATTERN'] + out_file = set_out_file(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}" + exit 1 + rescue ScriptError => ex + $stderr.puts "Erubis pre-processing failed: #{ex}" + exit 1 + end + + def self.set_out_file(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] + + 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 - pat = '{: :}' + 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 - # 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' + if File.writable?(in_dir) + out_file = File.join(in_dir, "#{in_base}#{out_ext}") elsif File.writable?('.') - out_file = './' + file_base + '.etx' + out_file = File.join('.', "#{in_base}#{out_ext}") else - of = Tempfile.new([File.basename(file_name), '.etx']) - out_file = of.path + out_file = Tempfile.new([in_base, out_ext]).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 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