The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
thmlcgi.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * thmlcgi.cpp - ThMLCGI: ThML to Diatheke/CGI format filter
4  *
5  * $Id: thmlcgi.cpp 3427 2016-07-03 14:30:33Z scribe $
6  *
7  * Copyright 2001-2013 CrossWire Bible Society (http://www.crosswire.org)
8  * CrossWire Bible Society
9  * P. O. Box 2528
10  * Tempe, AZ 85280-2528
11  *
12  * This program is free software; you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by the
14  * Free Software Foundation version 2.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details.
20  *
21  */
22 
23 #include <stdlib.h>
24 #include <string.h>
25 #include <map>
26 #include <utilstr.h>
27 #include "thmlcgi.h"
28 
30 
31 typedef std::map<SWBuf, SWBuf> DualStringMap;
32 
33 namespace {
34  class MyUserData : public BasicFilterUserData {
35  public:
36  MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {}
37  DualStringMap properties;
38  };
39 }
40 
42  return new MyUserData(module, key);
43 }
44 
46  setTokenStart("<");
47  setTokenEnd(">");
48 
50 
51  addTokenSubstitute("note", " <font color=\"#008000\"><small>(");
52  addTokenSubstitute("/note", ")</small></font> ");
53 }
54 
55 
56 bool ThMLCGI::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *baseUserData) {
57  MyUserData *userData = (MyUserData *) baseUserData;
58  unsigned long i;
59  if (!substituteToken(buf, token)) {
60  // manually process if it wasn't a simple substitution
61  if (!strncmp(token, "sync ", 5)) {
62  buf += "<a href=\"!DIATHEKE_URL!";
63  char* pbuf;
64  char typ[32]; typ[0] = 0;
65  char val[32]; val[0] = 0;
66  char cls[32]; cls[0] = 0;
67  for (unsigned int j = 5; j < strlen(token); j++) {
68  if (!strncmp(token+j, "type=\"", 6)) {
69  pbuf = typ;
70  j += 6;
71  for (;token[j] != '\"'; j++)
72  *(pbuf)++ = token[j];
73  *(pbuf) = 0;
74  }
75  else if (!strncmp(token+j, "value=\"", 7)) {
76  pbuf = val;
77  j += 7;
78  for (;token[j] != '\"'; j++)
79  *(pbuf)++ = token[j];
80  *(pbuf) = 0;
81  }
82  else if (!strncmp(token+j, "class=\"", 7)) {
83  pbuf = cls;
84  j += 7;
85  for (;token[j] != '\"'; j++)
86  *(pbuf)++ = token[j];
87  *(pbuf) = 0;
88  }
89  }
90  if (*cls && *val) {
91  buf.appendFormatted("%s=on&verse=%s", cls, val);
92  }
93  else if (*typ && *val) {
94  if (!strnicmp(typ, "Strongs", 7)) {
95  if (*val == 'G') {
96  buf.appendFormatted("StrongsGreek=on&verse=%s", val + 1);
97  }
98  else if (*val == 'H') {
99  buf.appendFormatted("StrongsHebrew=on&verse=%s", val + 1);
100  }
101  }
102 
103  else if (!strnicmp(typ, "Morph", 5)) {
104  if (*val == 'G') {
105  buf.appendFormatted("StrongsGreek=on&verse=%s", val + 1);
106  }
107  else if (*val == 'H') {
108  buf.appendFormatted("StrongsHebrew=on&verse=%s", val + 1);
109  }
110  else {
111  buf.appendFormatted("Packard=on&verse=%s", val);
112  }
113  }
114  else {
115  buf.appendFormatted("%s=on&verse=%s", typ, val);
116  }
117  }
118  buf += "\">";
119 
120  if (*val) {
121  buf += val;
122  }
123  buf += "</a>";
124  }
125 
126  else if (!strncmp(token, "scripRef p", 10) || !strncmp(token, "scripRef v", 10)) {
127  userData->properties["inscriptRef"] = "true";
128  buf += "<a href=\"!DIATHEKE_URL!";
129  for (i = 9; i < strlen(token); i++) {
130  if (!strncmp(token+i, "version=\"", 9)) {
131  i += 9;
132  for (;token[i] != '\"'; i++)
133  buf += token[i];
134  buf += "=on&";
135  }
136  if (!strncmp(token+i, "passage=\"", 9)) {
137  i += 9;
138  buf += "verse=";
139  for (;token[i] != '\"'; i++) {
140  if (token[i] == ' ') buf += '+';
141  else buf += token[i];
142  }
143  buf += '&';
144  }
145  }
146  buf += "\">";
147  }
148 
149  // we're starting a scripRef like "<scripRef>John 3:16</scripRef>"
150  else if (!strcmp(token, "scripRef")) {
151  userData->properties["inscriptRef"] = "false";
152  // let's stop text from going to output
153  userData->properties["suspendTextPassThru"] = "true";
154  }
155 
156  // we've ended a scripRef
157  else if (!strcmp(token, "/scripRef")) {
158  if (userData->properties["inscriptRef"] == "true") { // like "<scripRef passage="John 3:16">John 3:16</scripRef>"
159  userData->properties["inscriptRef"] = "false";
160  buf += "</a>";
161  }
162 
163  else { // like "<scripRef>John 3:16</scripRef>"
164  buf += "<a href=\"!DIATHEKE_URL!verse=";
165 
166  char* vref = (char*)userData->properties["lastTextNode"].c_str();
167  while (*vref) {
168  if (*vref == ' ') buf += '+';
169  else buf += *vref;
170  vref++;
171  }
172  buf += "\">";
173  buf += userData->properties["lastTextNode"].c_str();
174  // let's let text resume to output again
175  userData->properties["suspendTextPassThru"] = "false";
176  buf += "</a>";
177  }
178  }
179 
180  else if (!strncmp(token, "div class=\"sechead\"", 19)) {
181  userData->properties["SecHead"] = "true";
182  buf += "<br /><b><i>";
183  }
184  else if (!strncmp(token, "div class=\"title\"", 19)) {
185  userData->properties["SecHead"] = "true";
186  buf += "<br /><b><i>";
187  }
188  else if (!strncmp(token, "/div", 4)) {
189  if (userData->properties["SecHead"] == "true") {
190  buf += "</i></b><br />";
191  userData->properties["SecHead"] = "false";
192  }
193  }
194 
195  else if(!strncmp(token, "note", 4)) {
196  buf += " <small><font color=\"#008000\">{";
197  }
198 
199  else {
200  buf += '<';
201  for (i = 0; i < strlen(token); i++) {
202  buf += token[i];
203  }
204  buf += '>';
205  //return false; // we still didn't handle token
206  }
207  }
208  return true;
209 }
210 
211 
212 
213 
214 
215 
#define SWORD_NAMESPACE_START
Definition: defs.h:39
SWBuf & appendFormatted(const char *format,...)
Definition: swbuf.cpp:81
void setTokenEnd(const char *tokenEnd)
Definition: swbuf.h:47
SWText * module
Definition: osis2mod.cpp:105
void setTokenCaseSensitive(bool val)
bool substituteToken(SWBuf &buf, const char *token)
void setTokenStart(const char *tokenStart)
virtual bool handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData)
Definition: thmlcgi.cpp:56
BasicFilterUserData(const SWModule *module, const SWKey *key)
SWORD_NAMESPACE_START typedef std::map< SWBuf, SWBuf > DualStringMap
void addTokenSubstitute(const char *findString, const char *replaceString)
int strnicmp(const char *s1, const char *s2, int len)
Definition: utilstr.cpp:180
ThMLCGI()
Definition: thmlcgi.cpp:45
#define SWORD_NAMESPACE_END
Definition: defs.h:40
Definition: swkey.h:77
virtual BasicFilterUserData * createUserData(const SWModule *module, const SWKey *key)
Definition: thmlcgi.cpp:41