/********* * * This file is part of BibleTime's source code, http://www.bibletime.info/. * * Copyright 1999-2006 by the BibleTime developers. * The BibleTime source code is licensed under the GNU General Public License version 2.0. * **********/ //BibleTime includes #include "cswordmoduleinfo.h" #include "cswordbackend.h" #include "util/cpointers.h" #include "bt_gbfhtml.h" //sytsme includes #include #include //Sword includes #include //TQt includes #include #include using namespace Filters; BT_GBFHTML::BT_GBFHTML() : sword::GBFHTML() { setEscapeStringCaseSensitive(true); setPassThruUnknownEscapeString(true); //the HTML widget will render the HTML escape codes removeTokenSubstitute("Rf"); // addTokenSubstitute("RB", ""); //start of a footnote with embedded text addTokenSubstitute("FI", ""); // italics begin addTokenSubstitute("Fi", ""); addTokenSubstitute("FB", ""); // bold begin addTokenSubstitute("Fb", ""); addTokenSubstitute("FR", ""); addTokenSubstitute("Fr", ""); addTokenSubstitute("FU", ""); // underline begin addTokenSubstitute("Fu", ""); addTokenSubstitute("FO", ""); // Old Testament quote begin addTokenSubstitute("Fo", ""); addTokenSubstitute("FS", ""); // Superscript begin// Subscript begin addTokenSubstitute("Fs", ""); addTokenSubstitute("FV", ""); // Subscript begin addTokenSubstitute("Fv", ""); addTokenSubstitute("TT", "
"); addTokenSubstitute("Tt", "
"); addTokenSubstitute("TS", "
"); addTokenSubstitute("Ts", "
"); //addTokenSubstitute("PP", ""); // poetry begin //addTokenSubstitute("Pp", ""); addTokenSubstitute("Fn", ""); // font end addTokenSubstitute("CL", "
"); // new line addTokenSubstitute("CM", "
"); // paragraph is a non showing comment that can be changed in the front end to

