[sword-svn] r3853 - in trunk: examples/tasks src/modules

scribe at crosswire.org scribe at crosswire.org
Mon Apr 12 15:04:00 EDT 2021


Author: scribe
Date: 2021-04-12 15:04:00 -0400 (Mon, 12 Apr 2021)
New Revision: 3853

Added:
   trunk/examples/tasks/findHeadings.cpp
Modified:
   trunk/src/modules/swmodule.cpp
Log:
Added ability to find "presence" of an entry attribute
Added new example to show how to find and retrieve Heading entry attributes.


Added: trunk/examples/tasks/findHeadings.cpp
===================================================================
--- trunk/examples/tasks/findHeadings.cpp	                        (rev 0)
+++ trunk/examples/tasks/findHeadings.cpp	2021-04-12 19:04:00 UTC (rev 3853)
@@ -0,0 +1,69 @@
+/******************************************************************************
+ *
+ *  findHeadings.cpp -	this example shows how to locate and retrieve headings
+ *  			from a Bible
+ *
+ * $Id$
+ *
+ * Copyright 2013-2014 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <iostream>
+#include <swmgr.h>
+#include <markupfiltmgr.h>
+#include <swmodule.h>
+#include <versekey.h>
+#include <listkey.h>
+
+using namespace sword;
+using namespace std;
+
+
+int main(int argc, char **argv) {
+
+	SWBuf moduleName = argc > 1 ? argv[1] : "NASB";
+	SWBuf verseRange = argc > 2 ? argv[2] : "Matt-John";
+
+	SWMgr library(new MarkupFilterMgr(FMT_XHTML));
+	library.setGlobalOption("Headings", "On");
+
+        SWModule *module = library.getModule(moduleName);
+	ListKey results;
+
+	if (!module) return cerr << "\nCouldn't find module: " << moduleName << "\n\n", -1;
+
+	SWKey *key = module->getKey();
+	VerseKey *verseKey = SWDYNAMIC_CAST(VerseKey, key);
+	ListKey scope = verseKey->parseVerseList(verseRange, *verseKey, true);
+
+	results = module->search("/Heading", SWModule::SEARCHTYPE_ENTRYATTR, 0, &scope);
+
+	for (results = TOP; !results.popError(); results++) {
+		module->setKey(results);
+		module->renderText();
+
+		// get both Preverse and Interverse Headings and just merge them into the same map
+		AttributeValue headings = module->getEntryAttributes()["Heading"]["Preverse"];
+		AttributeValue interverseHeadings = module->getEntryAttributes()["Heading"]["Interverse"];
+		headings.insert(interverseHeadings.begin(), interverseHeadings.end());
+
+		for (AttributeValue::const_iterator it = headings.begin(); it != headings.end(); ++it) {
+			cout << it->second.c_str() << " (" << module->getKeyText() << ")\n";
+		}
+	}
+	cout << "\n";
+        return 0;
+}

Modified: trunk/src/modules/swmodule.cpp
===================================================================
--- trunk/src/modules/swmodule.cpp	2021-04-08 17:02:11 UTC (rev 3852)
+++ trunk/src/modules/swmodule.cpp	2021-04-12 19:04:00 UTC (rev 3853)
@@ -640,6 +640,10 @@
 
 	// entry attributes
 	case SEARCHTYPE_ENTRYATTR:
+		// if path starts with /, let's just pop it off the stack
+		// it's sometimes expressive to start the path with '/' but it is not required
+		if (term.startsWith('/')) term << 1;
+
 		// let's break the attribute segs down.  We'll reuse our words vector for each segment
 		while (1) {
 			const char *word = term.stripPrefix('/');
@@ -860,7 +864,7 @@
 							i3End   = i2Start->second.end();
 						}
 						for (;i3Start != i3End; i3Start++) {
-							if ((words.size()>3) && (words[3].length())) {
+							if (words.size() > 3) {
 								if (includeComponents) {
 									SWBuf key = i3Start->first.c_str();
 									key = key.stripPrefix('.', true);
@@ -868,7 +872,11 @@
 									// prefix (e.g., Lemma, Lemma.1, Lemma.2, etc.)
 									if (key != words[2]) continue;
 								}
-								if (flags & SEARCHFLAG_MATCHWHOLEENTRY) {
+								// we only want 0 length entries as hits
+								if (!words[3].length()) {
+									if (!i3Start->second.length()) sres = i3Start->second.c_str();
+								}
+								else if (flags & SEARCHFLAG_MATCHWHOLEENTRY) {
 									bool found = !(((flags & REG_ICASE) == REG_ICASE) ? sword::stricmp(i3Start->second.c_str(), words[3]) : strcmp(i3Start->second.c_str(), words[3]));
 									sres = (found) ? i3Start->second.c_str() : 0;
 								}
@@ -882,6 +890,13 @@
 									break;
 								}
 							}
+							// If we weren't provided a value for the Entry Attribute, then we simply return if present.
+							else {
+								*resultKey = *getKey();
+								resultKey->clearBounds();
+								listKey << *resultKey;
+								break;
+							}
 						}
 						if (i3Start != i3End)
 							break;



More information about the sword-cvs mailing list