File indexing completed on 2024-05-19 05:05:47
0001 /*************************************************************************** 0002 * SPDX-License-Identifier: GPL-2.0-or-later 0003 * * 0004 * SPDX-FileCopyrightText: 2004-2018 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 "journalabbreviations.h" 0021 0022 #include <QHash> 0023 #include <QFile> 0024 #include <QTextStream> 0025 #include <QRegularExpression> 0026 #include <QStandardPaths> 0027 0028 #include "logging_processing.h" 0029 0030 class JournalAbbreviations::Private 0031 { 0032 private: 0033 const QString journalFilename; 0034 0035 QHash<QString, QString> leftToRightMap, rightToLeftMap; 0036 0037 public: 0038 Private(JournalAbbreviations *parent) 0039 : journalFilename(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kbibtex/jabref_journalabbrevlist.txt"))) 0040 { 0041 Q_UNUSED(parent) 0042 } 0043 0044 bool loadMapping() { 0045 leftToRightMap.clear(); 0046 rightToLeftMap.clear(); 0047 0048 QFile journalFile(journalFilename); 0049 if (journalFile.open(QFile::ReadOnly)) { 0050 static const QRegularExpression splitRegExp(QStringLiteral("\\s*[=;]\\s*")); 0051 0052 QTextStream ts(&journalFile); 0053 // https://forum.qt.io/topic/135724/qt-6-replacement-for-qtextcodec 0054 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 0055 ts.setCodec("utf8"); 0056 #else 0057 ts.setEncoding(QStringConverter::Utf8); 0058 #endif 0059 0060 QString line; 0061 while (!(line = ts.readLine().trimmed()).isNull()) { 0062 /// Skip empty lines or comments 0063 if (line.isEmpty() || line.startsWith(QLatin1Char('#'))) continue; 0064 const QStringList columns = line.split(splitRegExp); 0065 /// Skip lines that do not have at least two columns 0066 if (columns.count() < 2) continue; 0067 /// At this point, a given line like 0068 /// Accounts of Chemical Research=Acc. Chem. Res.;ACHRE4;M 0069 /// may have been split into the columns of 0070 /// Accounts of Chemical Research 0071 /// Acc. Chem. Res. 0072 /// ACHRE4 0073 /// M 0074 /// The last two columns are optional and are not processed here. 0075 /// The first column is the journal's full name, the second column 0076 /// is its abbreviation. 0077 /// QHash leftToRightMap maps from full name to abbreviation, 0078 /// QHash rightToLeftMap maps from abbreviation to full name. 0079 0080 const QString alreadyInLeftToRightMap = leftToRightMap[columns[0]]; 0081 if (!alreadyInLeftToRightMap.isEmpty()) { 0082 if (alreadyInLeftToRightMap.length() > columns[1].length()) 0083 /// If there is already an existing mapping from full name to 0084 /// abbreviation, replace it if the newly found abbreviation 0085 /// is longer. 0086 leftToRightMap.insert(columns[0], columns[1]); 0087 } else 0088 /// Previously unknown journal full name, so add it to mapping. 0089 leftToRightMap.insert(columns[0], columns[1]); 0090 /// Always add/replace mapping from abbreviation to full name. 0091 rightToLeftMap.insert(columns[1], columns[0]); 0092 } 0093 0094 journalFile.close(); 0095 0096 /// Success means at least one mapping has been recorded. 0097 return !leftToRightMap.isEmpty(); 0098 } else { 0099 qCWarning(LOG_KBIBTEX_PROCESSING) << "Cannot open journal abbreviation list file at" << journalFilename; 0100 return false; 0101 } 0102 } 0103 0104 QString leftToRight(const QString &left) { 0105 if (leftToRightMap.isEmpty()) 0106 loadMapping(); ///< lazy loading of mapping, i.e. only when data gets requested the first time 0107 return leftToRightMap.value(left, left); 0108 } 0109 0110 QString rightToLeft(const QString &right) { 0111 if (rightToLeftMap.isEmpty()) 0112 loadMapping(); ///< lazy loading of mapping, i.e. only when data gets requested the first time 0113 return rightToLeftMap.value(right, right); 0114 } 0115 }; 0116 0117 0118 JournalAbbreviations::JournalAbbreviations() 0119 : d(new JournalAbbreviations::Private(this)) 0120 { 0121 /// nothing 0122 } 0123 0124 JournalAbbreviations::~JournalAbbreviations() 0125 { 0126 delete d; 0127 } 0128 0129 const JournalAbbreviations &JournalAbbreviations::instance() { 0130 static JournalAbbreviations singleton; 0131 return singleton; 0132 } 0133 0134 QString JournalAbbreviations::toShortName(const QString &longName) const { 0135 return d->leftToRight(longName); 0136 } 0137 0138 QString JournalAbbreviations::toLongName(const QString &shortName) const { 0139 return d->rightToLeft(shortName); 0140 }