The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
osiswordjs.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * osiswordjs.cpp - SWFilter descendant for ???
4  *
5  * $Id: osiswordjs.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 <osiswordjs.h>
26 #include <swmodule.h>
27 #include <ctype.h>
28 #include <utilxml.h>
29 #include <utilstr.h>
30 #include <versekey.h>
31 #include <stdio.h>
32 
33 
35 
36 namespace {
37 
38  static const char oName[] = "Word Javascript";
39  static const char oTip[] = "Toggles Word Javascript data";
40 
41  static const StringList *oValues() {
42  static const SWBuf choices[3] = {"Off", "On", ""};
43  static const StringList oVals(&choices[0], &choices[2]);
44  return &oVals;
45  }
46 }
47 
48 
50 
51  defaultGreekLex = 0;
52  defaultHebLex = 0;
54  defaultHebParse = 0;
55  mgr = 0;
56 }
57 
58 
60 }
61 
62 
63 char OSISWordJS::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
64  if (option) {
65  char token[2112]; // cheese. Fix.
66  int tokpos = 0;
67  bool intoken = false;
68  int wordNum = 1;
69  char wordstr[11];
70  SWBuf modName = (module)?module->getName():"";
71  // add TR to w src in KJV then remove this next line
72  SWBuf wordSrcPrefix = (modName == "KJV")?SWBuf("TR"):modName;
73 
74  const VerseKey *vkey = 0;
75  if (key) {
76  vkey = SWDYNAMIC_CAST(const VerseKey, key);
77  }
78 
79  const SWBuf orig = text;
80  const char * from = orig.c_str();
81 
82  for (text = ""; *from; ++from) {
83  if (*from == '<') {
84  intoken = true;
85  tokpos = 0;
86  token[0] = 0;
87  token[1] = 0;
88  token[2] = 0;
89  continue;
90  }
91  if (*from == '>') { // process tokens
92  intoken = false;
93  if ((*token == 'w') && (token[1] == ' ')) { // Word
94  XMLTag wtag(token);
95  sprintf(wordstr, "%03d", wordNum);
96  SWBuf lemmaClass;
97  SWBuf lemma;
98  SWBuf morph;
99  SWBuf page;
100  SWBuf src;
101  char gh = 0;
102  page = module->getEntryAttributes()["Word"][wordstr]["Page"].c_str();
103  if (page.length()) page = (SWBuf)"p:" + page;
104  int count = atoi(module->getEntryAttributes()["Word"][wordstr]["PartCount"].c_str());
105  for (int i = 0; i < count; i++) {
106 
107  // for now, lemma class can just be equal to last lemma class in multi part word
108  SWBuf tmp = "LemmaClass";
109  if (count > 1) tmp.appendFormatted(".%d", i+1);
110  lemmaClass = module->getEntryAttributes()["Word"][wordstr][tmp];
111 
112  tmp = "Lemma";
113  if (count > 1) tmp.appendFormatted(".%d", i+1);
114  tmp = (module->getEntryAttributes()["Word"][wordstr][tmp].c_str());
115 
116  // if we're strongs,
117  if (lemmaClass == "strong") {
118  gh = tmp[0];
119  tmp << 1;
120  }
121  if (lemma.size()) lemma += "|";
122  lemma += tmp;
123 
124  tmp = "Morph";
125  if (count > 1) tmp.appendFormatted(".%d", i+1);
126  tmp = (module->getEntryAttributes()["Word"][wordstr][tmp].c_str());
127  if (morph.size()) morph += "|";
128  morph += tmp;
129 
130  tmp = "Src";
131  if (count > 1) tmp.appendFormatted(".%d", i+1);
132  tmp = (module->getEntryAttributes()["Word"][wordstr][tmp].c_str());
133  if (!tmp.length()) tmp.appendFormatted("%d", wordNum);
134  tmp.insert(0, wordSrcPrefix);
135  if (src.size()) src += "|";
136  src += tmp;
137  }
138 
139  SWBuf lexName = "";
140  // we can pass the real lex name in, but we have some
141  // aliases in the javascript to optimize bandwidth
142  if ((gh == 'G') && (defaultGreekLex)) {
143  lexName = (!strcmp(defaultGreekLex->getName(), "StrongsGreek"))?"G":defaultGreekLex->getName();
144  }
145  else if ((gh == 'H') && (defaultHebLex)) {
146  lexName = (!strcmp(defaultHebLex->getName(), "StrongsHebrew"))?"H":defaultHebLex->getName();
147  }
148 
149  SWBuf xlit = wtag.getAttribute("xlit");
150 
151  if ((lemmaClass != "strong") && (xlit.startsWith("betacode:"))) {
152  lexName = "betacode";
153 // const char *m = strchr(xlit.c_str(), ':');
154 // strong = ++m;
155  }
156  SWBuf wordID;
157  if (vkey) {
158  // optimize for bandwidth and use only the verse as the unique entry id
159  wordID.appendFormatted("%d", vkey->getVerse());
160  }
161  else {
162  wordID = key->getText();
163  }
164  wordID.appendFormatted("_%s", src.c_str());
165  // clean up our word ID for XHTML
166  for (unsigned int i = 0; i < wordID.size(); i++) {
167  if ((!isdigit(wordID[i])) && (!isalpha(wordID[i]))) {
168  wordID[i] = '_';
169  }
170  }
171  // 'p' = 'fillpop' to save bandwidth
172  text.appendFormatted("<span class=\"clk\" onclick=\"p('%s','%s','%s','%s','%s','%s');\" >", lexName.c_str(), lemma.c_str(), wordID.c_str(), morph.c_str(), page.c_str(), modName.c_str());
173  wordNum++;
174 
175  if (wtag.isEmpty()) {
176  text += "</w></span>";
177  }
178  }
179  if ((*token == '/') && (token[1] == 'w') && option) { // Word
180  text += "</w></span>";
181  continue;
182  }
183 
184  // if not a strongs token, keep token in text
185  text.append('<');
186  text.append(token);
187  text.append('>');
188 
189  continue;
190  }
191  if (intoken) {
192  if (tokpos < 2045) {
193  token[tokpos++] = *from;
194  token[tokpos+2] = 0;
195  }
196  }
197  else {
198  text.append(*from);
199  }
200  }
201  }
202  return 0;
203 }
204 
SWModule * defaultHebParse
Definition: osiswordjs.h:40
const char * getName() const
Definition: swmodule.cpp:204
int page
Definition: imp2vs.cpp:303
#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
SWText * module
Definition: osis2mod.cpp:105
Definition: utilxml.h:38
bool startsWith(const SWBuf &prefix) const
Definition: swbuf.h:486
SWModule * defaultHebLex
Definition: osiswordjs.h:38
bool isEmpty() const
Definition: utilxml.h:60
static const StringList * oValues()
virtual char processText(SWBuf &text, const SWKey *key=0, const SWModule *module=0)
Definition: osiswordjs.cpp:63
SWModule * defaultGreekParse
Definition: osiswordjs.h:39
virtual const char * getText() const
Definition: swkey.cpp:184
void insert(unsigned long pos, const char *str, unsigned long start=0, signed long max=-1)
Definition: swbuf.cpp:99
virtual ~OSISWordJS()
Definition: osiswordjs.cpp:59
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]
const char * getAttribute(const char *attribName, int partNum=-1, char partSplit= '|') const
Definition: utilxml.cpp:230
static const char oTip[]
SWModule * defaultGreekLex
Definition: osiswordjs.h:37
SWMgr * mgr
Definition: osiswordjs.h:41
#define SWORD_NAMESPACE_END
Definition: defs.h:40
Definition: swkey.h:77