2015-12-30 16:08 GMT+02:00 Christian Mondrup <[email protected]>:
> But when I wanted to test the .ps result and applied the option '-g' (stop
> at postscript level) I got no postscript output file. When I look at the log
> file I notice that the postscript output file has been removed!
>
> I suspect there is a bug in function process_option within musixtex.lua
Thanks for the feedback. Version 0.16a, attached, fixes this.
Dirk
#!/usr/bin/env texlua
VERSION = "0.16a"
--[[
musixtex.lua: processes MusiXTeX files using prepmx and/or pmxab and/or
autosp as pre-processors (and deletes intermediate files)
(c) Copyright 2011-2015 Bob Tennent [email protected]
and Dirk Laurie [email protected]
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 WARRANTY; 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
--]]
--[[
ChangeLog:
version 0.16a 2015-12-30 DL
Corrects bug in -g option reported by Christian Mondrup.
version 0.16 2015-12-24 DL
Versions read from tempfile and written to musixtex.log.
version 0.15 2015-12-03 DL
Option -q added, which redirects most screen output into
a temporary file. If an error occurs at the TeX stage, processing
halts immediately and the tail of the log file is sent to stderr.
version 0.14 2015-12-01 DL
Writes `musixtex.log` and deletes other logfiles (except with -i)
Hierarchy of extensions emphasized in usage() and consistently
used elsewhere.
Unknown option-like arguments reported and ignored, not treated
as filenames
Warnings and error messages generated by musixtex.lua start with
respctively `!` and `!!`.
version 0.13 2015-11-30 RDT
Process .mtx and .pmx files (suggested by Dirk Laurie)
exit_code is now an error count
Use pmxab exit code to distinguish between errors and warnings
version 0.12 2015-11-28 RDT
Process .ltx files, with -l implied
version 0.11 2015-07-16 RDT
Automatic autosp preprocessing.
version 0.10 2015-04-23 RDT
Add -a option to preprocess using autosp
version 0.9 2015-02-13 RDT
Add an additional latex pass to resolve cross-references.
Add -e0 option to dvips as given in musixdoc.tex
Add -x option to call makeindex
version 0.8 2014-05-18 RDT
Add -g option
version 0.7 2013-12-11 RDT
Add -F fmt option
version 0.6 2012-09-14 RDT
Add -1 (one-pass [pdf][la]tex processing) option.
version 0.5 2011-11-28 RDT
Add -i (retain intermediate files) option.
version 0.4 2011-04-30 RDT
Allow multiple filenames (and options).
Add -f (default) and -l (latex) options.
version 0.3 2011-04-25 RDT
Add -d (dvipdfm) and -s (stop at dvi) options.
version 0.2 2011-04-21 RDT
Allow basename.tex as filename.
Add -p option for pdfetex processing.
Add standard -v -h options.
--]]
local orig_print = print
function usage()
orig_print
[[
Usage: [texlua] musixtex.lua { option | basename[.mtx | .pmx | .aspc | .tex | .ltx] } ...
When no extension is given, extensions are tried in the above order
until a source file is found. Preprocessing goes mtx-pmx-tex or
aspc-tex, with the entry point determined by the extension.
The normal route after preprocessing goes tex-dvi-ps-pdf, but shorter
routes are also available, see the options.
Options: -v version
-h help
-l latex source
-p direct tex-pdf (pdftex etc)
-F fmt use fmt as the TeX processor
-d tex-dvi-pdf (dvipdfm)
-c preprocess pmx file using pmxchords
-m stop at pmx
-t stop at tex/mid
-s stop at dvi
-g stop at ps
-i retain intermediate and log files
-q quiet mode (redirect screen logs, write summary on musixtex.log)
-1 one-pass [pdf][la]tex processing
-x run makeindex
-f restore default processing
Four TeX engines are available via the -l and -p options.
etex default
latex -l
pdfetex -p
pdflatex -l -p
The -F option allows any engine to be named. In that case, an attempt is made
to deduce implied -l and -p settings from the presence or absence of the
strings `latex` and `pdf` in the name of the engine. If this is not correct,
the user should explicitly specify the appropriate option.]]
end
function whoami ()
print("This is musixtex.lua version ".. VERSION .. ".")
end
function exists (filename, nolog)
local f = io.open(filename, "r")
if f then
f:close()
if not nolog then musixlog:write("Processing " .. filename,'\n' ) end
return true
else
return false
end
end
-- The global variables below may be changed by set_options(). System
-- commands for the various programs are mostly set to nil if the step
-- is to be omitted, which can be tested by a simple "if" statement.
-- Exceptions:
-- 'tex' is the command for processing a TeX file, but it is important
-- to know whether the user has explicitly specified an option that
-- affects this choice, in which case the automatic selection of the
-- command is restricted or disabled.
-- force_engine "use the command provided"
-- override records when 'l' and/or 'p' options are in effect
-- 'dvi' is the command for processing a DVI file, but there are two
-- reasons for not needing it and it is important for the automatic
-- selection of a TeX engine to know which is in effect. This is
-- possible by exploiting the the fact that Lua has two false values.
-- dvi == nil "do not produce a DVI file" (but maybe PDF)
-- dvi == false "do not process the DVI file" (but stop after TeX)
local dvips = "dvips -e0"
function defaults()
prepmx = "prepmx"
pmx = "pmxab"
tex = "etex"
musixflx = "musixflx"
dvi = dvips
ps2pdf = "ps2pdf"
cleanup = true -- clean up intermediate and log files
index = false
latex = false
force_engine = false -- indicates whether -F is specified
override = ""
passes = 2
quiet = "" -- set by "-q"
end
------------------------------------------------------------------------
if #arg == 0 then
whoami()
usage()
os.exit(0)
end
-- Logging on `musixtex.log` everything that is printed, all os calls,
-- and warnings from other log files.
musixlog = io.open("musixtex.log","w")
if not musixlog then
print"!! Can't open files for writing in current directory, aborting"
os.exit(1)
end
------------------------------------------------------------------------
print = function(...)
orig_print(...)
musixlog:write(...,"\n") -- only the first argument gets written!
end
local orig_remove = os.remove
remove = function(filename)
if exists(filename,"nolog") then
musixlog:write(" removing ",filename,"\n")
return orig_remove(filename)
end
end
local orig_execute = os.execute
execute = function(command)
musixlog:write(" ",command,"\n")
return orig_execute(command .. quiet)
end
function report_warnings(filename,pattern)
local log = io.open(filename)
if not log then
print("! No file "..filename)
return
end
for line in log:lines() do
if line:match(pattern) then
musixlog:write("! "..line,"\n")
end
end
end
function report_error(filename)
local log = io.open(filename)
if not log then
print("! No file "..filename)
return
end
local trigger = false
for line in log:lines() do
trigger = trigger or line:match"^!"
if trigger then
io.stderr:write("! "..line,"\n")
end
end
end
function process_option(this_arg)
if this_arg == "-v" then
os.exit(0)
elseif this_arg == "-h" then
usage()
os.exit(0)
elseif this_arg == "-l" then
latex = true
override = override .. 'l'
elseif this_arg == "-p" then
dvi = nil
override = override .. 'p'
elseif this_arg == "-d" then
dvi = "dvipdfm"; ps2pdf = nil
elseif this_arg == "-c" then
pmx = "pmxchords"
elseif this_arg == "-F" then
narg = narg+1
tex = arg[narg]
force_engine = true
elseif this_arg == "-s" then
dvi = false; ps2pdf = nil; protect.dvi = true
elseif this_arg == "-g" then
dvi = dvips; ps2pdf = nil; protect.ps = true
elseif this_arg == "-i" then
cleanup = false
elseif this_arg == "-x" then
index = true
elseif this_arg == "-1" then
passes = 1
elseif this_arg == "-f" then
defaults()
elseif this_arg == "-t" then
tex, dvi, ps2pdf = nil,nil,nil
protect.tex = true
elseif this_arg == "-m" then
pmx, tex, dvi, ps2pdf = nil,nil,nil,nil
protect.pmx = true
elseif this_arg == "-q" then
if not tempname then
tempname = tempname or os.tmpname()
print("Redirecting screen output to "..tempname)
end
if dvi == dvips then dvi = dvi .. " -q" end
quiet = " >> " .. tempname
else
print("! Unknown option "..this_arg.." ignored")
end
end
function find_file(this_arg)
basename, extension = this_arg:match"(.*)%.(.*)"
if not extension then
basename = this_arg
for ext in ("mtx,pmx,aspc,tex,ltx"):gmatch"[^,]+" do
if exists (basename .. "." .. ext) then
extension = ext
break
end
end
if not extension then
print("!! No file " .. basename .. "[.mtx|.pmx|.aspc|.tex|.ltx]")
exit_code = exit_code+1
return
end
end
if tex then -- tex output enabled, now select engine
if tex:match"pdf" then dvi = nil end
if not dvi then ps2pdf = nil end
-- .ltx extension will be taken into account later, in `process`
-- deduce tex/latex from current engine name if -l is not specified
if not override:match"l" then latex = tex:match"latex" end
if not force_engine then -- select appropriate default engine
if latex then
if dvi==nil then tex = "pdflatex" else tex = "latex" end
else
if dvi==nil then tex = "pdfetex" else tex = "etex" end
end
end
end
return basename, extension
end
function preprocess(basename,extension)
if not (basename and extension) then return end
if extension == "mtx" then
if execute(prepmx .. " " .. basename ) == 0 then
extension = "pmx"
else
print ("!! prepmx preprocessing of " .. basename .. ".mtx fails.")
return
end
end
if extension == "pmx" then
local OK = true
if pmx then
local code = execute(pmx .. " " .. basename)
local pmxaerr = io.open("pmxaerr.dat", "r")
if (not pmxaerr) then
OK = false
print("!! No pmx log file.")
else
extension = "tex"
local linebuf = pmxaerr:read()
local err = tonumber(linebuf)
if (code == 0) then
if err ~=0 then
print ("! pmx produced a warning on line "..err..
" of "..basename..".pmx")
end
else
OK = false
print ("!! pmx processing of " .. basename .. ".pmx fails.")
end
pmxaerr:close()
end
end
if not OK then
exit_code = exit_code+1
return
end
end
if extension == "aspc" then
if execute ("autosp " .. basename .. ".aspc" ) == 0 then
extension = "tex"
else
print ("!! autosp preprocessing of " .. filename .. " fails.")
exit_code = exit_code+1
return
end
end
return extension
end
function tex_process(tex,basename,extension)
if not (extension == "tex" or extension == "ltx") or not tex then return end
remove(basename .. ".mx2")
local filename = basename .. "." ..extension
-- .ltx extension re-selects engine only for the current file, and only
-- if default processing is plain TeX
local latex = latex
if extension == "ltx" then
if not force_engine and not latex then
if dvi then tex = "latex" else tex = "pdflatex" end
end
latex = true
end
if quiet ~= "" then
tex = tex .. " -halt-on-error"
end
local OK = (execute(tex .. " " .. filename) == 0)
if passes ~= 1 then
OK = OK and (execute(musixflx .. " " .. basename) == 0)
and (execute(tex .. " " .. filename) == 0)
if latex and index then
OK = OK and (execute("makeindex -q " .. basename) == 0)
and (execute(tex .. " " .. filename) == 0)
if exists (basename .. ".toc","nolog") then
-- an extra line for the index will have been added
OK = OK and (execute(tex .. " " .. filename) == 0)
-- there is a tiny possibility that the extra line for the index
-- has changed the pagination. If you feel this should not be
-- ignored, here are the possibilities:
-- a. Do an extra TeX pass regardless.
-- b. Provide a user option -4 to force the extra pass.
-- c. Compare aux files to find out.
end
end
end
if (quiet ~= "") and not OK then
report_error(basename..".log")
end
if OK and latex then
report_warnings(basename..".log","LaTeX.*Warning")
end
if dvi then OK = OK and (execute(dvi .. " " .. basename) == 0) end
if dvi and ps2pdf then
OK = OK and (execute(ps2pdf .. " " .. basename .. ".ps") == 0)
if OK then
print(basename .. ".pdf generated by " .. ps2pdf .. ".")
end
end
if not OK then
print("!! Processing of " .. filename .. " fails.\n")
exit_code = exit_code+1
end
end
-- Extracting version and path information from tempname.
-- The targets below rely on the exact output format used by various
-- programs and TeX files.
targets = {
mtxtex = "%(([^(]+mtx%.tex)%s*$",
mtxlatex = "%(([^(]+mtxlatex%.sty)",
mtxLaTeX = ".*mtxLaTeX.*",
pmxtex = "%(([^(]+pmx%.tex)",
musixtex = "%(([^(]+musixtex%.tex)",
musixltx = "%(([^(]+musixltx%.tex)",
musixlyr = "%(([^(]+musixlyr%.tex)",
MTx = "This is (M%-Tx.->)",
PMX = "This is (PMX[^\n]+)",
pdftex = "This is (pdfTeX[^\n]+)",
musixflx = "Musixflx%S+",
autosp = "This is autosp.*$",
index = "MTx,mtxtex,mtxlatex,mtxLaTeX,PMX,pmxtex,musixtex,musixltx,musixlyr,"
.."musixflx,pdftex"
}
extra_line = { mtxtex=true, musixtex=true, musixltx=true, pmxtex=true,
musixlyr=true }
function report_versions(tempname)
if not tempname then return end -- only available with -q
local logs = io.open(tempname)
if not logs then
print ("No version information: could not open "..tempname)
return
end
local versions = {}
local extra
musixlog:write("--- Packages actually used according to "..
tempname.." ---\n")
for line in logs:lines() do
if extra then
versions[extra] = versions[extra] .. "\n " ..line
extra = false
else for target, pattern in pairs(targets) do
if not versions[target] then
local found = line:match(pattern)
if found then
extra = extra_line[target] and target
versions[target] = found
end
end
end end
end
logs:close()
for target in targets.index:gmatch"[^,]+" do if versions[target] then
if target=="mtxLaTeX" then musixlog:write" " end
musixlog:write(versions[target],"\n")
end end
end
------------------------------------------------------------------------
whoami()
defaults()
exit_code = 0
narg = 1
protect = {} -- extensions not to be deleted, even if cleanup requested
repeat
this_arg = arg[narg]
if this_arg:match"^%-" then process_option(this_arg)
else
basename, extension = find_file(this_arg) -- nil,nil if not found
extension = preprocess(basename,extension)
tex_process(tex,basename,extension)
if basename and cleanup then
remove("pmxaerr.dat")
for ext in ("mx1,mx2,dvi,ps,idx,log,ilg,pml"):gmatch"[^,]+" do
if not protect[ext] then remove(basename.."."..ext)
end
end
end
protect = {}
end
narg = narg+1
until narg > #arg
report_versions(tempname)
musixlog:close()
os.exit( exit_code )
-------------------------------
[email protected] mailing list
If you want to unsubscribe or look at the archives, go to
http://tug.org/mailman/listinfo/tex-music