node-sword-interface 1.0.99 → 1.0.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-sword-interface",
3
- "version": "1.0.99",
3
+ "version": "1.0.101",
4
4
  "description": "Javascript (N-API) interface to SWORD library",
5
5
  "keywords": [
6
6
  "C++",
@@ -71,7 +71,7 @@ string TextProcessor::getFileUrl(const string& nativePath)
71
71
  #endif
72
72
  }
73
73
 
74
- string TextProcessor::getFilteredText(const string& text, int chapter, int verseNr, bool hasStrongs, bool hasInconsistentClosingEndDivs, const string& moduleDataPath)
74
+ string TextProcessor::getFilteredText(const string& text, int chapter, int verseNr, bool hasStrongs, bool hasInconsistentClosingEndDivs, const string& moduleFileUrl)
75
75
  {
76
76
  static string chapterFilter = "<chapter";
77
77
  static regex pbElement = regex("<pb .*?/> ");
@@ -244,18 +244,17 @@ string TextProcessor::getFilteredText(const string& text, int chapter, int verse
244
244
  filteredText = this->replaceSpacesInStrongs(filteredText);
245
245
  }
246
246
 
247
- // Prefix img src attributes starting with "/" with the module data path as a file:// URL
248
- if (!moduleDataPath.empty()) {
249
- string fileUrl = this->getFileUrl(moduleDataPath);
247
+ // Prefix img src attributes starting with "/" with the module file URL
248
+ if (!moduleFileUrl.empty()) {
250
249
  static string imgSrcSlash = "src=\"/";
251
- string imgSrcReplacement = "src=\"" + fileUrl + "/";
250
+ string imgSrcReplacement = "src=\"" + moduleFileUrl + "/";
252
251
  this->findAndReplaceAll(filteredText, imgSrcSlash, imgSrcReplacement);
253
252
  }
254
253
 
255
254
  return filteredText;
256
255
  }
257
256
 
258
- string TextProcessor::getCurrentChapterHeading(sword::SWModule* module)
257
+ string TextProcessor::getCurrentChapterHeading(sword::SWModule* module, const string& moduleFileUrl)
259
258
  {
260
259
  string currentModuleName = string(module->getName());
261
260
  string chapterHeading = "";
@@ -288,15 +287,62 @@ string TextProcessor::getCurrentChapterHeading(sword::SWModule* module)
288
287
  // Therefore we do not render chapter headings for the first verse of the chapter in this case.
289
288
  chapterHeading = "";
290
289
  } else {
291
- string moduleDataPath = this->_moduleStore.getModuleDataPath(module);
292
- chapterHeading = this->getFilteredText(chapterHeading, currentChapter, currentVerseNr, false, false, moduleDataPath);
290
+ chapterHeading = this->getFilteredText(chapterHeading, currentChapter, currentVerseNr, false, false, moduleFileUrl);
293
291
  }
294
292
  }
295
293
 
296
294
  return chapterHeading;
297
295
  }
298
296
 
297
+ string TextProcessor::getCurrentPreverseHeading(sword::SWModule* module, const string& moduleFileUrl)
298
+ {
299
+ string preverse = "";
300
+ VerseKey currentVerseKey = module->getKey();
301
+ int currentChapter = currentVerseKey.getChapter();
302
+ int currentVerseNr = currentVerseKey.getVerse();
303
+
304
+ // First, we need to access the rendered text to populate entry attributes
305
+ // The entry attributes are only available after rendering/stripping
306
+ module->renderText();
307
+
308
+ // Get the entry attributes map
309
+ sword::AttributeTypeList& attributes = module->getEntryAttributes();
310
+
311
+ // Look for Heading/Preverse entries (indexed 0, 1, 2, ...)
312
+ auto headingIt = attributes.find("Heading");
313
+ if (headingIt != attributes.end()) {
314
+ auto preverseIt = headingIt->second.find("Preverse");
315
+ if (preverseIt != headingIt->second.end()) {
316
+ // Iterate through all preverse entries (0, 1, 2, ...)
317
+ for (auto& entry : preverseIt->second) {
318
+ string preverseContent = string(entry.second.c_str());
319
+ StringHelper::trim(preverseContent);
320
+
321
+ if (!preverseContent.empty()) {
322
+ // Render the preverse content through the module
323
+ sword::SWBuf renderedBuf = module->renderText(preverseContent.c_str());
324
+ string rendered = string(renderedBuf.c_str());
325
+
326
+ if (this->_markupEnabled && !this->_rawMarkupEnabled) {
327
+ rendered = this->getFilteredText(rendered, currentChapter, currentVerseNr, false, false, moduleFileUrl);
328
+ }
329
+
330
+ preverse += rendered;
331
+ }
332
+ }
333
+ }
334
+ }
335
+
336
+ return preverse;
337
+ }
338
+
299
339
  string TextProcessor::getCurrentVerseText(sword::SWModule* module, bool hasStrongs, bool hasInconsistentClosingEndDivs, bool forceNoMarkup)
