diff options
Diffstat (limited to '')
-rwxr-xr-x | share/extensions/pdflatex.py | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/share/extensions/pdflatex.py b/share/extensions/pdflatex.py new file mode 100755 index 0000000..f989191 --- /dev/null +++ b/share/extensions/pdflatex.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# coding=utf-8 +# +# Copyright (C) 2019 Marc Jeanmougin +# +# 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 +# +""" +Generate Latex via a PDF using pdflatex +""" + +import os + +import inkex +from inkex.base import TempDirMixin +from inkex.command import ProgramRunError, call, inkscape +from inkex import load_svg, ShapeElement, Defs +from inkex.units import convert_unit +from inkex.localization import inkex_gettext as _ + + +class PdfLatex(TempDirMixin, inkex.GenerateExtension): + """ + Use pdflatex to generate LaTeX, this whole hack is required because + we don't want to open a LaTeX document as a document, but as a + generated fragment (like import, but done manually). + """ + + def add_arguments(self, pars): + pars.add_argument( + "--formule", + type=str, + default=r"\(\displaystyle\frac{\pi^2}{6}=\lim_{n \to \infty}\sum_{k=1}^n \frac{1}{k^2}\)", + ) + pars.add_argument( + "--preamble", + type=str, + default="".join( + f"\\usepackage{{ams{i}}}" for i in ["math", "symb", "fonts"] + ), + ) + pars.add_argument("--font_size", type=int, default=10) + pars.add_argument("--page", choices=["basic", "advanced"]) + pars.add_argument("--standalone", type=inkex.Boolean, default=True) + + def generate(self): + tex_file = os.path.join(self.tempdir, "input.tex") + pdf_file = os.path.join(self.tempdir, "input.pdf") # Auto-generate by pdflatex + svg_file = os.path.join(self.tempdir, "output.svg") + + with open(tex_file, "w") as fhl: + self.write_latex(fhl) + + try: + call( + "pdflatex", + tex_file, + output_directory=self.tempdir, + halt_on_error=True, + oldie=True, + ) + except ProgramRunError as err: + inkex.errormsg(_("An exception occurred during LaTeX compilation: ") + "\n") + inkex.errormsg(err.stdout.decode("utf8").replace("\r\n", "\n")) + raise inkex.AbortExtension() + + inkscape( + pdf_file, + export_filename=svg_file, + pdf_page=1, + pdf_poppler=True, + export_type="svg", + actions=( + "select-all;page-fit-to-selection;" + "clone-unlink-recursively;vacuum-defs" + ), + ) + + if not os.path.isfile(svg_file): + fn = os.path.basename(svg_file) + if os.path.isfile(fn): + # Inkscape bug detected, file got saved wrong + svg_file = fn + + with open(svg_file, "r") as fhl: + svg: inkex.SvgDocumentElement = load_svg(fhl).getroot() + + scale = convert_unit("1pt", "px") / self.svg.scale + if not self.options.standalone: + scale *= self.options.font_size / 10 + + for child in svg: + if isinstance(child, ShapeElement): + child.transform = inkex.Transform(scale=scale) @ child.transform + yield child + elif isinstance(child, Defs): + for def_child in child: + # The ids of both the imported and the target document should + # be off-limits + def_child.set_random_ids( + backlinks=True, blacklist=self.svg.get_ids() + ) + self.svg.defs.append(def_child) + + def write_latex(self, stream): + """Takes a formula and wraps it in latex""" + if self.options.standalone: + docclass = ( + f"\\documentclass[fontsize={self.options.font_size}pt, " + + "class=scrreprt, preview]{standalone}" + ) + else: + docclass = r"\documentclass{minimal}" + stream.write( + f"""%% processed with pdflatex.py +{docclass} +{self.options.preamble} +\\begin{{document}} +{self.options.formule} +\\end{{document}} +""" + ) + stream.flush() + + +if __name__ == "__main__": + PdfLatex().run() |