[sword-cvs] sword/apps/console/diatheke osiscgi.h,NONE,1.1 osiscgi.cpp,NONE,1.1 Makefile.am,1.5,1.6 diafiltmgr.cpp,1.1,1.2 corediatheke.cpp,1.29,1.30

sword@www.crosswire.org sword@www.crosswire.org
Tue, 21 Oct 2003 20:12:14 -0700


Update of /usr/local/cvsroot/sword/apps/console/diatheke
In directory www:/tmp/cvs-serv1953

Modified Files:
	Makefile.am diafiltmgr.cpp corediatheke.cpp 
Added Files:
	osiscgi.h osiscgi.cpp 
Log Message:
improved basic OSIS support

--- NEW FILE: osiscgi.h ---
/***************************************************************************
                   osiscgi.h  -  OSIS to Diatheke/CGI format
                             -------------------
    begin                : 2003-10-21
    copyright            : 2003 by CrossWire Bible Society
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef OSISCGI_H
#define OSISCGI_H

#include <swbasicfilter.h>

#include <defs.h>

SWORD_NAMESPACE_START

/** this filter converts OSIS text to Diatheke/CGI format
 */
class SWDLLEXPORT OSISCGI : public SWBasicFilter {
private:
protected:
	class MyUserData : public BasicFilterUserData {
	public:
		bool osisQToTick;
		bool inBold;
		SWBuf w;
		SWBuf fn;
		MyUserData(const SWModule *module, const SWKey *key);
	};
	virtual BasicFilterUserData *createUserData(const SWModule *module, const SWKey *key) {
		return new MyUserData(module, key);
	}
	virtual bool handleToken(SWBuf &buf, const char *token, BasicFilterUserData *userData);
public:
	OSISCGI();
};

SWORD_NAMESPACE_END
#endif

