00001 /***************************************************************************
00002 thmlhtmlhref.cpp - ThML to HTML filter with hrefs
00003 -------------------
00004 begin : 2001-09-03
00005 copyright : 2001 by CrossWire Bible Society
00006 ***************************************************************************/
00007
00008 /***************************************************************************
00009 * *
00010 * This program is free software; you can redistribute it and/or modify *
00011 * it under the terms of the GNU General Public License as published by *
00012 * the Free Software Foundation; either version 2 of the License, or *
00013 * (at your option) any later version. *
00014 * *
00015 ***************************************************************************/
00016
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <thmlhtmlhref.h>
00020 #include <swmodule.h>
00021
00022
00023 ThMLHTMLHREF::ThMLHTMLHREF() {
00024 setTokenStart("<");
00025 setTokenEnd(">");
00026 /*
00027 setEscapeStart("&");
00028 setEscapeEnd(";");
00029
00030 setEscapeStringCaseSensitive(true);
00031
00032 addEscapeStringSubstitute("nbsp", " ");
00033 addEscapeStringSubstitute("quot", "\"");
00034 addEscapeStringSubstitute("amp", "&");
00035 addEscapeStringSubstitute("lt", "<");
00036 addEscapeStringSubstitute("gt", ">");
00037 addEscapeStringSubstitute("brvbar", "|");
00038 addEscapeStringSubstitute("sect", "§");
00039 addEscapeStringSubstitute("copy", "©");
00040 addEscapeStringSubstitute("laquo", "«");
00041 addEscapeStringSubstitute("reg", "®");
00042 addEscapeStringSubstitute("acute", "´");
00043 addEscapeStringSubstitute("para", "¶");
00044 addEscapeStringSubstitute("raquo", "»");
00045
00046 addEscapeStringSubstitute("Aacute", "Á");
00047 addEscapeStringSubstitute("Agrave", "À");
00048 addEscapeStringSubstitute("Acirc", "Â");
00049 addEscapeStringSubstitute("Auml", "Ä");
00050 addEscapeStringSubstitute("Atilde", "Ã");
00051 addEscapeStringSubstitute("Aring", "Å");
00052 addEscapeStringSubstitute("aacute", "á");
00053 addEscapeStringSubstitute("agrave", "à");
00054 addEscapeStringSubstitute("acirc", "â");
00055 addEscapeStringSubstitute("auml", "ä");
00056 addEscapeStringSubstitute("atilde", "ã");
00057 addEscapeStringSubstitute("aring", "å");
00058 addEscapeStringSubstitute("Eacute", "É");
00059 addEscapeStringSubstitute("Egrave", "È");
00060 addEscapeStringSubstitute("Ecirc", "Ê");
00061 addEscapeStringSubstitute("Euml", "Ë");
00062 addEscapeStringSubstitute("eacute", "é");
00063 addEscapeStringSubstitute("egrave", "è");
00064 addEscapeStringSubstitute("ecirc", "ê");
00065 addEscapeStringSubstitute("euml", "ë");
00066 addEscapeStringSubstitute("Iacute", "Í");
00067 addEscapeStringSubstitute("Igrave", "Ì");
00068 addEscapeStringSubstitute("Icirc", "Î");
00069 addEscapeStringSubstitute("Iuml", "Ï");
00070 addEscapeStringSubstitute("iacute", "í");
00071 addEscapeStringSubstitute("igrave", "ì");
00072 addEscapeStringSubstitute("icirc", "î");
00073 addEscapeStringSubstitute("iuml", "ï");
00074 addEscapeStringSubstitute("Oacute", "Ó");
00075 addEscapeStringSubstitute("Ograve", "Ò");
00076 addEscapeStringSubstitute("Ocirc", "Ô");
00077 addEscapeStringSubstitute("Ouml", "Ö");
00078 addEscapeStringSubstitute("Otilde", "Õ");
00079 addEscapeStringSubstitute("oacute", "ó");
00080 addEscapeStringSubstitute("ograve", "ò");
00081 addEscapeStringSubstitute("ocirc", "ô");
00082 addEscapeStringSubstitute("ouml", "ö");
00083 addEscapeStringSubstitute("otilde", "õ");
00084 addEscapeStringSubstitute("Uacute", "Ú");
00085 addEscapeStringSubstitute("Ugrave", "Ù");
00086 addEscapeStringSubstitute("Ucirc", "Û");
00087 addEscapeStringSubstitute("Uuml", "Ü");
00088 addEscapeStringSubstitute("uacute", "ú");
00089 addEscapeStringSubstitute("ugrave", "ù");
00090 addEscapeStringSubstitute("ucirc", "û");
00091 addEscapeStringSubstitute("uuml", "ü");
00092 addEscapeStringSubstitute("Yacute", "Ý");
00093 addEscapeStringSubstitute("yacute", "ý");
00094 addEscapeStringSubstitute("yuml", "ÿ");
00095
00096 addEscapeStringSubstitute("deg", "°");
00097 addEscapeStringSubstitute("plusmn", "±");
00098 addEscapeStringSubstitute("sup2", "²");
00099 addEscapeStringSubstitute("sup3", "³");
00100 addEscapeStringSubstitute("sup1", "¹");
00101 addEscapeStringSubstitute("nbsp", "º");
00102 addEscapeStringSubstitute("pound", "£");
00103 addEscapeStringSubstitute("cent", "¢");
00104 addEscapeStringSubstitute("frac14", "¼");
00105 addEscapeStringSubstitute("frac12", "½");
00106 addEscapeStringSubstitute("frac34", "¾");
00107 addEscapeStringSubstitute("iquest", "¿");
00108 addEscapeStringSubstitute("iexcl", "¡");
00109 addEscapeStringSubstitute("ETH", "Ð");
00110 addEscapeStringSubstitute("eth", "ð");
00111 addEscapeStringSubstitute("THORN", "Þ");
00112 addEscapeStringSubstitute("thorn", "þ");
00113 addEscapeStringSubstitute("AElig", "Æ");
00114 addEscapeStringSubstitute("aelig", "æ");
00115 addEscapeStringSubstitute("Oslash", "Ø");
00116 addEscapeStringSubstitute("curren", "¤");
00117 addEscapeStringSubstitute("Ccedil", "Ç");
00118 addEscapeStringSubstitute("ccedil", "ç");
00119 addEscapeStringSubstitute("szlig", "ß");
00120 addEscapeStringSubstitute("Ntilde", "Ñ");
00121 addEscapeStringSubstitute("ntilde", "ñ");
00122 addEscapeStringSubstitute("yen", "¥");
00123 addEscapeStringSubstitute("not", "¬");
00124 addEscapeStringSubstitute("ordf", "ª");
00125 addEscapeStringSubstitute("uml", "¨");
00126 addEscapeStringSubstitute("shy", "");
00127 addEscapeStringSubstitute("macr", "¯");
00128 */
00129 setTokenCaseSensitive(true);
00130
00131 addTokenSubstitute("note", " <font color=\"#800000\"><small>(");
00132 addTokenSubstitute("/note", ")</small></font> ");
00133 addTokenSubstitute("/scripture", "</i> ");
00134 }
00135
00136
00137 bool ThMLHTMLHREF::handleToken(char **buf, const char *token, DualStringMap &userData) {
00138 const char *tok;
00139 if (!substituteToken(buf, token)) {
00140 // manually process if it wasn't a simple substitution
00141 if (!strncmp(token, "sync ", 5)) {
00142 pushString(buf, "<a href=\"");
00143 for (tok = token + 5; *(tok+1); tok++)
00144 if(*tok != '\"')
00145 *(*buf)++ = *tok;
00146 *(*buf)++ = '\"';
00147 *(*buf)++ = '>';
00148
00149 //scan for value and add it to the buffer
00150 for (tok = token + 5; *tok; tok++) {
00151 if (!strncmp(tok, "value=\"", 7)) {
00152 tok += 7;
00153 for (;*tok != '\"'; tok++)
00154 *(*buf)++ = *tok;
00155 break;
00156 }
00157 }
00158 pushString(buf, "</a>");
00159 }
00160
00161 else if (!strncmp(token, "scripture ", 10)) {
00162 userData["inscriptRef"] = "true";
00163 pushString(buf, "<i>");
00164 }
00165
00166 else if (!strncmp(token, "scripRef p", 10) || !strncmp(token, "scripRef v", 10)) {
00167 userData["inscriptRef"] = "true";
00168 pushString(buf, "<a href=\"");
00169 for (const char *tok = token + 9; *(tok+1); tok++)
00170 if(*tok != '\"')
00171 *(*buf)++ = *tok;
00172 *(*buf)++ = '\"';
00173 *(*buf)++ = '>';
00174 }
00175
00176 // we're starting a scripRef like "<scripRef>John 3:16</scripRef>"
00177 else if (!strcmp(token, "scripRef")) {
00178 userData["inscriptRef"] = "false";
00179 // let's stop text from going to output
00180 userData["suspendTextPassThru"] = "true";
00181 }
00182
00183 // we've ended a scripRef
00184 else if (!strcmp(token, "/scripRef")) {
00185 if (userData["inscriptRef"] == "true") { // like "<scripRef passage="John 3:16">John 3:16</scripRef>"
00186 userData["inscriptRef"] = "false";
00187 pushString(buf, "</a>");
00188 }
00189
00190 else { // like "<scripRef>John 3:16</scripRef>"
00191 pushString(buf, "<a href=\"passage=");
00192 //char *strbuf = (char *)userData["lastTextNode"].c_str();
00193 pushString(buf, userData["lastTextNode"].c_str());
00194 *(*buf)++ = '\"';
00195 *(*buf)++ = '>';
00196 pushString(buf, userData["lastTextNode"].c_str());
00197 // let's let text resume to output again
00198 userData["suspendTextPassThru"] = "false";
00199 pushString(buf, "</a>");
00200 }
00201 }
00202
00203 else if (!strncmp(token, "div class=\"sechead\"", 19)) {
00204 userData["SecHead"] = "true";
00205 pushString(buf, "<br /><b><i>");
00206 }
00207 else if (!strncmp(token, "div class=\"title\"", 19)) {
00208 userData["SecHead"] = "true";
00209 pushString(buf, "<br /><b><i>");
00210 }
00211 else if (!strncmp(token, "/div", 4)) {
00212 if (userData["SecHead"] == "true") {
00213 pushString(buf, "</i></b><br />");
00214 userData["SecHead"] = "false";
00215 }
00216 }
00217
00218 else if (!strncmp(token, "sync type=\"Strongs\" value=\"T", 28)) {
00219 pushString(buf, "<a href=\"");
00220 for (tok = token + 5; *(tok+1); tok++)
00221 if(*tok != '\"')
00222 *(*buf)++ = *tok;
00223 *(*buf)++ = '\"';
00224 *(*buf)++ = '>';
00225 for (tok = token + 29; *(tok+2); tok++)
00226 if(*tok != '\"')
00227 *(*buf)++ = *tok;
00228 pushString(buf, "</a>");
00229 }
00230 else if (!strncmp(token, "img ", 4)) {
00231 const char *src = strstr(token, "src");
00232 if (!src) // assert we have a src attribute
00233 return false;
00234
00235 *(*buf)++ = '<';
00236 for (const char *c = token; *c; c++) {
00237 if (c == src) {
00238 for (;((*c) && (*c != '"')); c++)
00239 *(*buf)++ = *c;
00240
00241 if (!*c) { c--; continue; }
00242
00243 *(*buf)++ = '"';
00244 if (*(c+1) == '/') {
00245 pushString(buf, "file:");
00246 pushString(buf, module->getConfigEntry("AbsoluteDataPath"));
00247 if (*((*buf)-1) == '/')
00248 c++; // skip '/'
00249 }
00250 continue;
00251 }
00252 *(*buf)++ = *c;
00253 }
00254 *(*buf)++ = '>';
00255 }
00256 else if (!strncmp(token, "note", 4)) {
00257 pushString(buf, " <small><font color=\"#800000\">(");
00258 }
00259 else {
00260 *(*buf)++ = '<';
00261 for (const char *tok = token; *tok; tok++)
00262 *(*buf)++ = *tok;
00263 *(*buf)++ = '>';
00264 //return false; // we still didn't handle token
00265 }
00266 }
00267 return true;
00268 }
00269
1.2.15