[sword-svn] r2138 - trunk/utilities
dmsmith at www.crosswire.org
dmsmith at www.crosswire.org
Thu Feb 28 13:31:45 MST 2008
Author: dmsmith
Date: 2008-02-28 13:31:44 -0700 (Thu, 28 Feb 2008)
New Revision: 2138
Modified:
trunk/utilities/osis2mod.cpp
Log:
osis2mod now handle osisRefs, workids and commentaries
Modified: trunk/utilities/osis2mod.cpp
===================================================================
--- trunk/utilities/osis2mod.cpp 2008-02-28 10:28:02 UTC (rev 2137)
+++ trunk/utilities/osis2mod.cpp 2008-02-28 20:31:44 UTC (rev 2138)
@@ -32,6 +32,9 @@
// Debug for simple transformation stack
//#define DEBUG2
+// Debug for parsing osisRefs
+//#define DEBUG3
+
#ifndef NO_SWORD_NAMESPACE
using namespace sword;
#endif
@@ -71,20 +74,123 @@
return match;
}
-// remove subverse elements from osisIDs
-void deleteSubverses(SWBuf &buf) {
- for (int i = 0; buf[i]; i++) {
- if (buf[i] == '!') {
- while (buf[i] && buf[i] != ' ') {
- buf[i] = ' ';
- i++;
+// This routine converts an osisID or osisRef into one that SWORD can parse into a verse list
+// An osisRef is made up of:
+// a single osisID
+// an osisID-osisID
+// or
+// an osisRef osisRef
+//
+// An osisID can have a work prefix which is terminated by a : and may have a grain
+// which is started by a !
+//
+// However, SWORD cannot handle work prefixes or grains and expects ranges to be
+// separated with a single;
+void prepareSWVerseKey(SWBuf &buf) {
+ // This routine modifies the buf in place
+ char* s = buf.getRawData();
+ char* p = s;
+ bool inRange = false;
+ while (*p) {
+ if (inRange) {
+#ifdef DEBUG3
+ cout << "Copy range marker:" << *p << endl;;
+#endif
+ // Range markers are copied as is
+ *s++ = *p++;
+ }
+
+ // Look ahead to see if we are in a work prefix
+ // but don't look past an osisID
+ char *n = p;
+ while (*n && *n != ':' && *n != ' ' && *n != '-') {
+ n++;
+ }
+
+ // We have found a work prefix
+ if (*n == ':') {
+ // set p to skip the work prefix
+ p = n + 1;
+#ifdef DEBUG3
+ cout << "Found a work prefix ";
+ for (char *x = s; x <= n; x++) {
+ cout << *x;
}
- i--;
+ cout << endl;
+#endif
}
+
+ // Now we are in the meat of an osisID.
+ // Copy it to its end but stop on a grain marker of '!'
+#ifdef DEBUG3
+ cout << "Copy osisID:";
+#endif
+ while (*p && *p != '!' && *p != ' ' && *p != '-') {
+#ifdef DEBUG3
+ cout << *p;
+#endif
+ *s++ = *p++;
+ }
+#ifdef DEBUG3
+ cout << endl;
+#endif
+
+ // The ! and everything following until we hit
+ // the end of the osisID is part of the grain reference
+ if (*p == '!') {
+ n = p;
+ while (*n && *n != ' ' && *n != '-') {
+ n++;
+ }
+#ifdef DEBUG3
+ cout << "Found a grain suffix ";
+ for (char *x = p; x < n; x++) {
+ cout << *x;
+ }
+ cout << endl;
+#endif
+ p = n;
+ }
+
+ // At this point we have processed an osisID
+
+ // if we are not in a range and the next characer is a -
+ // then we are entering a range
+ inRange = !inRange && *p == '-';
+
+#ifdef DEBUG3
+ if (inRange) {
+ cout << "Found a range" << endl;
+ }
+#endif
+
+ // between ranges and stand alone osisIDs we might have whitespace
+ if (!inRange && *p == ' ') {
+ // skip this and subsequent spaces
+ while (*p == ' ') {
+ p++;
+ }
+ // replacing them all with a ';'
+ *s++ = ';';
+#ifdef DEBUG3
+ cout << "replacing space with ;. Remaining: " << p << endl;
+#endif
+ }
}
+
+ // Determine whether we have modified the buffer
+ // We have modified the buffer if s is not sitting on the null byte of the original
+ if (*s) {
+ // null terminate the reference
+ *s = '\0';
+ // Since we modified the swbuf, we need to tell it what we have done
+ buf.setSize(s - buf.c_str());
+#ifdef DEBUG3
+ cout << "shortended keyVal to`" << buf.c_str() << "`"<< endl;
+#endif
+ }
}
-
bool isKJVRef(const char *buf) {
VerseKey vk, test;
vk.AutoNormalize(0);
@@ -299,8 +405,9 @@
#endif
}
- //-- WITH OSIS ID -------------------------------------------------------------------------
- if (token->getAttribute("osisID")) {
+ //-- WITH OSIS ID -------------------------------------------------------------------------
+ //-- OR ANNOTATE REF -------------------------------------------------------------------------
+ if (token->getAttribute("osisID") || token->getAttribute("annotateRef")) {
// BOOK START
if ((!strcmp(tokenName, "div")) && (typeAttr && !strcmp(typeAttr, "book"))) {
@@ -357,8 +464,13 @@
return true;
}
- // VERSE START
- else if (!strcmp(tokenName, "verse")) {
+ // VERSE OR COMMENTARY START
+ else if (!strcmp(tokenName, "verse") ||
+ (!strcmp(tokenName, "div") &&
+ token->getAttribute("annotateType"))) {
+#ifdef DEBUG
+ cout << "Entering verse" << endl;
+#endif
inVerse = true;
if (inChapterHeader) {
SWBuf heading = text;
@@ -399,31 +511,25 @@
inChapterHeader = false;
}
- SWBuf keyVal = token->getAttribute("osisID");
- deleteSubverses(keyVal);
+ SWBuf keyVal = token->getAttribute(strcmp(tokenName, "verse") ? "annotateRef" : "osisID");
+ prepareSWVerseKey(keyVal);
+ lastVerseIDs = currentVerse->ParseVerseList(keyVal, *currentVerse, true);
- // turn "Mat.1.1 Mat.1.2" into "Mat.1.1; Mat.1.2"
- bool skipSpace = false;
- for (int i = 0; keyVal[i]; i++) {
- if (keyVal[i] == ' ') {
- if (!skipSpace) {
- keyVal[i] = ';';
- skipSpace = true;
- }
- }
- else skipSpace = false;
+ // set currentVerse to the first value in the keyVal
+ VerseKey *element = SWDYNAMIC_CAST(VerseKey, lastVerseIDs.GetElement(0));
+ if (element) {
+ *currentVerse = element->LowerBound();
}
-
- lastVerseIDs = currentVerse->ParseVerseList(keyVal);
- if (lastVerseIDs.Count() > 1) {
- *currentVerse = lastVerseIDs.getElement(0)->getText();
- strcpy(currentOsisID, currentVerse->getOSISRef());
- }
else {
- strcpy(currentOsisID, keyVal.c_str());
- *currentVerse = currentOsisID;
+ *currentVerse = lastVerseIDs.GetElement(0);
}
+ strcpy(currentOsisID, currentVerse->getOSISRef());
+#ifdef DEBUG
+ cout << "Current verse is " << *currentVerse << endl;
+ cout << "osisID/annotateRef is adjusted to" << keyVal << endl;
+#endif
+
verseDepth = tagStack.size();
return true;
@@ -485,8 +591,8 @@
}
}
- // VERSE END
- if (!strcmp(tokenName, "verse")) {
+ // VERSE and COMMENTARY END
+ if (!strcmp(tokenName, "verse") || (inVerse && !strcmp(tokenName, "div"))) {
inVerse = false;
if (tagDepth != verseDepth) {
@@ -536,14 +642,18 @@
// If we found an osisID like osisID="Gen.1.1 Gen.1.2 Gen.1.3" we have to link Gen.1.2 and Gen.1.3 to Gen.1.1
VerseKey dest = *currentVerse;
- for (int i = 0; i < lastVerseIDs.Count(); ++i) {
- VerseKey linkKey;
- linkKey.AutoNormalize(0);
- linkKey.Headings(1); // turn on mod/testmnt/book/chap headings
- linkKey.Persist(1);
- linkKey = lastVerseIDs.getElement(i)->getText();
+ VerseKey linkKey;
+ linkKey.AutoNormalize(0);
+ linkKey.Headings(1); // turn on mod/testmnt/book/chap headings
+ linkKey.Persist(1);
+ for (lastVerseIDs = TOP; !lastVerseIDs.Error(); lastVerseIDs++) {
+ linkKey = lastVerseIDs;
- if (linkKey.Verse() != currentVerse->Verse() || linkKey.Chapter() != currentVerse->Chapter() || linkKey.Book() != currentVerse->Book() || linkKey.Testament() != currentVerse->Testament()) {
+ if (linkKey.Verse() != dest.Verse() ||
+ linkKey.Chapter() != dest.Chapter() ||
+ linkKey.Book() != dest.Book() ||
+ linkKey.Testament() != dest.Testament())
+ {
*currentVerse = linkKey;
linkToEntry(dest);
}
More information about the sword-cvs
mailing list