if desired addTokenSubstitute("CG", ">"); // literal greater-than sign addTokenSubstitute("CT", "<"); // literal less-than sign addTokenSubstitute("JR", ""); // right align begin addTokenSubstitute("JC", ""); // center align begin addTokenSubstitute("JL", ""); // align end } /** No descriptions */ char BT_GBFHTML::processText(sword::SWBuf& buf, const sword::SWKey * key, const sword::SWModule * module) { GBFHTML::processText(buf, key, module); if (!module->isProcessEntryAttributes()) { return 1; //no processing should be done, may happen in a search } CSwordModuleInfo* m = CPointers::backend()->findModuleByName( module->Name() ); if (m && !(m->has(CSwordModuleInfo::lemmas) || m->has(CSwordModuleInfo::morphTags) || m->has(CSwordModuleInfo::strongNumbers))) { //only parse if the module has strongs or lemmas return 1; //WARNING: Return alread here } //Am Anfang schuf Gott Himmel und Erde. //A simple word means: No entry for this word "word" TQString result; TQString t = TQString::fromUtf8(buf.c_str()); TQRegExp tag("([.,;:]?]*>\\s*)+"); TQStringList list; int lastMatchEnd = 0; int pos = tag.search(t,0); if (pos == -1) { //no strong or morph code found in this text return 1; //WARNING: Return already here } //split the text into parts which end with the GBF tag marker for strongs/lemmas while (pos != -1) { list.append(t.mid(lastMatchEnd, pos+tag.matchedLength()-lastMatchEnd)); lastMatchEnd = pos + tag.matchedLength(); pos = tag.search(t, pos + tag.matchedLength()); } //append the trailing text to the list. if (!t.right(t.length() - lastMatchEnd).isEmpty()) { list.append(t.right(t.length() - lastMatchEnd)); } //list is now a list of words with 1-n Strongs at the end, which belong to this word. //now create the necessary HTML in list entries and concat them to the result tag = TQRegExp("]*)>"); tag.setMinimal(true); for (TQStringList::iterator it = list.begin(); it != list.end(); ++it) { TQString e = (*it); //current entry to process //qWarning(e.latin1()); //check if there is a word to which the strongs info belongs to. //If yes, wrap that word with the strongs info //If not, leave out the strongs info, because it can't be tight to a text //Comparing the first char with < is not enough, because the tokenReplace is done already //so there might be html tags already. const bool textPresent = (e.stripWhiteSpace().remove(TQRegExp("[.,;:]")).left(2) != ""); pos += 7; //skip blanks, commas, dots and stuff at the beginning, it doesn't belong to the morph code TQString rep(""); hasMorphAttr = isMorph; hasLemmaAttr = !isMorph; int startPos = 0; TQChar c = e[startPos]; while ((startPos < pos) && (c.isSpace() || c.isPunct())) { ++startPos; c = e[startPos]; } e.insert( startPos, rep ); tagAttributeStart = startPos + 6; //to point to the start of the attributes pos += rep.length(); } else { //add the attribute to the existing tag e.remove(pos, tag.matchedLength()); if (tagAttributeStart == -1) { continue; //nothing valid found } if ((!isMorph && hasLemmaAttr) || (isMorph && hasMorphAttr)) { //we append another attribute value, e.g. 3000 gets 3000|5000 //search the existing attribute start TQRegExp attrRegExp( isMorph ? "morph=\".+(?=\")" : "lemma=\".+(?=\")" ); attrRegExp.setMinimal(true); const int foundPos = e.find(attrRegExp, tagAttributeStart); if (foundPos != -1) { e.insert(foundPos + attrRegExp.matchedLength(), TQString("|").append(value)); pos += value.length() + 1; hasLemmaAttr = !isMorph; hasMorphAttr = isMorph; } } else { //attribute was not yet inserted TQString attr; attr.setLatin1(isMorph ? "morph" : "lemma").append("=\"").append(value).append("\" "); e.insert(tagAttributeStart, attr); pos += attr.length(); hasMorphAttr = isMorph; hasLemmaAttr = !isMorph; } //tagAttributeStart remains the same } insertedTag = true; pos = tag.search(e, pos); } result += e; } if (list.count()) { buf = (const char*)result.utf8(); } return 1; } bool BT_GBFHTML::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { if (!substituteToken(buf, token)) { //more than a simple replace const unsigned int tokenLength = strlen(token); unsigned long i; sword::SWBuf value; BT_UserData* myUserData = dynamic_cast(userData); sword::SWModule* myModule = const_cast(myUserData->module); //hack to be able to call stuff like Lang() if ( !strncmp(token, "WG", 2) || !strncmp(token, "WH", 2) || !strncmp(token, "WT", 2) ) { buf.append('<'); buf.append(token); buf.append('>'); } else if (!strncmp(token, "RB", 2)) { myUserData->hasFootnotePreTag = true; buf.append(""); } else if (!strncmp(token, "RF", 2)) { //we use several append calls because appendFormatted slows down filtering, which should be fast if (myUserData->hasFootnotePreTag) { // qWarning("inserted footnotepre end"); buf.append(""); myUserData->hasFootnotePreTag = false; } buf.append(" Name()); buf.append('/'); buf.append(myUserData->key->getShortText()); buf.append('/'); buf.append( TQString::number(myUserData->swordFootnote++).latin1() ); buf.append("\">* "); userData->suspendTextPassThru = true; } else if (!strncmp(token, "Rf", 2)) { //end of footnote userData->suspendTextPassThru = false; } else if (!strncmp(token, "FN", 2)) { //the end tag is inserted in addTokenSubsitute buf.append(""); } else if (!strncmp(token, "CA", 2)) { // ASCII value buf.append( (char)atoi(&token[2]) ); } else { return GBFHTML::handleToken(buf, token, userData); } } return true; }