--- NEW FILE: osiscgi.cpp ---
/***************************************************************************
                     osiscgi.cpp  -  OSIS to Diatheke/CGI format
                             -------------------
    begin                : 2003-10-21
    copyright            : 2003 by CrossWire Bible Society
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdlib.h>
#include "osiscgi.h"
#include <utilxml.h>
#include <versekey.h>
#include <swmodule.h>

SWORD_NAMESPACE_START


OSISCGI::MyUserData::MyUserData(const SWModule *module, const SWKey *key) : BasicFilterUserData(module, key) {
	osisQToTick = ((!module->getConfigEntry("OSISqToTick")) || (strcmp(module->getConfigEntry("OSISqToTick"), "false")));
}


OSISCGI::OSISCGI() {
	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 OSISCGI::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")) {

			// start <w> tag
			if ((!tag.isEmpty()) && (!tag.isEndTag())) {
				u->w = token;
			}

			// end or empty <w> tag
			else {
				bool endTag = tag.isEndTag();
				SWBuf lastText;
				bool show = true;	// to handle unplaced article in kjv2003-- temporary till combined

				if (endTag) {
					tag = u->w.c_str();
					lastText = u->lastTextNode.c_str();
				}
				else lastText = "stuff";

				const char *attrib;
				const char *val;
				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;
						const char *val2 = val;
						if ((strchr("GH", *val)) && (isdigit(val[1])))
							val2++;
						if ((!strcmp(val2, "3588")) && (lastText.length() < 1))
							show = false;
						else {
						  if (!strchr("G", *val)) {
						        buf.appendFormatted(" <small><em>&lt;<a href=\"!DIATHEKE_URL!StrongsGreek=on&verse=%s\">%s</a>&gt;</em></small> ", val2, val);
						  }
						  else {
						        buf.appendFormatted(" <small><em>&lt;<a href=\"!DIATHEKE_URL!StrongsHebrew=on&verse=%s\">%s</a>&gt;</em></small> ", val2, val);
						  }
						}
					} while (++i < count);
				}
				if ((attrib = tag.getAttribute("morph")) && (show)) {
					SWBuf savelemma = tag.getAttribute("savlm");
					if ((strstr(savelemma.c_str(), "3588")) && (lastText.length() < 1))
						show = false;
					if (show) {
						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;
							const char *val2 = val;
							if ((*val == 'T') && (strchr("GH", val[1])) && (isdigit(val[2])))
								val2+=2;
							if (!strchr("G", *val)) {
							  buf.appendFormatted(" <small><em>(;<a href=\"!DIATHEKE_URL!StrongsGreek=on&verse=%s\">%s</a>)</em></small> ", val+1, tag.getAttribute("morph"));
							}
							else if (!strchr("H", *val)) {
							  buf.appendFormatted(" <small><em>(<a href=\"!DIATHEKE_URL!StrongsHebrew=on&verse=%s\">%s</a>)</em></small> ", val+1, tag.getAttribute("morph"));
							}
							else {
							  buf.appendFormatted(" <small><em>(<a href=\"!DIATHEKE_URL!Packard=on&verse=%s\">%s</a>)</em></small> ", val, tag.getAttribute("morph"));
							}
						} while (++i < count);
					}
				}
				if (attrib = tag.getAttribute("POS")) {
					val = strchr(attrib, ':');
					val = (val) ? (val + 1) : attrib;
					buf.appendFormatted(" %s", val);
				}

				/*if (endTag)
					buf += "}";*/
			}
		}

		// <note> tag
		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"))) ? '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><br />";
			}
			else if (tag.isEndTag()) {	// end tag
				buf += "</p><br />";
				userData->supressAdjacentWhitespace = true;
			}
			else {					// empty paragraph break marker
				buf += "<p><br />";
				userData->supressAdjacentWhitespace = true;
			}
		}

		// <reference> tag
		else if (!strcmp(tag.getName(), "reference")) {
		        const char *attrib;
		        const char *val;

			if ((!tag.isEndTag()) && (!tag.isEmpty())) {
			        buf += "<a href=\"!DIATHEKE_URL!verse=";
				if (attrib = tag.getAttribute("osisRef")) {
					val = strchr(attrib, ':');
					val = (val) ? (val + 1) : attrib;
					buf.appendFormatted("%s", val);
				}
				buf += "\">";
			}
			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 += "<b>";
			}
			else if (tag.isEndTag()) {
				buf += "</b><br />";
			}
		}

		// <hi> hi?  hi contrast?
		else if (!strcmp(tag.getName(), "hi")) {
			SWBuf type = tag.getAttribute("type");
			if ((!tag.isEndTag()) && (!tag.isEmpty())) {
				if (type == "bold" || 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 += "<font color=\"red\"> ";
				}
			}
			else if (tag.isEndTag()) {
				//alternate " and '
				if (u->osisQToTick)
					buf += (level % 2) ? '\"' : '\'';
				//buf += "</font>";
			}
			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?
			}
		}

		else {
		      return false;  // we still didn't handle token
		}
	}
	return true;
}


SWORD_NAMESPACE_END

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/sword/apps/console/diatheke/Makefile.am,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Makefile.am	29 Aug 2003 06:00:16 -0000	1.5
+++ Makefile.am	22 Oct 2003 03:12:12 -0000	1.6
@@ -5,7 +5,7 @@
 bin_PROGRAMS = diatheke
 
 diatheke_SOURCES = diatheke.cpp corediatheke.cpp diathekemgr.cpp \
-	diafiltmgr.cpp thmlcgi.cpp gbfcgi.cpp
+	diafiltmgr.cpp thmlcgi.cpp gbfcgi.cpp osiscgi.cpp
 
 if ICU
 iculibs = -licui18n -licuuc
@@ -17,6 +17,7 @@
 
 diatheke_LDADD = -L$(top_builddir)/lib -lsword $(iculibs) $(lucenelibs)
 
-noinst_HEADERS = corediatheke.h diafiltmgr.h diathekemgr.h gbfcgi.h thmlcgi.h
+noinst_HEADERS = corediatheke.h diafiltmgr.h diathekemgr.h gbfcgi.h thmlcgi.h \
+	osiscgi.h
 
 include cgi/Makefile.am

