20#include <QRegularExpression>
21#include <QRegularExpressionMatch>
22#include <QSharedPointer>
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 "../managers/cdisplaytemplatemgr.h"
34#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"
46#pragma clang diagnostic push
47#pragma clang diagnostic ignored "-Wsuggest-destructor-override"
55#pragma clang diagnostic pop
58#pragma GCC diagnostic pop
72 return QStringLiteral(
73 "<div class=\"abbreviation\"><h3>%1: text</h3><p>%2</p></div>")
74 .arg(QObject::tr(
"Abbreviation"), data);
81 return QStringLiteral(
"<div class=\"crossrefinfo\"><h3>%1</h3></div>")
82 .arg(QObject::tr(
"Cross references"));
98 static QRegularExpression
const re(QStringLiteral(R
"PCRE(^[^ ]+:)PCRE"));
100 int pos = re.match(data).capturedEnd();
105 auto moduleName = data.left(pos);
107 module = CSwordBackend::instance().findModuleByName(
108 std::move(moduleName));
112 module = btConfig().getDefaultSwordModuleByType(
113 QStringLiteral("standardBible"));
115 if (!module && modules.size() > 0)
116 module = modules.at(0);
126 sword::ListKey refs =
128 (
const char*) data.mid((pos == -1) ? 0 : pos + 1).toUtf8(),
132 for (
int i = 0; i < refs.getCount(); i++) {
133 sword::SWKey *
const key = refs.getElement(i);
135 sword::VerseKey *
const vk =
dynamic_cast<sword::VerseKey*
>(key);
137 if (vk && vk->isBoundSet()) {
139 QString::fromUtf8(vk->getLowerBound().getText()),
140 QString::fromUtf8(vk->getUpperBound().getText()),
144 tree.emplace_back(QString::fromUtf8(key->getText()),
145 QString::fromUtf8(key->getText()),
151 tree.emplace_back(data.mid((pos == -1) ? 0 : pos + 1),
159 return QStringLiteral(
"<div class=\"crossrefinfo\" lang=\"%1\"><h3>%2</h3>"
160 "<div class=\"para\" dir=\"%3\">%4</div></div>")
161 .arg(module ? module->
language()->abbrev() : QStringLiteral(
"en"),
162 QObject::tr(
"Cross references"),
163 module ? module->textDirectionAsHtml() : QString())
164 .arg(renderer.renderKeyTree(tree));
168 QStringList list = data.split(
'/');
177 const QString modulename = list.first();
178 const QString swordFootnote = list.last();
183 const QString keyname = list.join(
'/');
185 auto *
const module =
186 CSwordBackend::instance().findModuleByName(modulename);
190 QSharedPointer<CSwordKey> key(module->createKey());
191 key->setKey(keyname);
196 auto & m =
module->swordModule();
197 const char *
const note =
198 m.getEntryAttributes()
199 [
"Footnote"][swordFootnote.toLatin1().data()][
"body"].c_str();
200 return QStringLiteral(
"<div class=\"footnoteinfo\" lang=\"%1\"><h3>%2</h3>"
202 .arg(module->language()->abbrev(),
203 QObject::tr(
"Footnote"),
204 QString::fromUtf8(m.renderText(note).c_str()));
210 auto lexModule = qobject_cast<CSwordLexiconModuleInfo *>(m);
213 && lexModule->hasStrongsKeys())
217 && lexModule->hasStrongsKeys())
228 ? QStringLiteral(
"standardHebrewStrongsLexicon")
229 : QStringLiteral(
"standardGreekStrongsLexicon"));
235 for (
auto const & strongs : data.split(
'|')) {
236 bool const wantHebrew = strongs.left(1) ==
'H';
240 QSharedPointer<CSwordKey> key(module->createKey());
241 auto lexModule = qobject_cast<CSwordLexiconModuleInfo *>(module);
242 if (key->setKey(lexModule->normalizeStrongsKey(strongs)))
243 text = key->renderedText();
248 QStringLiteral(
"<div class=\"strongsinfo\" lang=\"%1\"><h3>%2: %3"
249 "</h3><p>%4</p></div>")
250 .arg(module ? module->language()->abbrev() : QStringLiteral(
"en"),
251 QObject::tr(
"Strongs"),
260 QStringList morphs = data.split(
'|');
263 for (
auto const & morph : morphs) {
266 bool skipFirstChar =
false;
270 int valStart = morph.indexOf(
':');
272 valueClass = morph.mid(0, valStart);
274 module = CSwordBackend::instance().findModuleByName(valueClass);
276 value = morph.mid(valStart + 1);
284 if (value.size() > 1 && value.at(1).isDigit()) {
285 switch (value.at(0).toLatin1()) {
287 module = btConfig().getDefaultSwordModuleByType(
289 "standardGreekMorphLexicon"));
290 skipFirstChar =
true;
293 module = btConfig().getDefaultSwordModuleByType(
295 "standardHebrewMorphLexicon"));
296 skipFirstChar =
true;
299 skipFirstChar =
false;
310 module = btConfig().getDefaultSwordModuleByType(
311 QStringLiteral("standardGreekMorphLexicon"));
317 QSharedPointer<CSwordKey> key(module->createKey());
320 const bool isOk = key->setKey(skipFirstChar ? value.mid(1) : value);
328 QStringLiteral(
"standardHebrewMorphLexicon")));
329 key->setKey(skipFirstChar ? value.mid(1) : value);
332 text = key->renderedText();
336 ret.append(QStringLiteral(
"<div class=\"morphinfo\" lang=\"%1\">"
337 "<h3>%2: %3</h3><p>%4</p></div>")
339 ? module->language()->abbrev()
340 : QStringLiteral(
"en"),
341 QObject::tr(
"Morphology"),
350 static QRegularExpression
const rx(
351 QStringLiteral(R
"PCRE(sword://(bible|lexicon)/(.*)/(.*))PCRE"),
352 QRegularExpression::CaseInsensitiveOption);
353 if (
auto const match = rx.match(data); match.hasMatch()) {
354 if (
auto *
const module =
358 std::unique_ptr<CSwordKey> key(module->createKey());
359 auto reference = match.captured(3);
360 key->setKey(reference);
361 return QStringLiteral(
"<div class=\"crossrefinfo\" lang=\"%1\">"
362 "<h3>%2</h3><p>%3</p></div>")
363 .arg(module->language()->abbrev(),
364 std::move(reference),
365 key->renderedText());
377 auto const attrList(data.split(QStringLiteral(
"||")));
379 for (
auto const & attrPair : attrList) {
380 auto const attr(attrPair.split(
'='));
381 if (attr.size() == 2) {
382 auto const & attrName = attr[0];
383 auto const & attrValue = attr[1];
384 if (attrName == QStringLiteral(
"note")) {
385 list.append(qMakePair(
Footnote, attrValue));
386 }
else if (attrName == QStringLiteral(
"lemma")) {
387 list.append(qMakePair(
Lemma, attrValue));
388 }
else if (attrName == QStringLiteral(
"morph")) {
389 list.append(qMakePair(
Morph, attrValue));
390 }
else if (attrName == QStringLiteral(
"expansion")) {
392 }
else if (attrName == QStringLiteral(
"crossrefs")) {
394 }
else if (attrName == QStringLiteral(
"href")) {
395 list.append(qMakePair(
Reference, attrValue));
405 BT_ASSERT(!modules.contains(
nullptr) && (modules.size() <= 1 &&
"not implemented"));
412 for (
auto const & infoData : list) {
413 auto const & value = infoData.second;
414 switch (infoData.first) {
416 text.append(decodeStrongs(value));
419 text.append(decodeMorph(value));
422 text.append(decodeCrossReference(value, modules));
425 text.append(decodeFootnote(value));
428 text.append(decodeAbbreviation(value));
434 if (value.contains(QStringLiteral(
"strongs:"))) {
435 auto v(value.right(value.size() - value.lastIndexOf(
'/')
437 if (value.contains(QStringLiteral(
"GREEK"))) {
439 }
else if (value.contains(QStringLiteral(
"HEBREW"))) {
444 text.append(decodeStrongs(v));
445 }
else if (value.contains(QStringLiteral(
"sword:"))) {
446 text.append(decodeSwordReference(value));
460QString
formatInfo(QString
const & info, QString
const & lang) {
465 settings.
pageCSS_ID = QStringLiteral(
"infodisplay");
469 QStringLiteral(
"<div class=\"infodisplay\"%1>%2</div>")
472 : 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.
static QString activeTemplateName()
QString fillTemplate(const QString &name, QString content, const Settings &settings) const
Fills the template.
static CDisplayTemplateMgr * instance()
CSwordModuleInfo * findModuleByName(const QString &name) const
Searches for a module with the given name.
static CSwordBackend & instance() noexcept
QList< CSwordModuleInfo * > const & moduleList() const
void setFilterOptions(const FilterOptions &options)
@ ProcessEntryAttributesOnly
std::shared_ptr< Language const > language() const
std::list< KeyTreeItem > KeyTree
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)
QString decodeAbbreviation(QString const &data)
CSwordModuleInfo * getStrongsModule(bool const wantHebrew)
CSwordModuleInfo * getFirstAvailableStrongsModule(bool wantHebrew)
QString decodeFootnote(QString const &data)
QString decodeSwordReference(QString const &data)
QString decodeCrossReference(QString const &data, BtConstModuleList const &modules)
@ CompleteShort
means key like "Gen 1:1"