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