Index: diafiltmgr.cpp
===================================================================
RCS file: /usr/local/cvsroot/sword/apps/console/diatheke/diafiltmgr.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- diafiltmgr.cpp	4 Dec 2001 13:54:34 -0000	1.1
+++ diafiltmgr.cpp	22 Oct 2003 03:12:12 -0000	1.2
@@ -28,12 +28,18 @@
 #include <gbfhtmlhref.h>
 #include <thmlrtf.h>
 #include <gbfrtf.h>
+#include <osisrtf.h>
+#include <osishtmlhref.h>
+#include <osisplain.h>
+#include <thmlosis.h>
+#include <gbfosis.h>
 
 #include <swmgr.h>
 
 #include "diafiltmgr.h"
 #include "thmlcgi.h"
 #include "gbfcgi.h"
+#include "osiscgi.h"
 
 DiathekeFilterMgr::DiathekeFilterMgr (char mark, char enc)
 		   : EncodingFilterMgr(enc) {
@@ -172,13 +178,13 @@
 			fromplain = NULL;
 			fromthml = new ThMLCGI();
 			fromgbf = new GBFCGI();
-			fromosis = NULL;
+			fromosis = new OSISCGI();
 			break;
                 case FMT_PLAIN:
                         fromplain = NULL;
                         fromthml = new ThMLPlain();
                         fromgbf = new GBFPlain();
-                        fromosis = NULL;
+                        fromosis = new OSISPlain();
                         break;
                 case FMT_THML:
                         fromplain = NULL;
@@ -202,18 +208,18 @@
                         fromplain = NULL;
                         fromthml = new ThMLHTMLHREF();
                         fromgbf = new GBFHTMLHREF();
-                        fromosis = NULL;
+                        fromosis = new OSISHTMLHREF();
                         break;
                 case FMT_RTF:
                         fromplain = NULL;
                         fromthml = new ThMLRTF();
                         fromgbf = new GBFRTF();
-                        fromosis = NULL;
+                        fromosis = new OSISRTF();
                         break;
                 case FMT_OSIS:
                         fromplain = NULL;
-                        fromthml = NULL;
-                        fromgbf = NULL;
+                        fromthml = new ThMLOSIS();
+                        fromgbf = new GBFOSIS();
                         fromosis = NULL;
                         break;
                 }

Index: corediatheke.cpp
===================================================================
RCS file: /usr/local/cvsroot/sword/apps/console/diatheke/corediatheke.cpp,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- corediatheke.cpp	27 Jun 2003 02:21:05 -0000	1.29
+++ corediatheke.cpp	22 Oct 2003 03:12:12 -0000	1.30
@@ -123,6 +123,8 @@
 				inputformat = FMT_GBF;
 			else if (!stricmp((char *)(*eit).second.c_str(), "ThML"))
 				inputformat = FMT_THML;
+			else if (!stricmp((char *)(*eit).second.c_str(), "OSIS"))
+				inputformat = FMT_OSIS;
 		}
 		encoding = ((eit = (*sit).second.find("Encoding")) != (*sit).second.end()) ? (*eit).second : (SWBuf)"";
 	}
@@ -136,6 +138,9 @@
 	  case FMT_GBF :
 	    *output << "GBF";
 	    break;
+	  case FMT_OSIS :
+	    *output << "OSIS";
+	    break;
 	  default:
 	    *output << "Other";
 	  }	 
@@ -380,6 +385,8 @@
 
 					if (inputformat != FMT_THML && (outputformat == FMT_HTML || outputformat == FMT_THML || outputformat == FMT_CGI))
 						*output << "<br />";
+					else if (outputformat == FMT_OSIS)
+						*output << "<milestone type=\"line\"\/>";
 					else if (outputformat == FMT_RTF)
 						*output << "\\par ";
 					else if (outputformat == FMT_GBF)
@@ -417,6 +424,8 @@
 					
 				if (inputformat != FMT_THML && (outputformat == FMT_HTML || outputformat == FMT_THML || outputformat == FMT_CGI))
 					*output << "<br />";
+				else if (outputformat == FMT_OSIS)
+					*output << "<milestone type=\"line\"\/>";
 				else if (outputformat == FMT_RTF)
 					*output << "\\par ";
 				else if (outputformat == FMT_GBF)