The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
thmlwordjs.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * thmlwordjs.cpp - SWFilter descendant to ???
4  *
5  * $Id: thmlwordjs.cpp 3808 2020-10-02 13:23:34Z scribe $
6  *
7  * Copyright 2005-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 <stdio.h>
25 #include <thmlwordjs.h>
26 #include <swmodule.h>
27 #include <ctype.h>
28 #include <utilxml.h>
29 #include <utilstr.h>
30 #include <versekey.h>
31 
32 
34 
35 namespace {
36 
37  static const char oName[] = "Word Javascript";
38  static const char oTip[] = "Toggles Word Javascript data";
39 
40  static const StringList *oValues() {
41  static const SWBuf choices[3] = {"Off", "On", ""};
42  static const StringList oVals(&choices[0], &choices[2]);
43  return &oVals;
44  }
45 }
46 
47 
49 
50  defaultGreekLex = 0;
51  defaultHebLex = 0;
53  defaultHebParse = 0;
54  mgr = 0;
55 }
56 
57 
59 }
60 
61 
62 char ThMLWordJS::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
63  if (option) {
64  char token[2112]; // cheese. Fix.
65  int tokpos = 0;
66  bool intoken = false;
67  int word = 1;
68  char val[128];
69  char *valto;
70  char *ch;
71  char wordstr[11];
72  unsigned int textStart = 0, lastAppendLen = 0, textEnd = 0;
73  SWBuf tmp;
74  bool newText = false;
75  bool needWordOut = false;
76  AttributeValue *wordAttrs = 0;
77  SWBuf modName = (module)?module->getName():"";
78  SWBuf wordSrcPrefix = modName;
79 
80  const SWBuf orig = text;
81  const char * from = orig.c_str();
82  const VerseKey *vkey = 0;
83  if (key) {
84  vkey = SWDYNAMIC_CAST(const VerseKey, key);
85  }
86 
87  for (text = ""; *from; from++) {
88  if (*from == '<') {
89  intoken = true;
90  tokpos = 0;
91  token[0] = 0;
92  token[1] = 0;
93  token[2] = 0;
94  textEnd = (unsigned int)text.length();
95  continue;
96  }
97  if (*from == '>') { // process tokens
98  intoken = false;
99  if (!strnicmp(token, "sync type=\"Strongs\" ", 20)) { // Strongs
100  valto = val;
101  for (unsigned int i = 27; token[i] != '\"' && i < 150; i++)
102  *valto++ = token[i];
103  *valto = 0;
104  if (atoi((!isdigit(*val))?val+1:val) < 5627) {
105  // normal strongs number
106  sprintf(wordstr, "%03d", word++);
107  needWordOut = (word > 2);
108  wordAttrs = &(module->getEntryAttributes()["Word"][wordstr]);
109  (*wordAttrs)["Strongs"] = val;
110  //printf("Adding: [\"Word\"][%s][\"Strongs\"] = %s\n", wordstr, val);
111  tmp = "";
112  tmp.append(text.c_str()+textStart, (int)(textEnd - textStart));
113  (*wordAttrs)["Text"] = tmp;
114  text.append("</span>");
115  SWBuf ts;
116  ts.appendFormatted("%d", textStart);
117  (*wordAttrs)["TextStart"] = ts;
118  //printf("Adding: [\"Word\"][%s][\"Text\"] = %s\n", wordstr, tmp.c_str());
119  newText = true;
120  }
121  else {
122  // verb morph
123  (*wordAttrs)["Morph"] = val;
124  //printf("Adding: [\"Word\"][%s][\"Morph\"] = %s\n", wordstr, val);
125  }
126 
127  }
128  if (!strncmp(token, "sync type=\"morph\"", 17)) {
129  for (ch = token+17; *ch; ch++) {
130  if (!strncmp(ch, "class=\"", 7)) {
131  valto = val;
132  for (unsigned int i = 7; ch[i] != '\"' && i < 127; i++)
133  *valto++ = ch[i];
134  *valto = 0;
135  (*wordAttrs)["MorphClass"] = val;
136  //printf("Adding: [\"Word\"][%s][\"MorphClass\"] = %s\n", wordstr, val);
137  }
138  if (!strncmp(ch, "value=\"", 7)) {
139  valto = val;
140  for (unsigned int i = 7; ch[i] != '\"' && i < 127; i++)
141  *valto++ = ch[i];
142  *valto = 0;
143  (*wordAttrs)["Morph"] = val;
144  //printf("Adding: [\"Word\"][%s][\"Morph\"] = %s\n", wordstr, val);
145  }
146  }
147  newText = true;
148  }
149  // if not a strongs token, keep token in text
150  text += '<';
151  text += token;
152  text += '>';
153  if (needWordOut) {
154  char wstr[11];
155  sprintf(wstr, "%03d", word-2);
156  AttributeValue *wAttrs = &(module->getEntryAttributes()["Word"][wstr]);
157  needWordOut = false;
158  SWBuf strong = (*wAttrs)["Strongs"];
159  SWBuf morph = (*wAttrs)["Morph"];
160  SWBuf morphClass = (*wAttrs)["MorphClass"];
161  SWBuf wordText = (*wAttrs)["Text"];
162  SWBuf textSt = (*wAttrs)["TextStart"];
163  if (strong.size()) {
164  char gh = 0;
165  gh = isdigit(strong[0]) ? 0:strong[0];
166  if (!gh) {
167  if (vkey) {
168  gh = vkey->getTestament() ? 'H' : 'G';
169  }
170  }
171  else strong << 1;
172 
173  SWModule *sLex = 0;
174  SWModule *sMorph = 0;
175  if (gh == 'G') {
176  sLex = defaultGreekLex;
177  sMorph = defaultGreekParse;
178  }
179  if (gh == 'H') {
180  sLex = defaultHebLex;
181  sMorph = defaultHebParse;
182  }
183  SWBuf lexName = "";
184  if (sLex) {
185  // we can pass the real lex name in, but we have some
186  // aliases in the javascript to optimize bandwidth
187  lexName = sLex->getName();
188  if (lexName == "StrongsGreek")
189  lexName = "G";
190  if (lexName == "StrongsHebrew")
191  lexName = "H";
192  }
193  SWBuf wordID;
194  if (vkey) {
195  // optimize for bandwidth and use only the verse as the unique entry id
196  wordID.appendFormatted("%d", vkey->getVerse());
197  }
198  else {
199  wordID = key->getText();
200  }
201  for (unsigned int i = 0; i < wordID.size(); i++) {
202  if ((!isdigit(wordID[i])) && (!isalpha(wordID[i]))) {
203  wordID[i] = '_';
204  }
205  }
206  wordID.appendFormatted("_%s%d", wordSrcPrefix.c_str(), atoi(wstr));
207  if (textSt.size()) {
208  int textStr = atoi(textSt.c_str());
209  textStr += lastAppendLen;
210  SWBuf spanStart = "";
211 
212 
213 
214  if (!sMorph) sMorph = 0; // avoid unused warnings for now
215 /*
216  if (sMorph) {
217  SWBuf popMorph = "<a onclick=\"";
218  popMorph.appendFormatted("p(\'%s\',\'%s\','%s','');\" >%s</a>", sMorph->getName(), morph.c_str(), wordID.c_str(), morph.c_str());
219  morph = popMorph;
220  }
221 */
222 
223  // 'p' = 'fillpop' to save bandwidth
224  const char *m = strchr(morph.c_str(), ':');
225  if (m) m++;
226  else m = morph.c_str();
227  spanStart.appendFormatted("<span class=\"clk\" onclick=\"p('%s','%s','%s','%s','','%s');\" >", lexName.c_str(), strong.c_str(), wordID.c_str(), m, modName.c_str());
228  text.insert(textStr, spanStart);
229  lastAppendLen = (unsigned int)spanStart.length();
230  }
231  }
232 
233  }
234  if (newText) {
235  textStart = (unsigned int)text.length(); newText = false;
236  }
237  continue;
238  }
239  if (intoken) {
240  if (tokpos < 2045) {
241  token[tokpos++] = *from;
242  // TODO: why is this + 2 ?
243  token[tokpos+2] = 0;
244  }
245  }
246  else {
247  text += *from;
248  }
249  }
250 
251  char wstr[11];
252  sprintf(wstr, "%03d", word-1);
253  AttributeValue *wAttrs = &(module->getEntryAttributes()["Word"][wstr]);
254  needWordOut = false;
255  SWBuf strong = (*wAttrs)["Strongs"];
256  SWBuf morph = (*wAttrs)["Morph"];
257  SWBuf morphClass = (*wAttrs)["MorphClass"];
258  SWBuf wordText = (*wAttrs)["Text"];
259  SWBuf textSt = (*wAttrs)["TextStart"];
260  if (strong.size()) {
261  char gh = 0;
262  gh = isdigit(strong[0]) ? 0:strong[0];
263  if (!gh) {
264  if (vkey) {
265  gh = vkey->getTestament() ? 'H' : 'G';
266  }
267  }
268  else strong << 1;
269 
270  SWModule *sLex = 0;
271  if (gh == 'G') {
272  sLex = defaultGreekLex;
273  }
274  if (gh == 'H') {
275  sLex = defaultHebLex;
276  }
277  SWBuf lexName = "";
278  if (sLex) {
279  // we can pass the real lex name in, but we have some
280  // aliases in the javascript to optimize bandwidth
281  lexName = sLex->getName();
282  if (lexName == "StrongsGreek")
283  lexName = "G";
284  if (lexName == "StrongsHebrew")
285  lexName = "H";
286  }
287  SWBuf wordID;
288  if (vkey) {
289  // optimize for bandwidth and use only the verse as the unique entry id
290  wordID.appendFormatted("%d", vkey->getVerse());
291  }
292  else {
293  wordID = key->getText();
294  }
295  for (unsigned int i = 0; i < wordID.size(); i++) {
296  if ((!isdigit(wordID[i])) && (!isalpha(wordID[i]))) {
297  wordID[i] = '_';
298  }
299  }
300  wordID.appendFormatted("_%s%d", wordSrcPrefix.c_str(), atoi(wstr));
301  if (textSt.size()) {
302  int textStr = atoi(textSt.c_str());
303  textStr += lastAppendLen;
304  SWBuf spanStart = "";
305  // 'p' = 'fillpop' to save bandwidth
306  const char *m = strchr(morph.c_str(), ':');
307  if (m) m++;
308  else m = morph.c_str();
309  spanStart.appendFormatted("<span class=\"clk\" onclick=\"p('%s','%s','%s','%s','','%s');\" >", lexName.c_str(), strong.c_str(), wordID.c_str(), m, modName.c_str());
310  text.insert(textStr, spanStart);
311  }
312  }
313  }
314 
315  return 0;
316 }
317 
const char * getName() const
Definition: swmodule.cpp:204
#define SWORD_NAMESPACE_START
Definition: defs.h:39
SWBuf & appendFormatted(const char *format,...)
Definition: swbuf.cpp:81
Definition: swbuf.h:47
unsigned long length() const
Definition: swbuf.h:197
SWModule * defaultHebParse
Definition: thmlwordjs.h:42
SWText * module
Definition: osis2mod.cpp:105
virtual char processText(SWBuf &text, const SWKey *key=0, const SWModule *module=0)
Definition: thmlwordjs.cpp:62
static const StringList * oValues()
virtual const char * getText() const
Definition: swkey.cpp:184
std::map< SWBuf, SWBuf, std::less< SWBuf > > AttributeValue
Definition: swmodule.h:73
void insert(unsigned long pos, const char *str, unsigned long start=0, signed long max=-1)
Definition: swbuf.cpp:99
const char * c_str() const
Definition: swbuf.h:158
std::list< SWBuf > StringList
Definition: swmodule.cpp:91
SWBuf & append(const char *str, long max=-1)
Definition: swbuf.h:274
static const char oName[]
virtual int getVerse() const
Definition: versekey.cpp:1534
#define SWDYNAMIC_CAST(className, object)
Definition: defs.h:47
unsigned long size() const
Definition: swbuf.h:185
virtual AttributeTypeList & getEntryAttributes() const
Definition: swmodule.h:817
static const char * choices[4]
static const char oTip[]
SWModule * defaultGreekLex
Definition: thmlwordjs.h:39
int strnicmp(const char *s1, const char *s2, int len)
Definition: utilstr.cpp:180
SWModule * defaultHebLex
Definition: thmlwordjs.h:40
#define SWORD_NAMESPACE_END
Definition: defs.h:40
virtual ~ThMLWordJS()
Definition: thmlwordjs.cpp:58
SWModule * defaultGreekParse
Definition: thmlwordjs.h:41
Definition: swkey.h:77
virtual char getTestament() const
Definition: versekey.cpp:1498
SWMgr * mgr
Definition: thmlwordjs.h:43