2007-01-24 22:24:01 +08:00
|
|
|
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():
|
2007-01-29 01:16:43 +08:00
|
|
|
options.append('--stylesheet=%s' % (sty.relto(f.dirpath()), ))
|
2007-01-24 22:24:01 +08:00
|
|
|
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()
|