From 70fd3da8263138072c8e7bab8dcfd68e6d1b717c Mon Sep 17 00:00:00 2001 From: Robert Griesel Date: Mon, 28 Jun 2021 02:30:41 +0200 Subject: [PATCH] use pexpect to control latex interpreters --- README.md | 2 +- org.cvfosammmm.Setzer.json | 19 ++++++++++++ .../builder/builder_build_latex.py | 30 +++++++++++-------- .../latex_log_parser/latex_log_parser.py | 2 +- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 60eeecdc..a2835ef6 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Warning: Building Setzer this way may take a long time (~ 30 minutes on my lapto This way is probably a bit faster and may save you some disk space. I develop Setzer on Debian and that's what I tested it with. On Debian derivatives (like Ubuntu) it should probably work the same. On distributions other than Debian and Debian derivatives it should work more or less the same. If you want to run Setzer from source on another distribution and don't know how please open an issue here on GitHub. I will then try to provide instructions for your system. 1. Run the following command to install prerequisite Debian packages:
-`apt-get install meson python3-gi gir1.2-gtk-3.0 gir1.2-gtksource-4 gir1.2-gspell-1 gir1.2-pango-1.0 gir1.2-poppler-0.18 gir1.2-webkit2-4.0 python3-xdg gettext xdg-utils python3-pdfminer python3-cairo` +`apt-get install meson python3-gi gir1.2-gtk-3.0 gir1.2-gtksource-4 gir1.2-gspell-1 gir1.2-pango-1.0 gir1.2-poppler-0.18 gir1.2-webkit2-4.0 python3-xdg gettext xdg-utils python3-pdfminer python3-cairo python3-pexpect` 2. Download und Unpack Setzer from GitHub diff --git a/org.cvfosammmm.Setzer.json b/org.cvfosammmm.Setzer.json index 34fac8e2..04180c68 100644 --- a/org.cvfosammmm.Setzer.json +++ b/org.cvfosammmm.Setzer.json @@ -154,6 +154,25 @@ } ] }, + { + "name": "python3-pexpect", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"pexpect\"" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/e5/9b/ff402e0e930e70467a7178abb7c128709a30dfb22d8777c043e501bc1b10/pexpect-4.8.0.tar.gz", + "sha256": "fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" + }, + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", + "sha256": "5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" + } + ] + }, { "name": "setzer", "buildsystem": "meson", diff --git a/setzer/document/latex/build_system/builder/builder_build_latex.py b/setzer/document/latex/build_system/builder/builder_build_latex.py index 3f5bf896..5a80aa65 100644 --- a/setzer/document/latex/build_system/builder/builder_build_latex.py +++ b/setzer/document/latex/build_system/builder/builder_build_latex.py @@ -17,9 +17,10 @@ import os import os.path +import sys import base64 import shutil -import subprocess +import pexpect from operator import itemgetter import setzer.document.latex.build_system.builder.builder_build as builder_build @@ -37,15 +38,15 @@ def __init__(self): def run(self, query): build_command_defaults = dict() - build_command_defaults['pdflatex'] = 'pdflatex -synctex=1 -interaction=nonstopmode -pdf' - build_command_defaults['xelatex'] = 'xelatex -synctex=1 -interaction=nonstopmode' - build_command_defaults['lualatex'] = 'lualatex --synctex=1 --interaction=nonstopmode' + build_command_defaults['pdflatex'] = 'pdflatex -synctex=1 -interaction=nonstopmode' + build_command_defaults['xelatex'] = 'xelatex -synctex=1 -interaction=errorstopmode' + build_command_defaults['lualatex'] = 'lualatex --synctex=1 --interaction=errorstopmode' if query.build_data['use_latexmk']: if query.build_data['latex_interpreter'] == 'pdflatex': interpreter_option = 'pdf' else: interpreter_option = query.build_data['latex_interpreter'] - build_command = 'latexmk -' + interpreter_option + ' -synctex=1 -interaction=nonstopmode' + query.build_data['additional_arguments'] + build_command = 'latexmk -' + interpreter_option + ' -synctex=1 -interaction=errorstopmode' + query.build_data['additional_arguments'] else: build_command = build_command_defaults[query.build_data['latex_interpreter']] + query.build_data['additional_arguments'] @@ -53,16 +54,21 @@ def run(self, query): arguments.append('-output-directory=' + os.path.dirname(query.tex_filename)) arguments.append(query.tex_filename) try: - self.process = subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=os.path.dirname(query.tex_filename)) + self.process = pexpect.spawn(build_command + ' -output-directory="' + os.path.dirname(query.tex_filename) + '" "' + query.tex_filename + '"', cwd=os.path.dirname(query.tex_filename)) except FileNotFoundError: self.cleanup_files(query) self.throw_build_error(query, 'interpreter_missing', arguments[0]) return - self.process.communicate() - try: - self.process.wait() - except AttributeError: - pass + + while True: + try: + out = self.process.expect(['\r\n', pexpect.EOF, pexpect.TIMEOUT], timeout=1) + except AttributeError: + break + if out == 0: + pass + else: + break # parse results try: @@ -92,7 +98,7 @@ def run(self, query): def stop_running(self): if self.process != None: - self.process.kill() + self.process.terminate(True) self.process = None def parse_build_log(self, query): diff --git a/setzer/document/latex/build_system/latex_log_parser/latex_log_parser.py b/setzer/document/latex/build_system/latex_log_parser/latex_log_parser.py index dd0902d0..2950757a 100644 --- a/setzer/document/latex/build_system/latex_log_parser/latex_log_parser.py +++ b/setzer/document/latex/build_system/latex_log_parser/latex_log_parser.py @@ -28,7 +28,7 @@ def __init__(self): r'(?:Overfull \\hbox|Underfull \\hbox|' + r'No file .*\.|File .* does not exist\.|' + r'(?:LaTeX|pdfTeX|LuaTeX|Package|Class) .*Warning.*:|LaTeX Font Warning:|' + - r'!(?:LaTeX|pdfTeX|LuaTeX|Package|Class) error|' + + r'!(?: )(?:LaTeX|pdfTeX|LuaTeX|Package|Class) error|' + r'! ).*\n)') self.badbox_line_number_regex = ServiceLocator.get_regex_object(r'lines ([0-9]+)--([0-9]+)') self.other_line_number_regex = ServiceLocator.get_regex_object(r'(l\.| input line \n| input line )([0-9]+)( |\.)')