141 using namespace std::literals;
144 if (!substituteToken(buf, token)) {
146 sword::SWModule* myModule =
const_cast<sword::SWModule*
>(myUserData->module);
148 sword::XMLTag
const tag(token);
150 auto const osisQToTickEntry =
151 userData->module->getConfigEntry(
"OSISqToTick");
152 bool const osisQToTick =
153 !osisQToTickEntry || osisQToTickEntry !=
"false"sv;
155 std::string_view
const tagName(tag.getName());
157 if (tagName ==
"div"sv) {
158 if (tag.isEndTag()) {
159 buf.append(
"</div>");
161 sword::SWBuf type( tag.getAttribute(
"type") );
162 if (type ==
"introduction") {
164 buf.append(
"<div class=\"introduction\">");
165 }
else if (type ==
"chapter") {
167 buf.append(
"<div class=\"chapter\" ></div>");
168 }
else if (type ==
"x-p") {
170 }
else if (type ==
"paragraph") {
171 if (tag.getAttribute(
"sID"))
173 else if (tag.getAttribute(
"eID"))
180 else if (tagName ==
"w"sv) {
181 if ((!tag.isEmpty()) && (!tag.isEndTag())) {
185 sword::XMLTag outTag(
"span");
186 sword::SWBuf attrValue;
188 if ((attrib = tag.getAttribute(
"xlit"))) {
189 val = strchr(attrib,
':');
190 val = (val) ? (val + 1) : attrib;
191 outTag.setAttribute(
"xlit", val);
194 if ((attrib = tag.getAttribute(
"gloss"))) {
195 val = strchr(attrib,
':');
196 val = (val) ? (val + 1) : attrib;
197 outTag.setAttribute(
"gloss", val);
200 if ((attrib = tag.getAttribute(
"lemma"))) {
201 char splitChar =
'|';
202 const int countSplit1 = tag.getAttributePartCount(
"lemma",
'|');
203 const int countSplit2 = tag.getAttributePartCount(
"lemma",
' ');
206 if (countSplit1 > countSplit2) {
215 int i = (count > 1) ? 0 : -1;
219 if (attrValue.length()) {
220 attrValue.append(
'|' );
223 attrib = tag.getAttribute(
"lemma", i, splitChar);
229 val = strchr(attrib,
':');
230 val = (val) ? (val + 1) : attrib;
232 attrValue.append(val);
236 if (attrValue.length()) {
237 outTag.setAttribute(
"lemma", attrValue.c_str());
241 if ((attrib = tag.getAttribute(
"morph"))) {
242 char splitChar =
'|';
243 const int countSplit1 = tag.getAttributePartCount(
"morph",
'|');
244 const int countSplit2 = tag.getAttributePartCount(
"morph",
' ');
247 if (countSplit1 > countSplit2) {
256 int i = (count > 1) ? 0 : -1;
261 if (attrValue.length()) {
262 attrValue.append(
'|');
265 attrib = tag.getAttribute(
"morph", i, splitChar);
271 val = strchr(attrib,
':');
275 if (!strncmp(
"robinson:", attrib, 9)) {
276 attrValue.append(
"Robinson:" );
277 attrValue.append( val + 1 );
284 attrValue.append( !strncmp(attrib,
"x-", 2) ? attrib + 2 : attrib );
289 const bool skipFirst = ((val[0] ==
'T') && ((val[1] ==
'H') || (val[1] ==
'G')));
290 attrValue.append( skipFirst ? val + 1 : val );
295 if (attrValue.length()) {
296 outTag.setAttribute(
"morph", attrValue.c_str());
300 if ((attrib = tag.getAttribute(
"POS"))) {
301 val = strchr(attrib,
':');
302 val = (val) ? (val + 1) : attrib;
303 outTag.setAttribute(
"pos", val);
306 buf.append( outTag.toString() );
308 else if (tag.isEndTag()) {
309 buf.append(
"</span>");
312 else if (tagName ==
"note"sv) {
313 if (!tag.isEndTag()) {
314 const sword::SWBuf type( tag.getAttribute(
"type") );
316 if (type ==
"crossReference") {
318 myUserData->
noteTypes.emplace_back(UserData::CrossReference);
329 buf.append(
"<span class=\"crossreference\">");
330 sword::SWBuf footnoteNumber = tag.getAttribute(
"swordFootnote");
331 sword::SWBuf footnoteBody = myUserData->
entryAttributes[
"Footnote"][footnoteNumber][
"body"];
332 buf += myModule->renderText(footnoteBody);
338 else if ((type ==
"strongsMarkup") || (type ==
"x-strongsMarkup")) {
344 myUserData->suspendTextPassThru =
true;
345 myUserData->
noteTypes.emplace_back(UserData::StrongsMarkup);
350 buf.append(
" <span class=\"footnote\" note=\"");
351 buf.append(myModule->getName());
353 buf.append(myUserData->key->getShortText());
355 buf.append( QString::number(myUserData->
swordFootnote++).toUtf8().constData() );
357 const sword::SWBuf n = tag.getAttribute(
"n");
360 buf.append( (n.length() > 0) ? QString::fromUtf8(n.c_str()).toHtmlEscaped().toUtf8().constData() :
"*" );
361 buf.append(
"</span> ");
363 myUserData->
noteTypes.emplace_back(UserData::Footnote);
364 myUserData->suspendTextPassThru =
true;
367 else if ( !myUserData->
noteTypes.empty()) {
368 if (myUserData->
noteTypes.back() == UserData::CrossReference) {
369 buf.append(
"</span> ");
375 myUserData->suspendTextPassThru =
false;
378 else if (tagName ==
"reference"sv) {
379 if (!tag.isEndTag() && !tag.isEmpty()) {
380 renderReference(tag.getAttribute(
"osisRef"),
385 else if (tag.isEndTag()) {
392 else if (tagName ==
"title"sv) {
393 if (!tag.isEndTag() && !tag.isEmpty()) {
394 buf.append(
"<div class=\"sectiontitle\">");
396 else if (tag.isEndTag()) {
397 buf.append(
"</div>");
404 else if (tagName ==
"hi"sv) {
405 const sword::SWBuf type = tag.getAttribute(
"type");
407 if ((!tag.isEndTag()) && (!tag.isEmpty())) {
408 if (type ==
"bold") {
409 buf.append(
"<span class=\"bold\">");
411 else if (type ==
"illuminated") {
412 buf.append(
"<span class=\"illuminated\">");
414 else if (type ==
"italic") {
415 buf.append(
"<span class=\"italic\">");
417 else if (type ==
"line-through") {
418 buf.append(
"<span class=\"line-through\">");
420 else if (type ==
"normal") {
421 buf.append(
"<span class=\"normal\">");
423 else if (type ==
"small-caps") {
424 buf.append(
"<span class=\"small-caps\">");
426 else if (type ==
"underline") {
427 buf.append(
"<span class=\"underline\">");
430 buf.append(
"<span>");
433 else if (tag.isEndTag()) {
434 buf.append(
"</span>");
437 else if (tagName ==
"name"sv) {
438 const sword::SWBuf type = tag.getAttribute(
"type");
440 if ((!tag.isEndTag()) && (!tag.isEmpty())) {
441 if (type ==
"geographic") {
442 buf.append(
"<span class=\"name\"><span class=\"geographic\">");
444 else if (type ==
"holiday") {
445 buf.append(
"<span class=\"name\"><span class=\"holiday\">");
447 else if (type ==
"nonhuman") {
448 buf.append(
"<span class=\"name\"><span class=\"nonhuman\">");
450 else if (type ==
"person") {
451 buf.append(
"<span class=\"name\"><span class=\"person\">");
453 else if (type ==
"ritual") {
454 buf.append(
"<span class=\"name\"><span class=\"ritual\">");
457 buf.append(
"<span class=\"name\"><span>");
460 else if (tag.isEndTag()) {
461 buf.append(
"</span></span> ");
464 else if (tagName ==
"transChange"sv) {
465 sword::SWBuf type( tag.getAttribute(
"type") );
467 if ( !type.length() ) {
468 type = tag.getAttribute(
"changeType");
471 if ((!tag.isEndTag()) && (!tag.isEmpty())) {
472 if (type ==
"added") {
473 buf.append(
"<span class=\"transchange\" title=\"");
474 buf.append(QObject::tr(
"Added text").toUtf8().constData());
475 buf.append(
"\"><span class=\"added\">");
477 else if (type ==
"amplified") {
478 buf.append(
"<span class=\"transchange\"><span class=\"amplified\">");
480 else if (type ==
"changed") {
481 buf.append(
"<span class=\"transchange\"><span class=\"changed\">");
483 else if (type ==
"deleted") {
484 buf.append(
"<span class=\"transchange\"><span class=\"deleted\">");
486 else if (type ==
"moved") {
487 buf.append(
"<span class=\"transchange\"><span class=\"moved\">");
489 else if (type ==
"tenseChange") {
490 buf.append(
"<span class=\"transchange\" title=\"");
491 buf.append(QObject::tr(
"Verb tense changed").toUtf8().constData());
492 buf.append(
"\"><span class=\"tenseChange\">");
495 buf.append(
"<span class=\"transchange\"><span>");
498 else if (tag.isEndTag()) {
499 buf.append(
"</span></span>");
502 else if (tagName ==
"p"sv) {
509 else if (tagName ==
"q"sv) {
511 sword::SWBuf who = tag.getAttribute(
"who");
512 const char *lev = tag.getAttribute(
"level");
513 int level = (lev) ? atoi(lev) : 1;
514 sword::SWBuf quoteMarker = tag.getAttribute(
"marker");
516 if ((!tag.isEndTag())) {
517 if (!tag.isEmpty()) {
521 if (quoteMarker.size() > 0) {
522 buf.append(quoteMarker);
524 else if (osisQToTick)
525 buf.append((level % 2) ?
'\"' :
'\'');
527 if (who ==
"Jesus") {
528 buf.append(
"<span class=\"jesuswords\">");
531 else if (tag.isEndTag()) {
532 if (myUserData->
quote.
who ==
"Jesus") {
533 buf.append(
"</span>");
535 if (quoteMarker.size() > 0) {
536 buf.append(quoteMarker);
538 else if (osisQToTick) {
539 buf.append((level % 2) ?
'\"' :
'\'');
545 else if (tagName ==
"abbr"sv) {
546 if (!tag.isEndTag() && !tag.isEmpty()) {
547 const sword::SWBuf expansion = tag.getAttribute(
"expansion");
549 buf.append(
"<span class=\"abbreviation\" expansion=\"");
550 buf.append(expansion);
553 else if (tag.isEndTag()) {
554 buf.append(
"</span>");
557 else if (tagName ==
"milestone"sv) {
558 const sword::SWBuf type = tag.getAttribute(
"type");
560 if ((type ==
"screen") || (type ==
"line")) {
562 userData->supressAdjacentWhitespace =
true;
564 else if (type ==
"x-p") {
566 const sword::SWBuf marker = tag.getAttribute(
"marker");
567 if (marker.length() > 0) {
572 else if (tagName ==
"seg"sv) {
573 if (!tag.isEndTag() && !tag.isEmpty()) {
575 const sword::SWBuf type = tag.getAttribute(
"type");
577 if (type ==
"morph") {
579 sword::XMLTag outTag(
"span");
580 outTag.setAttribute(
"class",
"morphSegmentation");
581 const char* attrValue;
584 if ((attrValue = tag.getAttribute(
"lemma"))) outTag.setAttribute(
"lemma", attrValue);
585 if ((attrValue = tag.getAttribute(
"morph"))) outTag.setAttribute(
"morph", attrValue);
586 if ((attrValue = tag.getAttribute(
"homonym"))) outTag.setAttribute(
"homonym", attrValue);
588 buf.append(outTag.toString());
592 buf.append(
"<span>");
596 buf.append(
"</span>");
601 else if (tagName ==
"divineName"sv) {
602 if (!tag.isEndTag()) {
603 buf.append(
"<span class=\"name\"><span class=\"divine\">");
606 buf.append(
"</span></span>");
610 return sword::OSISHTMLHREF::handleToken(buf, token, userData);