diff options
Diffstat (limited to 'src/modules/filters/gbfosis.cpp')
-rw-r--r-- | src/modules/filters/gbfosis.cpp | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/src/modules/filters/gbfosis.cpp b/src/modules/filters/gbfosis.cpp new file mode 100644 index 0000000..b5dd8e1 --- /dev/null +++ b/src/modules/filters/gbfosis.cpp @@ -0,0 +1,439 @@ +/****************************************************************************** + * + * gbfstrongs - SWFilter descendant to hide or show strongs number + * in a GBF module. + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <gbfosis.h> +#include <swmodule.h> +#include <versekey.h> +#include <swlog.h> +#include <stdarg.h> +#ifndef __GNUC__ +#else +#include <unixstr.h> +#endif + +SWORD_NAMESPACE_START + +GBFOSIS::GBFOSIS() { +} + + +GBFOSIS::~GBFOSIS() { +} + + +char GBFOSIS::processText(SWBuf &text, const SWKey *key, const SWModule *module) { +/* + char *to, *from, token[2048]; // cheese. Fix. + int tokpos = 0; + bool intoken = false; + int len; + bool lastspace = false; + int word = 1; + char val[128]; + char buf[128]; + char wordstr[5]; + char *valto; + char *ch; + char *textStart, *textEnd; + char *wordStart, *wordEnd; + char *fromStart; + bool newText = false; + bool newWord = false; + SWBuf tmp; + bool suspendTextPassThru = false; + bool keepToken = false; + bool handled = false; + + len = strlen(text) + 1; // shift string to right of buffer + if (len < maxlen) { + memmove(&text[maxlen - len], text, len); + from = &text[maxlen - len]; + } + else from = text; + + textStart = from; + fromStart = from; + wordStart = text; + + static QuoteStack quoteStack; + + // ------------------------------- + + for (to = text; *from; from++) { + if (*from == '<') { + intoken = true; + tokpos = 0; + token[0] = 0; + token[1] = 0; + token[2] = 0; + textEnd = from-1; + wordEnd = to; + continue; + } + if (*from == '>') { // process tokens + intoken = false; + keepToken = false; + suspendTextPassThru = false; + newWord = true; + handled = false; + + while (wordStart < (text+maxlen)) { +// if (strchr(" ,;.?!()'\"", *wordStart)) + if (strchr(";, .:?!()'\"", *wordStart) && wordStart[0] && wordStart[1]) + wordStart++; + else break; + } + while (wordEnd > wordStart) { + if (strchr(" ,;.:?!()'\"", *wordEnd)) + wordEnd--; + else break; + } + + // Scripture Reference + if (!strncmp(token, "scripRef", 8)) { + // pushString(buf, "<reference work=\"Bible.KJV\" reference=\""); + suspendTextPassThru = true; + newText = true; + handled = true; + } + else if (!strncmp(token, "/scripRef", 9)) { + tmp = ""; + tmp.append(textStart, (int)(textEnd - textStart)+1); + pushString(&to, convertToOSIS(tmp.c_str(), key)); + lastspace = false; + suspendTextPassThru = false; + handled = true; + } + + // Footnote + if (!strcmp(token, "RF")) { + // pushString(buf, "<reference work=\"Bible.KJV\" reference=\""); + pushString(&to, "<note type=\"x-StudyNote\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "Rf")) { + pushString(&to, "</note>"); + lastspace = false; + handled = true; + } + // hebrew titles + if (!strcmp(token, "TH")) { + pushString(&to, "<title type=\"psalm\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "Th")) { + pushString(&to, "</title>"); + lastspace = false; + handled = true; + } + // Italics assume transchange + if (!strcmp(token, "FI")) { + pushString(&to, "<transChange type=\"added\">"); + newText = true; + lastspace = false; + handled = true; + } + else if (!strcmp(token, "Fi")) { + pushString(&to, "</transChange>"); + lastspace = false; + handled = true; + } + // Paragraph break. For now use empty paragraph element + if (!strcmp(token, "CM")) { + pushString(&to, "<milestone type=\"x-p\" />"); + newText = true; + lastspace = false; + handled = true; + } + + // Figure + else if (!strncmp(token, "img ", 4)) { + const char *src = strstr(token, "src"); + if (!src) // assert we have a src attribute + continue; +// return false; + + pushString(&to, "<figure src=\""); + const char *c; + for (c = src;((*c) && (*c != '"')); c++); + +// uncomment for SWORD absolute path logic +// if (*(c+1) == '/') { +// pushString(buf, "file:"); +// pushString(buf, module->getConfigEntry("AbsoluteDataPath")); +// if (*((*buf)-1) == '/') +// c++; // skip '/' +// } +// end of uncomment for asolute path logic + + for (c++;((*c) && (*c != '"')); c++) + *to++ = *c; + + pushString(&to, "\" />"); + lastspace = false; + handled = true; + } + + // Strongs numbers + else if (*token == 'W' && (token[1] == 'G' || token[1] == 'H')) { // Strongs + bool divineName = false; + if (module->isProcessEntryAttributes()) { + valto = val; + for (unsigned int i = 1; ((token[i]) && (i < 150)); i++) + *valto++ = token[i]; + *valto = 0; + // normal strongs number + strstrip(val); + if (!strncmp(wordStart, "<w ", 3)) { + strtok(wordStart, ">"); + char *attStart = strstr(wordStart, "lemma"); + if (attStart) { + attStart += 7; + sprintf(buf, "x-Strongs:%s|", val); + } + else { + attStart = wordStart + 3; + sprintf(buf, "lemma=\"x-Strongs:%s\" ", val); + } + wordStart[strlen(wordStart)] = '>'; + memmove(attStart+strlen(buf), attStart, (to-attStart)+1); + memcpy(attStart, buf, strlen(buf)); + to+=strlen(buf); + } + else { + if (!strcmp(val, "H03068")) { //divineName + sprintf(buf, "<divineName><w lemma=\"x-Strongs:%s\">", val); + divineName = true; + } + else sprintf(buf, "<w lemma=\"x-Strongs:%s\">", val); + + memmove(wordStart+strlen(buf), wordStart, (to-wordStart)+1); + memcpy(wordStart, buf, strlen(buf)); + to+=strlen(buf); + + if (divineName) { + wordStart += 12; + pushString(&to, "</w></divineName>"); + } + else pushString(&to, "</w>"); + + module->getEntryAttributes()["Word"][wordstr]["Strongs"] = val; + lastspace = false; + } + } + handled = true; + } + + // Morphology + else if (*token == 'W' && token[1] == 'T' && (token[2] == 'G' || token[2] == 'H')) { // Strongs + valto = val; + for (unsigned int i = 1; ((token[i]) && (i < 150)); i++) + *valto++ = token[i]; + *valto = 0; + strstrip(val); + if (!strncmp(wordStart, "<w ", 3)) { + strtok(wordStart, ">"); + char *attStart = strstr(wordStart, "morph"); + if (attStart) { + attStart += 7; + sprintf(buf, "x-%s:%s|", "StrongsMorph", val); + } + else { + attStart = wordStart + 3; + sprintf(buf, "morph=\"x-%s:%s\" ", "StrongsMorph", val); + } + wordStart[strlen(wordStart)] = '>'; + memmove(attStart+strlen(buf), attStart, (to-attStart)+1); + memcpy(attStart, buf, strlen(buf)); + to+=strlen(buf); + } + else { + sprintf(buf, "<w morph=\"x-%s:%s\">", "StrongsMorph", val); + memmove(wordStart+strlen(buf), wordStart, (to-wordStart)+1); + memcpy(wordStart, buf, strlen(buf)); + to+=strlen(buf); + pushString(&to, "</w>"); + lastspace = false; + } + handled = true; + } + + if (!keepToken) { + if (!handled) { + SWLog::systemlog->LogError("Unprocessed Token: <%s>", token); +// exit(-1); + } + if (from[1] && strchr(" ,;.:?!()'\"", from[1])) { + if (lastspace) + to--; + } + if (newText) {textStart = from+1; newText = false; } +// if (newWord) {wordStart = to; newWord = false; } + continue; + } + // if not a strongs token, keep token in text + *to++ = '<'; + for (char *tok = token; *tok; tok++) + *to++ = *tok; + *to++ = '>'; + if (newText) {textStart = to; newWord = false; } +// if (newWord) {wordStart = to; newWord = false; } + continue; + } + if (intoken) { + if ((tokpos < 2045) && ((*from != 10)&&(*from != 13))) { + token[tokpos++] = *from; + token[tokpos+2] = 0; + } + } + else { + switch (*from) { + case '\'': + case '\"': + case '`': +// quoteStack.handleQuote(fromStart, from, &to); + *to++ = *from; + from++; + break; + default: + if (newWord && (*from != ' ')) {wordStart = to; newWord = false; memset(to, 0, 10); } + if (!suspendTextPassThru) { + *to++ = *from; + lastspace = (*from == ' '); + } + } + } + } + + VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key); + if (vkey) { + char ref[254]; + if (vkey->Verse()) + sprintf(ref, "\t\t<verse osisID=\"%s\">", vkey->getOSISRef()); + else *ref = 0; + if (*ref) { + memmove(text+strlen(ref), text, maxlen-strlen(ref)-1); + memcpy(text, ref, strlen(ref)); + to+=strlen(ref); + if (vkey->Verse()) { + VerseKey tmp; + tmp = *vkey; + tmp.AutoNormalize(0); + tmp.Headings(1); + sprintf(ref, "</verse>"); + pushString(&to, ref); + tmp = MAXVERSE; + if (*vkey == tmp) { + tmp.Verse(0); +// sprintf(ref, "\t</div>"); +// pushString(&to, ref); + tmp = MAXCHAPTER; + tmp = MAXVERSE; + if (*vkey == tmp) { + tmp.Chapter(0); + tmp.Verse(0); +// sprintf(ref, "\t</div>"); +// pushString(&to, ref); + if (!quoteStack.empty()) { + SWLog::systemlog->LogError("popping unclosed quote at end of book"); + quoteStack.clear(); + } + } + } + } + +// +// else if (vkey->Chapter()) { +// sprintf(ref, "\t<div type=\"chapter\" osisID=\"%s\">", vkey->getOSISRef()); +// } +// else sprintf(ref, "\t<div type=\"book\" osisID=\"%s\">", vkey->getOSISRef()); +// + } + } + *to++ = 0; + *to = 0; +*/ + return 0; +} + + +const char *GBFOSIS::convertToOSIS(const char *inRef, const SWKey *key) { + static SWBuf outRef; + + outRef = ""; + + VerseKey defLanguage; + ListKey verses = defLanguage.ParseVerseList(inRef, (*key), true); + const char *startFrag = inRef; + for (int i = 0; i < verses.Count(); i++) { + VerseKey *element = SWDYNAMIC_CAST(VerseKey, verses.GetElement(i)); + char buf[5120]; + char frag[800]; + if (element) { + memmove(frag, startFrag, ((const char *)element->userData - startFrag) + 1); + frag[((const char *)element->userData - startFrag) + 1] = 0; + startFrag = (const char *)element->userData + 1; + sprintf(buf, "<reference osisRef=\"%s-%s\">%s</reference>", element->LowerBound().getOSISRef(), element->UpperBound().getOSISRef(), frag); + } + else { + memmove(frag, startFrag, ((const char *)verses.GetElement(i)->userData - startFrag) + 1); + frag[((const char *)verses.GetElement(i)->userData - startFrag) + 1] = 0; + startFrag = (const char *)verses.GetElement(i)->userData + 1; + sprintf(buf, "<reference osisRef=\"%s\">%s</reference>", VerseKey(*verses.GetElement(i)).getOSISRef(), frag); + } + outRef+=buf; + } + return outRef.c_str(); +} + + +QuoteStack::QuoteStack() { + clear(); +} + + +void QuoteStack::clear() { + while (!quotes.empty()) quotes.pop(); +} + + +QuoteStack::~QuoteStack() { + clear(); +} + + +void QuoteStack::handleQuote(char *buf, char *quotePos, SWBuf &text) { +//QuoteInstance(char startChar = '\"', char level = 1, string uniqueID = "", char continueCount = 0) { + if (!quotes.empty()) { + QuoteInstance last = quotes.top(); + if (last.startChar == *quotePos) { + text += "</quote>"; + quotes.pop(); + } + else { + quotes.push(QuoteInstance(*quotePos, last.level+1)); + quotes.top().pushStartStream(text); + } + } + else { + quotes.push(QuoteInstance(*quotePos)); + quotes.top().pushStartStream(text); + } +} + +void QuoteStack::QuoteInstance::pushStartStream(SWBuf &text) { + text.appendFormatted("<quote level=\"%d\">", level); +} + +SWORD_NAMESPACE_END |