47 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
48 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
49 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
50 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
51 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
52 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
53 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
54 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
56 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
57 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
58 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
59 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
60 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
61 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
62 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
63 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
64 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
65 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
66 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
67 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
68 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
69 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
70 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
71 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
72 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
73 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
74 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
75 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
76 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
77 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
78 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
79 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
80 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
81 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
82 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
83 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
84 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
85 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
86 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
87 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
88 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
89 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
90 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
91 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
92 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", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
93 addEscapeStringSubstitute(
"otilde",
"õ );
addEscapeStringSubstitute("Uacute", "Ú");
addEscapeStringSubstitute("Ugrave", "Ù");
addEscapeStringSubstitute("Ucirc", "Û");
addEscapeStringSubstitute("Uuml", "Ü");
addEscapeStringSubstitute("uacute", "ú");
addEscapeStringSubstitute("ugrave", "ù");
addEscapeStringSubstitute("ucirc", "û");
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
94 addEscapeStringSubstitute(
"Uacute",
"Ú );
addEscapeStringSubstitute("Ugrave", "Ù");
addEscapeStringSubstitute("Ucirc", "Û");
addEscapeStringSubstitute("Uuml", "Ü");
addEscapeStringSubstitute("uacute", "ú");
addEscapeStringSubstitute("ugrave", "ù");
addEscapeStringSubstitute("ucirc", "û");
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
95 addEscapeStringSubstitute(
"Ugrave",
"Ù );
addEscapeStringSubstitute("Ucirc", "Û");
addEscapeStringSubstitute("Uuml", "Ü");
addEscapeStringSubstitute("uacute", "ú");
addEscapeStringSubstitute("ugrave", "ù");
addEscapeStringSubstitute("ucirc", "û");
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
96 addEscapeStringSubstitute(
"Ucirc",
"Û );
addEscapeStringSubstitute("Uuml", "Ü");
addEscapeStringSubstitute("uacute", "ú");
addEscapeStringSubstitute("ugrave", "ù");
addEscapeStringSubstitute("ucirc", "û");
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
97 addEscapeStringSubstitute(
"Uuml",
"Ü );
addEscapeStringSubstitute("uacute", "ú");
addEscapeStringSubstitute("ugrave", "ù");
addEscapeStringSubstitute("ucirc", "û");
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
98 addEscapeStringSubstitute(
"uacute",
"ú );
addEscapeStringSubstitute("ugrave", "ù");
addEscapeStringSubstitute("ucirc", "û");
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
99 addEscapeStringSubstitute(
"ugrave",
"ù );
addEscapeStringSubstitute("ucirc", "û");
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
100 addEscapeStringSubstitute(
"ucirc",
"û );
addEscapeStringSubstitute("uuml", "ü");
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
101 addEscapeStringSubstitute(
"uuml",
"ü );
addEscapeStringSubstitute("Yacute", "Ý");
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
102 addEscapeStringSubstitute(
"Yacute",
"Ý );
addEscapeStringSubstitute("yacute", "ý");
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
103 addEscapeStringSubstitute(
"yacute",
"ý );
addEscapeStringSubstitute("yuml", "ÿ");
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
104 addEscapeStringSubstitute(
"yuml",
"ÿ );
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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
106 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
107 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
108 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
109 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
110 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
111 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
112 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
113 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
114 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
115 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
116 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
117 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
118 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
119 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
120 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
121 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
122 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
123 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
124 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
125 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", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
126 addEscapeStringSubstitute(
"curren",
"¤ );
addEscapeStringSubstitute("Ccedil", "Ç");
addEscapeStringSubstitute("ccedil", "ç");
addEscapeStringSubstitute("szlig", "ß");
addEscapeStringSubstitute("Ntilde", "Ñ");
addEscapeStringSubstitute("ntilde", "ñ");
addEscapeStringSubstitute("yen", "¥");
addEscapeStringSubstitute("not", "¬");
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
127 addEscapeStringSubstitute(
"Ccedil",
"Ç );
addEscapeStringSubstitute("ccedil", "ç");
addEscapeStringSubstitute("szlig", "ß");
addEscapeStringSubstitute("Ntilde", "Ñ");
addEscapeStringSubstitute("ntilde", "ñ");
addEscapeStringSubstitute("yen", "¥");
addEscapeStringSubstitute("not", "¬");
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
128 addEscapeStringSubstitute(
"ccedil",
"ç );
addEscapeStringSubstitute("szlig", "ß");
addEscapeStringSubstitute("Ntilde", "Ñ");
addEscapeStringSubstitute("ntilde", "ñ");
addEscapeStringSubstitute("yen", "¥");
addEscapeStringSubstitute("not", "¬");
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
129 addEscapeStringSubstitute(
"szlig",
"ß );
addEscapeStringSubstitute("Ntilde", "Ñ");
addEscapeStringSubstitute("ntilde", "ñ");
addEscapeStringSubstitute("yen", "¥");
addEscapeStringSubstitute("not", "¬");
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
130 addEscapeStringSubstitute(
"Ntilde",
"Ñ );
addEscapeStringSubstitute("ntilde", "ñ");
addEscapeStringSubstitute("yen", "¥");
addEscapeStringSubstitute("not", "¬");
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
131 addEscapeStringSubstitute(
"ntilde",
"ñ );
addEscapeStringSubstitute("yen", "¥");
addEscapeStringSubstitute("not", "¬");
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
132 addEscapeStringSubstitute(
"yen",
"¥ );
addEscapeStringSubstitute("not", "¬");
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
133 addEscapeStringSubstitute(
"not",
"¬ );
addEscapeStringSubstitute("ordf", "ª");
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
134 addEscapeStringSubstitute(
"ordf",
"ª );
addEscapeStringSubstitute("uml", "¨");
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
135 addEscapeStringSubstitute(
"uml",
"¨ );
addEscapeStringSubstitute("shy", "");
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
136 addEscapeStringSubstitute(
"shy",
" );
addEscapeStringSubstitute("macr", "¯");
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
137 addEscapeStringSubstitute(
"macr",
"¯ );
addEscapeStringSubstitute("micro", "µ");
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
139 addEscapeStringSubstitute(
"micro",
"µ );
addEscapeStringSubstitute("middot", "·");
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
140 addEscapeStringSubstitute(
"middot",
"· );
addEscapeStringSubstitute("cedil", "¸");
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
141 addEscapeStringSubstitute(
"cedil",
"¸ );
addEscapeStringSubstitute("ordm", "º");
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
142 addEscapeStringSubstitute(
"ordm",
"º );
addEscapeStringSubstitute("times", "×");
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
143 addEscapeStringSubstitute(
"times",
"× );
addEscapeStringSubstitute("divide", "÷");
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
144 addEscapeStringSubstitute(
"divide",
"÷ );
addEscapeStringSubstitute("oslash", "ø");
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
145 addEscapeStringSubstitute(
"oslash",
"ø );
setTokenCaseSensitive(true);
addTokenSubstitute("br", "\\line ");
addTokenSubstitute("br /", "\\line ");
addTokenSubstitute("i", "{\\i1 ");
addTokenSubstitute("/i", "}");
addTokenSubstitute("b", "{\\b1 ");
addTokenSubstitute("/b", "}");
addTokenSubstitute("p", "{\\fi200\\par}");
addTokenSubstitute("p /", "\\pard\\par\\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", "}");
addTokenSubstitute("center", "\\qc ");
addTokenSubstitute("/center", "\\pard ");
}
char ThMLRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
// preprocess text buffer to escape RTF control codes
const char *from;
SWBuf orig = text;
from = orig.c_str();
for (text = ""; *from; from++) { //loop to remove extra spaces
switch (*from) {
case '{':
case '}':
case '\\':
text += "\\";
text += *from;
break;
default:
text += *from;
}
}
text += (char)0;
SWBasicFilter::processText(text, key, module); //handle tokens as usual
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; // probably not needed, but don't want to remove without investigating (same as above)
return 0;
}
ThMLRTF::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
isBiblicalText = false;
inSecHead = false;
XMLTag startTag = "";
if (module) {
version = module->getName();
isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
}
}
bool ThMLRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
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.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 += "}";
}
}
// <note> tag
else if (!strcmp(tag.getName(), "note")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
SWBuf type = tag.getAttribute("type");
SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
if (u->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, u->vkey->getVerse(), footnoteNumber.c_str());
}
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) {
u->suspendTextPassThru = false;
}
}
else if (!strcmp(tag.getName(), "scripRef")) {
if (!tag.isEndTag()) {
if (!tag.isEmpty()) {
u->suspendTextPassThru = true;
}
}
if (tag.isEndTag()) { // </scripRef>
if (!u->isBiblicalText) {
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");
if (u->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>} ", u->vkey->getVerse(), footnoteNumber.c_str());
}
}
// let's let text resume to output again
u->suspendTextPassThru = false;
}
}
else if (tag.getName() && !strcmp(tag.getName(), "div")) {
if (tag.isEndTag() && u->inSecHead) {
buf += "\\par}";
u->inSecHead = false;
}
else if (tag.getAttribute("class")) {
if (!stricmp(tag.getAttribute("class"), "sechead")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
else if (!stricmp(tag.getAttribute("class"), "title")) {
u->inSecHead = true;
buf += "{\\par\\i1\\b1 ";
}
}
}
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
}
}
return true;
}
SWORD_NAMESPACE_END
");
179 for (text =
""; *from; from++) {
197 for (text =
""; *from; from++) {
198 if ((strchr(
" \t\n\r", *from))) {
199 while (*(from+1) && (strchr(
" \t\n\r", *(from+1)))) {
236 if (value[0] ==
'H' || value[0] ==
'G' || value[0] ==
'A') {
240 else if (value[0] ==
'T') {
252 else if (!strcmp(tag.
getName(),
"note")) {
271 else if (!strcmp(tag.
getName(),
"scripRef")) {
283 buf +=
"<a href=\"\">";
284 buf += refList.
c_str();
309 buf +=
"{\\par\\i1\\b1 ";
313 buf +=
"{\\par\\i1\\b1 ";
322 char* filepath =
new char[strlen(u->
module->
getConfigEntry(
"AbsoluteDataPath")) + strlen(token)];
325 strcat(filepath, src);
const char * getName() const
MyUserData(const SWModule *module, const SWKey *key)
#define SWORD_NAMESPACE_START
SWBuf & appendFormatted(const char *format,...)
virtual char processText(SWBuf &text, const SWKey *key=0, const SWModule *module=0)
void setTokenEnd(const char *tokenEnd)
unsigned long length() const
virtual char processText(SWBuf &text, const SWKey *key=0, const SWModule *module=0)
const char * getType() const
virtual const char * getConfigEntry(const char *key) const
const char * getName() const
void setTokenCaseSensitive(bool val)
void setEscapeStart(const char *escStart)
bool substituteToken(SWBuf &buf, const char *token)
int stricmp(const char *s1, const char *s2)
void addEscapeStringSubstitute(const char *findString, const char *replaceString)
void setTokenStart(const char *tokenStart)
const char * c_str() const
virtual bool handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData)
virtual int getVerse() const
const char * getAttribute(const char *attribName, int partNum=-1, char partSplit= '|') const
void setEscapeStringCaseSensitive(bool val)
bool isEndTag(const char *eID=0) const
void addTokenSubstitute(const char *findString, const char *replaceString)
void setEscapeEnd(const char *escEnd)
#define SWORD_NAMESPACE_END