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