340
+ {
341
+ string moduleFileUrl = this->getFileUrl(this->_moduleStore.getModuleDataPath(module));
342
+ return this->getCurrentVerseText(module, hasStrongs, hasInconsistentClosingEndDivs, forceNoMarkup, moduleFileUrl);
343
+ }
344
+
345
+ string TextProcessor::getCurrentVerseText(sword::SWModule* module, bool hasStrongs, bool hasInconsistentClosingEndDivs, bool forceNoMarkup, const string& moduleFileUrl)
300
346
  {
301
347
  string verseText;
302
348
  string filteredText;
@@ -310,8 +356,7 @@ string TextProcessor::getCurrentVerseText(sword::SWModule* module, bool hasStron
310
356
  filteredText = verseText;
311
357
 
312
358
  if (!this->_rawMarkupEnabled) {
313
- string moduleDataPath = this->_moduleStore.getModuleDataPath(module);
314
- filteredText = this->getFilteredText(verseText, currentChapter, currentVerseNr, hasStrongs, hasInconsistentClosingEndDivs, moduleDataPath);
359
+ filteredText = this->getFilteredText(verseText, currentChapter, currentVerseNr, hasStrongs, hasInconsistentClosingEndDivs, moduleFileUrl);
315
360
  }
316
361
  } else {
317
362
  verseText = string(module->stripText());
@@ -394,6 +439,9 @@ vector<Verse> TextProcessor::getVersesFromReferences(string moduleName, vector<s
394
439
  bool moduleMarkupIsBroken = this->_moduleHelper.isBrokenMarkupModule(moduleName);
395
440
  bool hasInconsistentClosingEndDivs = this->_moduleHelper.isInconsistentClosingEndDivModule(moduleName);
396
441
 
442
+ // Compute file URL once for the entire module
443
+ string moduleFileUrl = this->getFileUrl(this->_moduleStore.getModuleDataPath(module));
444
+
397
445
  for (unsigned int i = 0; i < references.size(); i++) {
398
446
  string currentReference = references[i];
399
447
  string currentVerseText = "";
@@ -402,7 +450,13 @@ vector<Verse> TextProcessor::getVersesFromReferences(string moduleName, vector<s
402
450
  bool entryExisting = module->hasEntry(module->getKey());
403
451
 
404
452
  if (entryExisting) {
405
- currentVerseText = this->getCurrentVerseText(module, false, hasInconsistentClosingEndDivs, moduleMarkupIsBroken);
453
+ // Add preverse heading before verse text
454
+ if (!moduleMarkupIsBroken) {
455
+ string preverseHeading = this->getCurrentPreverseHeading(module, moduleFileUrl);
456
+ currentVerseText += preverseHeading;
457
+ }
458
+
459
+ currentVerseText += this->getCurrentVerseText(module, false, hasInconsistentClosingEndDivs, moduleMarkupIsBroken, moduleFileUrl);
406
460
  }
407
461
 
408
462
  Verse currentVerse;
@@ -450,6 +504,9 @@ vector<Verse> TextProcessor::getText(string moduleName, string key, QueryLimit q
450
504
  } else {
451
505
  bool hasStrongs = this->_moduleHelper.moduleHasGlobalOption(module, "Strongs");
452
506
 
507
+ // Compute file URL once for the entire module
508
+ string moduleFileUrl = this->getFileUrl(this->_moduleStore.getModuleDataPath(module));
509
+
453
510
  module->setKey(key.c_str());
454
511
 
455
512
  if (startVerseNumber >= 1) {
@@ -486,17 +543,25 @@ vector<Verse> TextProcessor::getText(string moduleName, string key, QueryLimit q
486
543
  // and if the module markup is not broken
487
544
  // and if the requested verse count is more than one or the default (-1 / all verses).
488
545
  if (firstVerseInChapter && !moduleMarkupIsBroken && (verseCount > 1 || verseCount == -1)) {
489
- string chapterHeading = this->getCurrentChapterHeading(module);
546
+ string chapterHeading = this->getCurrentChapterHeading(module, moduleFileUrl);
490
547
  verseText += chapterHeading;
491
548
  }
492
549
 
550
+ // Preverse heading (introductory material attached to this verse via entry attributes)
551
+ // This includes intro images and other material that should appear before the verse text
552
+ if (!moduleMarkupIsBroken) {
553
+ string preverseHeading = this->getCurrentPreverseHeading(module, moduleFileUrl);
554
+ verseText += preverseHeading;
555
+ }
556
+
493
557
  // Current verse text
494
558
  verseText += this->getCurrentVerseText(module,
495
559
  hasStrongs,
496
560
  hasInconsistentClosingEndDivs,
497
561
  // Note that if markup is broken this will enforce
498
562
  // the usage of the "stripped" / non-markup variant of the text
499
- moduleMarkupIsBroken);
563
+ moduleMarkupIsBroken,
564
+ moduleFileUrl);
500
565
 
501
566
  // If the current verse does not have any content and if it is the first verse in this book
502
567
  // we assume that the book is not existing.
@@ -559,12 +624,11 @@ string TextProcessor::getBookIntroduction(string moduleName, string bookCode)
559
624
  filteredText = regex_replace(filteredText, headEndElementFilter, "</div>");
560
625
  filteredText = regex_replace(filteredText, chapterDivFilter, "");
561
626
 
562
- // Prefix img src attributes starting with "/" with the module data path as a file:// URL
563
- string moduleDataPath = this->_moduleStore.getModuleDataPath(module);
564
- if (!moduleDataPath.empty()) {
565
- string fileUrl = this->getFileUrl(moduleDataPath);
627
+ // Prefix img src attributes starting with "/" with the module file URL
628
+ string moduleFileUrl = this->getFileUrl(this->_moduleStore.getModuleDataPath(module));
629
+ if (!moduleFileUrl.empty()) {
566
630
  static string imgSrcSlash = "src=\"/";
567
- string imgSrcReplacement = "src=\"" + fileUrl + "/";
631
+ string imgSrcReplacement = "src=\"" + moduleFileUrl + "/";
568
632
  this->findAndReplaceAll(filteredText, imgSrcSlash, imgSrcReplacement);
569
633
  }
570
634
  }
@@ -63,8 +63,10 @@ private:
63
63
  int startVerseNr=-1,
64
64
  int verseCount=-1);
65
65
 
66
- std::string getCurrentChapterHeading(sword::SWModule* module);
67
- std::string getFilteredText(const std::string& text, int chapter, int verseNr, bool hasStrongs=false, bool hasInconsistentClosingEndDivs=false, const std::string& moduleDataPath="");
66
+ std::string getCurrentChapterHeading(sword::SWModule* module, const std::string& moduleFileUrl);
67
+ std::string getCurrentPreverseHeading(sword::SWModule* module, const std::string& moduleFileUrl);
68
+ std::string getCurrentVerseText(sword::SWModule* module, bool hasStrongs, bool hasInconsistentClosingEndDivs, bool forceNoMarkup, const std::string& moduleFileUrl);
69
+ std::string getFilteredText(const std::string& text, int chapter, int verseNr, bool hasStrongs, bool hasInconsistentClosingEndDivs, const std::string& moduleFileUrl);
68
70
  std::string getFileUrl(const std::string& nativePath);
69
71
  std::string replaceSpacesInStrongs(const std::string& text);
70
72
  unsigned int findAndReplaceAll(std::string & data, std::string toSearch, std::string replaceStr);