File indexing completed on 2024-05-12 05:10:11

0001 /***************************************************************************
0002     Copyright (C) 2006-2009 Robby Stephenson <robby@periapsis.org>
0003  ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or         *
0008  *   modify it under the terms of the GNU General Public License as        *
0009  *   published by the Free Software Foundation; either version 2 of        *
0010  *   the License or (at your option) version 3 or any later version        *
0011  *   accepted by the membership of KDE e.V. (or its successor approved     *
0012  *   by the membership of KDE e.V.), which shall act as a proxy            *
0013  *   defined in Section 14 of version 3 of the license.                    *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful,       *
0016  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0018  *   GNU General Public License for more details.                          *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
0022  *                                                                         *
0023  ***************************************************************************/
0024 
0025 #include "grs1importer.h"
0026 #include "../collections/bibtexcollection.h"
0027 #include "../entry.h"
0028 #include "../field.h"
0029 #include "../fieldformat.h"
0030 #include "../tellico_debug.h"
0031 
0032 #include <KLocalizedString>
0033 
0034 #include <QTextStream>
0035 
0036 using Tellico::Import::GRS1Importer;
0037 GRS1Importer::TagMap* GRS1Importer::s_tagMap = nullptr;
0038 
0039 // static
0040 void GRS1Importer::initTagMap() {
0041   if(!s_tagMap) {
0042     s_tagMap =  new TagMap();
0043     // BT is special and is handled separately
0044     s_tagMap->insert(TagPair(2, 1), QStringLiteral("title"));
0045     s_tagMap->insert(TagPair(2, 2), QStringLiteral("author"));
0046     s_tagMap->insert(TagPair(2, 4), QStringLiteral("year"));
0047     s_tagMap->insert(TagPair(2, 7), QStringLiteral("publisher"));
0048     s_tagMap->insert(TagPair(2, 31), QStringLiteral("publisher"));
0049     s_tagMap->insert(TagPair(2, 20), QStringLiteral("language"));
0050     s_tagMap->insert(TagPair(2, 21), QStringLiteral("keyword"));
0051     s_tagMap->insert(TagPair(3, QLatin1String("isbn/issn")), QStringLiteral("isbn"));
0052     s_tagMap->insert(TagPair(3, QLatin1String("isbn")), QStringLiteral("isbn"));
0053     s_tagMap->insert(TagPair(3, QLatin1String("notes")), QStringLiteral("note"));
0054     s_tagMap->insert(TagPair(3, QLatin1String("note")), QStringLiteral("note"));
0055     s_tagMap->insert(TagPair(3, QLatin1String("series")), QStringLiteral("series"));
0056     s_tagMap->insert(TagPair(3, QLatin1String("physical description")), QStringLiteral("note"));
0057     s_tagMap->insert(TagPair(3, QLatin1String("subtitle")), QStringLiteral("subtitle"));
0058   }
0059 }
0060 
0061 GRS1Importer::GRS1Importer(const QString& text_) : TextImporter(text_) {
0062   initTagMap();
0063 }
0064 
0065 bool GRS1Importer::canImport(int type) const {
0066   return type == Data::Collection::Bibtex;
0067 }
0068 
0069 Tellico::Data::CollPtr GRS1Importer::collection() {
0070   Data::CollPtr coll(new Data::BibtexCollection(true));
0071 
0072   coll->addField(Data::Field::createDefaultField(Data::Field::IsbnField));
0073 
0074   Data::FieldPtr f(new Data::Field(QStringLiteral("language"), i18n("Language")));
0075   f->setCategory(i18n("Publishing"));
0076   f->setFlags(Data::Field::AllowCompletion | Data::Field::AllowGrouped | Data::Field::AllowMultiple);
0077   coll->addField(f);
0078 
0079   Data::EntryPtr e(new Data::Entry(coll));
0080   bool empty = true;
0081 
0082   // in format "(tag, tag) value"
0083   static const QRegularExpression rx(QLatin1String("^\\s*\\((\\d+),\\s*(.+)\\s*\\)\\s*(.+)\\s*$"));
0084   static const QRegularExpression dateRx(QLatin1String(",[^,]*\\d{3,4}[^,]*")); // remove dates from authors
0085   static const QRegularExpression pubRx(QLatin1String("([^:]+):([^,]+),?")); // split location and publisher
0086 
0087   bool ok;
0088   int n;
0089   QVariant v;
0090   QString tmp, field, val, str = text();
0091   if(str.isEmpty()) {
0092     return Data::CollPtr();
0093   }
0094   QTextStream t(&str, QIODevice::ReadOnly);
0095   for(QString line = t.readLine(); !t.atEnd(); line = t.readLine()) {
0096 //    myDebug() << line;
0097     QRegularExpressionMatch m = rx.match(line);
0098     if(!m.hasMatch()) {
0099       continue;
0100     }
0101     n = m.captured(1).toInt();
0102     v = m.captured(2).toInt(&ok);
0103     if(!ok) {
0104       v = m.captured(2).toLower();
0105     }
0106     field = (*s_tagMap)[TagPair(n, v)];
0107     if(field.isEmpty()) {
0108       continue;
0109     }
0110 //    myDebug() << "field is " << field;
0111     // assume if multiple values, it's allowed
0112     val = m.captured(3).trimmed();
0113     if(val.isEmpty()) {
0114       continue;
0115     }
0116     empty = false;
0117     if(field == QLatin1String("title")) {
0118       val = val.section(QLatin1Char('/'), 0, 0).trimmed(); // only take portion of title before slash
0119     } else if(field == QLatin1String("author")) {
0120       val.remove(dateRx);
0121     } else if(field == QLatin1String("publisher")) {
0122       QRegularExpressionMatch pubMatch = pubRx.match(val);
0123       if(pubMatch.hasMatch()) {
0124         e->setField(QStringLiteral("address"), pubMatch.captured(1));
0125         val = pubMatch.captured(2);
0126       }
0127     }
0128 
0129     tmp = e->field(field);
0130     if(!tmp.isEmpty()) {
0131       tmp += FieldFormat::delimiterString();
0132     }
0133     e->setField(field, tmp + val);
0134   }
0135 
0136   if(!empty) {
0137     coll->addEntries(e);
0138   }
0139   return coll;
0140 }