繁体   English   中英

恢复 Latex 编译错误

[英]Recovering Latex Compilation Errors

我有一个编写文本的程序,当我单击“编译”按钮时,它会编译为乳胶,转换为 pdf 并显示在我的应用程序上。 问题是当我遇到编译错误时,应用程序会出错,仅此而已。 我想知道是否有可能在应用程序不崩溃的情况下恢复编译错误。 我尝试过 try/expect 但这不是 python 错误,所以它不起作用。

您将需要 PDF.js 来查看 pdf https://mozilla.github.io/pdf.js/getting_started/#download

用户界面:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(841, 481)
        self.horizontalLayout = QtWidgets.QHBoxLayout(Dialog)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.textEdit = QtWidgets.QTextEdit(Dialog)
        self.textEdit.setMinimumSize(QtCore.QSize(0, 200))
        self.textEdit.setObjectName("textEdit")
        self.gridLayout.addWidget(self.textEdit, 0, 0, 1, 1)
        self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
        self.buttonBox.setOrientation(QtCore.Qt.Vertical)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.gridLayout.addWidget(self.buttonBox, 0, 1, 1, 1)
        #self.textEdit_2 = QtWidgets.QTextEdit(Dialog)
        #self.textEdit_2.setObjectName("textEdit_2")
        #self.gridLayout.addWidget(self.textEdit_2, 1, 0, 1, 1)
        self.horizontalLayout.addLayout(self.gridLayout)

        self.retranslateUi(Dialog)
        self.buttonBox.accepted.connect(Dialog.accept)
        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))

应用程序:

import os
import sys
from PyQt5.QtWidgets import QDialog, QPushButton, QWidget, QApplication
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
from sympy import Symbol
import untitled

x=Symbol('x')
class Test(QDialog, untitled.Ui_Dialog):
    def __init__(self):
        super(Test, self).__init__()
        self.setupUi(self)

        self.bouton= QPushButton('compile',self)
        self.horizontalLayout.addWidget(self.bouton)
        self.bouton.clicked.connect(self.crertest)

        self.widget = QWidget(self)
        self.gridLayout.addWidget(self.widget, 1, 0, 1, 1)
        self.t = Window()
        lay = QtWidgets.QVBoxLayout(self.widget)
        lay.addWidget(self.t)

    def crertest(self):
        try :
            def preambule(*packages):
                p = ""
                for i in packages:
                    p = p + "\\usepackage{" + i + "}\n"
                return p
            start = "\\documentclass[12pt,a4paper,french]{article}\n\\usepackage[utf8]{inputenc}\n"
            start = start + preambule('amsmath','graphicx')
            start = start + "\\begin{document}\n"
            end = "\\end{document}"
            body = self.textEdit.toPlainText()

            container = start + body + end
            file = "mypdf.tex"
            if os.path.exists(file):
                os.remove(file)
            fichier = open("mypdf.tex", "x")  #
            fichier.write(container)
            fichier.close()

            instructions = "pdflatex " + file
            os.system(instructions)
            readpdf = "START " + file[:-4] + ".pdf"
            self.t.loadd()
        except:
            print('Fail')

PDFJS = 'file:///C:/Users/pdf_js/web/viewer.html' #Path too viewer.htlm in your pddf_js folder
PDF = 'file:///C:/Users/mypdf.pdf' #Path to your pdf


class Window(QtWebEngineWidgets.QWebEngineView):
    def __init__(self):
        super(Window, self).__init__()
        self.loadd()
    try:
        def loadd(self):
            self.load(QtCore.QUrl.fromUserInput('%s?file=%s' % (PDFJS, PDF)))
    except:
        print ('Fail 2')
if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = Test()
    main.show()
    app.exec_()

我将这篇文章中的代码用于 pdf 显示: How to render PDF using pdf.js viewer in PyQt?

就像 Texmaker 这样的乳胶编辑器一样。

编辑。

我把在latex中编译并在另一个模块中显示pdf的程序部分。

我在我的主文件中调用该模块,除了我必须编译程序两次才能更新显示。 有时是在编译 3/4 次之后出现错误。 我需要添加一些东西来运行一次吗?

编译:test.py

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 Compile:
    def __init__(self, parent):
        super().__init__()
        self.process = QtCore.QProcess(parent)
        self.process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
        self.process.finished.connect(self.on_finished)
        self.process.setProgram("pdflatex")

        self.basename = "mypdf"

    def compile(self,body):
        doc = create_document(body, ("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_readyReadStandardOutput(self):
        print(self.process.readAllStandardOutput().data().decode(), end='')

    def on_finished(self):
        self.qfile.remove()

打电话给:

import os
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
import test


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.input = QtWidgets.QTextEdit()
        self.input.setText('.')

        self.a = test.Compile(self)
        self.a.compile('.')
        self.b = test.PdfViewer()
        self.b.load_pdf(your PDF path)

        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.b, 1, 1)
        lay.setColumnStretch(0, 1)
        lay.setColumnStretch(1, 1)

        compile_button.clicked.connect(self.call)

    def call(self):
        self.a.compile(self.input.toPlainText())
        self.b.load_pdf(your PDF path)


def main():
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.showMaximized()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

很难知道你的问题的错误,因为可能有很多原因,所以我从头开始创建我的例子。 为此,您必须具有以下文件结构: 在脚本的一侧必须有一个名为 3rdParty 的文件夹,您必须在其中解压缩从 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

与其使用 os.system() ,不如使用一种提供转换状态反馈的方法,在这种情况下使用 QProcess,此外还可以添加更多选项,例如“-interaction=nonstopmode”、“-jobname= FILENAME" 和 "-output-directory=DIR" 允许没有交互模式,指向文件夹输出和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()

在此处输入图片说明

注意: try-except 只处理python代码抛出的异常(不是错误),而不是其他程序如pdflatex。 在 QProcess 的情况下,readyReadStandardOutput 和 readyReadStandardError 信号分别通知程序(在本例中为 pdflatex)是否有 stdout 和 stderr 信息,并且可以分别使用 readAllStandardOutput() 和 readAllStandardError() 方法进行检索。 该信息打印在控制台上

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM