[sword-svn] r1950 - in trunk: include src/modules/filters

scribe at crosswire.org scribe at crosswire.org
Sun Jul 30 01:14:06 MST 2006


Author: scribe
Date: 2006-07-30 01:14:04 -0700 (Sun, 30 Jul 2006)
New Revision: 1950

Modified:
   trunk/include/osishtmlhref.h
   trunk/include/osisrtf.h
   trunk/src/modules/filters/osishtmlhref.cpp
   trunk/src/modules/filters/osisrtf.cpp
Log:
Updated q handling to use quote stack (DM Smith)


Modified: trunk/include/osishtmlhref.h
===================================================================
--- trunk/include/osishtmlhref.h	2006-07-28 08:27:46 UTC (rev 1949)
+++ trunk/include/osishtmlhref.h	2006-07-30 08:14:04 UTC (rev 1950)
@@ -30,21 +30,22 @@
 class SWDLLEXPORT OSISHTMLHREF : public SWBasicFilter {
 private:
 protected:
+	// used by derived classes so we have it in the header
+	class QuoteStack;
 	class MyUserData : public BasicFilterUserData {
 	public:
 		bool osisQToTick;
 		bool inBold;
-		bool inQuote;
 		bool inName;
-		bool providesQuote;
-		SWBuf quoteMark;
 		SWBuf wordsOfChristStart;
 		SWBuf wordsOfChristEnd;
+                QuoteStack *quoteStack;
 		SWBuf lastTransChange;
 		SWBuf w;
 		SWBuf fn;
 		SWBuf version;
 		MyUserData(const SWModule *module, const SWKey *key);
+		~MyUserData();
 	};
 	virtual BasicFilterUserData *createUserData(const SWModule *module, const SWKey *key) {
 		return new MyUserData(module, key);

Modified: trunk/include/osisrtf.h
===================================================================
--- trunk/include/osisrtf.h	2006-07-28 08:27:46 UTC (rev 1949)
+++ trunk/include/osisrtf.h	2006-07-30 08:14:04 UTC (rev 1950)
@@ -31,21 +31,7 @@
 private:
 
 protected:
-	class MyUserData : public BasicFilterUserData {
-	public:
-		bool osisQToTick;
-		bool BiblicalText;
-		bool inXRefNote;
-		bool inQuote;
-		bool providesQuote;
-		SWBuf quoteMark;
-		SWBuf w;
-		SWBuf version;
-		MyUserData(const SWModule *module, const SWKey *key);
-	};
-	virtual BasicFilterUserData *createUserData(const SWModule *module, const SWKey *key) {
-		return new MyUserData(module, key);
-	}
+	virtual BasicFilterUserData *createUserData(const SWModule *module, const SWKey *key);
 	virtual bool handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData);
 public:
 	OSISRTF();

Modified: trunk/src/modules/filters/osishtmlhref.cpp
===================================================================
--- trunk/src/modules/filters/osishtmlhref.cpp	2006-07-28 08:27:46 UTC (rev 1949)
+++ trunk/src/modules/filters/osishtmlhref.cpp	2006-07-30 08:14:04 UTC (rev 1950)
@@ -17,15 +17,19 @@
 #include <ctype.h>
 #include <osishtmlhref.h>
 #include <utilxml.h>
+#include <utilstr.h>
 #include <versekey.h>
 #include <swmodule.h>
 #include <url.h>
+#include <stack>
 
 SWORD_NAMESPACE_START
 
+class OSISHTMLHREF::QuoteStack : public std::stack<const char*> {
+};
 
 OSISHTMLHREF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
-	providesQuote = false;
+	quoteStack = new QuoteStack();
 	wordsOfChristStart = "<font color=\"red\"> ";
 	wordsOfChristEnd   = "</font> ";
 	if (module) {
@@ -38,6 +42,15 @@
 	}
 }
 
