"Fossies" - the Fresh Open Source Software Archive 
Member "cb2bib-2.0.1/src/c2b/crJson.cpp" (12 Feb 2021, 9012 Bytes) of package /linux/privat/cb2bib-2.0.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "crJson.cpp" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.0.0_vs_2.0.1.
1 /***************************************************************************
2 * Copyright (C) 2004-2021 by Pere Constans
3 * constans@molspaces.com
4 * cb2Bib version 2.0.1. Licensed under the GNU GPL version 3.
5 * See the LICENSE file that comes with this distribution.
6 ***************************************************************************/
7 #include "crJson.h"
8
9 #include "cb2bib_utilities.h"
10
11 #include <QJsonArray>
12 #include <QJsonDocument>
13 #include <QJsonObject>
14
15 #include <cmath>
16
17
18 crJson::crJson(const QString& json)
19 {
20 _reference.clearReference();
21 readReference(json);
22 }
23
24
25 void crJson::readReference(const QString& json)
26 {
27 _has_error = true;
28 _error_string.clear();
29
30 QJsonParseError jerr;
31 QJsonDocument jdoc(QJsonDocument::fromJson(json.toUtf8(), &jerr));
32 if (jdoc.isNull() || jdoc.isEmpty())
33 {
34 _error_string =
35 QObject::tr("Invalid data%1").arg(jerr.errorString().isEmpty() ? QString() : ": " + jerr.errorString());
36 return;
37 }
38 QJsonObject jobj(jdoc.object().value("message").toObject());
39 if (jobj.isEmpty())
40 {
41 _error_string = QObject::tr("Invalid reference data");
42 return;
43 }
44
45 #ifdef C2B_DEBUG
46 for (QJsonObject::const_iterator i = jobj.constBegin(); i != jobj.constEnd(); ++i)
47 qDebug() << "[crjson] " << i.key() << i.value();
48 #endif
49
50 if (jobj.value("DOI").isUndefined())
51 {
52 _error_string = QObject::tr("Invalid reference data: no DOI parsed");
53 return;
54 }
55 _reference["doi"] = jobj.value("DOI").toString();
56
57 if (!jobj.value("published-print").isUndefined())
58 {
59 const QJsonValue jyear(
60 jobj.value("published-print").toObject().value("date-parts").toArray().first().toArray().first());
61 if (!jyear.isUndefined())
62 _reference["year"] = QString::number(jyear.toDouble());
63 }
64 else if (!jobj.value("published-online").isUndefined())
65 {
66 // For articles no longer published in print
67 const QJsonValue jyear(
68 jobj.value("published-online").toObject().value("date-parts").toArray().first().toArray().first());
69 if (!jyear.isUndefined())
70 _reference["year"] = QString::number(jyear.toDouble());
71 }
72
73 _reference["volume"] = jobj.value("volume").toString();
74 _reference["number"] = jobj.value("issue").toString();
75 _reference["pages"] = jobj.value("page").toString();
76
77 QStringList authors;
78 const QJsonArray jauthors(jobj.value("author").toArray());
79 for (QJsonArray::const_iterator i = jauthors.constBegin(); i != jauthors.constEnd(); ++i)
80 {
81 const QJsonObject ja((*i).toObject());
82 authors.append(ja.value("given").toString() + ' ' + ja.value("family").toString());
83 }
84 _reference["author"] = authors.join(", ");
85
86 QStringList editors;
87 const QJsonArray jeditors(jobj.value("editor").toArray());
88 for (QJsonArray::const_iterator i = jeditors.constBegin(); i != jeditors.constEnd(); ++i)
89 {
90 const QJsonObject je((*i).toObject());
91 editors.append(je.value("given").toString() + ' ' + je.value("family").toString());
92 }
93 _reference["editor"] = editors.join(", ");
94
95 QStringList titles;
96 const QJsonArray jtitles(jobj.value("title").toArray());
97 for (QJsonArray::const_iterator i = jtitles.constBegin(); i != jtitles.constEnd(); ++i)
98 titles.append((*i).toString());
99 _normalize_jtitles(&titles);
100
101 QStringList subtitles;
102 const QJsonArray jsubtitles(jobj.value("subtitle").toArray());
103 for (QJsonArray::const_iterator i = jsubtitles.constBegin(); i != jsubtitles.constEnd(); ++i)
104 subtitles.append((*i).toString());
105 _normalize_jtitles(&subtitles);
106
107 QStringList containertitles;
108 const QJsonArray jcontainertitles(jobj.value("container-title").toArray());
109 for (QJsonArray::const_iterator i = jcontainertitles.constBegin(); i != jcontainertitles.constEnd(); ++i)
110 containertitles.append((*i).toString());
111 _normalize_jtitles(&containertitles);
112
113 const QString jisbn(jobj.value("ISBN").toArray().first().toString());
114 const QString jpublisher(jobj.value("publisher").toString());
115 const QString jabstract(jobj.value("abstract").toString());
116 _reference["abstract"] = _normalize_jabstract(jabstract);
117 _reference["title"] = _bibtex_title(titles, subtitles);
118
119 const QString jtype(jobj.value("type").toString());
120
121 if (jtype == "journal-article")
122 {
123 _reference.typeName = "article";
124 _reference["journal"] = containertitles.count() > 0 ? containertitles.first() : QString();
125 }
126 else if (jtype == "proceedings-article")
127 {
128 _reference.typeName = "inproceedings";
129 _reference["booktitle"] = _bibtex_booktitle(containertitles);
130 _reference["series"] = _bibtex_series(containertitles);
131 _reference["isbn"] = jisbn;
132 _reference["publisher"] = jpublisher;
133 }
134 else if (jtype == "book")
135 {
136 _reference.typeName = "book";
137 _reference["series"] = containertitles.count() > 0 ? containertitles.first() : QString();
138 _reference["isbn"] = jisbn;
139 _reference["publisher"] = jpublisher;
140 }
141 else if (jtype == "book-chapter")
142 {
143 _reference.typeName = "inbook";
144 _reference["booktitle"] = _bibtex_booktitle(containertitles);
145 _reference["series"] = _bibtex_series(containertitles);
146 _reference["isbn"] = jisbn;
147 _reference["publisher"] = jpublisher;
148 }
149 else
150 {
151 // jtype == "other"
152 _reference.typeName = "misc";
153 _reference["booktitle"] = _bibtex_booktitle(containertitles);
154 _reference["series"] = _bibtex_series(containertitles);
155 _reference["isbn"] = jisbn;
156 _reference["publisher"] = jpublisher;
157 }
158
159 if (_reference.value("series") == _reference.value("booktitle"))
160 _reference["series"] = QString();
161 if (jtype == "book-chapter" && !_reference.value("series").isEmpty())
162 _reference.typeName = "incollection";
163
164 #ifdef C2B_DEBUG
165 qDebug() << "[crjson] TITLES" << titles;
166 qDebug() << "[crjson] SUBTITLES" << subtitles;
167 qDebug() << "[crjson] CONTAINERTITLES" << containertitles;
168
169 qDebug() << "[crjson] BIBTEX";
170 qDebug() << "[crjson] type " << _reference.typeName;
171 qDebug() << "[crjson] title " << _reference.value("title");
172 qDebug() << "[crjson] booktitle " << _reference.value("booktitle");
173 qDebug() << "[crjson] series " << _reference.value("series");
174 qDebug() << "[crjson] publisher " << _reference.value("publisher");
175 qDebug() << "[crjson] isbn " << _reference.value("isbn");
176 qDebug() << "[crjson] year " << _reference.value("year");
177 #endif
178
179 _has_error = false;
180 }
181
182 void crJson::_normalize_jtitles(QStringList* titles)
183 {
184 if (titles->count() == 0)
185 return;
186 titles->removeDuplicates();
187 for (int i = 0; i < titles->count(); ++i)
188 {
189 QString t(titles->at(i).simplified());
190 for (int j = 0; j < t.length(); ++j)
191 if (t.at(j).category() == QChar::Punctuation_Dash)
192 t[j] = '-';
193 t.replace(" - ", ": ");
194 t.replace(" : ", ": ");
195 (*titles)[i] = t;
196 }
197 }
198
199 QString crJson::_normalize_jabstract(const QString& abstract)
200 {
201 if (abstract.isEmpty())
202 return abstract;
203 QString na(abstract);
204 na.replace("<", "<");
205 na.replace(">", ">");
206 na.replace(QRegExp("<[^>]+>"), " ");
207 na.remove(QRegExp("^\\W*(abstract|synopsis|summary)\\.*", Qt::CaseInsensitive));
208 return na.simplified();
209 }
210
211 QString crJson::_bibtex_title(const QStringList& titles, const QStringList& subtitles)
212 {
213 if (titles.count() > 0 && subtitles.count() > 0 && !titles.first().contains(": "))
214 {
215 const int wt(_words(titles.first()));
216 const int ws(_words(subtitles.first()));
217 const int wu(_words(titles.first() + ' ' + subtitles.first()));
218 const int s(100 * (wt + ws - wu) / sqrt(double(wt * ws)));
219 if (s < 30)
220 return titles.first() + ": " + subtitles.first();
221 }
222 return titles.count() > 0 ? titles.first() : QString();
223 }
224
225 QString crJson::_bibtex_booktitle(const QStringList& titles)
226 {
227 if (titles.count() == 0)
228 return QString();
229 if (titles.count() == 2)
230 return (!titles.at(1).contains(
231 QRegExp("(advances|series|lecture notes|studies in|topics in)", Qt::CaseInsensitive)))
232 ? titles.at(1)
233 : titles.at(0);
234 return titles.first();
235 }
236
237 QString crJson::_bibtex_series(const QStringList& titles)
238 {
239 if (titles.count() == 2)
240 return (titles.at(1).contains(
241 QRegExp("(advances|series|lecture notes|studies in|topics in)", Qt::CaseInsensitive)))
242 ? titles.at(1)
243 : titles.at(0);
244 return QString();
245 }
246
247 int crJson::_words(const QString& s)
248 {
249 QStringList wl(s.split(QRegExp("\\W"), QString::SkipEmptyParts));
250 wl.removeDuplicates();
251 return wl.count();
252 }