153 lines
4.3 KiB
Python
153 lines
4.3 KiB
Python
"""
|
|
sLaTeX support for Rubber.
|
|
"""
|
|
|
|
from os import unlink
|
|
from os.path import exists, getmtime, join
|
|
|
|
import rubber
|
|
from rubber import _, msg, Depend, DependLeaf
|
|
|
|
def run(doc, env, base):
|
|
msg.progress(_("running slatex on %s") % doc.src_base)
|
|
if env.execute(["slatex", "-n", base], {}):
|
|
msg.error(_("Error executing slatex"))
|
|
return 1
|
|
|
|
doc.must_compile = 1
|
|
return 0
|
|
|
|
def slatex_needed(target, srcs):
|
|
if not exists(target):
|
|
msg.log(_("File %s does not exist") % target, pkg="slatex")
|
|
return 1
|
|
for src in srcs:
|
|
if getmtime(target) < getmtime(src):
|
|
msg.log(_("File %s older than %s") % (target, src), pkg="slatex")
|
|
return 1
|
|
return 0
|
|
|
|
class RubberDep (Depend):
|
|
# Base is the slatex module
|
|
# Target is the autogenerated file (i.e. .Z# + doc.src_base + ".tex")
|
|
# Sources is a list of sources on which this file depends
|
|
def __init__ (self, mod, target, srcs):
|
|
self.mod = mod
|
|
self.doc = mod.doc
|
|
self.env = mod.doc.env
|
|
self.target = target
|
|
self.srcs = srcs
|
|
|
|
sources = {}
|
|
for src in srcs:
|
|
sources[src] = DependLeaf(self.env, src)
|
|
Depend.__init__(self, self.env,
|
|
prods=[target],
|
|
sources=sources)
|
|
|
|
self.urvater = join(self.doc.src_path, self.doc.src_base + ".tex")
|
|
|
|
def run(self):
|
|
# We may have been out of date before any dependency was run,
|
|
# but by this point we may be up to date since slatex builds
|
|
# all the files at once. Otherwise we'll run once per out of
|
|
# date generated file.
|
|
if slatex_needed(self.target, self.srcs):
|
|
run(self.doc, self.env, self.urvater)
|
|
|
|
class Module (rubber.rules.latex.Module):
|
|
def __init__ (self, doc, dict):
|
|
self.base = doc.src_base
|
|
self.base_file = join(doc.src_path, doc.src_base + ".tex")
|
|
self.final = join(doc.env.path[0], doc.env.final.prods[0])
|
|
self.count = 0
|
|
self.doc = doc
|
|
self.env = doc.env
|
|
self.file_deps = {}
|
|
self.path = doc.src_path
|
|
self.preamble = False
|
|
|
|
def add_scheme_file(dict, others=[]):
|
|
filename = ".Z" + str(self.count) + self.base + ".tex"
|
|
path = join(self.path, filename)
|
|
deps = [dict["pos"]["file"]]
|
|
if others:
|
|
deps.extend(others)
|
|
self.doc.sources[path] = RubberDep(self, path, deps)
|
|
msg.log(_("Marking %s as dependent on %s") % (path, deps), pkg = "slatex")
|
|
self.count += 1
|
|
|
|
scheme_macros = ["scheme", "schemeresult"]
|
|
|
|
scheme_envs = ["schemedisplay",
|
|
"schemeresponse",
|
|
"schemebox",
|
|
"schemeresponsebox"]
|
|
|
|
preamble_macros = ["setspecialsymbol",
|
|
"setkeyword",
|
|
"defschememathescape"]
|
|
|
|
def add_preamble_hook(name):
|
|
def h_preamb(dict):
|
|
if not self.preamble and slatex_needed(self.final, [self.base_file]):
|
|
run(self.doc, self.env, self.base_file)
|
|
self.preamble = True
|
|
doc.add_hook(name, h_preamb)
|
|
|
|
def add_macro_hook(name):
|
|
def h_macro(dict):
|
|
add_scheme_file(dict)
|
|
doc.add_hook(name, h_macro)
|
|
|
|
def add_env_hook(name):
|
|
beg_env = "begin{%s}" % name
|
|
end_env = "end{%s}" % name
|
|
def begin_env_hook(dict):
|
|
def end_env_hook(dict, self=doc, hooks=doc.hooks):
|
|
self.hooks = hooks
|
|
self.update_seq()
|
|
doc.hooks = { end_env : end_env_hook }
|
|
# \scheme, \schemeresult allowed in these.
|
|
for macro in scheme_macros:
|
|
add_macro_hook(macro)
|
|
doc.update_seq()
|
|
add_scheme_file(dict)
|
|
doc.add_hook(beg_env, begin_env_hook)
|
|
|
|
for macro in preamble_macros:
|
|
add_preamble_hook(macro)
|
|
for macro in scheme_macros:
|
|
add_macro_hook(macro)
|
|
for environ in scheme_envs:
|
|
add_env_hook(environ)
|
|
|
|
# handled specially so that we get dependence on the
|
|
# file being included as well.
|
|
def h_schemeinput(dict):
|
|
arg_path = join(self.path, dict["arg"])
|
|
add_scheme_file(dict, others=[arg_path])
|
|
|
|
doc.add_hook("schemeinput", h_schemeinput)
|
|
|
|
# schemeregions should generate one file for the entire
|
|
# thing, so we shouldn't allow the separate scheme
|
|
# hooks like above.
|
|
def h_schemeregion(dict, end = "end{schemeregion}"):
|
|
def end_env_hook(dict, self=doc, hooks=doc.hooks):
|
|
self.hooks = hooks
|
|
self.update_seq()
|
|
doc.hooks = doc.hooks.copy()
|
|
doc.hooks[end] = end_env_hook
|
|
for macro in scheme_macros:
|
|
if macro in doc.hooks:
|
|
del doc.hooks[macro]
|
|
for env in scheme_envs:
|
|
if ("begin{%s}" % env) in doc.hooks:
|
|
del doc.hooks["begin{%s}" % env]
|
|
doc.update_seq()
|
|
add_scheme_file(dict)
|
|
|
|
doc.add_hook("begin{schemeregion}", h_schemeregion)
|
|
|