test_ok1/py/rest/latex.py

154 lines
5.2 KiB
Python
Raw Normal View History

import py
from py.__.process.cmdexec import ExecutionFailed
font_to_package = {"times": "times", "helvetica": "times",
"new century schoolbock": "newcent", "avant garde": "newcent",
"palatino": "palatino",
}
sans_serif_fonts = {"helvetica": True,
"avant garde": True,
}
def merge_files(pathlist, pagebreak=False):
if len(pathlist) == 1:
return pathlist[0].read()
sectnum = False
toc = False
result = []
includes = {}
for path in pathlist:
lines = path.readlines()
for line in lines:
# prevent several table of contents
# and especially sectnum several times
if ".. contents::" in line:
if not toc:
toc = True
result.append(line)
elif ".. sectnum::" in line:
if not sectnum:
sectnum = True
result.append(line)
elif line.strip().startswith(".. include:: "):
#XXX slightly unsafe
inc = line.strip()[13:]
if inc not in includes:
includes[inc] = True
result.append(line)
else:
result.append(line)
if pagebreak:
result.append(".. raw:: latex \n\n \\newpage\n\n")
if pagebreak:
result.pop() #remove the last pagebreak again
return "".join(result)
def create_stylesheet(options, path):
fill_in = {}
if "logo" in options:
fill_in["have_logo"] = ""
fill_in["logo"] = options["logo"]
else:
fill_in["have_logo"] = "%"
fill_in["logo"] = ""
if "font" in options:
font = options["font"].lower()
fill_in["font_package"] = font_to_package[font]
fill_in["specified_font"] = ""
fill_in["sans_serif"] = font not in sans_serif_fonts and "%" or ""
else:
fill_in["specified_font"] = "%"
fill_in["sans_serif"] = "%"
fill_in["font_package"] = ""
if 'toc_depth' in options:
fill_in["have_tocdepth"] = ""
fill_in["toc_depth"] = options["toc_depth"]
else:
fill_in["have_tocdepth"] = "%"
fill_in["toc_depth"] = ""
fill_in["heading"] = options.get("heading", "")
template_file = path.join("rest.sty.template")
if not template_file.check():
template_file = py.magic.autopath().dirpath().join("rest.sty.template")
return template_file.read() % fill_in
def process_configfile(configfile, debug=False):
old = py.path.local()
py.path.local(configfile).dirpath().chdir()
configfile = py.path.local(configfile)
path = configfile.dirpath()
configfile_dic = {}
py.std.sys.path.insert(0, str(path))
execfile(str(configfile), configfile_dic)
pagebreak = configfile_dic.get("pagebreak", False)
rest_sources = [py.path.local(p)
for p in configfile_dic['rest_sources']]
rest = configfile.new(ext='txt')
if len(rest_sources) > 1:
assert rest not in rest_sources
content = merge_files(rest_sources, pagebreak)
if len(rest_sources) > 1:
rest.write(content)
sty = configfile.new(ext='sty')
content = create_stylesheet(configfile_dic, path)
sty.write(content)
rest_options = None
if 'rest_options' in configfile_dic:
rest_options = configfile_dic['rest_options']
process_rest_file(rest, sty.basename, debug, rest_options)
#cleanup:
if not debug:
sty.remove()
if rest not in rest_sources:
rest.remove()
old.chdir()
def process_rest_file(restfile, stylesheet=None, debug=False, rest_options=None):
from docutils.core import publish_cmdline
if not py.path.local.sysfind("pdflatex"):
raise SystemExit("ERROR: pdflatex not found")
old = py.path.local()
f = py.path.local(restfile)
path = f.dirpath()
path.chdir()
pdf = f.new(ext="pdf")
if pdf.check():
pdf.remove()
tex = f.new(ext="tex").basename
options = [f, "--input-encoding=latin-1", "--graphicx-option=auto",
"--traceback"]
if stylesheet is not None:
sty = path.join(stylesheet)
if sty.check():
options.append('--stylesheet=%s' % (sty.relto(f), ))
options.append(f.new(basename=tex))
options = map(str, options)
if rest_options is not None:
options.extend(rest_options)
publish_cmdline(writer_name='latex', argv=options)
i = 0
while i < 10: # there should never be as many as five reruns, but to be sure
try:
latexoutput = py.process.cmdexec('pdflatex "%s"' % (tex, ))
except ExecutionFailed, e:
print "ERROR: pdflatex execution failed"
print "pdflatex stdout:"
print e.out
print "pdflatex stderr:"
print e.err
raise SystemExit
if debug:
print latexoutput
if py.std.re.search("LaTeX Warning:.*Rerun", latexoutput) is None:
break
i += 1
old.chdir()
#cleanup:
if not debug:
for ext in "log aux tex out".split():
p = pdf.new(ext=ext)
p.remove()