Quite a while ago, Xiphos gained the capability to post-process the
*n/*x that come out of the engine so as to add the n=X identifiers that
emanate out of OSIS and ThML markup.  This is a fine and welcome idea,
but we have run into a problem.

Some modules have single-section content that is really big.  I mean,
*really* big, half a megabyte at a time Really Big.  Notably,
EarlyFathers' /NPNF109/Subject_Index is my current problem child and
proof case.

The problem presented by a post-processing step of this sort is that,
having the content in hand, we now need to make 2 calls to
getEntryAttributes() in order to retrieve both "n" and "type" elements.

Evidently, each such call requires that the engine retrieve original
content from disc, and fully parse it out.  Ouchie.

/NPNF109/Subject_Index has almost 2500 footnotes in its 480Kbytes.

Ergo, 5000 retrievals times 480Kbytes apiece = ...

Ow.  Ow ow ow ow ow.

Some rough timing when I discovered this problem earlier this week
showed that it would take -- I am not exaggerating -- just short of an
hour to render this section, on the rather beastly machine I now use.
95+% of the time is being spent in the engine's retrieval; virtually no
time is spent in the g_string routines that perform the actual textual
appendage.

So although the post-processing effect is a good one, being implemented
*as* a post-processing step is a disaster.  I had never noticed this
downside until I ran into these pathological cases this week.  The Right
Way to do this is for the filters to output the n=X content on the spot.

The attached patch provides this for all htmlhref and xhtml filters.
I'd like to apply this (I'll do it myself, I have privs) but I wanted to
make sure that adding this doesn't harm anyone else.  It's a
straightforward, simple change, and you can see the effect in a couple
screenshots:
http://karl.kleinpaste.org/xiphos/notes-xrefs-NASB.png
http://karl.kleinpaste.org/xiphos/notes-xrefs-NET.png

Please review and provide feedback.  I'll commit the patch in a day or
three if no one objects.

--karl

Index: src/modules/filters/thmlxhtml.cpp
===================================================================
--- src/modules/filters/thmlxhtml.cpp	(revision 2675)
+++ src/modules/filters/thmlxhtml.cpp	(working copy)
@@ -208,6 +208,7 @@
 				if (!tag.isEmpty()) {
 					SWBuf type = tag.getAttribute("type");
 					SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+					SWBuf noteName = tag.getAttribute("n");
 					VerseKey *vkey = NULL;
 					// see if we have a VerseKey * or descendant
 					SWTRY {
@@ -217,23 +218,25 @@
 					if (vkey) {
 						// leave this special osis type in for crossReference notes types?  Might thml use this some day? Doesn't hurt.
 						char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
-						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>", 
+						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>", 
 							ch, 
 							URL::encode(footnoteNumber.c_str()).c_str(), 
 							URL::encode(u->version.c_str()).c_str(), 
 							URL::encode(vkey->getText()).c_str(), 
 							ch,
-							ch);
+							ch, 
+							URL::encode(noteName.c_str()).c_str());
 					}
 					else {
 						char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
-						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>", 
+						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>", 
 							ch, 
 							URL::encode(footnoteNumber.c_str()).c_str(), 
 							URL::encode(u->version.c_str()).c_str(), 
 							URL::encode(u->key->getText()).c_str(),  
 							ch,
-							ch);
+							ch, 
+							URL::encode(noteName.c_str()).c_str());
 					}
 					u->suspendTextPassThru = true;
 				}
@@ -267,6 +270,7 @@
 				}
 				else {
 					SWBuf footnoteNumber = u->startTag.getAttribute("swordFootnote");
+					SWBuf noteName = tag.getAttribute("n");
 					VerseKey *vkey = NULL;
 					// see if we have a VerseKey * or descendant
 					SWTRY {
@@ -276,11 +280,11 @@
 					if (vkey) {
 						// leave this special osis type in for crossReference notes types?  Might thml use this some day? Doesn't hurt.
 						//buf.appendFormatted("<a href=\"noteID=%s.x.%s\"><small><sup>*x</sup></small></a> ", vkey->getText(), footnoteNumber.c_str());
-						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=x&value=%s&module=%s&passage=%s\"><small><sup class=\"x\">*x</sup></small></a>",
+						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=x&value=%s&module=%s&passage=%s\"><small><sup class=\"x\">*x%s</sup></small></a>",
 							URL::encode(footnoteNumber.c_str()).c_str(), 
 							URL::encode(u->version.c_str()).c_str(),
-							URL::encode(vkey->getText()).c_str());
-					
+							URL::encode(vkey->getText()).c_str(), 
+							URL::encode(noteName.c_str()).c_str());
 					}
 				}
 
Index: src/modules/filters/gbfhtmlhref.cpp
===================================================================
--- src/modules/filters/gbfhtmlhref.cpp	(revision 2675)
+++ src/modules/filters/gbfhtmlhref.cpp	(working copy)
@@ -231,6 +231,7 @@
 		else if (!strcmp(tag.getName(), "RF")) {
 			SWBuf type = tag.getAttribute("type");
 			SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+			SWBuf noteName = tag.getAttribute("n");
 			VerseKey *vkey = NULL;
 			// see if we have a VerseKey * or descendant
 			SWTRY {
@@ -240,10 +241,11 @@
 			if (vkey) {
 				// leave this special osis type in for crossReference notes types?  Might thml use this some day? Doesn't hurt.
 				//char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
-				buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=n&value=%s&module=%s&passage=%s\"><small><sup class=\"n\">*n</sup></small></a> ", 
+				buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=n&value=%s&module=%s&passage=%s\"><small><sup class=\"n\">*n%s</sup></small></a> ", 
 					URL::encode(footnoteNumber.c_str()).c_str(),
 					URL::encode(u->version.c_str()).c_str(), 
-					URL::encode(vkey->getText()).c_str());
+					URL::encode(vkey->getText()).c_str(), 
+					URL::encode(noteName.c_str()).c_str());
 			}
 			u->suspendTextPassThru = true;
 		}
Index: src/modules/filters/osisxhtml.cpp
===================================================================
--- src/modules/filters/osisxhtml.cpp	(revision 2675)
+++ src/modules/filters/osisxhtml.cpp	(working copy)
@@ -252,6 +252,7 @@
 
 					if (!strongsMarkup) {	// leave strong's markup notes out, in the future we'll probably have different option filters to turn different note types on or off
 						SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+						SWBuf noteName = tag.getAttribute("n");
 						VerseKey *vkey = NULL;
 						char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
 
@@ -265,22 +266,24 @@
 						SWCATCH ( ... ) {	}
 						if (vkey) {
 							//printf("URL = %s\n",URL::encode(vkey->getText()).c_str());
-							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>",
+							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>",
 								ch, 
 								URL::encode(footnoteNumber.c_str()).c_str(), 
 								URL::encode(u->version.c_str()).c_str(), 
 								URL::encode(vkey->getText()).c_str(), 
 								ch,
-								ch);
+								ch, 
+								URL::encode(noteName.c_str()).c_str());
 						}
 						else {
-							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>",
+							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>",
 								ch, 
 								URL::encode(footnoteNumber.c_str()).c_str(), 
 								URL::encode(u->version.c_str()).c_str(), 
 								URL::encode(u->key->getText()).c_str(),  
 								ch,
-								ch);
+								ch, 
+								URL::encode(noteName.c_str()).c_str());
 						}
 					}
 				}
Index: src/modules/filters/osishtmlhref.cpp
===================================================================
--- src/modules/filters/osishtmlhref.cpp	(revision 2675)
+++ src/modules/filters/osishtmlhref.cpp	(working copy)
@@ -240,6 +240,7 @@
 
 					if (!strongsMarkup) {	// leave strong's markup notes out, in the future we'll probably have different option filters to turn different note types on or off
 						SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+						SWBuf noteName = tag.getAttribute("n");
 						VerseKey *vkey = NULL;
 						char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
 
@@ -253,22 +254,24 @@
 						SWCATCH ( ... ) {	}
 						if (vkey) {
 							//printf("URL = %s\n",URL::encode(vkey->getText()).c_str());
-							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>",
+							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>",
 								ch, 
 								URL::encode(footnoteNumber.c_str()).c_str(), 
 								URL::encode(u->version.c_str()).c_str(), 
 								URL::encode(vkey->getText()).c_str(), 
 								ch,
-								ch);
+								ch, 
+								URL::encode(noteName.c_str()).c_str());
 						}
 						else {
-							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>",
+							buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>",
 								ch, 
 								URL::encode(footnoteNumber.c_str()).c_str(), 
 								URL::encode(u->version.c_str()).c_str(), 
 								URL::encode(u->key->getText()).c_str(),  
 								ch,
-								ch);
+								ch, 
+								URL::encode(noteName.c_str()).c_str());
 						}
 					}
 				}
Index: src/modules/filters/gbfxhtml.cpp
===================================================================
--- src/modules/filters/gbfxhtml.cpp	(revision 2675)
+++ src/modules/filters/gbfxhtml.cpp	(working copy)
@@ -168,6 +168,7 @@
 		else if (!strcmp(tag.getName(), "RF")) {
 			SWBuf type = tag.getAttribute("type");
 			SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+			SWBuf noteName = tag.getAttribute("n");
 			VerseKey *vkey = NULL;
 			// see if we have a VerseKey * or descendant
 			SWTRY {
@@ -177,10 +178,11 @@
 			if (vkey) {
 				// leave this special osis type in for crossReference notes types?  Might thml use this some day? Doesn't hurt.
 				//char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
-				buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=n&value=%s&module=%s&passage=%s\"><small><sup class=\"n\">*n</sup></small></a> ", 
+				buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=n&value=%s&module=%s&passage=%s\"><small><sup class=\"n\">*n%s</sup></small></a> ", 
 					URL::encode(footnoteNumber.c_str()).c_str(),
 					URL::encode(u->version.c_str()).c_str(), 
-					URL::encode(vkey->getText()).c_str());
+					URL::encode(vkey->getText()).c_str(), 
+					URL::encode(noteName.c_str()).c_str());
 			}
 			u->suspendTextPassThru = true;
 		}
Index: src/modules/filters/thmlhtmlhref.cpp
===================================================================
--- src/modules/filters/thmlhtmlhref.cpp	(revision 2675)
+++ src/modules/filters/thmlhtmlhref.cpp	(working copy)
@@ -206,6 +206,7 @@
 				if (!tag.isEmpty()) {
 					SWBuf type = tag.getAttribute("type");
 					SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+					SWBuf noteName = tag.getAttribute("n");
 					VerseKey *vkey = NULL;
 					// see if we have a VerseKey * or descendant
 					SWTRY {
@@ -215,23 +216,25 @@
 					if (vkey) {
 						// leave this special osis type in for crossReference notes types?  Might thml use this some day? Doesn't hurt.
 						char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
-						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>", 
+						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>", 
 							ch, 
 							URL::encode(footnoteNumber.c_str()).c_str(), 
 							URL::encode(u->version.c_str()).c_str(), 
 							URL::encode(vkey->getText()).c_str(), 
 							ch,
-							ch);
+							ch, 
+							URL::encode(noteName.c_str()).c_str());
 					}
 					else {
 						char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
-						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c</sup></small></a>", 
+						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=%c&value=%s&module=%s&passage=%s\"><small><sup class=\"%c\">*%c%s</sup></small></a>", 
 							ch, 
 							URL::encode(footnoteNumber.c_str()).c_str(), 
 							URL::encode(u->version.c_str()).c_str(), 
 							URL::encode(u->key->getText()).c_str(),  
 							ch,
-							ch);
+							ch, 
+							URL::encode(noteName.c_str()).c_str());
 					}
 					u->suspendTextPassThru = true;
 				}
@@ -265,6 +268,7 @@
 				}
 				else {
 					SWBuf footnoteNumber = u->startTag.getAttribute("swordFootnote");
+					SWBuf noteName = tag.getAttribute("n");
 					VerseKey *vkey = NULL;
 					// see if we have a VerseKey * or descendant
 					SWTRY {
@@ -274,11 +278,11 @@
 					if (vkey) {
 						// leave this special osis type in for crossReference notes types?  Might thml use this some day? Doesn't hurt.
 						//buf.appendFormatted("<a href=\"noteID=%s.x.%s\"><small><sup>*x</sup></small></a> ", vkey->getText(), footnoteNumber.c_str());
-						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=x&value=%s&module=%s&passage=%s\"><small><sup class=\"x\">*x</sup></small></a>",
+						buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=x&value=%s&module=%s&passage=%s\"><small><sup class=\"x\">*x%s</sup></small></a>",
 							URL::encode(footnoteNumber.c_str()).c_str(), 
 							URL::encode(u->version.c_str()).c_str(),
-							URL::encode(vkey->getText()).c_str());
-					
+							URL::encode(vkey->getText()).c_str(), 
+							URL::encode(noteName.c_str()).c_str());
 					}
 				}
 
Index: src/modules/filters/teihtmlhref.cpp
===================================================================
--- src/modules/filters/teihtmlhref.cpp	(revision 2675)
+++ src/modules/filters/teihtmlhref.cpp	(working copy)
@@ -259,11 +259,13 @@
 			}
 			if (tag.isEndTag()) {
 				SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+				SWBuf noteName = tag.getAttribute("n");
 				
-				buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=n&value=%s&module=%s&passage=%s\"><small><sup class=\"n\">*n</sup></small></a>",
+				buf.appendFormatted("<a href=\"passagestudy.jsp?action=showNote&type=n&value=%s&module=%s&passage=%s\"><small><sup class=\"n\">*n%s</sup></small></a>",
 					URL::encode(footnoteNumber.c_str()).c_str(), 
 					URL::encode(u->version.c_str()).c_str(),
-					URL::encode(u->key->getText()).c_str());
+					URL::encode(u->key->getText()).c_str(), 
+					URL::encode(noteName.c_str()).c_str());
 				
 				u->suspendTextPassThru = false;
 			}
_______________________________________________
sword-devel mailing list: sword-devel@crosswire.org
http://www.crosswire.org/mailman/listinfo/sword-devel
Instructions to unsubscribe/change your settings at above page

Reply via email to