The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
teirtf.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * teirtf.cpp - TEI to RTF filter
4  *
5  * $Id: teirtf.cpp 3695 2020-02-03 06:23:14Z refdoc $
6  *
7  * Copyright 2006-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 <ctype.h>
25 #include <teirtf.h>
26 #include <utilxml.h>
27 #include <swmodule.h>
28 #include <versekey.h>
29 
31 
32 
34  isBiblicalText = false;
35  inOsisRef = false;
36  if (module) {
37  version = module->getName();
38  isBiblicalText = (!strcmp(module->getType(), "Biblical Texts"));
39  }
40 }
41 
42 
44  setTokenStart("<");
45  setTokenEnd(">");
46 
47  setEscapeStart("&");
48  setEscapeEnd(";");
49 
51 
52  addEscapeStringSubstitute("amp", "&");
53  addEscapeStringSubstitute("apos", "'");
54  addEscapeStringSubstitute("lt", "<");
55  addEscapeStringSubstitute("gt", ">");
56  addEscapeStringSubstitute("quot", "\"");
57 
59 }
60 
61 
62 bool TEIRTF::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
63  // manually process if it wasn't a simple substitution
64  if (!substituteToken(buf, token)) {
65  MyUserData *u = (MyUserData *)userData;
66  XMLTag tag(token);
67 
68  // <p> paragraph tag
69  if (!strcmp(tag.getName(), "p")) {
70  if (!tag.isEndTag()) { // non-empty start tag
71  buf += "{\\sb100\\fi200\\par}";
72  }
73  }
74 
75  // <hi>
76  else if (!strcmp(tag.getName(), "hi") || !strcmp(tag.getName(), "emph")) {
77  SWBuf rend = tag.getAttribute("rend");
78  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
79  if (rend == "italic" || rend == "ital")
80  buf += "{\\i1 ";
81  else if (rend == "bold")
82  buf += "{\\b1 ";
83  else if (rend == "super" || rend == "sup")
84  buf += "{\\super ";
85  else if (rend == "sub")
86  buf += "{\\sub ";
87  }
88  else if (tag.isEndTag()) {
89  buf += "}";
90  }
91  }
92 
93  // <entryFree>
94  else if (!strcmp(tag.getName(), "entryFree")) {
95  SWBuf n = tag.getAttribute("n");
96  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
97  if (n != "") {
98  buf += "{\\b1 ";
99  buf += n;
100  buf += ". }"; }
101  }
102  }
103 
104  // <sense>
105  else if (!strcmp(tag.getName(), "sense")) {
106  SWBuf n = tag.getAttribute("n");
107  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
108  if (n != "") {
109  buf += "{\\sb100\\par\\b1 ";
110  buf += n;
111  buf += ". }";
112  }
113  }
114  }
115 
116  // <orth>
117  else if (!strcmp(tag.getName(), "orth")) {
118  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
119  buf += "{\\b1 ";
120  }
121  else if (tag.isEndTag()) {
122  buf += "}";
123  }
124  }
125 
126  // <div>
127  else if (!strcmp(tag.getName(), "div")) {
128 
129  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
130  buf.append("{\\pard\\sa300}");
131  }
132  else if (tag.isEndTag()) {
133  }
134  }
135 
136  // <pos>, <gen>, <case>, <gram>, <number>, <mood>
137  else if (!strcmp(tag.getName(), "pos") || !strcmp(tag.getName(), "gen") || !strcmp(tag.getName(), "case") || !strcmp(tag.getName(), "gram") || !strcmp(tag.getName(), "number") || !strcmp(tag.getName(), "mood")) {
138  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
139  buf += "{\\i1 ";
140  }
141  else if (tag.isEndTag()) {
142  buf += "}";
143  }
144  }
145 
146  // <tr>
147  else if (!strcmp(tag.getName(), "tr")) {
148  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
149  buf += "{\\i1 ";
150  }
151  else if (tag.isEndTag()) {
152  buf += "}";
153  }
154  }
155 
156  // <etym>
157  else if (!strcmp(tag.getName(), "etym")) {
158  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
159  buf += "[";
160  }
161  else if (tag.isEndTag()) {
162  buf += "]";
163  }
164  }
165 
166  // <note> tag
167  else if (!strcmp(tag.getName(), "note")) {
168  if (!tag.isEndTag()) {
169  if (!tag.isEmpty()) {
170  SWBuf type = tag.getAttribute("type");
171 
172  SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
173  if (u->vkey) {
174  buf.appendFormatted("{\\super <a href=\"\">*%s</a>} ", footnoteNumber.c_str());
175  }
176  u->suspendTextPassThru = true;
177  }
178  }
179  if (tag.isEndTag()) {
180  u->suspendTextPassThru = false;
181  }
182  }
183 
184  // <lb/> tag
185  else if (!strcmp(tag.getName(), "lb")) {
186  buf += "{\\par}";
187  userData->supressAdjacentWhitespace = true;
188  }
189 
190  // <ref> tag
191  else if (!strcmp(tag.getName(), "ref")) {
192  if (!tag.isEndTag() && tag.getAttribute("osisRef")) {
193  buf += "{<a href=\"\">";
194  u->inOsisRef = true;
195  }
196  else if (tag.isEndTag() && u->inOsisRef) {
197  buf += "</a>}";
198  u->inOsisRef = false;
199  }
200  }
201 
202  else if (!strcmp(tag.getName(), "graphic")) {
203  const char *src = tag.getAttribute("url");
204  if (!src) // assert we have a src attribute
205  return false;
206 
207  char* filepath = new char[strlen(u->module->getConfigEntry("AbsoluteDataPath")) + strlen(token)];
208  *filepath = 0;
209  strcpy(filepath, userData->module->getConfigEntry("AbsoluteDataPath"));
210  strcat(filepath, src);
211 
212 // we do this because BibleCS looks for this EXACT format for an image tag
213  buf += "<img src=\"";
214  buf += filepath;
215  buf += "\" />";
216  delete [] filepath;
217  }
218 
219  // <list> <item> - primitive implementation lacking numbered lists
220  else if (!strcmp(tag.getName(), "list")) {
221  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
222  buf += "\\par";
223  }
224  else if (tag.isEndTag()) {
225  buf += "\\par";
226  u->supressAdjacentWhitespace = true;
227  }
228  }
229  else if (!strcmp(tag.getName(), "item")) {
230  if ((!tag.isEndTag()) && (!tag.isEmpty())) {
231  buf += "\\tab* ";
232  }
233  else if (tag.isEndTag()) {
234  buf += "\\par";
235  }
236  }
237 
238  else {
239  return false; // we still didn't handle token
240  }
241 
242  }
243  return true;
244 }
245 
246 
248 
MyUserData(const SWModule *module, const SWKey *key)
Definition: teirtf.cpp:33
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
void setTokenEnd(const char *tokenEnd)
Definition: swbuf.h:47
TEIRTF()
Definition: teirtf.cpp:43
virtual bool handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData)
Definition: teirtf.cpp:62
const char * getType() const
Definition: swmodule.cpp:232
virtual const char * getConfigEntry(const char *key) const
Definition: swmodule.cpp:1159
const SWModule * module
Definition: swbasicfilter.h:42
const char * getName() const
Definition: utilxml.h:58
SWText * module
Definition: osis2mod.cpp:105
Definition: utilxml.h:38
void setTokenCaseSensitive(bool val)
void setEscapeStart(const char *escStart)
bool isEmpty() const
Definition: utilxml.h:60
bool substituteToken(SWBuf &buf, const char *token)
const VerseKey * vkey
Definition: swbasicfilter.h:44
void addEscapeStringSubstitute(const char *findString, const char *replaceString)
void setTokenStart(const char *tokenStart)
const char * c_str() const
Definition: swbuf.h:158
SWBuf & append(const char *str, long max=-1)
Definition: swbuf.h:274
bool isBiblicalText
Definition: teirtf.h:40
const char * getAttribute(const char *attribName, int partNum=-1, char partSplit= '|') const
Definition: utilxml.cpp:230
void setEscapeStringCaseSensitive(bool val)
bool isEndTag(const char *eID=0) const
Definition: utilxml.cpp:323
void setEscapeEnd(const char *escEnd)
#define SWORD_NAMESPACE_END
Definition: defs.h:40
Definition: swkey.h:77