summaryrefslogtreecommitdiffstats
path: root/src/ks_osishtml.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ks_osishtml.cpp')
-rw-r--r--src/ks_osishtml.cpp358
1 files changed, 358 insertions, 0 deletions
diff --git a/src/ks_osishtml.cpp b/src/ks_osishtml.cpp
new file mode 100644
index 0000000..973a627
--- /dev/null
+++ b/src/ks_osishtml.cpp
@@ -0,0 +1,358 @@
+/***************************************************************************
+ File: ks_osishtml.cpp
+ Project: Kio-Sword -- An ioslave for SWORD and KDE
+ Copyright: Copyright (C) 2004-2005 Luke Plant
+ and CrossWire Bible Society 2003
+ (file based on osishtmlhref.cpp and osiscgi.cpp)
+ ***************************************************************************/
+
+/***************************************************************************
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "ks_osishtml.h"
+#include "utils.h"
+
+#include <utilxml.h>
+#include <versekey.h>
+#include <swmodule.h>
+
+#include <qstring.h>
+
+#include <stdlib.h>
+
+using namespace sword;
+
+namespace KioSword {
+ OSISHTML::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
+ osisQToTick = ((!module->getConfigEntry("OSISqToTick")) || (strcmp(module->getConfigEntry("OSISqToTick"), "false")));
+ }
+
+
+ OSISHTML::OSISHTML() {
+ setTokenStart("<");
+ setTokenEnd(">");
+
+ setEscapeStart("&");
+ setEscapeEnd(";");
+
+ setEscapeStringCaseSensitive(true);
+
+ addEscapeStringSubstitute("amp", "&");
+ addEscapeStringSubstitute("apos", "'");
+ addEscapeStringSubstitute("lt", "<");
+ addEscapeStringSubstitute("gt", ">");
+ addEscapeStringSubstitute("quot", "\"");
+ addTokenSubstitute("lg", "<br />");
+ addTokenSubstitute("/lg", "<br />");
+
+ setTokenCaseSensitive(true);
+ }
+
+
+ bool OSISHTML::handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData) {
+ // manually process if it wasn't a simple substitution
+ if (!substituteToken(buf, token)) {
+ MyUserData *u = (MyUserData *)userData;
+ XMLTag tag(token);
+
+ // <w> tag
+ if (!strcmp(tag.getName(), "w")) {
+ if ((!tag.isEmpty()) && (!tag.isEndTag())) {
+ // start <w> tag
+ u->w = token;
+ } else {
+ // end <w> tag
+ const char *attrib;
+ const char *val;
+ if (tag.isEndTag())
+ tag = u->w.c_str();
+
+ if ((attrib = tag.getAttribute("xlit"))) {
+ val = strchr(attrib, ':');
+ val = (val) ? (val + 1) : attrib;
+ buf.appendFormatted(" %s", val);
+ }
+ if ((attrib = tag.getAttribute("gloss"))) {
+ val = strchr(attrib, ':');
+ val = (val) ? (val + 1) : attrib;
+ buf.appendFormatted(" %s", val);
+ }
+ if ((attrib = tag.getAttribute("lemma"))) {
+ int count = tag.getAttributePartCount("lemma");
+ int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0
+ do {
+ attrib = tag.getAttribute("lemma", i);
+ if (i < 0) i = 0; // to handle our -1 condition
+ val = strchr(attrib, ':');
+ val = (val) ? (val + 1) : attrib;
+ if (*val == 'G') {
+ buf.append(QString(" <span class='strongs'>&lt;<a href=\"%2\">%1</a>&gt;</span> ")
+ .arg(val+1)
+ .arg(swordUrlForSearch(GREEKSTRONGS, val+1, m_swordoptions))
+ .utf8());
+ } else if (*val == 'H') {
+ buf.append(QString(" <span class='strongs'>&lt;<a href=\"%2\">%1</a>&gt;</span> ")
+ .arg(val+1)
+ .arg(swordUrlForSearch(HEBREWSTRONGS, val+1, m_swordoptions))
+ .utf8());
+ }
+ } while (++i < count);
+ }
+ if ((attrib = tag.getAttribute("morph"))) {
+ int count = tag.getAttributePartCount("morph");
+ int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0
+ do {
+ attrib = tag.getAttribute("morph", i);
+ if (i < 0) i = 0; // to handle our -1 condition
+ val = strchr(attrib, ':');
+ val = (val) ? (val + 1) : attrib;
+ if (!strncmp(attrib, "x-Robinson",10)) { //robinson codes
+ buf.append(QString(" <span class='morph'>(<a href=\"%2\">%1</a>)</span> ")
+ .arg(val)
+ .arg(swordUrlForSearch(GREEKMORPH, val, m_swordoptions))
+ .utf8());
+ } else if ((*val == 'T')) {
+ if (val[1] == 'G') {
+ buf.append(QString(" <span class='morph'>(<a href=\"%2\">%1</a>)</span> ")
+ .arg(val+1)
+ .arg(swordUrlForSearch(GREEKMORPH, val+1, m_swordoptions))
+ .utf8());
+ } else if (val[1] == 'H') {
+ buf.append(QString(" <span class='morph'>(<a href=\"%2\">%1</a>)</span> ")
+ .arg(val+1)
+ .arg(swordUrlForSearch(HEBREWMORPH, val+1, m_swordoptions))
+ .utf8());
+ }
+ }
+ } while (++i < count);
+ }
+ if ((attrib = tag.getAttribute("POS"))) {
+ val = strchr(attrib, ':');
+ val = (val) ? (val + 1) : attrib;
+ buf.appendFormatted(" %s", val);
+ }
+ }
+ }
+
+ // <note> tag
+ // FIXME - needs to be modified for Kio-Sword
+ else if (!strcmp(tag.getName(), "note")) {
+ if (!tag.isEndTag()) {
+ if (!tag.isEmpty()) {
+ SWBuf type = tag.getAttribute("type");
+
+ if (type != "strongsMarkup") { // leave strong's markup notes out, in the future we'll probably have different option filters to turn different note types on or off
+ SWBuf footnoteNumber = tag.getAttribute("swordFootnote");
+ VerseKey *vkey;
+ // see if we have a VerseKey * or descendant
+ try {
+ vkey = SWDYNAMIC_CAST(VerseKey, u->key);
+ }
+ catch ( ... ) { }
+ if (vkey) {
+ char ch = ((tag.getAttribute("type") && ((!strcmp(tag.getAttribute("type"), "crossReference")) || (!strcmp(tag.getAttribute("type"), "x-cross-ref")))) ? 'x':'n');
+ buf.appendFormatted("<a href=\"noteID=%s.%c.%s\"><small><sup>*%c</sup></small></a> ", vkey->getText(), ch, footnoteNumber.c_str(), ch);
+ }
+ }
+ u->suspendTextPassThru = true;
+ }
+ }
+ if (tag.isEndTag()) {
+ u->suspendTextPassThru = false;
+ }
+ }
+
+ // <p> paragraph tag
+ else if (!strcmp(tag.getName(), "p")) {
+ if ((!tag.isEndTag()) && (!tag.isEmpty())) { // non-empty start tag
+ buf += "<p>";
+ }
+ else if (tag.isEndTag()) { // end tag
+ buf += "</P>";
+ userData->supressAdjacentWhitespace = true;
+ }
+ else { // empty paragraph break marker
+ buf += "<br />";
+ userData->supressAdjacentWhitespace = true;
+ }
+ }
+
+ // FIXME - needs to be modified for Kio-Sword
+ // <reference> tag
+ else if (!strcmp(tag.getName(), "reference")) {
+ if ((!tag.isEndTag()) && (!tag.isEmpty())) {
+ buf += "<a href=\"\">";
+ }
+ else if (tag.isEndTag()) {
+ buf += "</a>";
+ }
+ }
+
+ // <l> poetry, etc
+ else if (!strcmp(tag.getName(), "l")) {
+ if (tag.isEmpty()) {
+ buf += "<br />";
+ }
+ else if (tag.isEndTag()) {
+ buf += "<br />";
+ }
+ else if (tag.getAttribute("sID")) { // empty line marker
+ buf += "<br />";
+ }
+ }
+
+ // <milestone type="line"/>
+ else if ((!strcmp(tag.getName(), "milestone")) && (tag.getAttribute("type")) && (!strcmp(tag.getAttribute("type"), "line"))) {
+ buf += "<br />";
+ userData->supressAdjacentWhitespace = true;
+ }
+
+ // <title>
+ else if (!strcmp(tag.getName(), "title")) {
+ if ((!tag.isEndTag()) && (!tag.isEmpty())) {
+ buf += "<div class='title'>";
+ }
+ else if (tag.isEndTag()) {
+ buf += "</div>";
+ }
+ }
+
+ // <hi> hi? hi contrast?
+ else if (!strcmp(tag.getName(), "hi")) {
+ SWBuf type = tag.getAttribute("type");
+ if ((!tag.isEndTag()) && (!tag.isEmpty())) {
+ if (type == "b" || type == "x-b") {
+ buf += "<b>";
+ u->inBold = true;
+ }
+ else { // all other types
+ buf += "<i>";
+ u->inBold = false;
+ }
+ }
+ else if (tag.isEndTag()) {
+ if(u->inBold) {
+ buf += "</b>";
+ u->inBold = false;
+ }
+ else
+ buf += "</i>";
+ }
+ else { // empty hi marker
+ // what to do? is this even valid?
+ }
+ }
+
+ // <q> quote
+ else if (!strcmp(tag.getName(), "q")) {
+ SWBuf type = tag.getAttribute("type");
+ SWBuf who = tag.getAttribute("who");
+ const char *lev = tag.getAttribute("level");
+ int level = (lev) ? atoi(lev) : 1;
+
+ if ((!tag.isEndTag()) && (!tag.isEmpty())) {
+ /*buf += "{";*/
+
+ //alternate " and '
+ if (u->osisQToTick)
+ buf += (level % 2) ? '\"' : '\'';
+
+ if (who == "Jesus")
+ buf += "<span class='jesusquote'>";
+ else
+ buf += "<span class='quote'>";
+ }
+ else if (tag.isEndTag()) {
+ buf += "</span>";
+
+ //alternate " and '
+ if (u->osisQToTick)
+ buf += (level % 2) ? '\"' : '\'';
+
+ }
+ else { // empty quote marker
+ //alternate " and '
+ if (u->osisQToTick)
+ buf += (level % 2) ? '\"' : '\'';
+ }
+ }
+
+ // <transChange>
+ else if (!strcmp(tag.getName(), "transChange")) {
+ SWBuf type = tag.getAttribute("type");
+
+ if ((!tag.isEndTag()) && (!tag.isEmpty())) {
+
+ // just do all transChange tags this way for now
+ // if (type == "supplied")
+ buf += "<i>";
+ }
+ else if (tag.isEndTag()) {
+ buf += "</i>";
+ }
+ else { // empty transChange marker?
+ }
+ }
+
+ // FIXME - remove for Kio-Sword?
+ // image
+ else if (!strcmp(tag.getName(), "figure")) {
+ const char *src = tag.getAttribute("src");
+ if (!src) // assert we have a src attribute
+ return false;
+
+ char* filepath = new char[strlen(u->module->getConfigEntry("AbsoluteDataPath")) + strlen(token)];
+ *filepath = 0;
+ strcpy(filepath, userData->module->getConfigEntry("AbsoluteDataPath"));
+ strcat(filepath, src);
+
+ // we do this because BibleCS looks for this EXACT format for an image tag
+ buf+="<image src=\"";
+ buf+=filepath;
+ buf+="\" />";
+ /*
+ char imgc;
+ for (c = filepath + strlen(filepath); c > filepath && *c != '.'; c--);
+ c++;
+ FILE* imgfile;
+ if (strcasecmp(c, "jpg") || stricmp(c, "jpeg")) {
+ imgfile = fopen(filepath, "r");
+ if (imgfile != NULL) {
+ buf += "{\\nonshppict {\\pict\\jpegblip ";
+ while (feof(imgfile) != EOF) {
+ buf.appendFormatted("%2x", fgetc(imgfile));
+ }
+ fclose(imgfile);
+ buf += "}}";
+ }
+ }
+ else if (strcasecmp(c, "png")) {
+ buf += "{\\*\\shppict {\\pict\\pngblip ";
+
+ buf += "}}";
+ }
+ */
+ delete [] filepath;
+ }
+
+ else {
+ return false; // we still didn't handle token
+ }
+ }
+ return true;
+ }
+}