+OSISHTMLHREF::MyUserData::~MyUserData() {
+	// Just in case the quotes are not well formed
+	while (!quoteStack->empty()) {
+		const char *tagData = quoteStack->top();
+		quoteStack->pop();
+		delete tagData;
+	}
+	delete quoteStack;
+}
 
 OSISHTMLHREF::OSISHTMLHREF() {
 	setTokenStart("<");
@@ -259,6 +272,8 @@
 			userData->supressAdjacentWhitespace = true;
 		}
 		// <milestone type="line"/>
+		// <milestone type="x-p"/>
+		// <milestone type="cQuote" marker="x"/>
 		else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type"))) {
 			if(!strcmp(tag.getAttribute("type"), "line")) {
 				outText("<br />", buf, u);
@@ -269,6 +284,18 @@
 					outText(tag.getAttribute("marker"), buf, u);
 				else outText("<!p>", buf, u);
 			}
+			else if (!strcmp(tag.getAttribute("type"), "cQuote")) {
+				const char *mark = tag.getAttribute("marker");
+				const char *lev = tag.getAttribute("level");
+				int level = (lev) ? atoi(lev) : 1;
+
+				// first check to see if we've been given an explicit mark
+				if (mark)
+					outText(mark, buf, u);
+				// finally, alternate " and ', if config says we should supply a mark
+				else if (u->osisQToTick)
+					outText((level % 2) ? '\"' : '\'', buf, u);
+			}
 		}
 
 		// <title>
@@ -341,6 +368,13 @@
 		}
 
 		// <q> quote
