diff --git a/constants.rb b/constants.rb index 049ccb9..dd50133 100644 --- a/constants.rb +++ b/constants.rb @@ -17,14 +17,14 @@ # along with ltx2any. If not, see . # TODO move to a properties file? -NAME = "ltx2any" -VERSION = "0.9a" -YEAR = "2016" -AUTHOR = "Raphael Reitzig" -TMPSUFFIX = "_tmp" -HASHFILE = ".hashes" # relative to tmp directory +NAME = 'ltx2any' +VERSION = '0.9a' +YEAR = '2016' +AUTHOR = 'Raphael Reitzig' +TMPSUFFIX = '_tmp' +HASHFILE = '.hashes' # relative to tmp directory # TODO move this constant to HashManager? -LIBDIR = "lib" -EXTDIR = "extensions" -ENGDIR = "engines" +LIBDIR = 'lib' +EXTDIR = 'extensions' +ENGDIR = 'engines' diff --git a/engines/lualatex.rb b/engines/lualatex.rb index 8ddbf88..4bcbfeb 100644 --- a/engines/lualatex.rb +++ b/engines/lualatex.rb @@ -16,15 +16,15 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("lualatex", :binary, [:engine, "lualatex"], :essential) +Dependency.new('lualatex', :binary, [:engine, 'lualatex'], :essential) class LuaLaTeX < Engine def initialize super - @binary = "lualatex" - @extension = "pdf" - @description = "Uses lualatex to create a PDF" + @binary = 'lualatex' + @extension = 'pdf' + @description = 'Uses lualatex to create a PDF' @target_file = "#{ParameterManager.instance[:jobname]}.#{extension}" @old_hash = hash_result @@ -49,7 +49,7 @@ def exec() f = IO::popen(eval(lualatex)) log = f.readlines.map! { |s| Log.fix(s) } - return [File.exist?(@target_file), TeXLogParser.parse(log), log.join("").strip!] + [File.exist?(@target_file), TeXLogParser.parse(log), log.join('').strip!] end end diff --git a/engines/pdflatex.rb b/engines/pdflatex.rb index 35dcebf..1962a1d 100644 --- a/engines/pdflatex.rb +++ b/engines/pdflatex.rb @@ -16,15 +16,15 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("pdflatex", :binary, [:engine, "pdflatex"], :essential) +Dependency.new('pdflatex', :binary, [:engine, 'pdflatex'], :essential) class PdfLaTeX < Engine def initialize super - @binary = "pdflatex" - @extension = "pdf" - @description = "Uses pdflatex to create a PDF" + @binary = 'pdflatex' + @extension = 'pdf' + @description = 'Uses pdflatex to create a PDF' @target_file = "#{ParameterManager.instance[:jobname]}.#{extension}" @old_hash = hash_result @@ -48,7 +48,7 @@ def exec() f = IO::popen(eval(pdflatex)) log = f.readlines.map! { |s| Log.fix(s) } - return [File.exist?(@target_file), TeXLogParser.parse(log), log.join("").strip!] + [File.exist?(@target_file), TeXLogParser.parse(log), log.join('').strip!] end end diff --git a/engines/xelatex.rb b/engines/xelatex.rb index b5a0777..8c8b9ce 100644 --- a/engines/xelatex.rb +++ b/engines/xelatex.rb @@ -16,15 +16,15 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("xelatex", :binary, [:engine, "xelatex"], :essential) +Dependency.new('xelatex', :binary, [:engine, 'xelatex'], :essential) class XeLaTeX < Engine def initialize super - @binary = "xelatex" - @extension = "pdf" - @description = "Uses xelatex to create a PDF" + @binary = 'xelatex' + @extension = 'pdf' + @description = 'Uses xelatex to create a PDF' @target_file = "#{ParameterManager.instance[:jobname]}.#{extension}" @old_hash = hash_result @@ -48,7 +48,7 @@ def exec() f = IO::popen(eval(xelatex)) log = f.readlines.map! { |s| Log.fix(s) } - return [File.exist?(@target_file), TeXLogParser.parse(log), log.join("").strip!] + [File.exist?(@target_file), TeXLogParser.parse(log), log.join('').strip!] end end diff --git a/extensions/10_biber.rb b/extensions/10_biber.rb index d9a1fd5..b78f0dd 100644 --- a/extensions/10_biber.rb +++ b/extensions/10_biber.rb @@ -16,13 +16,13 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("biber", :binary, [:extension, "Biber"], :essential) +Dependency.new('biber', :binary, [:extension, 'Biber'], :essential) class Biber < Extension def initialize super - @name = "Biber" - @description = "Creates bibliographies (recommended)" + @name = 'Biber' + @description = 'Creates bibliographies (recommended)' @sources = [] end @@ -34,11 +34,11 @@ def do?(time) usesbib = File.exist?("#{params[:jobname]}.bcf") needrerun = false - if ( usesbib ) + if usesbib # Collect sources (needed for log parsing) @sources = [] IO.foreach("#{params[:jobname]}.bcf") { |line| - if ( /]*type="file"[^>]*>(.*?)<\/bcf:datasource>/ =~ line ) + if /]*type="file"[^>]*>(.*?)<\/bcf:datasource>/ =~ line @sources.push($~[1]) end } @@ -54,9 +54,9 @@ def do?(time) HashManager.instance.files_changed?("#{params[:jobname]}.bcf", *@sources) # Note: non-strict OR so that hashes are computed for next run - end - - return usesbib && needrerun + end + + usesbib && needrerun end def exec(time, progress) @@ -75,21 +75,21 @@ def exec(time, progress) errors = false linectr = 1 log.each { |line| - if ( /^INFO - (.*)$/ =~ line ) + if /^INFO - (.*)$/ =~ line msgs.push(LogMessage.new(:info, nil, nil, [linectr], $~[1])) - elsif ( /^WARN - (.*)$/ =~ line ) + elsif /^WARN - (.*)$/ =~ line msgs.push(LogMessage.new(:warning, nil, nil, [linectr], $~[1])) - elsif ( /^ERROR - BibTeX subsystem: .*?(#{@sources.map { |s| Regexp.escape(s) }.join("|")}).*?, line (\d+), (.*)$/ =~ line ) + elsif /^ERROR - BibTeX subsystem: .*?(#{@sources.map { |s| Regexp.escape(s) }.join('|')}).*?, line (\d+), (.*)$/ =~ line msgs.push(LogMessage.new(:error, $~[1], [Integer($~[2])], [linectr], $~[3].strip)) errors = true - elsif ( /^ERROR - (.*)$/ =~ line ) + elsif /^ERROR - (.*)$/ =~ line msgs.push(LogMessage.new(:error, nil, nil, [linectr], $~[1])) errors = true end linectr += 1 } - return [!errors, msgs, log.join("").strip!] + [!errors, msgs, log.join('').strip!] end end diff --git a/extensions/10_bibtex.rb b/extensions/10_bibtex.rb index 5cbecf0..2a2e326 100644 --- a/extensions/10_bibtex.rb +++ b/extensions/10_bibtex.rb @@ -16,18 +16,18 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("bibtex", :binary, [:extension, "BibTeX"], :essential) +Dependency.new('bibtex', :binary, [:extension, 'BibTeX'], :essential) class BibTeX < Extension def initialize super - @name = "BibTeX" - @description = "Creates bibliographies (old)" + @name = 'BibTeX' + @description = 'Creates bibliographies (old)' # For checking whether bibtex has to rerun, we need to keep the # relevant parts of the _.aux file handy. # TODO use internal store? - @grepfile = "bibtex_aux_grep" + @grepfile = 'bibtex_aux_grep' end def do?(time) @@ -39,18 +39,18 @@ def do?(time) stylefile = [] bibdata = [] grepdata = [] - if ( File.exist?("#{params[:jobname]}.aux") ) - File.open("#{params[:jobname]}.aux", "r") { |file| + if File.exist?("#{params[:jobname]}.aux") + File.open("#{params[:jobname]}.aux", 'r') { |file| while ( line = file.gets ) - if ( /^\\bibdata\{(.+?)\}$/ =~ line ) + if /^\\bibdata\{(.+?)\}$/ =~ line # If commas occur, add both a split version (multiple files) # and the hole string (filename with comma), to be safe. - bibdata += $~[1].split(",").map { |s| "#{s}.bib" } + [$~[1]] + bibdata += $~[1].split(',').map { |s| "#{s}.bib" } + [$~[1]] grepdata.push line.strip - elsif ( /^\\bibstyle\{(.+?)\}$/ =~ line ) + elsif /^\\bibstyle\{(.+?)\}$/ =~ line stylefile.push "#{$~[1]}.bst" grepdata.push line.strip - elsif ( /^\\(bibcite|citation)/ =~ line ) + elsif /^\\(bibcite|citation)/ =~ line grepdata.push line.strip end end @@ -62,7 +62,7 @@ def do?(time) # Write relevant part of the _.aux file into a separate file for hashing if usesbib - File.open(@grepfile, "w") { |f| + File.open(@grepfile, 'w') { |f| f.write grepdata.join("\n") } end @@ -73,7 +73,7 @@ def do?(time) # Note: non-strict OR so that hashes get computed and stored # for next run! - return usesbib && needsrerun + usesbib && needsrerun end def exec(time, progress) @@ -91,14 +91,14 @@ def exec(time, progress) msgs = [] errors = false linectr = 1 - lastline = "" + lastline = '' log.each { |line| - if ( /^Warning--(.*)$/ =~ line ) + if /^Warning--(.*)$/ =~ line msgs.push(LogMessage.new(:warning, nil, nil, [linectr], $~[1])) - elsif ( /^(.*?)---line (\d+) of file (.*)$/ =~ line ) + elsif /^(.*?)---line (\d+) of file (.*)$/ =~ line msg = $~[1].strip logline = [linectr] - if ( msg == "" ) + if msg == '' # Sometimes the message can be on the last line msg = lastline logline = [linectr - 1, linectr] @@ -111,7 +111,7 @@ def exec(time, progress) lastline = line } - return [!errors, msgs, log.join("").strip!] + [!errors, msgs, log.join('').strip!] end end diff --git a/extensions/20_makeindex.rb b/extensions/20_makeindex.rb index 30f811d..386e472 100644 --- a/extensions/20_makeindex.rb +++ b/extensions/20_makeindex.rb @@ -16,14 +16,14 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("makeindex", :binary, [:extension, "makeindex"], :essential) +Dependency.new('makeindex', :binary, [:extension, 'makeindex'], :essential) class MakeIndex < Extension def initialize super - @name = "makeindex" - @description = "Creates an index" + @name = 'makeindex' + @description = 'Creates an index' end def do?(time) @@ -46,13 +46,13 @@ def exec(time, progress) # Uses the following variables: # * jobname -- name of the main LaTeX file (without file ending) # * mistyle -- name of the makeindex style file (with file ending) - makeindex = { "default" => '"makeindex -q \"#{params[:jobname]}\" 2>&1"', - "styled" => '"makeindex -q -s \"#{mistyle}\" \"#{params[:jobname]}\" 2>&1"'} + makeindex = {'default' => '"makeindex -q \"#{params[:jobname]}\" 2>&1"', + 'styled' => '"makeindex -q -s \"#{mistyle}\" \"#{params[:jobname]}\" 2>&1"'} - version = "default" + version = 'default' mistyle = nil - Dir["*.ist"].each { |f| - version = "styled" + Dir['*.ist'].each { |f| + version = 'styled' mistyle = f } @@ -64,7 +64,7 @@ def exec(time, progress) } log2 = [] - File.open("#{params[:jobname]}.ilg", "r") { |f| + File.open("#{params[:jobname]}.ilg", 'r') { |f| log2 = f.readlines } @@ -75,27 +75,27 @@ def exec(time, progress) linectr = 1 errors = false log.each { |line| - if ( /^!! (.*?) \(file = (.+?), line = (\d+)\):$/ =~ line ) + if /^!! (.*?) \(file = (.+?), line = (\d+)\):$/ =~ line current = [:error, $~[2], [Integer($~[3])], [linectr], "#{$~[1]}: "] errors = true - elsif ( /^\#\# (.*?) \(input = (.+?), line = (\d+); output = .+?, line = \d+\):$/ =~ line ) + elsif /^\#\# (.*?) \(input = (.+?), line = (\d+); output = .+?, line = \d+\):$/ =~ line current = [:warning, $~[2], [Integer($~[3])], [linectr], "#{$~[1]}: "] - elsif ( current != [] && /^\s+-- (.*)$/ =~ line ) + elsif current != [] && /^\s+-- (.*)$/ =~ line current[3][1] = linectr msgs.push(LogMessage.new(current[0], current[1], current[2], current[3], current[4] + $~[1].strip)) current = [] - elsif ( /Option -g invalid/ =~ line ) + elsif /Option -g invalid/ =~ line msgs.push(LogMessage.new(:error, nil, nil, [linectr], line.strip)) errors = true - elsif ( /Can't create output index file/ =~ line ) + elsif /Can't create output index file/ =~ line msgs.push(LogMessage.new(:error, nil, nil, [linectr], line.strip)) errors = true end linectr += 1 } - return [!errors, msgs, log.join("").strip!] + [!errors, msgs, log.join('').strip!] end end diff --git a/extensions/30_metapost.rb b/extensions/30_metapost.rb index 9d5f1d5..2d9a591 100644 --- a/extensions/30_metapost.rb +++ b/extensions/30_metapost.rb @@ -16,13 +16,13 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("mpost", :binary, [:extension, "MetaPost"], :essential) +Dependency.new('mpost', :binary, [:extension, 'MetaPost'], :essential) class MetaPost < Extension def initialize super - @name = "MetaPost" - @description = "Compiles generated MetaPost files" + @name = 'MetaPost' + @description = 'Compiles generated MetaPost files' @mp_files = [] end @@ -35,7 +35,7 @@ def job_size # Count the number of changed _.mp files # Store because a check for changed hashes in exec later would give false! # Append because job_size may be called multiple times before exec - @mp_files += Dir.entries(".").delete_if { |f| + @mp_files += Dir.entries('.').delete_if { |f| (/\.mp$/ !~ f) || !HashManager.instance.files_changed?(f) } @mp_files.size @@ -51,7 +51,7 @@ def exec(time, progress) # Run mpost for each job file log = [[], []] - if ( !@mp_files.empty? ) + if !@mp_files.empty? # Run (latex) engine for each figure log = self.class.execute_parts(@mp_files, progress) { |f| compile(mpost, f) @@ -64,16 +64,16 @@ def exec(time, progress) # whole metapost block, not those inside. offset = 0 (0..(log[0].size - 1)).each { |i| - if ( log[0][i].size > 0 ) + if log[0][i].size > 0 internal_offset = 3 # Stuff we print per plot before log excerpt (see :compile) log[0][i].map! { |m| LogMessage.new(m.type, m.srcfile, m.srcline, - if ( m.logline != nil ) then + if m.logline != nil then m.logline.map { |ll| ll + offset + internal_offset} else nil end, - m.msg, if ( m.formatted? ) then :fixed else :none end) + m.msg, if m.formatted? then :fixed else :none end) } end offset += log[1][i].count(?\n) @@ -81,14 +81,14 @@ def exec(time, progress) log[0].flatten! errors = log[0].count { |m| m.type == :error } - return [errors <= 0, log[0], log[1].join] + [errors <= 0, log[0], log[1].join] end private def compile(cmd, f) params = ParameterManager.instance - log = "" + log = '' msgs = [] # Run twice to get LaTeX bits right @@ -100,18 +100,18 @@ def compile(cmd, f) io.readlines # Closes IO } - output = lines.join("").strip + output = lines.join('').strip log << "# #\n# #{f}\n\n" - if ( output != "" ) + if output != '' log << output msgs += msgs = parse(lines, f) else - log << "No output from mpost, so apparently everything went fine!" + log << 'No output from mpost, so apparently everything went fine!' end log << "\n\n" - - return [msgs, log] + + [msgs, log] end def parse(strings, file) @@ -125,10 +125,10 @@ def parse(strings, file) # ! message # ... # l.\d+ ... - if ( /^! (.*)$/ =~ line ) + if /^! (.*)$/ =~ line curmsg = $~[1].strip curline = linectr - elsif ( curmsg != nil && /^l\.(\d+)/ =~ line ) + elsif curmsg != nil && /^l\.(\d+)/ =~ line msgs.push(LogMessage.new(:error, "#{ParameterManager.instance[:tmpdir]}/#{file}", [Integer($~[1])], [curline, linectr], curmsg, :none)) @@ -137,8 +137,8 @@ def parse(strings, file) end linectr += 1 } - - return msgs + + msgs end end diff --git a/extensions/30_tikzext.rb b/extensions/30_tikzext.rb index a7f02e7..52cc196 100644 --- a/extensions/30_tikzext.rb +++ b/extensions/30_tikzext.rb @@ -17,13 +17,13 @@ # along with ltx2any. If not, see . ParameterManager.instance.addParameter(Parameter.new( - :imagerebuild, "ir", String, "", "Specify externalised TikZ images to rebuild, separated by ':'. Set to 'all' to rebuild all.")) + :imagerebuild, 'ir', String, '', "Specify externalised TikZ images to rebuild, separated by ':'. Set to 'all' to rebuild all.")) class TikZExt < Extension def initialize super - @name = "TikZ externalization" - @description = "Compiles externalized TikZ images" + @name = 'TikZ externalization' + @description = 'Compiles externalized TikZ images' end def do?(time) @@ -31,7 +31,7 @@ def do?(time) end def job_size - return collect_pending[0].size + collect_pending[0].size end def exec(time, progress) @@ -47,7 +47,7 @@ def exec(time, progress) figures,rebuildlog = collect_pending log = [[], []] - if ( !figures.empty? ) + if !figures.empty? # Run (latex) engine for each figure log = self.class.execute_parts(figures, progress) { |fig| compile(pdflatex, fig) @@ -59,16 +59,16 @@ def exec(time, progress) # whole tikzext block, not those inside. offset = 0 (0..(log[0].size - 1)).each { |i| - if ( log[0][i].size > 0 ) + if log[0][i].size > 0 internal_offset = 5 # Stuff we print per figure before log excerpt (see :compile) log[0][i].map! { |m| LogMessage.new(m.type, m.srcfile, m.srcline, - if ( m.logline != nil ) then + if m.logline != nil then m.logline.map { |ll| ll + offset + internal_offset - 1} # -1 because we drop first line! else nil end, - m.msg, if ( m.formatted? ) then :fixed else :none end) + m.msg, if m.formatted? then :fixed else :none end) } log[0][i] = [LogMessage.new(:info, nil, nil, nil, @@ -86,17 +86,17 @@ def exec(time, progress) log[0].flatten! errors = log[0].count { |m| m.type == :error } - return [errors <= 0, rebuildlog[0] + log[0], rebuildlog[1] + log[1].join] + [errors <= 0, rebuildlog[0] + log[0], rebuildlog[1] + log[1].join] end private def collect_pending params = ParameterManager.instance - figures,rebuildlog = [], [[], ""] - if ( File.exists?("#{params[:jobname]}.figlist") ) + figures,rebuildlog = [], [[], ''] + if File.exists?("#{params[:jobname]}.figlist") figures = IO.readlines("#{params[:jobname]}.figlist").map { |fig| - if ( fig.strip != "" ) + if fig.strip != '' fig.strip else nil @@ -105,11 +105,11 @@ def collect_pending # Remove results of figures that we want to rebuild rebuild = [] - if ( params[:imagerebuild] == "all" ) + if params[:imagerebuild] == 'all' rebuild = figures else - params[:imagerebuild].split(":").map { |s| s.strip }.each { |fig| - if ( figures.include?(fig) ) + params[:imagerebuild].split(':').map { |s| s.strip }.each { |fig| + if figures.include?(fig) rebuild.push(fig) else msg = "User requested rebuild of figure `#{fig}` which does not exist." @@ -124,8 +124,8 @@ def collect_pending !File.exist?("#{fig}.pdf") || rebuild.include?(fig) } end - - return [figures, rebuildlog] + + [figures, rebuildlog] end def compile(cmd, fig) @@ -141,7 +141,7 @@ def compile(cmd, fig) # Closes IO } # Shell output does not contain error messages -> read log - output = File.open("#{fig}.log", "r") { |f| + output = File.open("#{fig}.log", 'r') { |f| f.readlines.map { |s| Log.fix(s) } } @@ -155,12 +155,12 @@ def compile(cmd, fig) startregexp !~ line }.take_while { |line| endregexp !~ line - }.drop(1).join("").strip + }.drop(1).join('').strip - if ( string != "" ) + if string != '' log << "\n\n#{string}\n\n" else - log << "No errors detected." + log << 'No errors detected.' end # Parse whole log for messages (needed for filenames) but restrict @@ -172,8 +172,8 @@ def compile(cmd, fig) # log << "Fatal error on #{fig}. See #{$params["tmpdir"]}/#{fig}.log for details.\n" # end log << "\n\n" - - return [msgs, log] + + [msgs, log] end end diff --git a/extensions/50_gnuplot.rb b/extensions/50_gnuplot.rb index 806ff52..4fc51a7 100644 --- a/extensions/50_gnuplot.rb +++ b/extensions/50_gnuplot.rb @@ -16,13 +16,13 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new("gnuplot", :binary, [:extension, "Gnuplot"], :essential) +Dependency.new('gnuplot', :binary, [:extension, 'Gnuplot'], :essential) class Gnuplot < Extension def initialize super - @name = "Gnuplot" - @description = "Executes generated gnuplot files" + @name = 'Gnuplot' + @description = 'Executes generated gnuplot files' @gnuplot_files = [] end @@ -35,7 +35,7 @@ def job_size # Check whether there are any _.gnuplot files that have changed # Store because check for changed hashes in exec later would give false! # Append because job_size may be called multiple times before exec - @gnuplot_files += Dir.entries(".").delete_if { |f| + @gnuplot_files += Dir.entries('.').delete_if { |f| (/\.gnuplot$/ !~ f) || !HashManager.instance.files_changed?(f) } @gnuplot_files.size @@ -49,7 +49,7 @@ def exec(time, progress) # Run gnuplot for each remaining file log = [[], []] - if ( !@gnuplot_files.empty? ) + if !@gnuplot_files.empty? log = self.class.execute_parts(@gnuplot_files, progress) { |f| compile(gnuplot, f) }.transpose @@ -60,16 +60,16 @@ def exec(time, progress) # whole gnuplot block, not those inside. offset = 0 (0..(log[0].size - 1)).each { |i| - if ( log[0][i].size > 0 ) + if log[0][i].size > 0 internal_offset = 2 # Stuff we print per plot before log excerpt (see :compile) log[0][i].map! { |m| LogMessage.new(m.type, m.srcfile, m.srcline, - if ( m.logline != nil ) then + if m.logline != nil then m.logline.map { |ll| ll + offset + internal_offset} else nil end, - m.msg, if ( m.formatted? ) then :fixed else :none end) + m.msg, if m.formatted? then :fixed else :none end) } end offset += log[1][i].count(?\n) @@ -77,38 +77,38 @@ def exec(time, progress) log[0].flatten! errors = log[0].count { |m| m.type == :error } - return [errors <= 0, log[0], log[1].join] + [errors <= 0, log[0], log[1].join] end private def compile(cmd, f) params = ParameterManager.instance - log = "" + log = '' msgs = [] lines = IO::popen(eval(cmd)) { |io| io.readlines # Closes IO } - output = lines.join("").strip + output = lines.join('').strip log << "# #\n# #{f}\n\n" - if ( output != "" ) + if output != '' log << output msgs += parse(lines) else - log << "No output from gnuplot, so apparently everything went fine!" + log << 'No output from gnuplot, so apparently everything went fine!' end log << "\n\n" - - return [msgs, log] + + [msgs, log] end def parse(strings) msgs = [] - context = "" + context = '' contextline = 1 linectr = 1 strings.each { |line| @@ -119,12 +119,12 @@ def parse(strings) # I have never seen more than one error (seems to abort). # So I'm going to assume that multiple error messages # are separated by empty lines. - if ( /^"(.+?)", line (\d+): (.*)$/ =~ line ) + if /^"(.+?)", line (\d+): (.*)$/ =~ line msgs.push(LogMessage.new(:error, "#{ParameterManager.instance[:tmpdir]}/#{$~[1]}", [Integer($~[2])], [[contextline, linectr].min, linectr], "#{context}#{$~[3].strip}", :fixed)) - elsif ( line.strip == "" ) - context = "" + elsif line.strip == '' + context = '' contextline = strings.size + 1 # Larger than every line number else contextline = [contextline, linectr].min @@ -135,8 +135,8 @@ def parse(strings) # by position of circumflex # TODO drop context here and instead give log line numbers? } - - return msgs + + msgs end end diff --git a/extensions/60_synctex.rb b/extensions/60_synctex.rb index acb83b1..5286893 100644 --- a/extensions/60_synctex.rb +++ b/extensions/60_synctex.rb @@ -19,7 +19,7 @@ require 'zlib' ParameterManager.instance.addParameter(Parameter.new( - :synctex, "synctex", Boolean, false, "Set to make engines create SyncTeX files.")) + :synctex, 'synctex', Boolean, false, 'Set to make engines create SyncTeX files.')) # Add hook that adapts the :enginepar parameter whenever :synctex changes (including startup) ParameterManager.instance.addHook(:synctex) { |key, val| @@ -27,11 +27,11 @@ # Set engine parameter # TODO make nicer with array parameters - parameter = "--synctex=-1" + parameter = '--synctex=-1' if val && params[:enginepar][parameter] == nil # TODO what is the second access? params.add(:enginepar, parameter) elsif !val - params[:enginepar] = params[:enginepar].gsub(parameter, "") + params[:enginepar] = params[:enginepar].gsub(parameter, '') end # Add synctex file to those that should be ignored @@ -44,15 +44,15 @@ elsif val # && !params[:ignore].empty? params[:ignore] = params[:ignore] + ":#{synctexfile}" elsif !val - params[:ignore] = params[:ignore].gsub(/:?#{synctexfile}/, "") + params[:ignore] = params[:ignore].gsub(/:?#{synctexfile}/, '') end } class SyncTeX < Extension def initialize super - @name = "SyncTeX" - @description = "Provides support for SyncTeX" + @name = 'SyncTeX' + @description = 'Provides support for SyncTeX' end def do?(time) @@ -63,12 +63,12 @@ def exec(time, progress) params = ParameterManager.instance if !File.exist?("#{params[:jobname]}.synctex") - return [false, [LogMessage.new(:error, nil, nil, nil, "SyncTeX file not found.")], ""] + return [false, [LogMessage.new(:error, nil, nil, nil, 'SyncTeX file not found.')], ''] end # Fix paths in synctex file, gzip it and put result in main directory Zlib::GzipWriter.open("#{params[:jobpath]}/#{params[:jobname]}.synctex.gz") { |gz| - File.open("#{params[:jobname]}.synctex", "r") { |f| + File.open("#{params[:jobname]}.synctex", 'r') { |f| f.readlines.each { |line| # Replace tmp path with job path. # Catch tmp paths relative to job path first, then try to match it as absolute path. @@ -78,7 +78,7 @@ def exec(time, progress) } } - return [true, [], ""] + [true, [], ''] end end diff --git a/lib/CliHelp.rb b/lib/CliHelp.rb index f8604e7..e07850e 100644 --- a/lib/CliHelp.rb +++ b/lib/CliHelp.rb @@ -31,7 +31,7 @@ def provideHelp(args) params = ParameterManager.instance # Check for help/usage commands - if ( args.length == 0 || /--help|--h/ =~ args[0] ) + if args.length == 0 || /--help|--h/ =~ args[0] puts "\nUsage: " puts " #{NAME} [options] inputfile\tNormal execution (see below)" puts " #{NAME} --extensions\t\tList of extensions" @@ -50,37 +50,37 @@ def provideHelp(args) # TODO output unsatisfied dependencies - return true - elsif ( args[0] == "--extensions" ) - puts "Installed extensions in execution order:" + true + elsif args[0] == '--extensions' + puts 'Installed extensions in execution order:' maxwidth = Extension.list.map { |e| e.name.length }.max Extension.list.each { |e| - puts " #{e.name}#{" " * (maxwidth - e.name.length)}\t#{e.description}" + puts " #{e.name}#{' ' * (maxwidth - e.name.length)}\t#{e.description}" } return true - elsif ( args[0] == "--engines" ) - puts "Installed engines:" + elsif args[0] == '--engines' + puts 'Installed engines:' Engine.list.each { |e| if DependencyManager.list(source: [:engine, e.binary], relevance: :essential).all? { |d| d.available? } print " #{e.name}\t#{e.description}" - if ( e.to_sym == params[:engine] ) - print " (default)" + if e.to_sym == params[:engine] + print ' (default)' end - puts "" + puts '' end } return true - elsif ( args[0] == "--dependencies" ) + elsif args[0] == '--dependencies' puts DependencyManager.to_s # TODO make prettier? return true - elsif ( args[0] == "--version" ) + elsif args[0] == '--version' puts "#{NAME} #{VERSION}" puts "Copyright \u00A9 #{AUTHOR} #{YEAR}".encode('utf-8') - puts "This is free software; see the source for copying conditions." - puts "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + puts 'This is free software; see the source for copying conditions.' + puts 'There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.' return true else # No help requested - return false + false end end diff --git a/lib/DaemonPrompt.rb b/lib/DaemonPrompt.rb index 73db868..731c362 100644 --- a/lib/DaemonPrompt.rb +++ b/lib/DaemonPrompt.rb @@ -20,22 +20,22 @@ class DaemonPrompt def self.run params = ParameterManager.instance command = getCommand - while ( command.size > 0 ) + while command.size > 0 begin case command[0] when :set - if ( command.size < 3 ) - respond "Please supply a parameter name and a value." + if command.size < 3 + respond 'Please supply a parameter name and a value.' else - value = command[2,command.size-1].join(" ") + value = command[2,command.size-1].join(' ') params[command[1].to_sym] = value respond "Set parameter '#{command[1]}' to '#{params[command[1].to_sym]}'." end when :add - if ( command.size < 3 ) - respond "Please supply a parameter name and a value." + if command.size < 3 + respond 'Please supply a parameter name and a value.' else - value = command[2,command.size-1].join(" ") # TODO join with `:` instead? + value = command[2,command.size-1].join(' ') # TODO join with `:` instead? params.add(command[1].to_sym, value) respond "Changed parameter '#{command[1]}' to '#{params[command[1].to_sym]}'." end @@ -43,18 +43,18 @@ def self.run respond "#{command[1]} = #{params[command[1].to_sym]}" when :clean FileUtils::rm_rf(params[:tmpdir]) - respond "Temporary files deleted" - if ( command.size > 1 && command[1].to_sym == :all ) + respond 'Temporary files deleted' + if command.size > 1 && command[1].to_sym == :all FileUtils::rm("#{params[:log]}.#{params[:logformat].to_s}") # TODO may fail when MD fallback? - respond "Log file deleted" + respond 'Log file deleted' # TODO remove result end when :run break when :quit - raise SystemExit.new("User issued quit command") + raise SystemExit.new('User issued quit command') when :help - respond "Work in progress. Supports commands set, show, clean (partial), run and quit." + respond 'Work in progress. Supports commands set, show, clean (partial), run and quit.' else respond "Command #{command[0].to_s} unknown" end @@ -82,9 +82,9 @@ def self.respond(msg) end def self.getCommand - print "> " + print '> ' command = gets.strip.split(/\s+/) # User may quit by hitting ^C at this point - if ( command.size > 0 ) + if command.size > 0 command[0] = command[0].to_sym else command[0] = :run diff --git a/lib/DependencyManager.rb b/lib/DependencyManager.rb index e64d3ef..b19afe3 100644 --- a/lib/DependencyManager.rb +++ b/lib/DependencyManager.rb @@ -23,8 +23,8 @@ class DependencyManager @@dependencies = [] def self.more_recent(v1, v2) - v1i = v1.gsub(/[^\d]/, "").to_i - v2i = v2.gsub(/[^\d]/, "").to_i + v1i = v1.gsub(/[^\d]/, '').to_i + v2i = v2.gsub(/[^\d]/, '').to_i return v1i > v2i ? v1 : v2 end @@ -122,7 +122,7 @@ class MissingDependencyError < StandardError; end class Dependency - def initialize(name, type, source, relevance, reason = "", version = nil) + def initialize(name, type, source, relevance, reason = '', version = nil) if ![:gem, :binary, :file].include?(type) raise "Illegal dependency type #{type.to_s}" elsif source != :core && (!source.kind_of?(Array) || ![:core, :extension, :engine].include?(source[0]) ) @@ -130,14 +130,14 @@ def initialize(name, type, source, relevance, reason = "", version = nil) elsif ![:recommended, :essential].include?(relevance) raise "Illegal relevance #{relevance.to_s}" end - if ( type != :gem && !(version.nil? || version.empty?) ) + if type != :gem && !(version.nil? || version.empty?) # Should not happen in production - puts "Developer warning: versions of binaries and files are not checked!" + puts 'Developer warning: versions of binaries and files are not checked!' end @name = name @type = type - @source = source.kind_of?(Array) ? source : [source, ""] + @source = source.kind_of?(Array) ? source : [source, ''] @relevance = relevance @reason = reason @version = version @@ -173,7 +173,7 @@ def available? end def to_s - "#{@type} #{@name} is #{@relevance} for #{@source.join(" ").strip}" + "#{@type} #{@name} is #{@relevance} for #{@source.join(' ').strip}" end attr_reader :name, :type, :source, :relevance, :reason, :version diff --git a/lib/Engine.rb b/lib/Engine.rb index 76b2047..07129df 100644 --- a/lib/Engine.rb +++ b/lib/Engine.rb @@ -49,9 +49,9 @@ def self.extension end def initialize - @binary = "dummy" - @extension = "dummy" - @description = "Dummy Description" + @binary = 'dummy' + @extension = 'dummy' + @description = 'Dummy Description' end public @@ -66,7 +66,7 @@ def do?() # 2. A list of log messages (cf LogMessage) # 3. The raw output of the external program def exec() - return [true, ["No execution code, need to overwrite!"], "No execution code, need to overwrite!"] + [true, ['No execution code, need to overwrite!'], 'No execution code, need to overwrite!'] end def name @@ -94,11 +94,11 @@ def to_sym # Add engine-related parameters ParameterManager.instance.addParameter(Parameter.new( - :engine, "e", Engine.list.map { |e| e.to_sym }, :pdflatex, - "The output engine. Call with --engines for a list.")) + :engine, 'e', Engine.list.map { |e| e.to_sym }, :pdflatex, + 'The output engine. Call with --engines for a list.')) ParameterManager.instance.addParameter(Parameter.new( - :enginepar, "ep", String, "", - "Parameters passed to the engine, separated by spaces.")) + :enginepar, 'ep', String, '', + 'Parameters passed to the engine, separated by spaces.')) ParameterManager.instance.addParameter(Parameter.new( - :engineruns, "er", Integer, 0, - "How often the LaTeX engine runs. Values smaller than one will cause it to run until the resulting file no longer changes. May not apply to all engines.")) + :engineruns, 'er', Integer, 0, + 'How often the LaTeX engine runs. Values smaller than one will cause it to run until the resulting file no longer changes. May not apply to all engines.')) diff --git a/lib/Extension.rb b/lib/Extension.rb index 11249c1..db24c25 100644 --- a/lib/Extension.rb +++ b/lib/Extension.rb @@ -16,12 +16,12 @@ # You should have received a copy of the GNU General Public License # along with ltx2any. If not, see . -Dependency.new('parallel', :gem, [:core, "Extension"], :recommended, "Faster execution for some extensions", ">=1.9.0") -Dependency.new('system', :gem, [:core, "Extension"], :recommended, "Required for parallel", ">=0.1.3") +Dependency.new('parallel', :gem, [:core, 'Extension'], :recommended, 'Faster execution for some extensions', '>=1.9.0') +Dependency.new('system', :gem, [:core, 'Extension'], :recommended, 'Required for parallel', '>=0.1.3') class Extension @@list = {} - @@dependencies = DependencyManager.list(source: [:core, "Extension"]) + @@dependencies = DependencyManager.list(source: [:core, 'Extension']) def self.add(e) @@list[e.to_sym] = e @@ -40,8 +40,8 @@ def self.to_sym end def initialize - @name = "Dummy name" - @description = "Dummy description" + @name = 'Dummy name' + @description = 'Dummy description' end # Hacky hack? Need to refactor this @@ -107,7 +107,7 @@ def self.run_all(time, output, log) log.add_messages(e.name, :extension, r[1], r[2]) else # TODO log message? - output.separate.error("Missing dependencies:", *dependencies.select { |d| !d.available? }.map { |d| d.to_s }) + output.separate.error('Missing dependencies:', *dependencies.select { |d| !d.available? }.map { |d| d.to_s }) end end } @@ -119,11 +119,11 @@ def do?(time) end def job_size - return 1 + 1 end def exec(time, progress) - return [true, "No execution code, need to overwrite!"] + [true, 'No execution code, need to overwrite!'] end def to_s @@ -143,7 +143,7 @@ def to_sym # Load all extensions Dir["#{BASEDIR}/#{EXTDIR}/*.rb"].sort.each { |f| - if ( !(/^\d\d/ !~ File.basename(f)) ) + if !(/^\d\d/ !~ File.basename(f)) load(f) end } diff --git a/lib/FileListener.rb b/lib/FileListener.rb index 6edca64..eb7a7dc 100644 --- a/lib/FileListener.rb +++ b/lib/FileListener.rb @@ -18,20 +18,20 @@ require 'singleton' -Dependency.new("listen", :gem, [:core, "FileListener"], :recommended, "Listening to files for automatic recompilation.", ">=3.1.5") +Dependency.new('listen', :gem, [:core, 'FileListener'], :recommended, 'Listening to files for automatic recompilation.', '>=3.1.5') ParameterManager.instance.addParameter(Parameter.new( - :daemon, "d", Boolean, false, "Re-compile automatically when files change.")) + :daemon, 'd', Boolean, false, 'Re-compile automatically when files change.')) ParameterManager.instance.addParameter(Parameter.new( - :listeninterval, "di", Float, 0.5, - "Time after which daemon mode checks for changes (in seconds).")) + :listeninterval, 'di', Float, 0.5, + 'Time after which daemon mode checks for changes (in seconds).')) class FileListener include Singleton private - def ignoreFileName(jobname = "") + def ignoreFileName(jobname = '') ".#{NAME}ignore_#{jobname}" end @@ -54,7 +54,7 @@ def ignored # Function that reads the ignorefile fo another process and # adds the contained files to the ignore list. def readIgnoreFile(ignoreFile) - if ( File.exist?(ignoreFile) ) + if File.exist?(ignoreFile) IO.foreach(ignoreFile) { |line| @ignore.push(line.strip) } @@ -71,7 +71,7 @@ def start(jobname, ignores = []) if @jobfilelistener != nil # Should never happen unless I programmed crap - raise StandardError.new("Listener already running, what are you doing?!") + raise StandardError.new('Listener already running, what are you doing?!') end params = ParameterManager.instance @@ -82,13 +82,13 @@ def start(jobname, ignores = []) @ignore.push(@ignorefile) # Write ignore list for other processes - File.open("#{params[:jobpath]}/#{@ignorefile}", "w") { |file| + File.open("#{params[:jobpath]}/#{@ignorefile}", 'w') { |file| file.write(@ignore.join("\n")) } # Collect all existing ignore files - Dir.entries(".") \ - .select { |f| /(\.\/)?#{Regexp.escape(ignoreFileName(""))}[^\/]+/ =~ f } \ + Dir.entries('.') \ + .select { |f| /(\.\/)?#{Regexp.escape(ignoreFileName(''))}[^\/]+/ =~ f } \ .each { |f| readIgnoreFile(f) } @@ -103,7 +103,7 @@ def start(jobname, ignores = []) latency: params[:listeninterval] * 0.25, ignore: [ /(\.\/)?#{Regexp.escape(ignoreFileName())}[^\/]+/, #/(\.\/)?\..*/, # ignore hidden files, e.g. .git - /\A(\.\/)?(#{@ignore.map { |s| Regexp.escape(s) }.join("|")})/ ], + /\A(\.\/)?(#{@ignore.map { |s| Regexp.escape(s) }.join('|')})/ ], ) \ do |modified, added, removed| # TODO cruel hack; can we do better? @@ -133,7 +133,7 @@ def start(jobname, ignores = []) added.each { |ignf| files = ignoremore(ignf) - @jobfilelistener.ignore(/\A(\.\/)?(#{files.map { |s| Regexp.escape(s) }.join("|")})/) + @jobfilelistener.ignore(/\A(\.\/)?(#{files.map { |s| Regexp.escape(s) }.join('|')})/) } # TODO If another daemon terminates we keep its ignorefiles. Potential leak! @@ -149,17 +149,17 @@ def start(jobname, ignores = []) end def waitForChanges(output) - output.start("Waiting for file changes (press ENTER to pause)") + output.start('Waiting for file changes (press ENTER to pause)') @jobfilelistener.start if @jobfilelistener.paused? params = ParameterManager.instance files = Thread.new do - while ( @changetime <= @lastraise || Time.now - @changetime < params[:listeninterval] ) + while @changetime <= @lastraise || Time.now - @changetime < params[:listeninterval] sleep(params[:listeninterval] * 0.5) end @lastraise = Time.now - Thread.current[:raisetarget].raise(FilesChanged.new("Files have changed")) + Thread.current[:raisetarget].raise(FilesChanged.new('Files have changed')) end files[:raisetarget] = Thread.current @@ -222,6 +222,7 @@ def runs? # Removes temporary files outside of the tmp folder, # closes file handlers, etc. def cleanup + # TODO this really needs to be done via CLEAN FileUtils::rm("#{ParameterManager.instance[:jobpath]}/#{@ignorefile}") end diff --git a/lib/HashManager.rb b/lib/HashManager.rb index 68b52dc..609843b 100644 --- a/lib/HashManager.rb +++ b/lib/HashManager.rb @@ -31,6 +31,7 @@ def initialize # Hashes the given string def self.hash(string) Digest::MD5.hexdigest(string) + # TODO SHA-256? end # Computes a hash of the given file. @@ -49,14 +50,14 @@ def self.hash_file(filename, drop_from: nil, without: nil) elsif drop_from == nil && without == nil Digest::MD5.file(filename).to_s else - string = File.open(filename, "r") { |f| f.read } + string = File.open(filename, 'r') { |f| f.read } # Fix string encoding; regexp matching below may fail otherwise # TODO check if this is necessary with Ruby versions beyond 2.0.0 if !string.valid_encoding? - string = string.encode("UTF-16be", - :invalid => :replace, - :replace => "?").encode('UTF-8') + string = string.encode('UTF-16be', + :invalid => :replace, + :replace => '?').encode('UTF-8') end # Drop undesired prefix if necessary @@ -95,8 +96,8 @@ def files_changed?(*files) @hashes[f] = hash end } - - return result + + result end # Reads hashes from a file in format @@ -104,12 +105,12 @@ def files_changed?(*files) # Overwrites any hashes that are already known. def from_file(filename) if File.exist?(filename) - File.open(filename, "r") { |f| + File.open(filename, 'r') { |f| f.readlines.each { |l| - parts = l.split(",") + parts = l.split(',') # Comma may appear as filename, so we have to make sure to only # use the last component as hash - @hashes[parts.take(parts.size - 1).join(",").strip] = parts.last.strip + @hashes[parts.take(parts.size - 1).join(',').strip] = parts.last.strip } } end @@ -119,7 +120,7 @@ def from_file(filename) # filename,hash # Overwrites existing file. def to_file(filename) - File.open(filename, "w") { |f| + File.open(filename, 'w') { |f| @hashes.each_pair { |k,v| f.write("#{k},#{v}\n") } diff --git a/lib/Log.rb b/lib/Log.rb index f08a913..1bd186b 100644 --- a/lib/Log.rb +++ b/lib/Log.rb @@ -19,13 +19,13 @@ require "#{File.dirname(__FILE__)}/LogMessage.rb" ParameterManager.instance.addParameter(Parameter.new( - :logformat, "lf", [:raw, :md, :latex, :pdf], :md, - "Set to 'raw' for raw, 'md' for Markdown, 'latex' for LaTeX, or 'pdf' for PDF log.")) + :logformat, 'lf', [:raw, :md, :latex, :pdf], :md, + "Set to 'raw' for raw, 'md' for Markdown, 'latex' for LaTeX, or 'pdf' for PDF log.")) ParameterManager.instance.addParameter(Parameter.new( - :loglevel, "ll", [:error, :warning, :info], :warning, - "Set to 'error' to see only errors, to 'warning' to see also warnings, or to 'info' for everything.")) + :loglevel, 'll', [:error, :warning, :info], :warning, + "Set to 'error' to see only errors, to 'warning' to see also warnings, or to 'info' for everything.")) -Dependency.new("xelatex", :binary, [:core, "Log"], :recommended, "Compilation of PDF logs") +Dependency.new('xelatex', :binary, [:core, 'Log'], :recommended, 'Compilation of PDF logs') class Log def initialize @@ -68,8 +68,8 @@ def only_level(level = @level) # 3. List of LogMessage objects # 4. Raw log/output def add_messages(source, sourcetype, msgs, raw) - if ( !@messages.has_key?(source) ) - @messages[source] = [sourcetype, [], ""] + if !@messages.has_key?(source) + @messages[source] = [sourcetype, [], ''] @counts[:error][source] = 0 @counts[:warning][source] = 0 @counts[:info][source] = 0 @@ -87,19 +87,19 @@ def add_messages(source, sourcetype, msgs, raw) end def has_messages?(source) - return @messages.has_key?(source) + @messages.has_key?(source) end def messages(source) - return @messages[source].clone + @messages[source].clone end def empty? - return @messages.empty? + @messages.empty? end def count(type) - return @counts[type][:total] + @counts[type][:total] end # Creates a Markdown-formatted log file at the specified location. @@ -115,7 +115,7 @@ def to_md(target_file = nil ) result << "**Disclaimer:** \nThis is but a digest of the original log file.\n" + "For full detail, check out `#{params[:tmpdir]}/#{params[:log]}.full`.\n" + - "In case we failed to pick up an error or warning, please " + + 'In case we failed to pick up an error or warning, please ' + "[report it to us](https://github.com/akerbos/ltx2any/issues/new).\n\n" result << "We found **#{count(:error)} error#{pls(count(:error))}**, " + @@ -128,18 +128,18 @@ def to_md(target_file = nil ) result << "## `#{name}`\n\n" - if ( msgs.empty? ) + if msgs.empty? result << "Lucky you, `#{name}` had nothing to complain about!\n\n" - if ( (@level == :warning && @counts[:info][name] > 0) || - (@level == :error && @counts[:info][name] + @counts[:warning][name] > 0 ) ) - if ( @level != :info ) - result << "Note, though, that this log only lists errors" - if ( @level == :warning ) - result << " and warnings" + if (@level == :warning && @counts[:info][name] > 0) || + (@level == :error && @counts[:info][name] + @counts[:warning][name] > 0) + if @level != :info + result << 'Note, though, that this log only lists errors' + if @level == :warning + result << ' and warnings' end - result << ". There were " - if ( @level == :error ) + result << '. There were ' + if @level == :error result << "#{@counts[:warning][name]} warning#{pls(@counts[:warning][name])} and " end result << "#{@counts[:info][name]} information message#{pls(@counts[:info][name])} " + @@ -158,46 +158,46 @@ def to_md(target_file = nil ) # * file:line flushed to the right after # * The message, indented to the type stands out # * Log line, flushed right - result << " * " + - { :error => "**Error**", - :warning => "*Warning*", - :info => "Info " + result << ' * ' + + { :error => '**Error**', + :warning => '*Warning*', + :info => 'Info ' }[m.type] - if ( m.srcfile != nil ) + if m.srcfile != nil srcline = nil - if ( m.srcline != nil ) - srcline = m.srcline.join("--") + if m.srcline != nil + srcline = m.srcline.join('--') end - srcfilelength = 76 - 9 - (if ( srcline != nil ) then srcline.length + 1 else 0 end) - 2 - result << if ( m.srcfile.length > srcfilelength ) + srcfilelength = 76 - 9 - (if srcline != nil then srcline.length + 1 else 0 end) - 2 + result << if m.srcfile.length > srcfilelength " `...#{m.srcfile[m.srcfile.length - srcfilelength + 5, m.srcfile.length]}" else - (" " * (srcfilelength - m.srcfile.length)) + "`#{m.srcfile}" + (' ' * (srcfilelength - m.srcfile.length)) + "`#{m.srcfile}" end - if ( srcline != nil ) + if srcline != nil result << ":#{srcline}" end - result << "`" + result << '`' end result << "\n\n" - if ( m.formatted? ) + if m.formatted? result << indent(m.msg.strip, 8) + "\n\n" else result << break_at_spaces(m.msg.strip, 68, 8) + "\n\n" end - if ( m.logline != nil ) + if m.logline != nil # We have line offset in the raw log! - logline = m.logline.map { |i| i += @rawoffsets[name] }.join("--") - result << (" " * (80 - (6 + logline.length))) + "`log:" + logline + "`\n\n\n" + logline = m.logline.map { |i| i += @rawoffsets[name] }.join('--') + result << (' ' * (80 - (6 + logline.length))) + '`log:' + logline + "`\n\n\n" end } end } - if ( target_file != nil ) - File.open("#{target_file}", "w") { |f| f.write(result) } + if target_file != nil + File.open("#{target_file}", 'w') { |f| f.write(result) } end - return result + result end # Creates a LaTeX document containing all messages at the specified location. @@ -205,9 +205,9 @@ def to_latex(target_file = "#{ParameterManager.instance[:jobname]}.log.tex") to_s if @rawoffsets == nil # Determines offsets in raw log params = ParameterManager.instance - File.open(target_file, "w") { |f| + File.open(target_file, 'w') { |f| # Copy template - File.open("#{File.dirname(__FILE__)}/logtemplate.tex", "r") { |template| + File.open("#{File.dirname(__FILE__)}/logtemplate.tex", 'r') { |template| f.write(template.read) } f.write("\\def\\author{ltx2any}\n\\def\\title{Log for #{params[:user_jobname]}}\n") @@ -219,7 +219,7 @@ def to_latex(target_file = "#{ParameterManager.instance[:jobname]}.log.tex") f.write("\\textbf{Disclaimer:} This is but a digest of the original log file. " + "For full detail, check out \\loglink. " + - "In case we failed to pick up an error or warning, please " + + 'In case we failed to pick up an error or warning, please ' + "\\href{https://github.com/akerbos/ltx2any/issues/new}{report it to us}.\n\n") f.write("We found \\errlink{\\textbf{#{count(:error)}~error#{pls(count(:error))}}}, " + @@ -233,7 +233,7 @@ def to_latex(target_file = "#{ParameterManager.instance[:jobname]}.log.tex") f.write("\\subsection{\\texttt{#{name}}}\n\n") - if ( msgs.empty? ) + if msgs.empty? f.write("Lucky you, \\texttt{#{name}} had nothing to complain about!\n\n") else f.write("\n\\begin{itemize}\n") @@ -248,13 +248,13 @@ def to_latex(target_file = "#{ParameterManager.instance[:jobname]}.log.tex") f.write("\\#{m.type.to_s}{") end - srcline = m.srcline || ["",""] - srcline.push("") if srcline.length < 2 + srcline = m.srcline || ['', ''] + srcline.push('') if srcline.length < 2 f.write("#{makeFileref(m.srcfile, srcline[0], srcline[1])}}\n\n") # Write the log message itself f.write("\\begin{verbatim}\n") - if ( m.formatted? ) + if m.formatted? f.write(indent(m.msg.strip, 0)) else f.write(break_at_spaces(m.msg.strip, 68, 1)) @@ -262,10 +262,10 @@ def to_latex(target_file = "#{ParameterManager.instance[:jobname]}.log.tex") f.write("\n\\end{verbatim}") # Write the raw log reference - if ( m.logline != nil ) + if m.logline != nil # We have line offsets in the raw log! logline = m.logline.map { |i| i += @rawoffsets[name] } - logline.push("") if logline.length < 2 + logline.push('') if logline.length < 2 f.write("\n\n\\logref{#{logline[0]}}{#{logline[1]}}") end @@ -301,8 +301,8 @@ def to_pdf(target_file = "#{ParameterManager.instance[:jobname]}.log.pdf") if !File.exist?("#{tmplogprefix}pdf") # This should never happen! - msg = "Log failed to compile!" - if ( params[:daemon] || !params[:clean] ) + msg = 'Log failed to compile!' + if params[:daemon] || !params[:clean] msg += " See #{params[:tmpdir]}/#{tmplogprefix}log." end raise msg @@ -315,7 +315,7 @@ def to_pdf(target_file = "#{ParameterManager.instance[:jobname]}.log.pdf") # at the specified location. # Returns the resulting string. def to_s(target_file = nil) - result = "" + result = '' messages = only_level(:info) offset = 0 @@ -335,10 +335,10 @@ def to_s(target_file = nil) offset += 10 + messages[source][2].count(?\n) } - if ( target_file != nil ) - File.open("#{target_file}", "w") { |f| f.write(result) } + if target_file != nil + File.open("#{target_file}", 'w') { |f| f.write(result) } end - return result + result end def self.fix(s) @@ -356,36 +356,36 @@ def self.fix(s) def break_at_spaces(s, length, indent) words = s.split(/\s+/) - res = "" - line = " " * [0, indent - 1].max + res = '' + line = ' ' * [0, indent - 1].max words.each { |w| - newline = line + " " + w - if ( newline.length > length ) + newline = line + ' ' + w + if newline.length > length res += line + "\n" - line = (" " * indent) + w + line = (' ' * indent) + w else line = newline end } - - return res + line + + res + line end def indent(s, indent) - s.split("\n").map { |line| (" " * indent) + line }.join("\n") + s.split("\n").map { |line| (' ' * indent) + line }.join("\n") end def pls(count) - if ( count == 1 ) - "" + if count == 1 + '' else - "s" + 's' end end def makeFileref(file, linefrom, lineto) - fileref = "" - if ( file != nil ) + fileref = '' + if file != nil #file = file.gsub(/_/, '\_') fileref = "\\fileref{#{file}}{#{linefrom}}{#{lineto}}" end diff --git a/lib/Output.rb b/lib/Output.rb index 60da619..0925fe7 100644 --- a/lib/Output.rb +++ b/lib/Output.rb @@ -18,16 +18,16 @@ require 'singleton' -Dependency.new("ruby-progressbar", :gem, [:core, "Output"], :recommended, "nice progress indicators", ">=1.7.5") +Dependency.new('ruby-progressbar', :gem, [:core, 'Output'], :recommended, 'nice progress indicators', '>=1.7.5') class Output include Singleton def initialize() - @success = "Done" - @error = "Error" - @warning = "Warning" - @cancel = "Cancelled" + @success = 'Done' + @error = 'Error' + @warning = 'Warning' + @cancel = 'Cancelled' @shortcode = "[#{NAME}]" @dependencies = DependencyManager.list(source: [:core, self.class.to_s]) end @@ -35,13 +35,13 @@ def initialize() private def puts_indented(msgs) msgs.each { |m| - puts "#{" " * @shortcode.length} #{m}" + puts "#{' ' * @shortcode.length} #{m}" } end public def msg(*msg) - if ( msg.size > 0 ) + if msg.size > 0 puts "#{@shortcode} #{msg[0]}" puts_indented(msg.drop(1)) if msg.size > 1 end @@ -49,14 +49,14 @@ def msg(*msg) end def warn(*msg) - if ( msg.size > 0 ) + if msg.size > 0 msg[0] = "#{@warning}: #{msg[0]}" msg(*msg) end end def error(*msg) - if ( msg.size > 0 ) + if msg.size > 0 msg[0] = "#{@error}: #{msg[0]}" msg(*msg) end @@ -65,14 +65,14 @@ def error(*msg) def start(msg, count=1) if count > 1 && @dependencies.all? { |d| d.available? } # Set up progress bar if needed - require "ruby-progressbar" + require 'ruby-progressbar' progress = ProgressBar.create(:title => "#{@shortcode} #{msg} ...", :total => count, - :format => "%t [%c/%C]", + :format => '%t [%c/%C]', :autofinish => false) return [lambda { progress.increment }, lambda { |state, *msgs| - progress.format("#{@shortcode} #{msg} ... #{instance_variable_get(("@#{state}").intern).to_s}" + (" " * 5)) # Add some spaces to hide all for up to 999 steps + progress.format("#{@shortcode} #{msg} ... #{instance_variable_get(("@#{state}").intern).to_s}" + (' ' * 5)) # Add some spaces to hide all for up to 999 steps # TODO We *know* that we need 2*ceil(log_2(count)) - 1 spaces... progress.stop puts_indented(*msgs) if msgs.size > 0 @@ -84,7 +84,7 @@ def start(msg, count=1) # Fallback if progress bar not needed, or gem not available print "#{@shortcode} #{msg} ... " STDOUT.flush - return [lambda {}, lambda { |state, *msgs| stop(state, *msgs) }] + [lambda {}, lambda { |state, *msgs| stop(state, *msgs) }] end def stop(state, *msg) @@ -94,7 +94,7 @@ def stop(state, *msg) end def separate - puts "" - return self + puts '' + self end end diff --git a/lib/ParameterManager.rb b/lib/ParameterManager.rb index 4ee8973..1f8bfc3 100644 --- a/lib/ParameterManager.rb +++ b/lib/ParameterManager.rb @@ -22,6 +22,7 @@ class ParameterManager include Singleton # TODO Make it so that keys are (also) "long" codes as fas as users are concerned. Interesting for DaemonPrompt! + # TODO add Array type (for -i -ir -ep ...) def initialize @values = {} @hooks = {} @@ -35,9 +36,9 @@ def initialize public def addParameter(p) - if ( !@processed ) - if ( p.is_a?(Parameter) ) - if ( @values.has_key?(p.key) ) + if !@processed + if p.is_a?(Parameter) + if @values.has_key?(p.key) raise ParameterException.new("Parameter #{p.key} already exists.") else @values[p.key] = p @@ -48,7 +49,7 @@ def addParameter(p) raise ParameterException.new("Can not add object of type #{p.class} as parameter.") end else - raise ParameterException.new("Can not add parameters after CLI input has been processed.") + raise ParameterException.new('Can not add parameters after CLI input has been processed.') end end @@ -56,10 +57,10 @@ def processArgs(args) # Check for input file first # Try to find an existing file by attaching common endings original = ARGV.last - endings = ["tex", "ltx", "latex", ".tex", ".ltx", ".latex"] + endings = ['tex', 'ltx', 'latex', '.tex', '.ltx', '.latex'] jobfile = original - while ( !File.exist?(jobfile) || File.directory?(jobfile) ) - if ( endings.length == 0 ) + while !File.exist?(jobfile) || File.directory?(jobfile) + if endings.length == 0 raise ParameterException.new("No input file fitting #{original} exists.") end @@ -68,33 +69,33 @@ def processArgs(args) # TODO do basic checks as to whether we really have a LaTeX file? addParameter(Parameter.new(:jobpath, nil, String, File.dirname(File.expand_path(jobfile)), - "Absolute path of source directory")) + 'Absolute path of source directory')) addHook(:tmpdir) { |key,val| - if ( self[:jobpath].start_with?(File.expand_path(val)) ) - raise ParameterException.new("Temporary directory may not contain job directory.") + if self[:jobpath].start_with?(File.expand_path(val)) + raise ParameterException.new('Temporary directory may not contain job directory.') end } - addParameter(Parameter.new(:jobfile, nil, String, File.basename(jobfile), "Name of the main input file")) - addParameter(Parameter.new(:jobname, nil, String, /\A(.+?)\.\w+\z/.match(self[:jobfile])[1], - "Internal job name, in particular name of the main file and logs.")) + addParameter(Parameter.new(:jobfile, nil, String, File.basename(jobfile), 'Name of the main input file')) + addParameter(Parameter.new(:jobname, nil, String, /\A(.+?)\.\w+\z/.match(self[:jobfile])[1], + 'Internal job name, in particular name of the main file and logs.')) set(:user_jobname, self[:jobname]) if self[:user_jobname] == nil # Read in parameters # TODO use/build proper CLI and parameter handler? i = 0 - while ( i < ARGV.length - 1 ) + while i < ARGV.length - 1 p = /\A-(\w+)\z/.match(ARGV[i]) if p != nil code = p[1] key = @code2key[code] - if ( @values.has_key?(key) ) - if ( @values[key].type == Boolean ) + if @values.has_key?(key) + if @values[key].type == Boolean set(key, :true) i += 1 else val = ARGV[i+1] - if ( i + 1 < ARGV.length - 1 ) + if i + 1 < ARGV.length - 1 set(key, val) # Does all the checking and converting i += 2 else @@ -113,7 +114,7 @@ def processArgs(args) # TODO Parameter values now contain user input. Security risk? keys.each { |key| val = @values[key].value - if ( val != nil && val.is_a?(String) && val.length > 0 ) + if val != nil && val.is_a?(String) && val.length > 0 begin @values[key].value = eval(val) rescue Exception => e @@ -123,18 +124,18 @@ def processArgs(args) end } - if ( jobfile == nil ) - raise ParameterException.new("Please provide an input file. Call with --help for details.") + if jobfile == nil + raise ParameterException.new('Please provide an input file. Call with --help for details.') end @processed = true end def [](key) - if ( @values.has_key?(key) ) - return @values[key].value + if @values.has_key?(key) + @values[key].value else - return nil + nil end end @@ -145,42 +146,42 @@ def []=(key,val) def set(key, val, once=false) # TODO implement "once" behaviour # TODO allow for proper validation functions? # TODO fall back to defaults instead of killing? - if( !@values.has_key?(key) ) + if !@values.has_key?(key) raise ParameterException.new("Parameter #{key} does not exist.") end code = @values[key].code - if ( @values[key].type == String ) + if @values[key].type == String @values[key].value = val.strip - elsif ( @values[key].type == Integer ) - if ( val.is_a?(Integer) ) + elsif @values[key].type == Integer + if val.is_a?(Integer) @values[key].value = val - elsif ( /\d+/ =~ val ) + elsif /\d+/ =~ val @values[key].value = val.to_i else raise ParameterException.new("Parameter -#{code} requires an integer ('#{val}' given).") end - elsif ( @values[key].type == Float ) - if ( val.is_a?(Float) ) + elsif @values[key].type == Float + if val.is_a?(Float) @values[key].value = val - elsif ( /\d+(\.\d+)?/ =~ val ) + elsif /\d+(\.\d+)?/ =~ val @values[key].value = val.to_f else raise ParameterException.new("Parameter -#{code} requires a number ('#{val}' given).") end - elsif ( @values[key].type == Boolean ) - if ( val.is_a?(Boolean) ) + elsif @values[key].type == Boolean + if val.is_a?(Boolean) @values[key].value = val - elsif ( val.to_s.to_sym == :true || val.to_s.to_sym == :false ) + elsif val.to_s.to_sym == :true || val.to_s.to_sym == :false @values[key].value = ( val.to_s.to_sym == :true ) else raise ParameterException.new("Parameter -#{code} requires a boolean ('#{val}' given).") end - elsif ( @values[key].type.is_a? Array ) - if ( @values[key].type.include?(val.to_sym) ) + elsif @values[key].type.is_a? Array + if @values[key].type.include?(val.to_sym) @values[key].value = val.to_sym else - raise ParameterException.new("Invalid value '#{val}' for parameter -#{code}\nChoose one of [#{@values[key].type.map { |e| e.to_s }.join(", ")}].") + raise ParameterException.new("Invalid value '#{val}' for parameter -#{code}\nChoose one of [#{@values[key].type.map { |e| e.to_s }.join(', ')}].") end else # This should never happen @@ -195,8 +196,8 @@ def set(key, val, once=false) # TODO implement "once" behaviour end def add(key, val, once=false) # TODO implement "once" behaviour - if ( @values.has_key?(key) ) - if ( @values[key].type == String ) + if @values.has_key?(key) + if @values[key].type == String @values[key].value += val.to_s # TODO should we add separating `:`? @hooks[key].each { |b| @@ -214,14 +215,14 @@ def add(key, val, once=false) # TODO implement "once" behaviour def addHook(key, &block) #if ( @values.has_key?(key) ) - if ( !@hooks.has_key?(key) ) + if !@hooks.has_key?(key) @hooks[key] = [] end - if ( block.arity == 2 ) + if block.arity == 2 @hooks[key].push(block) else - raise ParameterException.new("Parameter hooks need to take two parameters (key, new value).") + raise ParameterException.new('Parameter hooks need to take two parameters (key, new value).') end #else # raise ParameterException.new("Parameter #{key} does not exist.") @@ -229,7 +230,7 @@ def addHook(key, &block) end def keys - return @values.keys + @values.keys end def reset @@ -283,7 +284,7 @@ def initialize(key, code, type, default, help) public def value=(val) - if ( ( @type.is_a?(Array) && val.is_a?(@type[0].class) ) || val.is_a?(@type) ) + if (@type.is_a?(Array) && val.is_a?(@type[0].class)) || val.is_a?(@type) @value = val else raise ParameterException.new("Value if type #{val.class} is not compatible with parameter #{@key}.") diff --git a/lib/TeXLogParser.rb b/lib/TeXLogParser.rb index 3121000..74d955b 100644 --- a/lib/TeXLogParser.rb +++ b/lib/TeXLogParser.rb @@ -43,54 +43,54 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) current = Finalizer.new ongoing = nil log.each { |line| - if ( !collecting && startregexp =~ line ) + if !collecting && startregexp =~ line collecting = true linectr = 1 end - if ( collecting && endregexp =~ line ) + if collecting && endregexp =~ line messages += [current.get_msg].compact break end # Even when not collecting, we need to keep track of which file # we are in. - if ( collecting && line.strip == "" ) + if collecting && line.strip == '' # Empty line ends messages messages += [current.get_msg].compact - elsif ( /^l\.(\d+) (.*)$/ =~ line ) + elsif /^l\.(\d+) (.*)$/ =~ line # Line starting with a line number ends messages - if ( current.type != nil ) - if ( current.srcline == nil ) + if current.type != nil + if current.srcline == nil current.srcline = [Integer($~[1])] end current.message += $~[2].strip current.logline[1] = linectr messages += [current.get_msg].compact end - elsif ( /^<\*> (.*)$/ =~ line ) + elsif /^<\*> (.*)$/ =~ line # Some messages end with a line of the form '<*> file' - if ( current.type != nil ) + if current.type != nil current.srcfile = $~[1].strip current.logline[1] = linectr messages += [current.get_msg].compact end - elsif ( /^(\([^()]*\)|[^()])*\)/ =~ line ) + elsif /^(\([^()]*\)|[^()])*\)/ =~ line # End of messages regarding current file - if ( collecting ) + if collecting messages += [current.get_msg].compact end filestack.pop # Multiple files may close; cut away matching part and start over. - line = line.gsub($~.regexp, "") + line = line.gsub($~.regexp, '') redo - elsif ( current.type == nil && # When we have an active message, it has - # to complete before a new file can open. - # Probably. (Without, error messages with - # opening but no closing parenthesis would - # skrew up file tracking.) - /^[^()]*(\([^()]*\).*?)*[^()]*\(([^()]*?(\(|$))/ =~ line ) + elsif current.type == nil && # When we have an active message, it has + # to complete before a new file can open. + # Probably. (Without, error messages with + # opening but no closing parenthesis would + # skrew up file tracking.) + /^[^()]*(\([^()]*\).*?)*[^()]*\(([^()]*?(\(|$))/ =~ line # { } # skip series of matching parens and gutter # { } @@ -99,23 +99,25 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) # A new file has started. Match only those that don't close immediately. candidate = $~[2] - while( !File.exist?(candidate) && candidate != "" ) do # TODO can be long; use heuristics? + while !File.exist?(candidate) && candidate != '' do # TODO can be long; use heuristics? candidate = candidate[0,candidate.length - 1] end - if ( File.exist?(candidate) ) + if File.exist?(candidate) filestack.push(candidate) else # Lest we break everything by false negatives (due to linebreaks), # add a dummy and hope it closes. - filestack.push("dummy") + filestack.push('dummy') end # Multiple files may open; cut away matching part and start over. - replace = if ( ["("].include?($~[3]) ) then $~[3] else "" end + replace = if ['('].include?($~[3]) then $~[3] else + '' + end line = line.gsub($~.regexp, replace) redo - elsif ( collecting ) # Do all the checks only when collecting - if ( /^(\S*?):(\d+): (.*)/ =~ line && ongoing == nil ) # such lines appear in fontspec-style messages, see below + elsif collecting # Do all the checks only when collecting + if /^(\S*?):(\d+): (.*)/ =~ line && ongoing == nil # such lines appear in fontspec-style messages, see below messages += [current.get_msg].compact # messages.push(LogMessage.new(:error, $~[1], [Integer($~[2])], [linectr], $~[3].strip)) @@ -126,13 +128,13 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) current.message = $~[3].strip + "\n" current.slicer = nil current.format = :fixed - elsif ( /(Package|Class)\s+([\w]+)\s+(Warning|Error|Info)/ =~ line ) + elsif /(Package|Class)\s+([\w]+)\s+(Warning|Error|Info)/ =~ line # Message from some package or class, may be multi-line messages += [current.get_msg].compact - current.type = if ( $~[3] == "Warning" ) + current.type = if $~[3] == 'Warning' then :warning - elsif ( $~[3] == "Info" ) + elsif $~[3] == 'Info' then :info else :error end @@ -141,13 +143,13 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) current.logline = [linectr] current.message = line.strip current.slicer = /^\(#{$~[2]}\)\s*/ - elsif ( /\w+?TeX\s+(Warning|Error|Info)/ =~ line ) + elsif /\w+?TeX\s+(Warning|Error|Info)/ =~ line # Some message from the engine, may be multi-line messages += [current.get_msg].compact - current.type = if ( $~[1] == "Warning" ) + current.type = if $~[1] == 'Warning' then :warning - elsif ( $~[1] == "Info" ) + elsif $~[1] == 'Info' then :info else :error end @@ -156,24 +158,24 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) current.logline = [linectr] current.message = line.strip current.slicer = /^\s*/ - elsif ( /^(LaTeX Font Warning: .*?)(?: #{space_sep("on input line")} (\d+).)?$/ =~ line ) + elsif /^(LaTeX Font Warning: .*?)(?: #{space_sep('on input line')} (\d+).)?$/ =~ line # Some issue with fonts messages += [current.get_msg].compact current.type = :warning current.srcfile = filestack.last - current.srcline = if ( $~[2] ) then [Integer($~[2])] else nil end + current.srcline = if $~[2] then [Integer($~[2])] else nil end current.logline = [linectr] current.message = $~[1].strip current.slicer = /^\(Font\)\s*/ - elsif ( /^((Under|Over)full .*?) #{space_sep("at lines")} (\d+)--(\d+)?/ =~ line ) + elsif /^((Under|Over)full .*?) #{space_sep('at lines')} (\d+)--(\d+)?/ =~ line # Engine complains about under-/overfilled boxes messages += [current.get_msg].compact fromLine = Integer($~[3]) toLine = Integer($~[4]) srcLine = [fromLine] - if ( toLine >= fromLine ) + if toLine >= fromLine srcLine[1] = toLine else # This seems to happen for included files. The first number is the @@ -183,10 +185,10 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) end messages.push(LogMessage.new(:warning, filestack.last, srcLine, [linectr], $~[1].strip)) - elsif ( /^((Under|Over)full .*?)[\d\[\]]*$/ =~ line ) + elsif /^((Under|Over)full .*?)[\d\[\]]*$/ =~ line messages += [current.get_msg].compact messages.push(LogMessage.new(:warning, filestack.last, nil, [linectr], $~[1].strip)) - elsif ( /^Runaway .*?\?$/ =~ line ) + elsif /^Runaway .*?\?$/ =~ line messages += [current.get_msg].compact current.type = :error current.srcfile = filestack.last @@ -194,7 +196,7 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) current.logline = [linectr] current.message = line.strip + "\n" current.format = :fixed - elsif ( /^!!+/ =~ line ) + elsif /^!!+/ =~ line # Messages in the style of fontspec messages += [current.get_msg].compact @@ -203,39 +205,41 @@ def self.parse(log, startregexp = /.*/, endregexp = /(?=a)b/) current.srcfile = filestack.last # may be overwritten later current.srcline = nil current.logline = [linectr] - current.message = "" + current.message = '' current.format = :fixed - elsif ( ongoing == :fontspec ) # Precedence over other lines starting with !, see below - if ( /^!\.+/ =~ line.strip ) + elsif ongoing == :fontspec # Precedence over other lines starting with !, see below + if /^!\.+/ =~ line.strip # Message is done ongoing = nil messages += [current.get_msg].compact current = Finalizer.new - elsif ( /^(?:\.\/)?(\S+?):(\d+): (.*)/ =~ line ) + elsif /^(?:\.\/)?(\S+?):(\d+): (.*)/ =~ line current.srcfile = $~[1] current.srcline = [Integer($~[2])] current.message += $~[3].strip + "\n" - elsif ( /^! For immediate help.*/ =~ line ) + elsif /^! For immediate help.*/ =~ line # Drop useless note - elsif ( /^!(.*)/ =~ line ) + elsif /^!(.*)/ =~ line # A new line - if ( $~[1].strip.size > 0 ) + if $~[1].strip.size > 0 current.message += $~[1].strip + "\n" end end - elsif ( /^! (.*?)(after line (\d+).)?$/ =~ line ) + elsif /^! (.*?)(after line (\d+).)?$/ =~ line messages += [current.get_msg].compact current.type = :error current.srcfile = filestack.last - current.srcline = if ( $~[3] ) then [Integer($~[3])] else nil end + current.srcline = if $~[3] then [Integer($~[3])] else nil end current.logline = [linectr] - current.message = $~[1] + (if ( $~[2] ) then $~[2] else "" end) - elsif ( current.type != nil ) - if ( current.slicer != nil ) - line = line.gsub(current.slicer, "") + current.message = $~[1] + (if $~[2] then $~[2] else + '' + end) + elsif current.type != nil + if current.slicer != nil + line = line.gsub(current.slicer, '') end - if ( current.format != :fixed ) - line = " " + line.strip! + if current.format != :fixed + line = ' ' + line.strip! end current.message += line current.logline[1] = linectr @@ -281,8 +285,8 @@ def reset # (initially: @currentmessage = [nil, nil, nil, nil, nil, nil, :none] ) def get_msg() - if ( @type != nil ) - if ( @srcline == nil && @message =~ /(.+?) #{TeXLogParser::space_sep("on input line")} (\d+)\.?$/ ) + if @type != nil + if @srcline == nil && @message =~ /(.+?) #{TeXLogParser::space_sep('on input line')} (\d+)\.?$/ # The first line did not contain the line of warning, but # the last did! @message = $~[1].strip @@ -290,10 +294,10 @@ def get_msg() end res = LogMessage.new(@type, @srcfile, @srcline, @logline, @message, @format) reset - return res + res else reset - return nil + nil end end end diff --git a/ltx2any.rb b/ltx2any.rb index ae8d959..4a901cb 100644 --- a/ltx2any.rb +++ b/ltx2any.rb @@ -18,7 +18,7 @@ # along with ltx2any. If not, see . # Set process name to something less cumbersome -$0="ltx2any" +$0='ltx2any' BASEDIR = File.dirname(__FILE__) require "#{BASEDIR}/constants.rb" @@ -66,7 +66,7 @@ } if !missing.empty? # TODO enter into log? - OUTPUT.separate.error("Missing dependencies", missing) + OUTPUT.separate.error('Missing dependencies', missing) Process.exit end end @@ -81,7 +81,7 @@ } if !missing.empty? # TODO enter into log? - OUTPUT.separate.warn("Missing dependencies", missing) + OUTPUT.separate.warn('Missing dependencies', missing) end end @@ -95,7 +95,7 @@ "#{PARAMS[:user_jobname]}.#{Engine[PARAMS[:engine]].extension}", "#{PARAMS[:log]}", "#{PARAMS[:user_jobname]}.err" - ] + PARAMS[:ignore].split(":") + ] + PARAMS[:ignore].split(':') begin FileListener.instance.start(PARAMS[:user_jobname], toignore) if PARAMS[:daemon] @@ -112,17 +112,17 @@ log.level = PARAMS[:loglevel] start_time = Time.now - OUTPUT.start("Copying files to tmp") + OUTPUT.start('Copying files to tmp') # Copy all files to tmp directory (some LaTeX packages fail to work with # output dir) excepting those we ignore anyways. # Oh, and don't recurse outside the main directory, duh. ignore = FileListener.instance.ignored + toignore exceptions = ignore + ignore.map { |s| "./#{s}" } + - Dir[".*"] + Dir["./.*"] # drop hidden files, in p. . and .. + Dir['.*'] + Dir['./.*'] # drop hidden files, in p. . and .. define_singleton_method(:copy2tmp) { |files| files.each { |f| - if ( File.symlink?(f) ) + if File.symlink?(f) # Avoid trouble with symlink loops # Delete old symlink if there is one, because: @@ -130,16 +130,16 @@ # remove the obsolete stuff. # If there already is a symlink, delete because it might have been # relinked. - if ( File.exists?("#{PARAMS[:tmpdir]}/#{f}") ) + if File.exists?("#{PARAMS[:tmpdir]}/#{f}") FileUtils::rm("#{PARAMS[:tmpdir]}/#{f}") end # Create new symlink instead of copying File.symlink("#{PARAMS[:jobpath]}/#{f}", "#{PARAMS[:tmpdir]}/#{f}") - elsif ( File.directory?(f) ) + elsif File.directory?(f) FileUtils::mkdir_p("#{PARAMS[:tmpdir]}/#{f}") copy2tmp(Dir.entries(f)\ - .delete_if { |s| [".", "..", ]\ + .delete_if { |s| ['.', '..', ]\ .include?(s) }.map { |s| "#{f}/#{s}" }) # TODO Is this necessary? Why not just copy? (For now, safer and more adaptable.) else @@ -149,22 +149,22 @@ } # tmp dir may have been removed (either by DaemonPrompt or the outside) - if ( !File.exist?(PARAMS[:tmpdir]) ) + if !File.exist?(PARAMS[:tmpdir]) FileUtils.mkdir_p(PARAMS[:tmpdir]) - elsif ( !File.directory?(PARAMS[:tmpdir]) ) + elsif !File.directory?(PARAMS[:tmpdir]) OUTPUT.message("File #{PARAMS[:tmpdir]} exists but is not a directory") Process.exit end # (Re-)Copy content to tmp - copy2tmp(Dir.entries(".").delete_if { |f| exceptions.include?(f) }) + copy2tmp(Dir.entries('.').delete_if { |f| exceptions.include?(f) }) OUTPUT.stop(:success) # Move into temporary directory Dir.chdir(PARAMS[:tmpdir]) # Delete former results in order not to pretend success - if ( File.exist?("#{PARAMS[:jobname]}.#{engine.extension}") ) + if File.exist?("#{PARAMS[:jobname]}.#{engine.extension}") FileUtils::rm("#{PARAMS[:jobname]}.#{engine.extension}") end @@ -200,36 +200,44 @@ Extension.run_all(:after, OUTPUT, log) # Give error/warning counts to user - errorS = if ( log.count(:error) != 1 ) then "s" else "" end - warningS = if ( log.count(:warning) != 1 ) then "s" else "" end + errorS = if log.count(:error) != 1 then + 's' + else + '' + end + warningS = if log.count(:warning) != 1 then + 's' + else + '' + end OUTPUT.msg("There were #{log.count(:error)} error#{errorS} " + "and #{log.count(:warning)} warning#{warningS}.") # Pick up output if present - if ( File.exist?("#{PARAMS[:jobname]}.#{engine.extension}") ) + if File.exist?("#{PARAMS[:jobname]}.#{engine.extension}") FileUtils::cp("#{PARAMS[:jobname]}.#{engine.extension}", "#{PARAMS[:jobpath]}/#{PARAMS[:user_jobname]}.#{engine.extension}") OUTPUT.msg("Output generated at #{PARAMS[:user_jobname]}.#{engine.extension}") else - OUTPUT.msg("No output generated, probably due to fatal errors.") + OUTPUT.msg('No output generated, probably due to fatal errors.') end # Write log - if ( !log.empty? ) - OUTPUT.start("Assembling log files") + if !log.empty? + OUTPUT.start('Assembling log files') # Manage messages from extensions Extension.list.each { |ext| - if ( !log.has_messages?(ext.name) \ - && File.exist?(".#{NAME}_extensionmsg_#{ext.name}") ) + if !log.has_messages?(ext.name) \ + && File.exist?(".#{NAME}_extensionmsg_#{ext.name}") # Extension did not run but has run before; load messages from then! - old = File.open(".#{NAME}_extensionmsg_#{ext.name}", "r") { |f| + old = File.open(".#{NAME}_extensionmsg_#{ext.name}", 'r') { |f| f.readlines.join } old = YAML.load(old) log.add_messages(ext.name, old[0], old[1], old[2]) - elsif ( log.has_messages?(ext.name) ) + elsif log.has_messages?(ext.name) # Write new messages - File.open(".#{NAME}_extensionmsg_#{ext.name}", "w") { |f| + File.open(".#{NAME}_extensionmsg_#{ext.name}", 'w') { |f| f.write(YAML.dump(log.messages(ext.name))) } end @@ -240,38 +248,38 @@ log.to_s("#{PARAMS[:log]}.full") mdfallback = false - if ( PARAMS[:logformat] == :pdf ) + if PARAMS[:logformat] == :pdf begin tmpsrc = "#{PARAMS[:log]}.pdf" log.to_pdf(tmpsrc) # Sucks, but OS might not offer correct apps otherwise - if ( !PARAMS[:log].end_with?(".pdf") ) + if !PARAMS[:log].end_with?('.pdf') target = "#{PARAMS[:log]}.pdf" end rescue RuntimeError => e - OUTPUT.stop(:error, "Failed to build PDF log:", e.message) + OUTPUT.stop(:error, 'Failed to build PDF log:', e.message) # Fall back to Markdown log - OUTPUT.start("Falling back to Markdown log") + OUTPUT.start('Falling back to Markdown log') mdfallback = true end end - if ( PARAMS[:logformat] == :latex ) + if PARAMS[:logformat] == :latex tmpsrc = "#{PARAMS[:log]}.tex" log.to_latex(tmpsrc) # Sucks, but viewers can not choose proper highlighting otherwise - if ( !PARAMS[:log].end_with?(".tex") ) + if !PARAMS[:log].end_with?('.tex') target = "#{PARAMS[:log]}.tex" end end - if ( PARAMS[:logformat] == :md || mdfallback ) + if PARAMS[:logformat] == :md || mdfallback tmpsrc = "#{PARAMS[:log]}.md" log.to_md(tmpsrc) # Sucks, but viewers can not choose proper highlighting otherwise - if ( !PARAMS[:log].end_with?(".md") ) + if !PARAMS[:log].end_with?('.md') target = "#{PARAMS[:log]}.md" end end @@ -284,8 +292,8 @@ runtime = Time.now - start_time # Don't show runtimes of less than 5s (arbitrary) - if ( runtime / 60 >= 1 || runtime % 60 >= 5 ) - OUTPUT.msg("Took " + sprintf("%d min ", runtime / 60) + " " + sprintf("%d sec", runtime % 60)) + if runtime / 60 >= 1 || runtime % 60 >= 5 + OUTPUT.msg('Took ' + sprintf('%d min ', runtime / 60) + ' ' + sprintf('%d sec', runtime % 60)) end end rescue Interrupt, SystemExit # User cancelled current run @@ -303,11 +311,11 @@ OUTPUT.separate end while ( PARAMS[:daemon] ) rescue Interrupt, SystemExit - OUTPUT.separate.msg("Shutdown") + OUTPUT.separate.msg('Shutdown') rescue Exception => e - if ( PARAMS[:user_jobname] != nil ) + if PARAMS[:user_jobname] != nil OUTPUT.separate.error(e.message, "See #{PARAMS[:user_jobname]}.err for details.") - File.open("#{PARAMS[:jobpath]}/#{PARAMS[:user_jobname]}.err", "w") { |file| + File.open("#{PARAMS[:jobpath]}/#{PARAMS[:user_jobname]}.err", 'w') { |file| file.write("#{e.inspect}\n\n#{e.backtrace.join("\n")}") } CLEANALL.push("#{PARAMS[:jobpath]}/#{PARAMS[:user_jobname]}.err") diff --git a/parameters.rb b/parameters.rb index a7c1c49..9defa6e 100644 --- a/parameters.rb +++ b/parameters.rb @@ -17,18 +17,18 @@ # along with ltx2any. If not, see . [ - Parameter.new(:user_jobname, "j", String, '"#{self[:jobname]}"', - "Job name, in particular name of the resulting file"), - Parameter.new(:clean, "c", Boolean, false, - "Delete temporary files"), - Parameter.new(:cleanall, "ca", Boolean, false, - "Delete temporary files and logs"), - Parameter.new(:log, "l", String, '"#{self[:user_jobname]}.log"', - "(Base-)Name of log file"), - Parameter.new(:tmpdir, "t", String, '"#{self[:user_jobname]}#{TMPSUFFIX}"', - "Directory for temporary files"), - Parameter.new(:ignore, "i", String, "", - "Files to ignore, separated by colons"), + Parameter.new(:user_jobname, 'j', String, '"#{self[:jobname]}"', + 'Job name, in particular name of the resulting file'), + Parameter.new(:clean, 'c', Boolean, false, + 'Delete temporary files'), + Parameter.new(:cleanall, 'ca', Boolean, false, + 'Delete temporary files and logs'), + Parameter.new(:log, 'l', String, '"#{self[:user_jobname]}.log"', + '(Base-)Name of log file'), + Parameter.new(:tmpdir, 't', String, '"#{self[:user_jobname]}#{TMPSUFFIX}"', + 'Directory for temporary files'), + Parameter.new(:ignore, 'i', String, '', + 'Files to ignore, separated by colons'), ].each { |p| ParameterManager.instance.addParameter(p) } diff --git a/test/test_logparser.rb b/test/test_logparser.rb index 588ac1f..71c5da6 100755 --- a/test/test_logparser.rb +++ b/test/test_logparser.rb @@ -6,11 +6,11 @@ require '../lib/TeXLogParser.rb' if ARGV.size < 1 || !File.exist?(ARGV[0]) - puts "Usage: test_logparser.rb [tex.log]" + puts 'Usage: test_logparser.rb [tex.log]' Process.exit end -File.open(ARGV[0], "r") { |f| +File.open(ARGV[0], 'r') { |f| log = TeXLogParser::parse(f.readlines) puts log.map { |m| m.to_s }.join("\n\n") }