20 #include <QRegularExpression>
21 #include <QRegularExpressionMatch>
22 #include <QSharedPointer>
23 #include <QStringList>
26 #include "../../util/btassert.h"
27 #include "../btglobal.h"
28 #include "../config/btconfig.h"
29 #include "../drivers/btmodulelist.h"
30 #include "../drivers/cswordlexiconmoduleinfo.h"
31 #include "../drivers/cswordmoduleinfo.h"
32 #include "../keys/cswordkey.h"
33 #include "../language.h"
34 #include "../managers/cdisplaytemplatemgr.h"
35 #include "../managers/cswordbackend.h"
40 #pragma GCC diagnostic push
41 #pragma GCC diagnostic ignored "-Wextra-semi"
42 #pragma GCC diagnostic ignored "-Wsuggest-override"
43 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
45 #pragma clang diagnostic push
46 #pragma clang diagnostic ignored "-Wsuggest-destructor-override"
54 #pragma clang diagnostic pop
56 #pragma GCC diagnostic pop
69 return QStringLiteral(
70 "<div class=\"abbreviation\"><h3>%1: text</h3><p>%2</p></div>")
71 .arg(QObject::tr(
"Abbreviation"), data);
78 return QStringLiteral(
"<div class=\"crossrefinfo\"><h3>%1</h3></div>")
79 .arg(QObject::tr(
"Cross references"));
95 static QRegularExpression
const re(QStringLiteral(R
"PCRE(^[^ ]+:)PCRE"));
97 int pos = re.match(data).capturedEnd();
102 auto moduleName = data.left(pos);
105 std::move(moduleName));
110 QStringLiteral(
"standardBible"));
112 if (!module && modules.size() > 0)
113 module = modules.at(0);
123 sword::ListKey refs =
125 (
const char*) data.mid((pos == -1) ? 0 : pos + 1).toUtf8(),
129 for (
int i = 0; i < refs.getCount(); i++) {
130 sword::SWKey *
const key = refs.getElement(i);
132 sword::VerseKey *
const vk =
dynamic_cast<sword::VerseKey*
>(key);
134 if (vk && vk->isBoundSet()) {
136 QString::fromUtf8(vk->getLowerBound().getText()),
137 QString::fromUtf8(vk->getUpperBound().getText()),
141 tree.emplace_back(QString::fromUtf8(key->getText()),
142 QString::fromUtf8(key->getText()),
148 tree.emplace_back(data.mid((pos == -1) ? 0 : pos + 1),
156 return QStringLiteral(
"<div class=\"crossrefinfo\" lang=\"%1\"><h3>%2</h3>"
157 "<div class=\"para\" dir=\"%3\">%4</div></div>")
158 .arg(module ? module->
language()->abbrev() : QStringLiteral(
"en"),
159 QObject::tr(
"Cross references"),
165 QStringList list = data.split(
'/');
174 const QString modulename = list.first();
175 const QString swordFootnote = list.last();
180 const QString keyname = list.join(
'/');
182 auto *
const module =
187 QSharedPointer<CSwordKey> key(module->createKey());
188 key->setKey(keyname);
193 auto & m = module->swordModule();
194 const char *
const note =
195 m.getEntryAttributes()
196 [
"Footnote"][swordFootnote.toLatin1().data()][
"body"].c_str();
197 return QStringLiteral(
"<div class=\"footnoteinfo\" lang=\"%1\"><h3>%2</h3>"
199 .arg(module->language()->abbrev(),
200 QObject::tr(
"Footnote"),
201 QString::fromUtf8(m.renderText(note).c_str()));
207 auto lexModule = qobject_cast<CSwordLexiconModuleInfo *>(m);
210 && lexModule->hasStrongsKeys())
214 && lexModule->hasStrongsKeys())
225 ? QStringLiteral(
"standardHebrewStrongsLexicon")
226 : QStringLiteral(
"standardGreekStrongsLexicon"));
232 for (
auto const & strongs : data.split(
'|')) {
233 bool const wantHebrew = strongs.left(1) ==
'H';
237 QSharedPointer<CSwordKey> key(module->
createKey());
238 auto lexModule = qobject_cast<CSwordLexiconModuleInfo *>(module);
239 key->setKey(lexModule->normalizeStrongsKey(strongs));
240 text = key->renderedText();
245 QStringLiteral(
"<div class=\"strongsinfo\" lang=\"%1\"><h3>%2: %3"
246 "</h3><p>%4</p></div>")
247 .arg(module ? module->
language()->abbrev() : QStringLiteral(
"en"),
248 QObject::tr(
"Strongs"),
257 QStringList morphs = data.split(
'|');
260 for (
auto const & morph : morphs) {
263 bool skipFirstChar =
false;
267 int valStart = morph.indexOf(
':');
269 valueClass = morph.mid(0, valStart);
273 value = morph.mid(valStart + 1);
281 if (value.size() > 1 && value.at(1).isDigit()) {
282 switch (value.at(0).toLatin1()) {
286 "standardGreekMorphLexicon"));
287 skipFirstChar =
true;
292 "standardHebrewMorphLexicon"));
293 skipFirstChar =
true;
296 skipFirstChar =
false;
308 QStringLiteral(
"standardGreekMorphLexicon"));
314 QSharedPointer<CSwordKey> key(module->
createKey());
317 const bool isOk = key->setKey(skipFirstChar ? value.mid(1) : value);
324 btConfig().getDefaultSwordModuleByType(
325 QStringLiteral(
"standardHebrewMorphLexicon")));
326 key->setKey(skipFirstChar ? value.mid(1) : value);
329 text = key->renderedText();
333 ret.append(QStringLiteral(
"<div class=\"morphinfo\" lang=\"%1\">"
334 "<h3>%2: %3</h3><p>%4</p></div>")
337 : QStringLiteral(
"en"),
338 QObject::tr(
"Morphology"),
347 static QRegularExpression
const rx(
348 QStringLiteral(R
"PCRE(sword://(bible|lexicon)/(.*?)/(.*?))PCRE"),
349 QRegularExpression::CaseInsensitiveOption);
350 if (
auto const match = rx.match(data); match.hasMatch()) {
351 if (
auto *
const module =
355 std::unique_ptr<CSwordKey> key(module->createKey());
356 auto reference = match.captured(3);
357 key->setKey(reference);
358 return QStringLiteral(
"<div class=\"crossrefinfo\" lang=\"%1\">"
359 "<h3>%2</h3><p>%3</p></div>")
360 .arg(module->language()->abbrev(),
361 std::move(reference),
362 key->renderedText());
374 auto const attrList(data.split(QStringLiteral(
"||")));
376 for (
auto const & attrPair : attrList) {
377 auto const attr(attrPair.split(
'='));
378 if (attr.size() == 2) {
379 auto const & attrName = attr[0];
380 auto const & attrValue = attr[1];
381 if (attrName == QStringLiteral(
"note")) {
382 list.append(qMakePair(
Footnote, attrValue));
383 }
else if (attrName == QStringLiteral(
"lemma")) {
384 list.append(qMakePair(
Lemma, attrValue));
385 }
else if (attrName == QStringLiteral(
"morph")) {
386 list.append(qMakePair(
Morph, attrValue));
387 }
else if (attrName == QStringLiteral(
"expansion")) {
389 }
else if (attrName == QStringLiteral(
"crossrefs")) {
391 }
else if (attrName == QStringLiteral(
"href")) {
392 list.append(qMakePair(
Reference, attrValue));
402 BT_ASSERT(!modules.contains(
nullptr) && (modules.size() <= 1 &&
"not implemented"));
409 for (
auto const & infoData : list) {
410 auto const & value = infoData.second;
411 switch (infoData.first) {
431 if (value.contains(QStringLiteral(
"strongs:"))) {
432 auto v(value.right(value.size() - value.lastIndexOf(
'/')
434 if (value.contains(QStringLiteral(
"GREEK"))) {
436 }
else if (value.contains(QStringLiteral(
"HEBREW"))) {
442 }
else if (value.contains(QStringLiteral(
"sword:"))) {
457 QString
formatInfo(QString
const & info, QString
const & lang) {
462 settings.
pageCSS_ID = QStringLiteral(
"infodisplay");
466 QStringLiteral(
"<div class=\"infodisplay\"%1>%2</div>")
469 : QStringLiteral(
" lang=\"%1\"").arg(lang),
BtConfig & btConfig()
This is a shortchand for BtConfig::getInstance().
QList< CSwordModuleInfo const * > BtConstModuleList
CSwordModuleInfo * getDefaultSwordModuleByType(const QString &moduleType)
Returns default sword module info class for a given module type.
QString fillTemplate(const QString &name, const QString &content, const Settings &settings) const
Fills the template.
static QString activeTemplateName()
static CDisplayTemplateMgr * instance()
CSwordModuleInfo * findModuleByName(const QString &name) const
Searches for a module with the given name.
static CSwordBackend & instance() noexcept
void setFilterOptions(const FilterOptions &options)
@ ProcessEntryAttributesOnly
virtual CSwordKey * createKey() const =0
std::shared_ptr< Language const > language() const
char const * textDirectionAsHtml() const
std::list< KeyTreeItem > KeyTree
QString renderKeyTree(KeyTree const &tree) const
QList< InfoData > ListInfoData
QString formatInfo(const ListInfoData &list, BtConstModuleList const &modules)
ListInfoData detectInfo(QString const &data)
QString decodeMorph(QString const &data)
QString decodeStrongs(QString const &data)
CSwordModuleInfo * getFirstAvailableStrongsModule(bool wantHebrew)
QString decodeAbbreviation(QString const &data)
QString decodeFootnote(QString const &data)
QString decodeSwordReference(QString const &data)
QString decodeCrossReference(QString const &data, BtConstModuleList const &modules)
CSwordModuleInfo * getStrongsModule(bool const wantHebrew)
@ CompleteShort
means key like "Gen 1:1"