The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
thmlheadings.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * thmlheadings.cpp - SWFilter descendant to hide or show headings
4  * in a ThML module
5  *
6  * $Id: thmlheadings.cpp 3191 2014-04-19 17:06:38Z 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 #include <stdlib.h>
25 #include <stdio.h>
26 #include <thmlheadings.h>
27 #include <utilxml.h>
28 #include <utilstr.h>
29 #include <swmodule.h>
30 #include <stdio.h>
31 
32 
34 
35 namespace {
36 
37  static const char oName[] = "Headings";
38  static const char oTip[] = "Toggles Headings On and Off if they exist";
39 
40  static const StringList *oValues() {
41  static const SWBuf choices[3] = {"Off", "On", ""};
42  static const StringList oVals(&choices[0], &choices[2]);
43  return &oVals;
44  }
45 }
46 
47 
49 }
50 
51 
53 }
54 
55 
56 char ThMLHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
57  SWBuf token;
58  bool intoken = false;
59  bool isheader = false;
60  bool hide = false;
61  bool preverse = false;
62  bool withinDiv = false;
63  SWBuf header;
64  int headerNum = 0;
65  int pvHeaderNum = 0;
66  char buf[254];
67  XMLTag startTag;
68 
69  SWBuf orig = text;
70  const char *from = orig.c_str();
71 
72  XMLTag tag;
73 
74  for (text = ""; *from; ++from) {
75  if (*from == '<') {
76  intoken = true;
77  token = "";
78 
79  continue;
80  }
81  if (*from == '>') { // process tokens
82  intoken = false;
83 
84  if (!strnicmp(token.c_str(), "div", 3) || !strnicmp(token.c_str(), "/div", 4)) {
85  withinDiv = (!strnicmp(token.c_str(), "div", 3));
86  tag = token;
87  if (hide && tag.isEndTag()) {
88  if (module->isProcessEntryAttributes() && (option || (!preverse))) {
89  SWBuf heading;
90  SWBuf cls = startTag.getAttribute("class");
91  if (!cls.startsWith("fromEntryAttributes")) {
92  cls = SWBuf("fromEntryAttributes ") + cls;
93  startTag.setAttribute("class", cls);
94  }
95  heading += startTag;
96  heading += header;
97  heading += tag;
98  if (preverse) {
99  sprintf(buf, "%i", pvHeaderNum++);
100  module->getEntryAttributes()["Heading"]["Preverse"][buf] = heading;
101  }
102  else {
103  sprintf(buf, "%i", headerNum++);
104  module->getEntryAttributes()["Heading"]["Interverse"][buf] = heading;
105  if (option) { // we want the tag in the text
106  text.append(header);
107  }
108  }
109 
110  StringList attributes = startTag.getAttributeNames();
111  for (StringList::const_iterator it = attributes.begin(); it != attributes.end(); it++) {
112  module->getEntryAttributes()["Heading"][buf][it->c_str()] = startTag.getAttribute(it->c_str());
113  }
114  }
115 
116  hide = false;
117  if (!option || preverse) { // we don't want the tag in the text anymore
118  preverse = false;
119  continue;
120  }
121  preverse = false;
122  }
123  if (tag.getAttribute("class") && ((!stricmp(tag.getAttribute("class"), "sechead"))
124  || (!stricmp(tag.getAttribute("class"), "title")))) {
125 
126  isheader = true;
127 
128  if (!tag.isEndTag()) { //start tag
129  if (!tag.isEmpty()) {
130  startTag = tag;
131 
132 /* how do we tell a ThML preverse title from one that should be in the text? probably if any text is before the title... just assuming all are preverse for now
133  }
134  if (tag.getAttribute("subtype") && !stricmp(tag.getAttribute("subtype"), "x-preverse")) {
135 */
136  hide = true;
137  preverse = true;
138  header = "";
139  continue;
140  } // move back up under startTag = tag
141  }
142 /* this is where non-preverse will go eventually
143  if (!tag.isEndTag()) { //start tag
144  hide = true;
145  header = "";
146  if (option) { // we want the tag in the text
147  text.append('<');
148  text.append(token);
149  text.append('>');
150  }
151  continue;
152  }
153 */
154  }
155  else {
156  isheader = false;
157  SWBuf cls = tag.getAttribute("class");
158  if (cls.startsWith("fromEntryAttributes ")) {
159  cls << SWBuf("fromEntryAttributes ").size();
160  tag.setAttribute("class", cls);
161  token = tag;
162  token << 1;
163  token.setSize(token.size() - 1);
164  }
165  }
166  }
167 
168  if (withinDiv && isheader) {
169  header.append('<');
170  header.append(token);
171  header.append('>');
172  } else {
173  // if not a heading token, keep token in text
174  if (!hide) {
175  text.append('<');
176  text.append(token);
177  text.append('>');
178  }
179  }
180  continue;
181  }
182  if (intoken) { //copy token
183  token.append(*from);
184  }
185  else if (!hide) { //copy text which is not inside a token
186  text.append(*from);
187  }
188  else header.append(*from);
189  }
190  return 0;
191 }
192 
193 
#define SWORD_NAMESPACE_START
Definition: defs.h:39
Definition: swbuf.h:47
const char * setAttribute(const char *attribName, const char *attribValue, int partNum=-1, char partSplit= '|')
Definition: utilxml.cpp:248
SWText * module
Definition: osis2mod.cpp:105
Definition: utilxml.h:38
bool startsWith(const SWBuf &prefix) const
Definition: swbuf.h:486
bool isEmpty() const
Definition: utilxml.h:60
static const StringList * oValues()
int stricmp(const char *s1, const char *s2)
Definition: utilstr.cpp:194
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[]
unsigned long size() const
Definition: swbuf.h:185
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[]
bool isEndTag(const char *eID=0) const
Definition: utilxml.cpp:323
int strnicmp(const char *s1, const char *s2, int len)
Definition: utilstr.cpp:180
virtual ~ThMLHeadings()
#define SWORD_NAMESPACE_END
Definition: defs.h:40
Definition: swkey.h:77
void setSize(unsigned long len)
Definition: swbuf.h:255
virtual char processText(SWBuf &text, const SWKey *key=0, const SWModule *module=0)