File indexing completed on 2024-04-28 03:51:16
0001 /*. 0002 SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "latexformula.h" 0008 0009 #include <QApplication> 0010 #include <QDebug> 0011 #include <QFile> 0012 #include <QProcess> 0013 #include <QStandardPaths> 0014 #include <QTemporaryDir> 0015 #include <QTextStream> 0016 0017 #include <KLocalizedString> 0018 0019 namespace { 0020 0021 bool executeCommand(const QString& cmd, const QStringList& args, 0022 const QString& workDir, const QString& resultFile, QString* error) 0023 { 0024 QProcess proc; 0025 proc.setProcessChannelMode(QProcess::MergedChannels); 0026 proc.setWorkingDirectory(workDir); 0027 proc.start(cmd, args); 0028 0029 if(!proc.waitForStarted()) { 0030 *error = i18n("can not launch %1", cmd); return false; 0031 } 0032 0033 proc.closeWriteChannel(); 0034 0035 while(proc.state() == QProcess::Running) { 0036 qApp->processEvents(QEventLoop::ExcludeUserInputEvents); 0037 } 0038 0039 if(proc.exitStatus() != QProcess::NormalExit) { 0040 *error = i18n("error running %1", cmd); return false; 0041 } 0042 0043 if(proc.exitCode() != 0) { // XXX TODO: verbose error message 0044 *error = i18n("%1 reported an error (exit status %2):\n%3", 0045 cmd, proc.exitCode(), QString::fromLocal8Bit(proc.readAll())); return false; 0046 } 0047 0048 if(!QFile::exists(resultFile)) { 0049 *error = i18n("%1 did not create output file", cmd); return false; 0050 } 0051 0052 return true; 0053 } 0054 0055 } 0056 0057 bool LatexFormula::isLatexInstalled() 0058 { 0059 if(QStandardPaths::findExecutable(QStringLiteral("latex")).isEmpty()) return false; 0060 if(QStandardPaths::findExecutable(QStringLiteral("dvips")).isEmpty()) return false; 0061 if(QStandardPaths::findExecutable(QStringLiteral("gs")).isEmpty()) return false; 0062 return true; 0063 } 0064 0065 bool LatexFormula::compileFormula(const QString& formula, QByteArray* result, QString* error) 0066 { 0067 QTemporaryDir tempDir; 0068 if (!tempDir.isValid()) { 0069 // tempDir could not be created 0070 qDebug() << "tempDir.isValid() = false"; 0071 return false; 0072 } 0073 qDebug() << "tempDir.path() = " << tempDir.path(); 0074 QString baseFileName = tempDir.path() + "/formula"; 0075 qDebug() << "baseFileName = " << baseFileName; 0076 0077 QFile latexFile(baseFileName + ".tex"); 0078 qDebug() << "latexFile filename = " << (baseFileName + ".tex"); 0079 0080 if(!latexFile.open(QIODevice::WriteOnly)) { 0081 *error = i18n("can not open temporary file"); 0082 qDebug() << "cannot open latexFile:\n" << &error; 0083 return false; 0084 } 0085 0086 QTextStream latexStream(&latexFile); 0087 latexStream << "\\documentclass[12pt]{article}\n" 0088 << "\\pagestyle{empty}\n" 0089 << "\\usepackage[utf8]{inputenc}\n" 0090 << "\\usepackage[dvips]{graphicx}\n" 0091 << "\\usepackage[dvips]{color}\n" 0092 << "\\usepackage{amssymb,amsmath}\n" 0093 << "\\begin{document}\n" 0094 << "\\begin{displaymath}" 0095 << formula 0096 << "\\end{displaymath}\n" 0097 << "\\end{document}\n"; 0098 0099 latexFile.close(); 0100 0101 if(!executeCommand(QStringLiteral("latex"), QStringList() << QStringLiteral("--interaction=nonstopmode") << baseFileName + ".tex", 0102 tempDir.path(), baseFileName+".tex", error)) return false; 0103 0104 if(!executeCommand(QStringLiteral("dvips"), QStringList() << QStringLiteral("-E") << baseFileName+".dvi" << QStringLiteral("-o") << baseFileName+".eps", 0105 tempDir.path(), baseFileName+".eps", error)) return false; 0106 0107 QStringList gsArgs; 0108 gsArgs << QStringLiteral("-dNOPAUSE") << QStringLiteral("-dSAFER") << QStringLiteral("-dEPSCrop") << QStringLiteral("-r100") 0109 << QStringLiteral("-dTextAlphaBits=4") << QStringLiteral("-dGraphicsAlphaBits=4") << QStringLiteral("-sDEVICE=pngalpha") 0110 << "-sOutputFile="+baseFileName+".png" << QStringLiteral("-q") << QStringLiteral("-dBATCH") << baseFileName+".eps"; 0111 if(!executeCommand(QStringLiteral("gs"), gsArgs, tempDir.path(), baseFileName+".png", error)) return false; 0112 0113 QFile pngFile(baseFileName + ".png"); 0114 if(!pngFile.open(QIODevice::ReadOnly)) { 0115 *error = i18n("can not open result file"); 0116 return false; 0117 } 0118 0119 *result = pngFile.readAll(); 0120 0121 return true; 0122 } 0123