File indexing completed on 2024-05-19 05:05:33

0001 /***************************************************************************
0002  *   SPDX-License-Identifier: GPL-2.0-or-later
0003  *                                                                         *
0004  *   SPDX-FileCopyrightText: 2004-2023 Thomas Fischer <fischer@unix-ag.uni-kl.de>
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  *   This program is distributed in the hope that it will be useful,       *
0012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0014  *   GNU General Public License for more details.                          *
0015  *                                                                         *
0016  *   You should have received a copy of the GNU General Public License     *
0017  *   along with this program; if not, see <https://www.gnu.org/licenses/>. *
0018  ***************************************************************************/
0019 
0020 #include "fileexporterbibtexoutput.h"
0021 
0022 #include <QBuffer>
0023 #include <QFile>
0024 #include <QDir>
0025 #include <QStringList>
0026 #include <QUrl>
0027 #include <QTextStream>
0028 
0029 #include <KBibTeX>
0030 #include <Preferences>
0031 #include <Element>
0032 #include <Entry>
0033 #include "fileexporterbibtex.h"
0034 #include "fileexporter_p.h"
0035 #include "logging_io.h"
0036 
0037 FileExporterBibTeXOutput::FileExporterBibTeXOutput(OutputType outputType, QObject *parent)
0038         : FileExporterToolchain(parent), m_outputType(outputType)
0039 {
0040     m_fileBasename = QStringLiteral("bibtex-to-output");
0041     m_fileStem = tempDir.path() + QDir::separator() + m_fileBasename;
0042 }
0043 
0044 FileExporterBibTeXOutput::~FileExporterBibTeXOutput()
0045 {
0046     /// nothing
0047 }
0048 
0049 bool FileExporterBibTeXOutput::save(QIODevice *iodevice, const File *bibtexfile)
0050 {
0051     check_if_bibtexfile_or_iodevice_invalid(bibtexfile, iodevice);
0052 
0053     bool result = false;
0054 
0055     QFile bibTeXFile(m_fileStem + KBibTeX::extensionBibTeX);
0056     if (bibTeXFile.open(QIODevice::WriteOnly)) {
0057         FileExporterBibTeX bibtexExporter(this);
0058         bibtexExporter.setEncoding(QStringLiteral("utf-8"));
0059         result = bibtexExporter.save(&bibTeXFile, bibtexfile);
0060         bibTeXFile.close();
0061     }
0062 
0063     if (result)
0064         result = generateOutput();
0065 
0066     if (result)
0067         result = writeFileToIODevice(m_fileStem + (m_outputType == OutputType::BibTeXLogFile ? KBibTeX::extensionBLG : KBibTeX::extensionBBL), iodevice);
0068 
0069     return result;
0070 }
0071 
0072 bool FileExporterBibTeXOutput::save(QIODevice *iodevice, const QSharedPointer<const Element> &element, const File *bibtexfile)
0073 {
0074     check_if_iodevice_invalid(iodevice);
0075 
0076     bool result = false;
0077 
0078     QFile bibTeXFile(m_fileStem + KBibTeX::extensionBibTeX);
0079     if (bibTeXFile.open(QIODevice::WriteOnly)) {
0080         FileExporterBibTeX bibtexExporter(this);
0081         bibtexExporter.setEncoding(QStringLiteral("utf-8"));
0082         result = bibtexExporter.save(&bibTeXFile, element, bibtexfile);
0083         bibTeXFile.close();
0084     }
0085 
0086     if (result)
0087         result = generateOutput();
0088 
0089     if (result)
0090         result = writeFileToIODevice(m_fileStem + (m_outputType == OutputType::BibTeXLogFile ? KBibTeX::extensionBLG : KBibTeX::extensionBBL), iodevice);
0091 
0092     return result;
0093 }
0094 
0095 bool FileExporterBibTeXOutput::generateOutput()
0096 {
0097     const QStringList cmdLinesBeforeBibTeX {QStringLiteral("pdflatex -halt-on-error ") + m_fileBasename + KBibTeX::extensionTeX};
0098     const QStringList bibTeXarguments {m_fileBasename + KBibTeX::extensionAux};
0099     const QStringList cmdLinesAfterBibTeX {};
0100 
0101     if (writeLatexFile(m_fileStem + KBibTeX::extensionTeX) && runProcesses(cmdLinesBeforeBibTeX) && runProcess(QStringLiteral("bibtex"), bibTeXarguments, true) && runProcesses(cmdLinesAfterBibTeX))
0102         return true;
0103     else {
0104         qCWarning(LOG_KBIBTEX_IO) << "Generating BibTeX output failed";
0105         return false;
0106     }
0107 }
0108 
0109 bool FileExporterBibTeXOutput::writeLatexFile(const QString &filename)
0110 {
0111     QFile latexFile(filename);
0112     if (latexFile.open(QIODevice::WriteOnly)) {
0113         QTextStream ts(&latexFile);
0114         // https://forum.qt.io/topic/135724/qt-6-replacement-for-qtextcodec
0115 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
0116         ts.setCodec("UTF-8");
0117 #else
0118         ts.setEncoding(QStringConverter::Utf8);
0119 #endif
0120         ts << "\\documentclass{article}\n";
0121         ts << "\\usepackage[T1]{fontenc}\n";
0122         ts << "\\usepackage[utf8]{inputenc}\n";
0123         if (kpsewhich(QStringLiteral("babel.sty")))
0124             ts << "\\usepackage[" << Preferences::instance().laTeXBabelLanguage() << "]{babel}\n";
0125         if (kpsewhich(QStringLiteral("hyperref.sty")))
0126             ts << "\\usepackage[pdfproducer={KBibTeX: https://userbase.kde.org/KBibTeX},pdftex]{hyperref}\n";
0127         else if (kpsewhich(QStringLiteral("url.sty")))
0128             ts << "\\usepackage{url}\n";
0129         const QString latexBibStyle = Preferences::instance().bibTeXBibliographyStyle();
0130         ts << "\\bibliographystyle{" << latexBibStyle << "}\n";
0131         ts << "\\begin{document}\n";
0132         ts << "\\nocite{*}\n";
0133         ts << QStringLiteral("\\bibliography{") + m_fileBasename + QStringLiteral("}\n");
0134         ts << "\\end{document}\n";
0135         latexFile.close();
0136         return true;
0137     } else
0138         return false;
0139 }