Recovering Latex Compilation Errors

前端 未结 1 941
情歌与酒
情歌与酒 2021-01-24 23:57

I have a program to write a text and when I click on the \'compile\' button, it compiles to latex, converts to pdf and displays it on my application. The problem is that when I

相关标签:
1条回答
  • 2021-01-25 00:30

    It is difficult to know the error of your problem since there can be many causes so I have created my example from scratch. To do this you must have the following file structure: At the side of the script there must be a folder called 3rdParty where you must unzip the file downloaded from PDF.js.

    ├── 3rdParty
    │   └── pdfjs-2.2.228-dist
    │       ├── build
    │       │   ├── pdf.js
    │       │   ├── pdf.js.map
    │       │   ├── pdf.worker.js
    │       │   └── pdf.worker.js.map
    │       ├── LICENSE
    │       └── web
    │           ├── cmaps
    │           ├── compressed.tracemonkey-pldi-09.pdf
    │           ├── debugger.js
    │           ├── images
    │           ├── locale
    │           ├── viewer.css
    │           ├── viewer.html
    │           ├── viewer.js
    │           └── viewer.js.map
    ├── main.py
    └── tmp
    

    Instead of using os.system () it is better to use a method that gives feedback on the state of the conversion, in this case use QProcess, in addition to adding more options such as "-interaction=nonstopmode", "-jobname=FILENAME" and "-output-directory=DIR" that allow that there is no interactive mode, point to the folder Output and name of pdf:

    import os
    from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
    
    CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
    TMP_DIR = os.path.join(CURRENT_DIR, "tmp")
    PDFJS = os.path.join(CURRENT_DIR, "3rdParty/pdfjs-2.2.228-dist/web/viewer.html")
    
    
    def create_document(content, packages):
        lines = (
            r"\documentclass[12pt,a4paper,french]{article}",
            r"\usepackage[utf8]{inputenc}",
            *(r"\usepackage {%s}" % (package,) for package in packages),
            r"\begin{document}",
            content,
            r"\end{document}",
        )
        return "\n".join(lines)
    
    
    class PdfViewer(QtWebEngineWidgets.QWebEngineView):
        def load_pdf(self, filename):
            url = QtCore.QUrl.fromUserInput(
                "%s?file=%s" % (QtCore.QUrl.fromLocalFile(PDFJS).toString(), filename)
            )
            self.load(url)
    
    
    class Widget(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super().__init__(parent)
    
            self.input = QtWidgets.QTextEdit()
            self.output = PdfViewer()
    
            compile_button = QtWidgets.QPushButton(self.tr("Compile"))
    
            lay = QtWidgets.QGridLayout(self)
            lay.addWidget(compile_button, 0, 0, 1, 2)
            lay.addWidget(self.input, 1, 0)
            lay.addWidget(self.output, 1, 1)
            lay.setColumnStretch(0, 1)
            lay.setColumnStretch(1, 1)
    
            compile_button.clicked.connect(self.compile)
    
            self.process = QtCore.QProcess(self)
            self.process.readyReadStandardError.connect(self.on_readyReadStandardError)
            self.process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
            self.process.finished.connect(self.on_finished)
            self.process.setProgram("pdflatex")
    
            self.basename = "mypdf"
    
        def compile(self):
            doc = create_document(self.input.toPlainText(), ("amsmath", "graphicx"))
            QtCore.QDir().mkpath(TMP_DIR)
            self.qfile = QtCore.QFile(os.path.join(TMP_DIR, self.basename + ".tex"))
            if self.qfile.open(QtCore.QIODevice.WriteOnly):
                self.qfile.write(doc.encode())
                self.qfile.close()
    
            self.process.setArguments(
                [
                    "-interaction=nonstopmode",
                    "-jobname={}".format(self.basename),
                    "-output-directory={}".format(TMP_DIR),
                    self.qfile.fileName(),
                ]
            )
            self.process.start()
    
        def on_readyReadStandardError(self):
            print(self.process.readAllStandardError().data().decode(), end='')
    
        def on_readyReadStandardOutput(self):
            print(self.process.readAllStandardOutput().data().decode(), end='')
    
        def on_finished(self):
            self.qfile.remove()
            pdf_filename = os.path.join(TMP_DIR, self.basename + ".pdf")
            self.output.load_pdf(pdf_filename)
    
    
    def main():
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
        w = Widget()
        w.showMaximized()
        sys.exit(app.exec_())
    
    
    if __name__ == "__main__":
        main()
    

    Note: try-except only handles the exceptions (not errors) thrown by the python code, not by other programs such as pdflatex. In the case of QProcess the readyReadStandardOutput and readyReadStandardError signal notifies if there is stdout and stderr information from the program(in this case pdflatex), respectively and can be retrieved using the readAllStandardOutput() and readAllStandardError() methods, respectively. That information is printed on the console

    0 讨论(0)
提交回复
热议问题