1 /******************************************************************************
2 *
3 * gbfrtf.cpp - SWFilter descendant to convert all GBF tags to RTF tags
4 *
5 * $Id: gbfrtf.cpp 3427 2016-07-03 14:30:33Z scribe $
6 *
7 * Copyright 1997-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 <gbfrtf.h>
24 #include <utilstr.h>
25 #include <ctype.h>
26 #include <swbuf.h>
27
28 SWORD_NAMESPACE_START
29
GBFRTF()30 GBFRTF::GBFRTF() {
31 }
32
33
processText(SWBuf & text,const SWKey * key,const SWModule * module)34 char GBFRTF::processText(SWBuf &text, const SWKey *key, const SWModule *module)
35 {
36 char token[2048];
37 char val[128];
38 char *valto;
39 char *num;
40 int tokpos = 0;
41 bool intoken = false;
42 const char *tok;
43 SWBuf strongnum;
44 SWBuf strongtense;
45 bool hideText = false;
46 int wordCount = 0;
47
48 const char *from;
49 SWBuf orig = text;
50 from = orig.c_str();
51 for (text = ""; *from; from++) {
52 if (*from == '<') {
53 wordCount = 0;
54 intoken = true;
55 tokpos = 0;
56 token[0] = 0;
57 token[1] = 0;
58 token[2] = 0;
59 continue;
60 }
61 if (*from == '>') {
62 intoken = false;
63 // process desired tokens
64 // deal with OSIS note tags. Just hide till OSISRTF
65 if (!strncmp(token, "note ", 5)) {
66 hideText = true;
67 }
68 if (!strncmp(token, "/note", 5)) {
69 hideText = false;
70 }
71
72 switch (*token) {
73 case 'w': // OSIS Word (temporary until OSISRTF is done)
74 strongnum = "";
75 strongtense = "";
76 valto = val;
77 num = strstr(token, "lemma=\"x-Strongs:");
78 if (num) {
79 for (num+=17; ((*num) && (*num != '\"')); num++)
80 *valto++ = *num;
81 *valto = 0;
82 if (atoi((!isdigit(*val))?val+1:val) < 5627) {
83 // normal strongs number
84 strongnum += "{\\cf3 \\sub <";
85 for (tok = (!isdigit(*val))?val+1:val; *tok; tok++)
86 strongnum += *tok;
87 strongnum += ">}";
88 }
89 /* forget these for now
90 else {
91 // verb morph
92 sprintf(wordstr, "%03d", word-1);
93 module->getEntryAttributes()["Word"][wordstr]["Morph"] = val;
94 }
95 */
96 }
97 else {
98 num = strstr(token, "lemma=\"strong:");
99 if (num) {
100 for (num+=14; ((*num) && (*num != '\"')); num++)
101 *valto++ = *num;
102 *valto = 0;
103 if (atoi((!isdigit(*val))?val+1:val) < 5627) {
104 // normal strongs number
105 strongnum += "{\\cf3 \\sub <";
106 for (tok = (!isdigit(*val))?val+1:val; *tok; tok++)
107 strongnum += *tok;
108 strongnum += ">}";
109 }
110 /* forget these for now
111 else {
112 // verb morph
113 sprintf(wordstr, "%03d", word-1);
114 module->getEntryAttributes()["Word"][wordstr]["Morph"] = val;
115 }
116 */
117 }
118 }
119 valto = val;
120 num = strstr(token, "morph=\"x-Robinson:");
121 if (num) {
122 for (num+=18; ((*num) && (*num != '\"')); num++)
123 *valto++ = *num;
124 *valto = 0;
125 // normal robinsons tense
126 strongtense += "{\\cf4 \\sub (";
127 for (tok = val; *tok; tok++)
128 strongtense += *tok;
129 strongtense += ")}";
130 }
131 continue;
132
133 case '/':
134 if (token[1] == 'w') {
135 if ((wordCount > 0) || (strongnum != "{\\cf3 \\sub <3588>}")) {
136 //for (i = 0; i < strongnum.length(); i++)
137 text += strongnum;
138 //for (i = 0; i < strongtense.length(); i++)
139 text += strongtense;
140 }
141 }
142 continue;
143
144 case 'W': // Strongs
145 switch(token[1]) {
146 case 'G': // Greek
147 case 'H': // Hebrew
148 text += "{\\cf3 \\sub <";
149 for (tok = token + 2; *tok; tok++)
150 text += *tok;
151 text += ">}";
152 continue;
153
154 case 'T': // Tense
155 text += "{\\cf4 \\sub (";
156 bool separate = false;
157 for (tok = token + 2; *tok; tok++) {
158 if (separate) {
159 text += "; ";
160 separate = false;
161 }
162 switch (*tok) {
163 case 'G':
164 case 'H':
165 for (tok++; *tok; tok++) {
166 if (isdigit(*tok)) {
167 text += *tok;
168 separate = true;
169 }
170 else {
171 tok--;
172 break;
173 }
174 }
175 break;
176 default:
177 for (; *tok; tok++) {
178 text += *tok;
179 }
180 }
181 }
182 text += ")}";
183 continue;
184 }
185 break;
186 case 'R':
187 switch(token[1]) {
188 case 'X':
189 text += "<a href=\"\">";
190 continue;
191 case 'x':
192 text += "</a>";
193 continue;
194 case 'F': // footnote begin
195 text += "{\\i1 \\sub [ ";
196 continue;
197 case 'f': // footnote end
198 text += " ] }";
199 continue;
200 }
201 break;
202 case 'F': // font tags
203 switch(token[1]) {
204 case 'I': // italic start
205 text += "\\i1 ";
206 continue;
207 case 'i': // italic end
208 text += "\\i0 ";
209 continue;
210 case 'B': // bold start
211 text += "\\b1 ";
212 continue;
213 case 'b': // bold end
214 text += "\\b0 ";
215 continue;
216 case 'N':
217 text += '{';
218 if (!strnicmp(token+2, "Symbol", 6))
219 text += "\\f7 ";
220 if (!strnicmp(token+2, "Courier", 7))
221 text += "\\f8 ";
222 continue;
223 case 'n':
224 text += '}';
225 continue;
226 case 'S':
227 text += "{\\super ";
228 continue;
229 case 's':
230 text += '}';
231 continue;
232 case 'R':
233 text += "{\\cf6 ";
234 continue;
235 case 'r':
236 text += '}';
237 continue;
238 case 'O':
239 case 'C':
240 text += "\\scaps1 ";
241 continue;
242 case 'o':
243 case 'c':
244 text += "\\scaps0 ";
245 continue;
246 case 'V':
247 text += "{\\sub ";
248 continue;
249 case 'v':
250 text += '}';
251 continue;
252 case 'U':
253 text += "\\ul1 ";
254 continue;
255 case 'u':
256 text += "\\ul0 ";
257 continue;
258 }
259 break;
260 case 'C': // special character tags
261 switch(token[1]) {
262 case 'A': // ASCII value
263 text += (char)atoi(&token[2]);
264 continue;
265 case 'G':
266 text += '>';
267 continue;
268 case 'L': // line break
269 text += "\\line ";
270 continue;
271 case 'M': // new paragraph
272 text += "\\par ";
273 continue;
274 case 'T':
275 text += '<';
276 }
277 break;
278 case 'T': // title formatting
279 switch(token[1])
280 {
281 case 'T': // Book title begin
282 text += "{\\large ";
283 continue;
284 case 't':
285 text += '}';
286 continue;
287 case 'S':
288 text += "\\par {\\i1\\b1 ";
289 continue;
290 case 's':
291 text += "}\\par ";
292 continue;
293 }
294 break;
295 case 'J': // Strongs
296 switch(token[1]) {
297 case 'L':
298 text += "\\ql ";
299 case 'C':
300 text += "\\qc ";
301 case 'R':
302 text += "\\qr ";
303 case 'F':
304 text += "\\qj ";
305 }
306 }
307 continue;
308 }
309 if (intoken) {
310 if (tokpos < 2045) {
311 token[tokpos++] = *from;
312 // TODO: why is this + 2 ?
313 token[tokpos+2] = 0;
314 }
315 }
316 else {
317 if (!hideText) {
318 wordCount++;
319 text += *from;
320 }
321 }
322 }
323 return 0;
324 }
325
326 SWORD_NAMESPACE_END
327
328