diff options
Diffstat (limited to 'src/modules/filters/thmlhtmlhref.cpp')
-rw-r--r-- | src/modules/filters/thmlhtmlhref.cpp | 350 |
1 files changed, 145 insertions, 205 deletions
diff --git a/src/modules/filters/thmlhtmlhref.cpp b/src/modules/filters/thmlhtmlhref.cpp index ce7e3fd..b94b8ae 100644 --- a/src/modules/filters/thmlhtmlhref.cpp +++ b/src/modules/filters/thmlhtmlhref.cpp @@ -15,255 +15,195 @@ ***************************************************************************/ #include <stdlib.h> -#include <string.h> #include <thmlhtmlhref.h> #include <swmodule.h> +#include <utilxml.h> +#include <versekey.h> +SWORD_NAMESPACE_START -ThMLHTMLHREF::ThMLHTMLHREF() { - setTokenStart("<"); - setTokenEnd(">"); -/* - setEscapeStart("&"); - setEscapeEnd(";"); - setEscapeStringCaseSensitive(true); +ThMLHTMLHREF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + if (module) { + version = module->Name(); + BiblicalText = (!strcmp(module->Type(), "Biblical Texts")); + } +} - addEscapeStringSubstitute("nbsp", " "); - addEscapeStringSubstitute("quot", "\""); - addEscapeStringSubstitute("amp", "&"); - addEscapeStringSubstitute("lt", "<"); - addEscapeStringSubstitute("gt", ">"); - addEscapeStringSubstitute("brvbar", "|"); - addEscapeStringSubstitute("sect", "§"); - addEscapeStringSubstitute("copy", "©"); - addEscapeStringSubstitute("laquo", "«"); - addEscapeStringSubstitute("reg", "®"); - addEscapeStringSubstitute("acute", "´"); - addEscapeStringSubstitute("para", "¶"); - addEscapeStringSubstitute("raquo", "»"); - addEscapeStringSubstitute("Aacute", "Á"); - addEscapeStringSubstitute("Agrave", "À"); - addEscapeStringSubstitute("Acirc", "Â"); - addEscapeStringSubstitute("Auml", "Ä"); - addEscapeStringSubstitute("Atilde", "Ã"); - addEscapeStringSubstitute("Aring", "Å"); - addEscapeStringSubstitute("aacute", "á"); - addEscapeStringSubstitute("agrave", "à"); - addEscapeStringSubstitute("acirc", "â"); - addEscapeStringSubstitute("auml", "ä"); - addEscapeStringSubstitute("atilde", "ã"); - addEscapeStringSubstitute("aring", "å"); - addEscapeStringSubstitute("Eacute", "É"); - addEscapeStringSubstitute("Egrave", "È"); - addEscapeStringSubstitute("Ecirc", "Ê"); - addEscapeStringSubstitute("Euml", "Ë"); - addEscapeStringSubstitute("eacute", "é"); - addEscapeStringSubstitute("egrave", "è"); - addEscapeStringSubstitute("ecirc", "ê"); - addEscapeStringSubstitute("euml", "ë"); - addEscapeStringSubstitute("Iacute", "Í"); - addEscapeStringSubstitute("Igrave", "Ì"); - addEscapeStringSubstitute("Icirc", "Î"); - addEscapeStringSubstitute("Iuml", "Ï"); - addEscapeStringSubstitute("iacute", "í"); - addEscapeStringSubstitute("igrave", "ì"); - addEscapeStringSubstitute("icirc", "î"); - addEscapeStringSubstitute("iuml", "ï"); - addEscapeStringSubstitute("Oacute", "Ó"); - addEscapeStringSubstitute("Ograve", "Ò"); - addEscapeStringSubstitute("Ocirc", "Ô"); - addEscapeStringSubstitute("Ouml", "Ö"); - addEscapeStringSubstitute("Otilde", "Õ"); - addEscapeStringSubstitute("oacute", "ó"); - addEscapeStringSubstitute("ograve", "ò"); - addEscapeStringSubstitute("ocirc", "ô"); - addEscapeStringSubstitute("ouml", "ö"); - addEscapeStringSubstitute("otilde", "õ"); - addEscapeStringSubstitute("Uacute", "Ú"); - addEscapeStringSubstitute("Ugrave", "Ù"); - addEscapeStringSubstitute("Ucirc", "Û"); - addEscapeStringSubstitute("Uuml", "Ü"); - addEscapeStringSubstitute("uacute", "ú"); - addEscapeStringSubstitute("ugrave", "ù"); - addEscapeStringSubstitute("ucirc", "û"); - addEscapeStringSubstitute("uuml", "ü"); - addEscapeStringSubstitute("Yacute", "Ý"); - addEscapeStringSubstitute("yacute", "ý"); - addEscapeStringSubstitute("yuml", "ÿ"); +ThMLHTMLHREF::ThMLHTMLHREF() { + setTokenStart("<"); + setTokenEnd(">"); - addEscapeStringSubstitute("deg", "°"); - addEscapeStringSubstitute("plusmn", "±"); - addEscapeStringSubstitute("sup2", "²"); - addEscapeStringSubstitute("sup3", "³"); - addEscapeStringSubstitute("sup1", "¹"); - addEscapeStringSubstitute("nbsp", "º"); - addEscapeStringSubstitute("pound", "£"); - addEscapeStringSubstitute("cent", "¢"); - addEscapeStringSubstitute("frac14", "¼"); - addEscapeStringSubstitute("frac12", "½"); - addEscapeStringSubstitute("frac34", "¾"); - addEscapeStringSubstitute("iquest", "¿"); - addEscapeStringSubstitute("iexcl", "¡"); - addEscapeStringSubstitute("ETH", "Ð"); - addEscapeStringSubstitute("eth", "ð"); - addEscapeStringSubstitute("THORN", "Þ"); - addEscapeStringSubstitute("thorn", "þ"); - addEscapeStringSubstitute("AElig", "Æ"); - addEscapeStringSubstitute("aelig", "æ"); - addEscapeStringSubstitute("Oslash", "Ø"); - addEscapeStringSubstitute("curren", "¤"); - addEscapeStringSubstitute("Ccedil", "Ç"); - addEscapeStringSubstitute("ccedil", "ç"); - addEscapeStringSubstitute("szlig", "ß"); - addEscapeStringSubstitute("Ntilde", "Ñ"); - addEscapeStringSubstitute("ntilde", "ñ"); - addEscapeStringSubstitute("yen", "¥"); - addEscapeStringSubstitute("not", "¬"); - addEscapeStringSubstitute("ordf", "ª"); - addEscapeStringSubstitute("uml", "¨"); - addEscapeStringSubstitute("shy", ""); - addEscapeStringSubstitute("macr", "¯"); -*/ setTokenCaseSensitive(true); - - addTokenSubstitute("note", " <font color=\"#800000\"><small>("); - addTokenSubstitute("/note", ")</small></font> "); + addTokenSubstitute("scripture", "<i> "); addTokenSubstitute("/scripture", "</i> "); } -bool ThMLHTMLHREF::handleToken(char **buf, const char *token, DualStringMap &userData) { +bool ThMLHTMLHREF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { const char *tok; - if (!substituteToken(buf, token)) { - // manually process if it wasn't a simple substitution - if (!strncmp(token, "sync ", 5)) { - pushString(buf, "<a href=\""); - for (tok = token + 5; *(tok+1); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - - //scan for value and add it to the buffer - for (tok = token + 5; *tok; tok++) { - if (!strncmp(tok, "value=\"", 7)) { - tok += 7; - for (;*tok != '\"'; tok++) - *(*buf)++ = *tok; - break; - } + if (!substituteToken(buf, token)) { // manually process if it wasn't a simple substitution + MyUserData *u = (MyUserData *)userData; + + XMLTag tag(token); + if ((!tag.isEndTag()) && (!tag.isEmpty())) + u->startTag = tag; + + if (tag.getName() && !strcmp(tag.getName(), "sync")) { + SWBuf value = tag.getAttribute("value"); + if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "morph")) { //> + buf += "<small><em>(<a href=\""; + buf += "type="; + buf += tag.getAttribute("type"); + + //const char* value = tag.getAttribute("value"); + buf += " value="; + buf += (value.length()) ? value.c_str() : ""; + buf += "\">"; + buf += (value.length()) ? value.c_str() : ""; + buf += "</a>) </em></small>"; + } + else if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Strongs")) { + buf += "<small><em><<a href=\""; + buf += "type="; + buf += tag.getAttribute("type"); + + //const char* value = tag.getAttribute("value"); + buf += " value="; + buf += (value.length()) ? value.c_str() : ""; + buf += "\">"; + value<<1; + buf += (value.length()) ? value.c_str() : ""; + buf += "</a>> </em></small>"; + } + else if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Dict")) { + if (!tag.isEndTag()) + buf += "<b>"; + else buf += "</b>"; } - pushString(buf, "</a>"); + } - - else if (!strncmp(token, "scripture ", 10)) { - userData["inscriptRef"] = "true"; - pushString(buf, "<i>"); - } - - else if (!strncmp(token, "scripRef p", 10) || !strncmp(token, "scripRef v", 10)) { - userData["inscriptRef"] = "true"; - pushString(buf, "<a href=\""); - for (const char *tok = token + 9; *(tok+1); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - } - - // we're starting a scripRef like "<scripRef>John 3:16</scripRef>" - else if (!strcmp(token, "scripRef")) { - userData["inscriptRef"] = "false"; - // let's stop text from going to output - userData["suspendTextPassThru"] = "true"; + // <note> tag + else if (!strcmp(tag.getName(), "note")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + SWBuf type = tag.getAttribute("type"); + SWBuf footnoteNumber = tag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) { } + 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=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), ch, footnoteNumber.c_str(), ch); + } + u->suspendTextPassThru = true; + } + } + if (tag.isEndTag()) { + u->suspendTextPassThru = false; + } } - - // we've ended a scripRef - else if (!strcmp(token, "/scripRef")) { - if (userData["inscriptRef"] == "true") { // like "<scripRef passage="John 3:16">John 3:16</scripRef>" - userData["inscriptRef"] = "false"; - pushString(buf, "</a>"); + // <scripRef> tag + else if (!strcmp(tag.getName(), "scripRef")) { + if (!tag.isEndTag()) { + if (!tag.isEmpty()) { + u->suspendTextPassThru = true; + } } - - else { // like "<scripRef>John 3:16</scripRef>" - pushString(buf, "<a href=\"passage="); - //char *strbuf = (char *)userData["lastTextNode"].c_str(); - pushString(buf, userData["lastTextNode"].c_str()); - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - pushString(buf, userData["lastTextNode"].c_str()); + if (tag.isEndTag()) { // </scripRef> + if (!u->BiblicalText) { + SWBuf refList = u->startTag.getAttribute("passage"); + if (!refList.length()) + refList = u->lastTextNode; + SWBuf version = tag.getAttribute("version"); + buf += " <a href=\""; + if (version.length()) { + buf += "version="; + buf += version; + buf += " "; + } + buf += "passage="; + buf += refList.c_str(); + buf += "\">"; + buf += u->lastTextNode.c_str(); + buf += "</a> "; + } + else { + SWBuf footnoteNumber = u->startTag.getAttribute("swordFootnote"); + VerseKey *vkey; + // see if we have a VerseKey * or descendant + try { + vkey = SWDYNAMIC_CAST(VerseKey, u->key); + } + catch ( ... ) {} + 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()); + } + } + // let's let text resume to output again - userData["suspendTextPassThru"] = "false"; - pushString(buf, "</a>"); + u->suspendTextPassThru = false; } } - - else if (!strncmp(token, "div class=\"sechead\"", 19)) { - userData["SecHead"] = "true"; - pushString(buf, "<br /><b><i>"); - } - else if (!strncmp(token, "div class=\"title\"", 19)) { - userData["SecHead"] = "true"; - pushString(buf, "<br /><b><i>"); - } - else if (!strncmp(token, "/div", 4)) { - if (userData["SecHead"] == "true") { - pushString(buf, "</i></b><br />"); - userData["SecHead"] = "false"; + else if (tag.getName() && !strcmp(tag.getName(), "div")) { + if (tag.isEndTag() && u->SecHead) { + buf += "</i></b><br />"; + u->SecHead = false; + } + else if (tag.getAttribute("class")) { + if (!stricmp(tag.getAttribute("class"), "sechead")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } + else if (!stricmp(tag.getAttribute("class"), "title")) { + u->SecHead = true; + buf += "<br /><b><i>"; + } } } - - else if (!strncmp(token, "sync type=\"Strongs\" value=\"T", 28)) { - pushString(buf, "<a href=\""); - for (tok = token + 5; *(tok+1); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - *(*buf)++ = '\"'; - *(*buf)++ = '>'; - for (tok = token + 29; *(tok+2); tok++) - if(*tok != '\"') - *(*buf)++ = *tok; - pushString(buf, "</a>"); - } - else if (!strncmp(token, "img ", 4)) { + else if (tag.getName() && (!strcmp(tag.getName(), "img") || !strcmp(tag.getName(), "image"))) { const char *src = strstr(token, "src"); if (!src) // assert we have a src attribute return false; - *(*buf)++ = '<'; + buf += '<'; for (const char *c = token; *c; c++) { if (c == src) { for (;((*c) && (*c != '"')); c++) - *(*buf)++ = *c; + buf += *c; if (!*c) { c--; continue; } - *(*buf)++ = '"'; + buf += '"'; if (*(c+1) == '/') { - pushString(buf, "file:"); - pushString(buf, module->getConfigEntry("AbsoluteDataPath")); - if (*((*buf)-1) == '/') + buf += "file:"; + buf += userData->module->getConfigEntry("AbsoluteDataPath"); + if (buf[buf.length()-2] == '/') c++; // skip '/' } continue; } - *(*buf)++ = *c; + buf += *c; } - *(*buf)++ = '>'; + buf += '>'; } - else if (!strncmp(token, "note", 4)) { - pushString(buf, " <small><font color=\"#800000\">("); - } else { - *(*buf)++ = '<'; - for (const char *tok = token; *tok; tok++) - *(*buf)++ = *tok; - *(*buf)++ = '>'; + buf += '<'; + /*for (const char *tok = token; *tok; tok++) + buf += *tok;*/ + buf += token; + buf += '>'; //return false; // we still didn't handle token } } return true; } + +SWORD_NAMESPACE_END |