[sword-svn] r2353 - trunk/utilities
dmsmith at crosswire.org
dmsmith at crosswire.org
Mon Apr 27 09:19:30 MST 2009
Author: dmsmith
Date: 2009-04-27 09:19:30 -0700 (Mon, 27 Apr 2009)
New Revision: 2353
Modified:
trunk/utilities/osis2mod.cpp
Log:
fixed re-versification bug in osis2mod
Modified: trunk/utilities/osis2mod.cpp
===================================================================
--- trunk/utilities/osis2mod.cpp 2009-04-27 07:57:50 UTC (rev 2352)
+++ trunk/utilities/osis2mod.cpp 2009-04-27 16:19:30 UTC (rev 2353)
@@ -61,6 +61,9 @@
// Debug for titles
//#define DEBUG_TITLE
+// Debug for re-v11n
+//#define DEBUG_REV11N
+
//Include all tags starting with the first div in the module
//#define INCLUDE_TAGS
@@ -288,27 +291,48 @@
}
}
+/**
+ * Determine whether a verse as given is valid for the versification.
+ * This is done by comparing the before and after of normalization.
+ */
bool isValidRef(const char *buf) {
- VerseKey vk, test;
- vk.setVersificationSystem(currentVerse.getVersificationSystem());
- test.setVersificationSystem(currentVerse.getVersificationSystem());
- vk.AutoNormalize(0);
- vk.Headings(1); // turn on mod/testmnt/book/chap headings
- vk.Persist(1);
- // lets do some tests on the verse --------------
- vk = buf;
- test = buf;
+ // Create a VerseKey that does not do auto normalization
+ // Note: need to turn on headings so that a heading does not get normalized anyway
+ // And set it to the reference under question
+ VerseKey before;
+ before.setVersificationSystem(currentVerse.getVersificationSystem());
+ before.AutoNormalize(0);
+ before.Headings(1);
+ before.setText(buf);
- if (vk.Testament() && vk.Book() && vk.Chapter() && vk.Verse()) { // if we're not a heading
-#ifdef DEBUG
- cout << (const char*)vk << " == " << (const char*)test << endl;
+ // If we are a heading we must bail
+ // These will autonormalize to the last verse of the prior chapter
+ if (!before.Testament() || !before.Book() || !before.Chapter() || !before.Verse()) {
+ return true;
+ }
+
+ // Create a VerseKey that does do auto normalization
+ // And set it to the reference under question
+ VerseKey after;
+ after.setVersificationSystem(currentVerse.getVersificationSystem());
+ after.AutoNormalize(1);
+ after.setText(buf);
+
+ if (before == after)
+ {
+ return true;
+ }
+
+ // If we have gotten here the reference is not in the selected versification.
+ cout << before << " is not in the " << currentVerse.getVersificationSystem() << " versification." << endl;
+
+#ifdef DEBUG_REV11N
+ cout << "\t" << before << " normalizes to " << after << endl;
#endif
- return (vk == test);
- }
- else return true; // no check if we're a heading... Probably bad.
+
+ return false;
}
-
/**
* This routine is used to ensure that all the text in the input is saved to the module.
* Assumption: The input orders all the verses for a chapter in numerical order. Thus, any
@@ -334,39 +358,48 @@
* param key the key that may need to be adjusted
*/
void makeValidRef(VerseKey &key) {
- VerseKey saveKey;
- saveKey.setVersificationSystem(key.getVersificationSystem());
- saveKey.AutoNormalize(0);
- saveKey.Headings(1);
- saveKey = currentVerse;
+ int chapterMax = key.getChapterMax();
+ int verseMax = key.getVerseMax();
+
+#ifdef DEBUG_REV11N
+ cout << "Chapter max:" << chapterMax << ", Verse Max:" << verseMax << endl;
+#endif
+
cout << "re-versified " << key;
-#ifdef DEBUG
- cout << "\tC" << (int)(key.getChapterMax()) << ":V" << (int)(key.getVerseMax());
-#endif
- if (key.Chapter() > key.getChapterMax()) {
- key.Chapter(key.getChapterMax());
- key.Verse(key.getVerseMax());
+ // Since isValidRef returned false constrain the key to the nearest prior reference.
+ // If we are past the last chapter set the reference to the last chapter
+ if (key.Chapter() > chapterMax) {
+ key.Chapter(chapterMax);
}
- else if (key.Verse() > key.getVerseMax()) {
- key.Verse(key.getVerseMax());
- }
- currentVerse = key;
- currentVerse.ClearBounds();
- currentVerse--;
- while (!currentVerse.Error() && currentVerse.getVerse() > 0) {
- SWBuf currentText = module->getRawEntry();
- if (currentText.length()) {
- break;
- }
- currentVerse--;
+ // Either we set the chapter to the last chapter and now need to set to the last verse in the chapter
+ // Or the verse is beyond the end of the chapter.
+ // In any case we need to constrain the verse to it's chapter.
+ key.Verse(verseMax);
+
+ // There are three cases we want to handle:
+ // In the examples we are using the KJV versification where the last verse of Matt.7 is Matt.7.29.
+ // In each of these cases the out-of-versification, extra verse is Matt.7.30.
+ // 1) The "extra" verse follows the last verse in the chapter.
+ // <verse osisID="Matt.7.29">...</verse><verse osisID="Matt.7.30">...</verse>
+ // In this case re-versify Matt.7.30 as Matt.7.29.
+ //
+ // 2) The "extra" verse follows a range (a set of linked verses).
+ // <verse osisID="Matt.7.28-Matt.7.29">...</verse><verse osisID="Matt.7.30">...</verse>
+ // In this case, re-versify Matt.7.30 as Matt.7.28, the first verse in the linked set.
+ // Since we are post-poning linking, we want to re-reversify to the last entry in the module.
+ //
+ // 3) The last verse in the chapter is not in the input. There may be other verses missing as well.
+ // <verse osisID="Matt.7.8">...</verse><verse osisID="Matt.7.30">...</verse>
+ // In this case we should re-versify Matt.7.30 as Matt.7.29.
+ // However, since this and 2) are ambiguous, we'll re-reversify to the last entry in the module.
+
+ while (!key.Error() && !module->hasEntry(&key)) {
+ key.decrement(1);
}
- key = currentVerse;
cout << "\tas " << key << endl;
-
- currentVerse = saveKey;
}
void writeEntry(SWBuf &text, bool force = false) {
@@ -401,12 +434,12 @@
// If we have seen a verse and the supplied one is different then we output the collected one.
if (*activeOsisID && strcmp(activeOsisID, keyOsisID)) {
+ if (!isValidRef(lastKey)) {
+ makeValidRef(lastKey);
+ }
+
currentVerse = lastKey;
- if (!isValidRef(currentVerse)) {
- makeValidRef(currentVerse);
- }
-
#ifdef _ICU_
int utf8State = detectUTF8(activeVerseText.c_str());
if (normalize) {
@@ -497,7 +530,6 @@
strcpy(activeOsisID, keyOsisID);
}
-
void linkToEntry(VerseKey &linkKey, VerseKey &dest) {
// Only link verses that are in the versification.
@@ -772,7 +804,11 @@
// See if this osisID or annotateRef refers to more than one verse.
// If it does, save it until all verses have been seen.
// At that point we will output links.
- if (verseKeys++ != verseKeys) {
+ // This can be done by incrementing, which will produce an error
+ // if there is only one verse.
+ verseKeys.setPosition(TOP);
+ verseKeys.increment(1);
+ if (!verseKeys.Error()) {
linkedVerses.push_back(verseKeys);
}
}
More information about the sword-cvs
mailing list