diff options
Diffstat (limited to 'src/modules/filters/osisheadings.cpp')
-rw-r--r-- | src/modules/filters/osisheadings.cpp | 228 |
1 files changed, 99 insertions, 129 deletions
diff --git a/src/modules/filters/osisheadings.cpp b/src/modules/filters/osisheadings.cpp index 8872f24..783fa81 100644 --- a/src/modules/filters/osisheadings.cpp +++ b/src/modules/filters/osisheadings.cpp @@ -1,10 +1,11 @@ /****************************************************************************** * - *osisheadings - SWFilter descendant to hide or show headings - * in an OSIS module. + * osisheadings.cpp - SWFilter descendant to hide or show headings + * in an OSIS module * + * $Id: osisheadings.cpp 2980 2013-09-14 21:51:47Z scribe $ * - * Copyright 2009 CrossWire Bible Society (http://www.crosswire.org) + * Copyright 2003-2013 CrossWire Bible Society (http://www.crosswire.org) * CrossWire Bible Society * P. O. Box 2528 * Tempe, AZ 85280-2528 @@ -27,151 +28,120 @@ #include <utilxml.h> #include <utilstr.h> + SWORD_NAMESPACE_START -const char oName[] = "Headings"; -const char oTip[] = "Toggles Headings On and Off if they exist"; +namespace { + + static const char oName[] = "Headings"; + static const char oTip[] = "Toggles Headings On and Off if they exist"; + + static const StringList *oValues() { + static const SWBuf choices[3] = {"Off", "On", ""}; + static const StringList oVals(&choices[0], &choices[2]); + return &oVals; + } + -const SWBuf choices[3] = {"Off", "On", ""}; -const StringList oValues(&choices[0], &choices[2]); + class MyUserData : public BasicFilterUserData { + public: + SWBuf currentHeadingName; + XMLTag currentHeadingTag; + const char *sID; + SWBuf heading; + int depth; + int headerNum; -OSISHeadings::OSISHeadings() : SWOptionFilter(oName, oTip, &oValues) { - setOptionValue("Off"); + MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) { + clear(); + } + void clear() { + currentHeadingName = ""; + currentHeadingTag = ""; + sID = 0; + heading = ""; + depth = 0; + headerNum = 0; + } + }; } -OSISHeadings::~OSISHeadings() { +BasicFilterUserData *OSISHeadings::createUserData(const SWModule *module, const SWKey *key) { + return new MyUserData(module, key); } -char OSISHeadings::processText(SWBuf &text, const SWKey *key, const SWModule *module) { - SWBuf token; - bool intoken = false; - bool hide = false; - bool preverse = false; - bool withinTitle = false; - bool withinPreverseDiv = false; - SWBuf preverseDivID = ""; - const char *pvDID = 0; - bool canonical = false; - SWBuf header; - int headerNum = 0; - int pvHeaderNum = 0; - char buf[254]; - XMLTag startTag; - - SWBuf orig = text; - const char *from = orig.c_str(); - - XMLTag tag; - - for (text = ""; *from; ++from) { - if (*from == '<') { - intoken = true; - token = ""; - - continue; - } - if (*from == '>') { // process tokens - intoken = false; - tag = token; - - // <title> </title> <div subType="x-preverse"> (</div> ## when in previous) - if ( (!withinPreverseDiv && !strcmp(tag.getName(), "title")) || - (!strcmp(tag.getName(), "div") && - ((withinPreverseDiv && (tag.isEndTag(pvDID))) || - (tag.getAttribute("subType") && !strcmp(tag.getAttribute("subType"), "x-preverse"))) - )) { - - withinTitle = (!tag.isEndTag(pvDID)); - if (!strcmp(tag.getName(), "div")) { - withinPreverseDiv = (!tag.isEndTag(pvDID)); - if (!pvDID) { - preverseDivID = tag.getAttribute("sID"); - pvDID = (preverseDivID.length())? preverseDivID.c_str() : 0; - } - } - - if (!tag.isEndTag(pvDID)) { //start tag - if (!tag.isEmpty() || pvDID) { - startTag = tag; - } - } - - if ( !tag.isEndTag(pvDID) && (withinPreverseDiv - || (tag.getAttribute("subType") && !stricmp(tag.getAttribute("subType"), "x-preverse")) - || (tag.getAttribute("subtype") && !stricmp(tag.getAttribute("subtype"), "x-preverse")) // deprecated - )) { - hide = true; - preverse = true; - header = ""; - canonical = (tag.getAttribute("canonical") && (!stricmp(tag.getAttribute("canonical"), "true"))); - continue; - } - if (!tag.isEndTag(pvDID)) { //start tag - hide = true; - header = ""; - if (option || canonical) { // we want the tag in the text - text.append('<'); - text.append(token); - text.append('>'); - } - continue; - } - if (hide && tag.isEndTag(pvDID)) { - if (module->isProcessEntryAttributes() && ((option || canonical) || (!preverse))) { - if (preverse) { - sprintf(buf, "%i", pvHeaderNum++); - module->getEntryAttributes()["Heading"]["Preverse"][buf] = header; - } - else { - sprintf(buf, "%i", headerNum++); - module->getEntryAttributes()["Heading"]["Interverse"][buf] = header; - if (option || canonical) { // we want the tag in the text - text.append(header); - } - } - - StringList attributes = startTag.getAttributeNames(); +OSISHeadings::OSISHeadings() : SWOptionFilter(oName, oTip, oValues()) { + setPassThruUnknownToken(true); +} + + +bool OSISHeadings::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) { + + MyUserData *u = (MyUserData *)userData; + XMLTag tag(token); + SWBuf name = tag.getName(); + + // we only care about titles and divs or if we're already in a heading + // + // are we currently in a heading? + if (u->currentHeadingName.size()) { + u->heading.append(u->lastTextNode); + if (name == u->currentHeadingName) { + if (tag.isEndTag(u->sID)) { + if (!u->depth-- || u->sID) { + // we've just finished a heading. It's all stored up in u->heading + bool canonical = (SWBuf("true") == u->currentHeadingTag.getAttribute("canonical")); + bool preverse = (SWBuf("x-preverse") == u->currentHeadingTag.getAttribute("subType") || SWBuf("x-preverse") == u->currentHeadingTag.getAttribute("subtype")); + + // do we want to put anything in EntryAttributes? + if (u->module->isProcessEntryAttributes() && (option || canonical || !preverse)) { + SWBuf buf; buf.appendFormatted("%i", u->headerNum++); + u->module->getEntryAttributes()["Heading"][(preverse)?"Preverse":"Interverse"][buf] = u->heading; + + StringList attributes = u->currentHeadingTag.getAttributeNames(); for (StringList::const_iterator it = attributes.begin(); it != attributes.end(); it++) { - module->getEntryAttributes()["Heading"][buf][it->c_str()] = startTag.getAttribute(it->c_str()); + u->module->getEntryAttributes()["Heading"][buf][it->c_str()] = u->currentHeadingTag.getAttribute(it->c_str()); } } - - hide = false; - if (!(option || canonical) || preverse) { // we don't want the tag in the text anymore - preverse = false; - continue; - } - preverse = false; - pvDID = 0; - } - } - if (withinTitle) { - header.append('<'); - header.append(token); - header.append('>'); - } else { - // if not a heading token, keep token in text - if (!hide) { - text.append('<'); - text.append(token); - text.append('>'); + // do we want the heading in the body? + if (!preverse && (option || canonical)) { + buf.append(u->currentHeadingTag); + buf.append(u->heading); + buf.append(tag); + } + u->suspendTextPassThru = false; + u->clear(); } } - continue; + else u->depth++; } - if (intoken) { //copy token - token.append(*from); - } - else if (!hide) { //copy text which is not inside a token - text.append(*from); - } - else header.append(*from); + u->heading.append(tag); + return true; } - return 0; + + // are we a title or a preverse div? + else if ( name == "title" + || (name == "div" + && ( SWBuf("x-preverse") == tag.getAttribute("subType") + || SWBuf("x-preverse") == tag.getAttribute("subtype")))) { + + u->currentHeadingName = name; + u->currentHeadingTag = tag; + u->heading = ""; + u->sID = u->currentHeadingTag.getAttribute("sID"); + u->depth = 0; + u->suspendTextPassThru = true; + + return true; + } + + return false; } + + SWORD_NAMESPACE_END |