Blame lib/dbtexmf/dblatex/runtex.py

Packit 0f19cf
#
Packit 0f19cf
# Basic module compiling a file with LaTeX
Packit 0f19cf
#
Packit 0f19cf
import os
Packit 0f19cf
import re
Packit 0f19cf
import shutil
Packit Service f3de8e
from io import open
Packit 0f19cf
Packit Service f3de8e
from dbtexmf.dblatex.grubber.texbuilder import LatexBuilder
Packit 0f19cf
Packit 0f19cf
Packit 0f19cf
class RunLatex:
Packit 0f19cf
    def __init__(self):
Packit 0f19cf
        self.fig_paths = []
Packit 0f19cf
        self.index_style = ""
Packit 0f19cf
        self.backend = "pdftex"
Packit 0f19cf
        self.texpost = ""
Packit 0f19cf
        self.texer = LatexBuilder()
Packit 0f19cf
Packit 0f19cf
    def set_fig_paths(self, paths):
Packit 0f19cf
        # Assume the paths are already absolute
Packit 0f19cf
        if not(paths):
Packit 0f19cf
            return
Packit 0f19cf
Packit 0f19cf
        # Use TEXINPUTS to handle paths containing spaces
Packit 0f19cf
        paths_blank = []
Packit 0f19cf
        paths_input = []
Packit 0f19cf
        for p in paths:
Packit 0f19cf
            if p.find(" ") != -1:
Packit 0f19cf
                paths_blank.append(p + "//")
Packit 0f19cf
            else:
Packit 0f19cf
                paths_input.append(p)
Packit 0f19cf
Packit 0f19cf
        if paths_blank:
Packit 0f19cf
            texinputs = os.pathsep.join(paths_blank)
Packit 0f19cf
            os.environ["TEXINPUTS"] = os.getenv("TEXINPUTS") + os.pathsep + \
Packit 0f19cf
                                      texinputs
Packit 0f19cf
Packit 0f19cf
        paths = paths_input
Packit 0f19cf
Packit 0f19cf
        # Unixify the paths when under Windows
Packit 0f19cf
        if os.sep != "/":
Packit 0f19cf
            paths = [p.replace(os.sep, "/") for p in paths]
Packit 0f19cf
Packit 0f19cf
        # Protect from tilde active char (maybe others?)
Packit 0f19cf
        self.fig_paths = [p.replace("~", r"\string~") for p in paths]
Packit 0f19cf
Packit 0f19cf
    def set_bib_paths(self, bibpaths, bstpaths=None):
Packit 0f19cf
        # Just set BIBINPUTS and/or BSTINPUTS
Packit 0f19cf
        if bibpaths:
Packit 0f19cf
            os.environ["BIBINPUTS"] = os.pathsep.join(bibpaths +
Packit 0f19cf
                                                   [os.getenv("BIBINPUTS", "")])
Packit 0f19cf
        if bstpaths:
Packit 0f19cf
            os.environ["BSTINPUTS"] = os.pathsep.join(bstpaths +
Packit 0f19cf
                                                   [os.getenv("BSTINPUTS", "")])
Packit 0f19cf
Packit 0f19cf
    def set_backend(self, backend):
Packit 0f19cf
        if not(backend in ("dvips", "pdftex", "xetex")):
Packit 0f19cf
            raise ValueError("'%s': invalid backend" % backend)
Packit 0f19cf
        self.backend = backend
Packit 0f19cf
Packit 0f19cf
    def get_backend(self):
Packit 0f19cf
        return self.backend
Packit 0f19cf
Packit 0f19cf
    def _clear_params(self):
Packit 0f19cf
        self._param_started = 0
Packit 0f19cf
        self._param_ended = 0
Packit 0f19cf
        self._params = {}
Packit 0f19cf
Packit 0f19cf
    def _set_params(self, line):
Packit 0f19cf
        # FIXME
Packit 0f19cf
        if self._param_ended:
Packit 0f19cf
            return
Packit 0f19cf
        if not(self._param_started):
Packit 0f19cf
            if line.startswith("%%<params>"): self._param_started = 1
Packit 0f19cf
            return
Packit 0f19cf
        if line.startswith("%%</params>"):
Packit 0f19cf
            self._param_ended = 1
Packit 0f19cf
            return
Packit 0f19cf
        # Expected format is: '%% <param_name> <param_string>\n'
Packit 0f19cf
        p = line.split(" ", 2)
Packit 0f19cf
        self._params[p[1]] = p[2].strip()
Packit 0f19cf
Packit 0f19cf
    def compile(self, texfile, binfile, format, batch=1):
Packit 0f19cf
        root = os.path.splitext(texfile)[0]
Packit 0f19cf
        tmptex = root + "_tmp" + ".tex"
Packit 0f19cf
        texout = root + "." + format
Packit 0f19cf
Packit 0f19cf
        # The temporary file contains the extra paths
Packit Service f3de8e
        f = open(tmptex, "wt", encoding="latin-1")
Packit 0f19cf
        if self.fig_paths:
Packit 0f19cf
            paths = "{" + "//}{".join(self.fig_paths) + "//}"
Packit Service f3de8e
            f.write(u"\\makeatletter\n")
Packit Service f3de8e
            f.write(u"\\def\\input@path{%s}\n" % paths)
Packit Service f3de8e
            f.write(u"\\makeatother\n")
Packit 0f19cf
Packit 0f19cf
        # Copy the original file and collect parameters embedded in the tex file
Packit 0f19cf
        self._clear_params()
Packit Service f3de8e
        input = open(texfile, "rt", encoding="latin-1")
Packit 0f19cf
        for line in input:
Packit 0f19cf
            self._set_params(line)
Packit 0f19cf
            f.write(line)
Packit 0f19cf
        f.close()
Packit 0f19cf
        input.close()
Packit 0f19cf
Packit 0f19cf
        # Replace the original file with the new one
Packit 0f19cf
        shutil.move(tmptex, texfile)
Packit 0f19cf
Packit 0f19cf
        # Build the output file
Packit 0f19cf
        try:
Packit 0f19cf
            self.texer.batch = batch
Packit 0f19cf
            self.texer.texpost = self.texpost
Packit 0f19cf
            self.texer.encoding = self._params.get("latex.encoding", "latin-1")
Packit 0f19cf
            self.texer.options = self._params.get("latex.engine.options")
Packit 0f19cf
            self.texer.lang = self._params.get("document.language")
Packit 0f19cf
            self.texer.set_format(format)
Packit 0f19cf
            self.texer.set_backend(self.backend)
Packit 0f19cf
            if self.index_style:
Packit 0f19cf
                self.texer.index.style = self.index_style
Packit 0f19cf
            self.texer.index.tool = self._params.get("latex.index.tool")
Packit 0f19cf
            self.texer.index.lang = self._params.get("latex.index.language")
Packit 0f19cf
            self.texer.compile(texfile)
Packit 0f19cf
            self.texer.print_misschars()
Packit 0f19cf
        except:
Packit 0f19cf
            # On error, dump the log errors and raise again
Packit 0f19cf
            self.texer.print_errors()
Packit 0f19cf
            raise
Packit 0f19cf
Packit 0f19cf
        if texout != binfile:
Packit 0f19cf
            shutil.move(texout, binfile)
Packit 0f19cf
Packit 0f19cf
    def clean(self):
Packit 0f19cf
        self.texer.clean()
Packit 0f19cf
Packit 0f19cf
    def reinit(self):
Packit 0f19cf
        self.texer.reinit()
Packit 0f19cf