summaryrefslogtreecommitdiff
path: root/src/modules/filters/thmlrtf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/filters/thmlrtf.cpp')
-rw-r--r--src/modules/filters/thmlrtf.cpp243
1 files changed, 169 insertions, 74 deletions
diff --git a/src/modules/filters/thmlrtf.cpp b/src/modules/filters/thmlrtf.cpp
index 76289ec..4487921 100644
--- a/src/modules/filters/thmlrtf.cpp
+++ b/src/modules/filters/thmlrtf.cpp
@@ -15,12 +15,14 @@
***************************************************************************/
#include <stdlib.h>
-#include <string.h>
#include <thmlrtf.h>
+#include <swmodule.h>
+#include <utilxml.h>
+#include <versekey.h>
+SWORD_NAMESPACE_START
-ThMLRTF::ThMLRTF()
-{
+ThMLRTF::ThMLRTF() {
setTokenStart("<");
setTokenEnd(">");
@@ -30,6 +32,7 @@ ThMLRTF::ThMLRTF()
setEscapeStringCaseSensitive(true);
addEscapeStringSubstitute("nbsp", " ");
+ addEscapeStringSubstitute("apos", "'");
addEscapeStringSubstitute("quot", "\"");
addEscapeStringSubstitute("amp", "&");
addEscapeStringSubstitute("lt", "<");
@@ -128,87 +131,178 @@ ThMLRTF::ThMLRTF()
setTokenCaseSensitive(true);
- addTokenSubstitute("/scripRef", "|}");
- addTokenSubstitute("/note", ") }");
-
- addTokenSubstitute("br", "\\line ");
- addTokenSubstitute("br /", "\\line ");
- addTokenSubstitute("i", "{\\i1 ");
- addTokenSubstitute("/i", "}");
- addTokenSubstitute("b", "{\\b1 ");
- addTokenSubstitute("/b", "}");
- addTokenSubstitute("p", "\\par ");
-
- //we need uppercase forms for the moment to support a few early ThML modules that aren't XHTML compliant
- addTokenSubstitute("BR", "\\line ");
- addTokenSubstitute("I", "{\\i1 ");
- addTokenSubstitute("/I", "}");
- addTokenSubstitute("B", "{\\b1 ");
- addTokenSubstitute("/B", "}");
- addTokenSubstitute("P", "\\par ");
+
+ addTokenSubstitute("br", "\\line ");
+ addTokenSubstitute("br /", "\\line ");
+ addTokenSubstitute("i", "{\\i1 ");
+ addTokenSubstitute("/i", "}");
+ addTokenSubstitute("b", "{\\b1 ");
+ addTokenSubstitute("/b", "}");
+ addTokenSubstitute("p", "\\par ");
+
+ //we need uppercase forms for the moment to support a few early ThML modules that aren't XHTML compliant
+ addTokenSubstitute("BR", "\\line ");
+ addTokenSubstitute("I", "{\\i1 ");
+ addTokenSubstitute("/I", "}");
+ addTokenSubstitute("B", "{\\b1 ");
+ addTokenSubstitute("/B", "}");
+ addTokenSubstitute("P", "\\par ");
+ addTokenSubstitute("scripture", "{\\i1 ");
+ addTokenSubstitute("/scripture", "}");
}
-bool ThMLRTF::handleToken(char **buf, const char *token, DualStringMap &userData) {
- if (!substituteToken(buf, token)) {
- // manually process if it wasn't a simple substitution
- if (!strncmp(token, "sync type=\"Strongs\" value=\"", 27)) {
-/* if (token[27] == 'H' || token[27] == 'G' || token[27] == 'A') {
- pushString(buf, " {\\fs15 <");
- for (unsigned int i = 28; token[i] != '\"'; i++)
- *(*buf)++ = token[i];
- pushString(buf, ">}");
- }
- else if (token[27] == 'T') {
- pushString(buf, " {\\fs15 (");
- for (unsigned int i = 28; token[i] != '\"'; i++)
- *(*buf)++ = token[i];
- pushString(buf, ")}");
+
+char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
+ SWBasicFilter::processText(text, key, module); //handle tokens as usual
+ const char *from;
+ SWBuf orig = text;
+ from = orig.c_str();
+ for (text = ""; *from; from++) { //loop to remove extra spaces
+ if ((strchr(" \t\n\r", *from))) {
+ while (*(from+1) && (strchr(" \t\n\r", *(from+1)))) {
+ from++;
}
+ text += " ";
+ }
+ else {
+ text += *from;
+ }
+ }
+ text += (char)0;
+ return 0;
+}
+
+
+ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
+ if (module) {
+ version = module->Name();
+ BiblicalText = (!strcmp(module->Type(), "Biblical Texts"));
+ }
+}
+
+
+bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
+ const char *tok;
+ 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")) { //&gt;
+ buf.appendFormatted(" {\\cf4 \\sub (%s)}", value.c_str());
+ }
+ else if( tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Strongs")) {
+ if (value[0] == 'H' || value[0] == 'G' || value[0] == 'A') {
+ value<<1;
+ buf.appendFormatted(" {\\cf3 \\sub <%s>}", value.c_str());
+ }
+ else if (value[0] == 'T') {
+ value<<1;
+ buf.appendFormatted(" {\\cf4 \\sub (%s)}", value.c_str());
+ }
+ }
+ else if (tag.getAttribute("type") && !strcmp(tag.getAttribute("type"), "Dict")) {
+ if (!tag.isEndTag())
+ buf += "{\\b ";
+ else buf += "}";
+ }
}
- else if (!strncmp(token, "sync type=\"morph\" ", 18)) {
- pushString(buf, " {\\fs15 (");
- for (const char *tok = token + 5; *tok; tok++) {
- if (!strncmp(tok, "value=\"", 7)) {
- tok += 7;
- for (;*tok != '\"'; tok++)
- *(*buf)++ = *tok;
- break;
+ // <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("{\\super <a href=\"\">*%c%i.%s</a>} ", ch, vkey->Verse(), footnoteNumber.c_str());
+ }
+ u->suspendTextPassThru = true;
}
}
+ if (tag.isEndTag()) {
+ u->suspendTextPassThru = false;
+ }
+ }
+
- pushString(buf, ")}");
-*/ }
- else if (!strncmp(token, "sync type=\"lemma\" value=\"", 25)) {
- pushString(buf, "{\\fs15 (");
- for (unsigned int i = 25; token[i] != '\"'; i++)
- *(*buf)++ = token[i];
- pushString(buf, ")}");
+ else if (!strcmp(tag.getName(), "scripRef")) {
+ if (!tag.isEndTag()) {
+ if (!tag.isEmpty()) {
+ u->suspendTextPassThru = true;
+ }
+ }
+ 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=\"\">";
+ buf += refList.c_str();
+// 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("{\\super <a href=\"\">*x%i.%s</a>} ", vkey->Verse(), footnoteNumber.c_str());
+ }
+ }
+
+ // let's let text resume to output again
+ u->suspendTextPassThru = false;
+ }
}
- else if (!strncmp(token, "scripRef", 8)) {
- pushString(buf, "{\\cf2 #");
+
+ else if (tag.getName() && !strcmp(tag.getName(), "div")) {
+ if (tag.isEndTag() && u->SecHead) {
+ buf += "\\par}";
+ u->SecHead = false;
+ }
+ else if (tag.getAttribute("class")) {
+ if (!stricmp(tag.getAttribute("class"), "sechead")) {
+ u->SecHead = true;
+ buf += "{\\par\\i1\\b1 ";
+ }
+ else if (!stricmp(tag.getAttribute("class"), "title")) {
+ u->SecHead = true;
+ buf += "{\\par\\i1\\b1 ";
+ }
+ }
}
- else if (!strncmp(token, "div", 3)) {
- *(*buf)++ = '{';
- if (!strncmp(token, "div class=\"title\"", 17)) {
- pushString(buf, "\\par\\i1\\b1 ");
- userData["sechead"] = "true";
- }
- else if (!strncmp(token, "div class=\"sechead\"", 19)) {
- pushString(buf, "\\par\\i1\\b1 ");
- userData["sechead"] = "true";
- }
- }
- else if (!strncmp(token, "/div", 4)) {
- *(*buf)++ = '}';
- if (userData["sechead"] == "true") {
- pushString(buf, "\\par ");
- userData["sechead"] == "false";
- }
- }
- else if (!strncmp(token, "note", 4)) {
- pushString(buf, " {\\i1\\fs15 (");
- }
+ else if (tag.getName() && (!strcmp(tag.getName(), "img") || !strcmp(tag.getName(), "image"))) {
+ const char *src = tag.getAttribute("src");
+ if (!src) // assert we have a src attribute
+ return false;
+ char* filepath = new char[strlen(u->module->getConfigEntry("AbsoluteDataPath")) + strlen(token)];
+ *filepath = 0;
+ strcpy(filepath, userData->module->getConfigEntry("AbsoluteDataPath"));
+ strcat(filepath, src);
+
+// we do this because BibleCS looks for this EXACT format for an image tag
+ buf+="<img src=\"";
+ buf+=filepath;
+ buf+="\" />";
+ delete [] filepath;
+ }
else {
return false; // we still didn't handle token
}
@@ -217,3 +311,4 @@ bool ThMLRTF::handleToken(char **buf, const char *token, DualStringMap &userData
}
+SWORD_NAMESPACE_END