+		// Rules for a quote element:
+		// If the tag is empty with an sID or an eID then use whatever it specifies for quoting.
+		//    Note: empty elements without sID or eID are ignored.
+		// If the tag is <q> then use it's specifications and push it onto a stack for </q>
+		// If the tag is </q> then use the pushed <q> for specification
+		// If there is a marker attribute, possibly empty, this overrides osisQToTick.
+		// If osisQToTick, then output the marker, using level to determine the type of mark.
 		else if (!strcmp(tag.getName(), "q")) {
 			SWBuf type = tag.getAttribute("type");
 			SWBuf who = tag.getAttribute("who");
@@ -350,74 +384,53 @@
 
 			// open <q> or <q sID... />
 			if ((!tag.isEmpty()) || (tag.getAttribute("sID"))) {
-				// Do this first so quote marks are red
-				if (who == "Jesus" && !u->suspendTextPassThru) {
-					outText(u->wordsOfChristStart, buf, u);
-					u->inQuote = true;
+				// if <q> then remember it for the </q>
+				if (!tag.isEmpty()) {
+					char *tagData = 0;
+					stdstr(&tagData, tag.toString());
+					u->quoteStack->push(tagData);
 				}
 
-				// Honor the marker attribute, ignoring the osisQToTick
-				if (!tag.isEmpty()) {
-					u->providesQuote = false;
-				}
-				if (mark) {
-					if (*mark) {
-						outText(mark, buf, u);
-					}
-					if (!tag.isEmpty()) {
-						u->quoteMark = mark;
-						u->providesQuote = true;
-					}
-				}
+				// Do this first so quote marks are included as WoC
+				if (who == "Jesus")
+					outText(u->wordsOfChristStart, buf, u);
+
+				// first check to see if we've been given an explicit mark
+				if (mark)
+					outText(mark, buf, u);
 				//alternate " and '
 				else if (u->osisQToTick)
 					outText((level % 2) ? '\"' : '\'', buf, u);
 			}
 			// close </q> or <q eID... />
 			else if ((tag.isEndTag()) || (tag.getAttribute("eID"))) {
+				// if it is </q> then pop the stack for the attributes
+				if (tag.isEndTag() && !u->quoteStack->empty()) {
+					const char *tagData  = u->quoteStack->top();
+					u->quoteStack->pop();
+					XMLTag qTag(tagData);
+					delete tagData;
+
+					type  = qTag.getAttribute("type");
+					who   = qTag.getAttribute("who");
+					lev   = qTag.getAttribute("level");
+					mark  = qTag.getAttribute("marker");
+					level = (lev) ? atoi(lev) : 1;
+				}
+
 				// first check to see if we've been given an explicit mark
-				if (mark) {
-					if (*mark) {
-						outText(mark, buf, u);
-					}
-				}
-				// next check to see if our opening q provided an explicit mark
-				else if (u->providesQuote && !tag.getAttribute("eID")) {
-					if (u->quoteMark.length()) {
-						outText(u->quoteMark, buf, u);
-					}
-					u->providesQuote = false;
-				}
+				if (mark)
+					outText(mark, buf, u);
 				// finally, alternate " and ', if config says we should supply a mark
 				else if (u->osisQToTick)
 					outText((level % 2) ? '\"' : '\'', buf, u);
 
-				// if we've changed font color, we should put it back
-				// Do this last so quote mark is colored
-				if (u->inQuote && (who == "Jesus" || tag.isEndTag())) {
+				// Do this last so quote marks are included as WoC
+				if (who == "Jesus")
 					outText(u->wordsOfChristEnd, buf, u);
-					u->inQuote = false;
-				}
 			}
 		}
 
-		// <milestone type="cQuote" marker="x"/>
-		else if (!strcmp(tag.getName(), "milestone") && tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "cQuote")) {
-			const char *mark = tag.getAttribute("marker");
-			const char *lev = tag.getAttribute("level");
-			int level = (lev) ? atoi(lev) : 1;
-
-			// first check to see if we've been given an explicit mark
-			if (mark) {
-				if (*mark) {
-					outText(mark, buf, u);
-				}
-			}
-			// finally, alternate " and ', if config says we should supply a mark
-			else if (u->osisQToTick)
-				outText((level % 2) ? '\"' : '\'', buf, u);
-		}
-
 		// <transChange>
 		else if (!strcmp(tag.getName(), "transChange")) {
 			if ((!tag.isEndTag()) && (!tag.isEmpty())) {

Modified: trunk/src/modules/filters/osisrtf.cpp
===================================================================
--- trunk/src/modules/filters/osisrtf.cpp	2006-07-28 08:27:46 UTC (rev 1949)
+++ trunk/src/modules/filters/osisrtf.cpp	2006-07-30 08:14:04 UTC (rev 1950)
@@ -17,18 +17,32 @@
 #include <ctype.h>
 #include <osisrtf.h>
 #include <utilxml.h>
+#include <utilstr.h>
 #include <versekey.h>
 #include <swmodule.h>
 #include <stringmgr.h>
+#include <stack>
 
 SWORD_NAMESPACE_START
 
+namespace {
+	class MyUserData : public BasicFilterUserData {
+	public:
+		bool osisQToTick;
+		bool BiblicalText;
+		bool inXRefNote;
+		std::stack<const char*> quoteStack;
+		SWBuf w;
+		SWBuf version;
+		MyUserData(const SWModule *module, const SWKey *key);
+		~MyUserData();
+	};
+};
 
-OSISRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
+
+MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
 	inXRefNote    = false;
 	BiblicalText  = false;
-	inQuote       = false;
-	providesQuote = false;
 	if (module) {
 		version = module->Name();
 		BiblicalText = (!strcmp(module->Type(), "Biblical Texts"));
@@ -37,6 +51,16 @@
 }
 
 
+MyUserData::~MyUserData() {
+	// Just in case the quotes are not well formed
+	while (!quoteStack.empty()) {
+		const char *tagData = quoteStack.top();
+		quoteStack.pop();
+		delete tagData;
+	}
+}
+
+
 OSISRTF::OSISRTF() {
 	setTokenStart("<");
 	setTokenEnd(">");
@@ -58,6 +82,11 @@
 }
 
 
+BasicFilterUserData *OSISRTF::createUserData(const SWModule *module, const SWKey *key) {
+	return new MyUserData(module, key);
+}
+
+
 bool OSISRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
   // manually process if it wasn't a simple substitution
 	if (!substituteToken(buf, token)) {
@@ -259,6 +288,13 @@
 		}
 
 		// <q> quote
+		// Rules for a quote element:
+		// If the tag is empty with an sID or an eID then use whatever it specifies for quoting.
+		//    Note: empty elements without sID or eID are ignored.
+		// If the tag is <q> then use it's specifications and push it onto a stack for </q>
+		// If the tag is </q> then use the pushed <q> for specification
+		// If there is a marker attribute, possibly empty, this overrides osisQToTick.
+		// If osisQToTick, then output the marker, using level to determine the type of mark.
 		else if (!strcmp(tag.getName(), "q")) {
 			SWBuf type = tag.getAttribute("type");
 			SWBuf who = tag.getAttribute("who");
@@ -268,57 +304,54 @@
 
 			// open <q> or <q sID... />
 			if ((!tag.isEmpty()) || (tag.getAttribute("sID"))) {
+				// if <q> then remember it for the </q>
+				if (!tag.isEmpty()) {
+					char *tagData = 0;
+					stdstr(&tagData, tag.toString());
+					u->quoteStack.push(tagData);
+				}
 
-				if (who == "Jesus") {
+				// Do this first so quote marks are included as WoC
+				if (who == "Jesus")
 					buf += "\\cf6 ";
-					u->inQuote = true;
-				}
 
-				// Honor the marker attribute, ignoring the osisQToTick
-				if (!tag.isEmpty()) {
-					u->providesQuote = false;
-				}
-				if (mark) {
-					if (*mark) {
-						buf += mark;
-					}
-					if (!tag.isEmpty()) {
-						u->quoteMark = mark;
-						u->providesQuote = true;
-					}
-				}
+				// first check to see if we've been given an explicit mark
+				if (mark)
+					buf += mark;
 				//alternate " and '
 				else if (u->osisQToTick)
 					buf += (level % 2) ? '\"' : '\'';
 			}
 			// close </q> or <q eID... />
 			else if ((tag.isEndTag()) || (tag.getAttribute("eID"))) {
+				// if it is </q> then pop the stack for the attributes
+				if (tag.isEndTag() && !u->quoteStack.empty()) {
+					const char *tagData  = u->quoteStack.top();
+					u->quoteStack.pop();
+					XMLTag qTag(tagData);
+					delete tagData;
+
+					type  = qTag.getAttribute("type");
+					who   = qTag.getAttribute("who");
+					lev   = qTag.getAttribute("level");
+					mark  = qTag.getAttribute("marker");
+					level = (lev) ? atoi(lev) : 1;
+				}
+
 				// first check to see if we've been given an explicit mark
-				if (mark) {
-					if (*mark) {
-						buf += mark;
-					}
-				}
-				// next check to see if our opening q provided an explicit mark
-				else if (u->providesQuote && !tag.getAttribute("eID")) {
-					if (u->quoteMark.length()) {
-						buf += u->quoteMark;
-					}
-					u->providesQuote = false;
-				}
+				if (mark)
+					buf += mark;
 				// finally, alternate " and ', if config says we should supply a mark
 				else if (u->osisQToTick)
 					buf += (level % 2) ? '\"' : '\'';
 
-				// if we've changed color, we should put it back
-				// Do this last so quote mark is colored
-				if (u->inQuote && (who == "Jesus" || tag.isEndTag())) {
+				// Do this last so quote marks are included as WoC
+				if (who == "Jesus")
 					buf += "\\cf0 ";
-					u->inQuote = false;
-				}
 			}
 		}
 
+
 		// <milestone type="cQuote" marker="x"/>
 		else if (!strcmp(tag.getName(), "milestone") && tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "cQuote")) {
 			const char *mark = tag.getAttribute("marker");
@@ -326,11 +359,8 @@
 			int level = (lev) ? atoi(lev) : 1;
 
 			// first check to see if we've been given an explicit mark
-			if (mark) {
-				if (*mark) {
-					buf += mark;
-				}
-			}
+			if (mark)
+				buf += mark;
 			// finally, alternate " and ', if config says we should supply a mark
 			else if (u->osisQToTick)
 				buf += (level % 2) ? '\"' : '\'';



More information about the sword-cvs mailing list