<html><head></head><body bgcolor="#FFFFFF"><div>I've always thought that the value of the n attribute should be used if it were there. <br><br>Cent from my fone so theer mite be tipos. ;)</div><div><br>On Feb 4, 2012, at 1:34 PM, Karl Kleinpaste <<a href="mailto:karl@kleinpaste.org">karl@kleinpaste.org</a>> wrote:<br><br></div><div></div><blockquote type="cite"><div><span>Quite a while ago, Xiphos gained the capability to post-process the</span><br><span>*n/*x that come out of the engine so as to add the n=X identifiers that</span><br><span>emanate out of OSIS and ThML markup.  This is a fine and welcome idea,</span><br><span>but we have run into a problem.</span><br><span></span><br><span>Some modules have single-section content that is really big.  I mean,</span><br><span>*really* big, half a megabyte at a time Really Big.  Notably,</span><br><span>EarlyFathers' /NPNF109/Subject_Index is my current problem child and</span><br><span>proof case.</span><br><span></span><br><span>The problem presented by a post-processing step of this sort is that,</span><br><span>having the content in hand, we now need to make 2 calls to</span><br><span>getEntryAttributes() in order to retrieve both "n" and "type" elements.</span><br><span></span><br><span>Evidently, each such call requires that the engine retrieve original</span><br><span>content from disc, and fully parse it out.  Ouchie.</span><br><span></span><br><span>/NPNF109/Subject_Index has almost 2500 footnotes in its 480Kbytes.</span><br><span></span><br><span>Ergo, 5000 retrievals times 480Kbytes apiece = ...</span><br><span></span><br><span>Ow.  Ow ow ow ow ow.</span><br><span></span><br><span>Some rough timing when I discovered this problem earlier this week</span><br><span>showed that it would take -- I am not exaggerating -- just short of an</span><br><span>hour to render this section, on the rather beastly machine I now use.</span><br><span>95+% of the time is being spent in the engine's retrieval; virtually no</span><br><span>time is spent in the g_string routines that perform the actual textual</span><br><span>appendage.</span><br><span></span><br><span>So although the post-processing effect is a good one, being implemented</span><br><span>*as* a post-processing step is a disaster.  I had never noticed this</span><br><span>downside until I ran into these pathological cases this week.  The Right</span><br><span>Way to do this is for the filters to output the n=X content on the spot.</span><br><span></span><br><span>The attached patch provides this for all htmlhref and xhtml filters.</span><br><span>I'd like to apply this (I'll do it myself, I have privs) but I wanted to</span><br><span>make sure that adding this doesn't harm anyone else.  It's a</span><br><span>straightforward, simple change, and you can see the effect in a couple</span><br><span>screenshots:</span><br><span><a href="http://karl.kleinpaste.org/xiphos/notes-xrefs-NASB.png">http://karl.kleinpaste.org/xiphos/notes-xrefs-NASB.png</a></span><br><span><a href="http://karl.kleinpaste.org/xiphos/notes-xrefs-NET.png">http://karl.kleinpaste.org/xiphos/notes-xrefs-NET.png</a></span><br><span></span><br><span>Please review and provide feedback.  I'll commit the patch in a day or</span><br><span>three if no one objects.</span><br><span></span><br><span>--karl</span><br><span></span><br></div></blockquote><blockquote type="cite"><div>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;
                        }
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>sword-devel mailing list: <a href="mailto:sword-devel@crosswire.org">sword-devel@crosswire.org</a></span><br><span><a href="http://www.crosswire.org/mailman/listinfo/sword-devel">http://www.crosswire.org/mailman/listinfo/sword-devel</a></span><br><span>Instructions to unsubscribe/change your settings at above page</span></div></blockquote></body></html>