Compare commits

..

1 Commits
main ... master

Author SHA1 Message Date
Admar Schoonen 9768a3ab89 Added printing empty lines after compilation
Adding printing an empty line after a compile iteration has finished
makes it easier to parse the output and look for errors.
2018-06-22 20:56:04 +02:00
3 changed files with 86 additions and 93 deletions

View File

View File

179
rubberin
View File

@ -13,31 +13,29 @@
# the result of the LaTeX compilation and forces it to reload every time
# rubberin has recompiled the LaTeX file.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WAR RANTY; without even the implied warranty of
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WAR RANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this p rogram; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
require "English"
require "getoptlong"
require "rb-inotify"
require "pathname"
require 'getoptlong'
require 'rb-inotify'
require 'pathname'
# Small necessary Pathname class extension.
class Pathname
def extname=(ext)
raise "Invalid extension" unless ext.is_a?(String) && ext.match(/^\./)
raise "Invalid extension" unless ext.is_a? String and ext.match(/^\./)
@path.sub!(/#{extname}$/, ext)
end
end
@ -46,7 +44,7 @@ end
# Print the usage.
def usage
puts "Usage: #{PROGRAM} [options]... [tex-file] [rubber-options]..."
puts "Usage: #{Program} [options]... [tex-file] [rubber-options]..."
end
# Print the command line help.
@ -64,33 +62,34 @@ end
# Compile the input file using the right options based on the mode.
def compile(infile, mode)
mode_opt = { pdf: "--pdf",
ps: "--ps",
pspdf: "--ps --pdf" }[mode]
params = ARGV.join(" ")
err_file = infile.with_extname("err")
mode_opt = {:pdf => "--pdf",
:ps => "--ps",
:pspdf => "--ps --pdf"}[mode]
params = ARGV.join(' ')
err_file = infile.with_extname('err')
system "rubber --inplace #{mode_opt} #{params} #{infile} 2> #{err_file}"
ret = system "rubber --inplace #{mode_opt} #{params} #{infile} 2> #{err_file}"
File.open(err_file) { |file| puts file.read }
# Remove the output save file if compile was succesful.
#clean(infile) if ret
end
# Start the right viewer based on the mode.
def view(infile, mode)
case mode
when :dvi
system "xdvi.bin",
"-watchfile", "1",
"-name", "xdvi", infile.with_extname("dvi").to_s
when :ps
system "evince", infile.with_extname("ps").to_s
when :pdf, :pspdf
system "evince", infile.with_extname("pdf").to_s
when :dvi
exec "xdvi.bin", "-watchfile", "1",
"-name", "xdvi", infile.with_extname('dvi').to_s
when :ps
exec "evince", infile.with_extname('ps').to_s
when :pdf, :pspdf
exec "evince", infile.with_extname('pdf').to_s
end
end
# Clean up cruft related to compilation of the input file.
def clean(infile)
err_file = infile.with_extname("err")
err_file = infile.with_extname('err')
File.unlink(err_file) if err_file.exist?
system "rubber --clean --inplace #{infile}"
end
@ -98,54 +97,55 @@ end
# Reload the right viewer based on the mode.
def reload(infile, mode)
case mode
when :ps
system "evince", infile.with_extname("ps").to_s
when :pdf, :pspdf
system "evince", infile.with_extname("pdf").to_s
when :ps
system "evince", infile.with_extname('ps').to_s
when :pdf, :pspdf
system "evince", infile.with_extname('pdf').to_s
end
end
## Initialisation
PROGRAM = File.basename($PROGRAM_NAME).freeze
VERSION = "0.9".freeze
Program = File.basename $0
Version = '0.6'
# Parse the command line options.
# Determine the compile mode from the options.
mode = :dvi
opts = GetoptLong.new(["--help", "-h", GetoptLong::NO_ARGUMENT],
["--ps", "-p", GetoptLong::NO_ARGUMENT],
["--pdf", "-d", GetoptLong::NO_ARGUMENT],
["--version", "-v", GetoptLong::NO_ARGUMENT])
opts = GetoptLong.new(
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
[ "--ps", "-p", GetoptLong::NO_ARGUMENT ],
[ "--pdf", "-d", GetoptLong::NO_ARGUMENT ],
[ "--version", "-v", GetoptLong::NO_ARGUMENT ])
opts.ordering = GetoptLong::REQUIRE_ORDER
opts.quiet = true
opts.each do |opt, _arg|
opts.each do |opt, arg|
case opt
when "--help"
help
exit 0
when "--ps"
mode = :ps
when "--pdf"
mode = if mode == :ps
:pspdf
else
:pdf
end
when "--version"
puts "#{PROGRAM} #{VERSION}"
exit 0
when "--help"
help
exit 0
when "--ps"
mode = :ps
when "--pdf"
mode = if mode == :ps then :pspdf
else :pdf
end
when "--version"
puts "#{Program} #{Version}"
exit 0
end
end
# Get the input file from the arguments.
if ARGV.empty?
if ARGV.length < 1
usage
exit 1
else
infile = Pathname.new(ARGV.shift)
def infile.base
self.basename(self.extname)
end
def infile.with_extname(ext)
file = dirname + basename(extname)
file = self.base
file.extname = ".#{ext}"
file
end
@ -154,58 +154,51 @@ end
# Check the input file.
begin
File.open(infile) {}
rescue SystemCallError => e
puts "#{PROGRAM}: #{e}"
rescue => err
puts "#{Program}: #{err}"
exit 2
end
# Find the dependencies of the input file using rubber-info and
# Find the dependancies of the input file using rubber-info and
# do an initial run.
files = `rubber-info --deps #{infile}`.chomp.split
compile(infile, mode)
puts
puts ""
# Spawn a viewer based on the mode.
pid = $PROCESS_ID
viewer_pid =
fork do
view(infile, mode)
# If xdvi/evince exits, this program should exit too.
puts "#{PROGRAM}: viewer exited, so will I!"
Process.kill("HUP", pid)
viewer_pid = fork
view(infile, mode) if not viewer_pid
# Handle signals.
["INT", "TERM", "QUIT"].each do |sig|
Signal.trap(sig) do
Process.kill(sig, viewer_pid)
clean(infile)
exit
end
end
# If xdvi exits, this program should exit too.
Signal.trap("CLD") do
puts "#{Program}: viewer exited, so will I!"
clean(infile)
exit
end
## Main event loop
# Add input file with dependancies to the watch list and start event loop.
notifier = INotify::Notifier.new
dirs = files.map { |file| Pathname.new(file).dirname }.uniq
dirs = files.map { |file| File.dirname(file) }
dirs.each do |dir|
# Set up a watch per directory
notifier.watch(dir.to_s, :close_write) do |ev|
notifier.watch(dir, :close_write) do |ev|
# Only compile if a dependency of the input file has been modified
file_path = (dir + ev.name).to_s
next unless files.include? file_path
puts "#{PROGRAM}: file #{ev.name} modified, compiling #{infile}..."
next unless files.include?(dir + "/" + ev.name)
puts "I: file #{ev.name} modified, compiling #{infile}..."
compile(infile, mode)
reload(infile, mode)
puts
puts ""
end
end
# Handle signals during the main event loop.
["INT", "TERM", "QUIT"].each do |sig|
Signal.trap(sig) do
puts "#{PROGRAM}: caught signal #{sig}, stopping the viewer..."
Process.kill(sig, viewer_pid)
notifier.stop
end
end
Signal.trap("HUP") { notifier.stop }
# Run the main event loop.
notifier.run
# Clean before finishing!
clean(infile)