The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
thmlfootnotes.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * thmlfootnotes.cpp - SWFilter descendant to hide or show footnotes
4  * in a ThML module
5  *
6  * $Id: thmlfootnotes.cpp 2980 2013-09-14 21:51:47Z scribe $
7  *
8  * Copyright 2001-2013 CrossWire Bible Society (http://www.crosswire.org)
9  * CrossWire Bible Society
10  * P. O. Box 2528
11  * Tempe, AZ 85280-2528
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the
15  * Free Software Foundation version 2.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * General Public License for more details.
21  *
22  */
23 
24 
25 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <thmlfootnotes.h>
29 #include <swmodule.h>
30 #include <swbuf.h>
31 #include <versekey.h>
32 #include <utilxml.h>
33 
34 
36 
37 namespace {
38 
39  static const char oName[] = "Footnotes";
40  static const char oTip[] = "Toggles Footnotes On and Off if they exist";
41 
42  static const StringList *oValues() {
43  static const SWBuf choices[3] = {"Off", "On", ""};
44  static const StringList oVals(&choices[0], &choices[2]);
45  return &oVals;
46  }
47 }
48 
49 
51 }
52 
53 
55 }
56 
57 
58 char ThMLFootnotes::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
59  SWBuf token;
60  bool intoken = false;
61  bool hide = false;
62  SWBuf tagText;
63  XMLTag startTag;
64  SWBuf refs = "";
65  int footnoteNum = 1;
66  char buf[254];
67  SWKey *p = (module) ? module->createKey() : (key) ? key->clone() : new VerseKey();
68  VerseKey *parser = SWDYNAMIC_CAST(VerseKey, p);
69  if (!parser) {
70  delete p;
71  parser = new VerseKey();
72  }
73  *parser = key->getText();
74 
75  SWBuf orig = text;
76  const char *from = orig.c_str();
77 
78  for (text = ""; *from; from++) {
79  if (*from == '<') {
80  intoken = true;
81  token = "";
82  continue;
83  }
84  if (*from == '>') { // process tokens
85  intoken = false;
86 
87  XMLTag tag(token);
88  if (!strcmp(tag.getName(), "note")) {
89  if (!tag.isEndTag()) {
90  if (!tag.isEmpty()) {
91  refs = "";
92  startTag = tag;
93  hide = true;
94  tagText = "";
95  continue;
96  }
97  }
98  if (hide && tag.isEndTag()) {
99  if (module->isProcessEntryAttributes()) {
100  SWBuf fc = module->getEntryAttributes()["Footnote"]["count"]["value"];
101  footnoteNum = (fc.length()) ? atoi(fc.c_str()) : 0;
102  sprintf(buf, "%i", ++footnoteNum);
103  module->getEntryAttributes()["Footnote"]["count"]["value"] = buf;
104  StringList attributes = startTag.getAttributeNames();
105  for (StringList::iterator it = attributes.begin(); it != attributes.end(); it++) {
106  module->getEntryAttributes()["Footnote"][buf][it->c_str()] = startTag.getAttribute(it->c_str());
107  }
108  module->getEntryAttributes()["Footnote"][buf]["body"] = tagText;
109  startTag.setAttribute("swordFootnote", buf);
110  if ((startTag.getAttribute("type")) && (!strcmp(startTag.getAttribute("type"), "crossReference"))) {
111  if (!refs.length())
112  refs = parser->parseVerseList(tagText.c_str(), *parser, true).getRangeText();
113  module->getEntryAttributes()["Footnote"][buf]["refList"] = refs.c_str();
114  }
115  }
116  hide = false;
117  if ((option) || ((startTag.getAttribute("type") && (!strcmp(startTag.getAttribute("type"), "crossReference"))))) { // we want the tag in the text; crossReferences are handled by another filter
118  text += startTag;
119  text.append(tagText);
120  }
121  else continue;
122  }
123  }
124 
125  // if not a note token, keep token in text
126  if ((!strcmp(tag.getName(), "scripRef")) && (!tag.isEndTag())) {
127  SWBuf osisRef = tag.getAttribute("passage");
128  if (refs.length())
129  refs += "; ";
130  refs += osisRef;
131  }
132  if (!hide) {
133  text += '<';
134  text.append(token);
135  text += '>';
136  }
137  else {
138  tagText += '<';
139  tagText.append(token);
140  tagText += '>';
141  }
142  continue;
143  }
144  if (intoken) { //copy token
145  token += *from;
146  }
147  else if (!hide) { //copy text which is not inside a token
148  text += *from;
149  }
150  else tagText += *from;
151  }
152  delete parser;
153  return 0;
154 }
155 
#define SWORD_NAMESPACE_START
Definition: defs.h:39
Definition: swbuf.h:47
unsigned long length() const
Definition: swbuf.h:197
const char * setAttribute(const char *attribName, const char *attribValue, int partNum=-1, char partSplit= '|')
Definition: utilxml.cpp:248
const char * getName() const
Definition: utilxml.h:58
SWText * module
Definition: osis2mod.cpp:105
Definition: utilxml.h:38
bool isEmpty() const
Definition: utilxml.h:60
static const StringList * oValues()
virtual SWKey * clone() const
Definition: swkey.cpp:75
virtual const char * getText() const
Definition: swkey.cpp:184
const StringList getAttributeNames() const
Definition: utilxml.cpp:188
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 ListKey parseVerseList(const char *buf, const char *defaultKey=0, bool expandRange=false, bool useChapterAsVerse=false)
Definition: versekey.cpp:515
#define SWDYNAMIC_CAST(className, object)
Definition: defs.h:47
virtual bool isProcessEntryAttributes() const
Definition: swmodule.h:832
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[]
virtual char processText(SWBuf &text, const SWKey *key=0, const SWModule *module=0)
bool isEndTag(const char *eID=0) const
Definition: utilxml.cpp:323
virtual ~ThMLFootnotes()
#define SWORD_NAMESPACE_END
Definition: defs.h:40
virtual SWKey * createKey() const
Definition: swmodule.cpp:173
Definition: swkey.h:77