Index: include/canon_synodal.h =================================================================== --- include/canon_synodal.h (revision 2571) +++ include/canon_synodal.h (working copy) @@ -285,6 +285,194 @@ 20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 17, 18, 20, 8, 21, 18, 24, 21, 15, 27, 21 }; +unsigned char mappings_synodal[] = { + 3, 14, 55, 0, 14, 55, 56, + 4, 13, 1, 0, 12, 16, 0, + 4, 13, 2, 0, 13, 1, 0, + 4, 30, 1, 0, 29, 40, 0, + 4, 30, 2, 0, 30, 1, 0, + 6, 5, 16, 0, 6, 1, 0, + 6, 6, 1, 0, 6, 2, 0, + 9, 24, 1, 0, 23, 29, 0, + 9, 24, 2, 0, 24, 1, 0, + 22, 39, 31, 0, 40, 1, 0, + 22, 40, 1, 0, 40, 6, 0, + 22, 40, 20, 0, 41, 1, 0, + 22, 41, 1, 0, 41, 9, 0, + 23, 3, 1, 0, 3, 0, 0, + 23, 4, 1, 0, 4, 0, 0, + 23, 5, 1, 0, 5, 0, 0, + 23, 6, 1, 0, 6, 0, 0, + 23, 7, 1, 0, 7, 0, 0, + 23, 8, 1, 0, 8, 0, 0, + 23, 9, 1, 0, 9, 0, 0, + 23, 9, 22, 0, 10, 1, 0, + 23, 10, 1, 0, 11, 0, 1, + 23, 11, 1, 0, 12, 0, 0, + 23, 12, 1, 0, 13, 0, 0, + 23, 12, 6, 0, 13, 5, 6, + 23, 13, 1, 0, 14, 0, 1, + 23, 14, 1, 0, 15, 0, 1, + 23, 15, 1, 0, 16, 0, 1, + 23, 16, 1, 0, 17, 0, 1, + 23, 17, 1, 0, 18, 0, 0, + 23, 18, 1, 0, 19, 0, 0, + 23, 19, 1, 0, 20, 0, 0, + 23, 20, 1, 0, 21, 0, 0, + 23, 21, 1, 0, 22, 0, 0, + 23, 22, 1, 0, 23, 0, 1, + 23, 23, 1, 0, 24, 0, 1, + 23, 24, 1, 0, 25, 0, 1, + 23, 25, 1, 0, 26, 0, 1, + 23, 26, 1, 0, 27, 0, 1, + 23, 27, 1, 0, 28, 0, 1, + 23, 28, 1, 0, 29, 0, 1, + 23, 29, 1, 0, 30, 0, 0, + 23, 30, 1, 0, 31, 0, 0, + 23, 31, 1, 0, 32, 0, 1, + 23, 32, 1, 0, 33, 0, 1, + 23, 33, 1, 0, 34, 0, 0, + 23, 34, 1, 0, 35, 0, 1, + 23, 35, 1, 0, 36, 0, 0, + 23, 36, 1, 0, 37, 0, 1, + 23, 37, 1, 0, 38, 0, 0, + 23, 38, 1, 0, 39, 0, 0, + 23, 39, 1, 0, 40, 0, 0, + 23, 40, 1, 0, 41, 0, 0, + 23, 41, 1, 0, 42, 0, 0, + 23, 42, 0, 0, 43, 0, 0, + 23, 43, 1, 0, 44, 0, 0, + 23, 44, 1, 0, 45, 0, 0, + 23, 45, 1, 0, 46, 0, 0, + 23, 46, 1, 0, 47, 0, 0, + 23, 47, 1, 0, 48, 0, 0, + 23, 48, 1, 0, 49, 0, 0, + 23, 49, 0, 0, 50, 0, 0, + 23, 50, 1, 2, 51, 0, 0, + 23, 51, 1, 2, 52, 0, 0, + 23, 52, 1, 0, 53, 0, 0, + 23, 53, 1, 2, 54, 0, 0, + 23, 54, 1, 0, 55, 0, 0, + 23, 55, 1, 0, 56, 0, 0, + 23, 56, 1, 0, 57, 0, 0, + 23, 57, 1, 0, 58, 0, 0, + 23, 58, 1, 0, 59, 0, 0, + 23, 59, 1, 2, 60, 0, 0, + 23, 60, 1, 0, 61, 0, 0, + 23, 61, 1, 0, 62, 0, 0, + 23, 62, 1, 0, 63, 0, 0, + 23, 63, 1, 0, 64, 0, 0, + 23, 64, 1, 0, 65, 0, 0, + 23, 65, 1, 0, 66, 0, 1, + 23, 66, 1, 0, 67, 0, 0, + 23, 67, 1, 0, 68, 0, 0, + 23, 68, 1, 0, 69, 0, 0, + 23, 69, 1, 0, 70, 0, 0, + 23, 70, 0, 0, 71, 0, 0, + 23, 71, 0, 0, 72, 0, 0, + 23, 72, 0, 0, 73, 0, 0, + 23, 73, 0, 0, 74, 0, 0, + 23, 74, 1, 0, 75, 0, 0, + 23, 75, 1, 0, 76, 0, 0, + 23, 76, 1, 0, 77, 0, 0, + 23, 77, 0, 0, 78, 0, 0, + 23, 78, 0, 0, 79, 0, 0, + 23, 79, 1, 0, 80, 0, 0, + 23, 80, 1, 0, 81, 0, 0, + 23, 81, 0, 0, 82, 0, 0, + 23, 82, 1, 0, 83, 0, 0, + 23, 83, 1, 0, 84, 0, 0, + 23, 84, 1, 0, 85, 0, 0, + 23, 85, 0, 0, 86, 0, 0, + 23, 86, 1, 0, 87, 0, 0, + 23, 86, 2, 0, 87, 1, 2, + 23, 87, 1, 0, 88, 0, 0, + 23, 88, 1, 0, 89, 0, 0, + 23, 89, 1, 0, 90, 0, 0, + 23, 89, 6, 0, 90, 5, 6, + 23, 90, 0, 0, 91, 0, 0, + 23, 91, 1, 0, 92, 0, 0, + 23, 92, 0, 0, 93, 0, 0, + 23, 93, 0, 0, 94, 0, 0, + 23, 94, 0, 0, 95, 0, 0, + 23, 95, 0, 0, 96, 0, 0, + 23, 96, 0, 0, 97, 0, 0, + 23, 97, 0, 0, 98, 0, 0, + 23, 98, 0, 0, 99, 0, 0, + 23, 99, 0, 0, 100, 0, 0, + 23, 100, 0, 0, 101, 0, 0, + 23, 101, 1, 0, 102, 0, 0, + 23, 102, 0, 0, 103, 0, 0, + 23, 103, 0, 0, 104, 0, 0, + 23, 104, 0, 0, 105, 0, 0, + 23, 105, 0, 0, 106, 0, 0, + 23, 106, 0, 0, 107, 0, 0, + 23, 107, 1, 0, 108, 0, 0, + 23, 108, 0, 0, 109, 0, 0, + 23, 109, 0, 0, 110, 0, 0, + 23, 110, 0, 0, 111, 0, 0, + 23, 111, 0, 1, 112, 1, 0, + 23, 112, 0, 1, 113, 1, 0, + 23, 113, 0, 0, 114, 0, 0, + 23, 113, 9, 0, 115, 1, 0, + 23, 114, 0, 0, 116, 0, 0, + 23, 115, 1, 0, 116, 10, 0, + 23, 116, 0, 0, 117, 0, 0, + 23, 117, 0, 0, 118, 0, 0, + 23, 118, 0, 0, 119, 0, 0, + 23, 119, 0, 0, 120, 0, 0, + 23, 120, 0, 0, 121, 0, 0, + 23, 121, 0, 0, 122, 0, 0, + 23, 122, 0, 0, 123, 0, 0, + 23, 123, 0, 0, 124, 0, 0, + 23, 124, 0, 0, 125, 0, 0, + 23, 125, 0, 0, 126, 0, 0, + 23, 126, 0, 0, 127, 0, 0, + 23, 127, 0, 0, 128, 0, 0, + 23, 128, 0, 0, 129, 0, 0, + 23, 129, 0, 0, 130, 0, 0, + 23, 130, 0, 0, 131, 0, 0, + 23, 131, 0, 0, 132, 0, 0, + 23, 132, 0, 0, 133, 0, 0, + 23, 133, 0, 0, 134, 0, 0, + 23, 134, 0, 1, 135, 1, 0, + 23, 135, 0, 0, 136, 0, 0, + 23, 136, 0, 0, 137, 0, 0, + 23, 137, 0, 0, 138, 0, 0, + 23, 138, 0, 0, 139, 0, 0, + 23, 139, 1, 0, 140, 0, 0, + 23, 140, 0, 0, 141, 0, 0, + 23, 141, 0, 0, 142, 0, 0, + 23, 142, 0, 0, 143, 0, 0, + 23, 143, 0, 0, 144, 0, 0, + 23, 144, 0, 0, 145, 0, 0, + 23, 145, 0, 1, 146, 1, 0, + 23, 146, 0, 1, 147, 1, 0, + 23, 147, 1, 0, 147, 12, 0, + 23, 148, 0, 1, 148, 1, 0, + 23, 149, 0, 1, 149, 1, 0, + 23, 150, 0, 1, 150, 1, 0, + 25, 4, 17, 0, 5, 1, 0, + 25, 5, 1, 0, 5, 2, 0, + 26, 1, 0, 0, 1, 1, 0, + 26, 7, 1, 0, 6, 13, 0, + 26, 7, 2, 0, 7, 1, 0, + 35, 3, 24, 90, 0, 0, 0, + 35, 3, 91, 0, 3, 24, 0, + 35, 3, 98, 0, 4, 1, 0, + 35, 4, 1, 0, 4, 4, 0, + 35, 13, 0, 0, 0, 0, 0, + 35, 14, 0, 0, 0, 0, 0, + 36, 14, 1, 0, 13, 16, 0, + 36, 14, 2, 0, 14, 1, 0, + 40, 2, 1, 0, 1, 17, 0, + 40, 2, 2, 0, 2, 1, 0, + 56, 19, 40, 0, 19, 40, 41, + 64, 14, 24, 0, 16, 25, 0, + 66, 13, 12, 0, 13, 12, 13, + 62, 1, 14, 15, 1, 14, 0, + 0 +}; SWORD_NAMESPACE_END Index: include/versemgr.h =================================================================== --- include/versemgr.h (revision 2571) +++ include/versemgr.h (working copy) @@ -141,11 +141,12 @@ int getBookNumberByOSISName(const char *bookName) const; const Book *getBook(int number) const; int getBookCount() const; - void loadFromSBook(const sbook *ot, const sbook *nt, int *chMax); + void loadFromSBook(const sbook *ot, const sbook *nt, int *chMax, const unsigned char *mappings=NULL); long getOffsetFromVerse(int book, int chapter, int verse) const; char getVerseFromOffset(long offset, int *book, int *chapter, int *verse) const; const int *getBMAX() const { return BMAX; }; long getNTStartOffset() const { return ntStartOffset; } + void translateVerse(const System *dstSys, const char **book, int *chapter, int *verse, int *verse_end) const; }; VerseMgr() { init(); } ~VerseMgr(); @@ -153,7 +154,7 @@ static void setSystemVerseMgr(VerseMgr *newVerseMgr); const StringList getVersificationSystems() const; const System *getVersificationSystem(const char *name) const; - void registerVersificationSystem(const char *name, const sbook *ot, const sbook *nt, int *chMax); + void registerVersificationSystem(const char *name, const sbook *ot, const sbook *nt, int *chMax, const unsigned char *mappings=NULL); void registerVersificationSystem(const char *name, const TreeKey *); }; Index: src/keys/versekey.cpp =================================================================== --- src/keys/versekey.cpp (revision 2571) +++ src/keys/versekey.cpp (working copy) @@ -119,20 +119,52 @@ */ void VerseKey::setFromOther(const VerseKey &ikey) { - if (refSys == ikey.refSys) { - testament = ikey.Testament(); - book = ikey.Book(); - chapter = ikey.Chapter(); - verse = ikey.Verse(); - suffix = ikey.getSuffix(); + if (refSys == ikey.refSys) { + testament = ikey.Testament(); + book = ikey.Book(); + chapter = ikey.Chapter(); + verse = ikey.Verse(); + suffix = ikey.getSuffix(); + } + else { + // map verse between systems + // TODO if range is greater then chapter + // maybe negative and greater then chap-max numbers + if (refSys->getBookNumberByOSISName(ikey.getOSISBookName()) == -1) + // TODO set key to error or empty + return; + + const char* map_book = ikey.getOSISBookName(); + int map_chapter = ikey.Chapter(); + // TODO range handling + int map_verse = ikey.Verse(); + int map_range = map_verse; + + ikey.refSys->translateVerse(refSys, &map_book, &map_chapter, &map_verse, &map_range); + //printf("verse: %s.%i.%i-%i\n",map_book,map_chapter,map_verse,map_range); + + // TODO check key existence in v11n + book = refSys->getBookNumberByOSISName(map_book); + if (book <= -1) + error = KEYERR_OUTOFBOUNDS; + if (book > BMAX[0]) + book -= BMAX[0], testament = 2; + else + testament = 1; + chapter = map_chapter; + // TODO howto position on headings? + //if (map_verse < 1) + // Headings(1); + verse = map_verse; + suffix = ikey.getSuffix(); + // TODO range handling + if (map_verse < map_range) { + LowerBound(this); + UpperBound(this); + UpperBound().verse = map_range; } - // Here is where we will do v11n system conversions in the future - // when we have a conversion mechanism (Ben Morgan has started - // thinking about this) - else { - // For now, this is the best we can do - setText(ikey.getText()); - } + // Normalize(1) ? + } } Index: src/mgr/versemgr.cpp =================================================================== --- src/mgr/versemgr.cpp (revision 2571) +++ src/mgr/versemgr.cpp (working copy) @@ -60,7 +60,7 @@ systemVerseMgr->registerVersificationSystem("KJVA", otbooks_kjva, ntbooks, vm_kjva); systemVerseMgr->registerVersificationSystem("NRSV", otbooks, ntbooks, vm_nrsv); systemVerseMgr->registerVersificationSystem("NRSVA", otbooks_nrsva, ntbooks, vm_nrsva); - systemVerseMgr->registerVersificationSystem("Synodal", otbooks_synodal, ntbooks_synodal, vm_synodal); + systemVerseMgr->registerVersificationSystem("Synodal", otbooks_synodal, ntbooks_synodal, vm_synodal, mappings_synodal); systemVerseMgr->registerVersificationSystem("Vulg", otbooks_vulg, ntbooks_vulg, vm_vulg); systemVerseMgr->registerVersificationSystem("German", otbooks_german, ntbooks, vm_german); systemVerseMgr->registerVersificationSystem("Luther", otbooks_luther, ntbooks_luther, vm_luther); @@ -77,6 +77,18 @@ /** Array[chapmax] of maximum verses in chapters */ vector books; map osisLookup; + /** General mapping rule is that first verse of every chapter corresponds first + verse of another chapter in default intermediate canon(kjva), so mapping data + contains expections. Intermediate canon could not contain corresponding data. + + pointers on uchar[7]: 1 value - book id 1-based, ot+nt, 2-4 map to, 5-7 map + from (chap,verse from, verse to if greater then "verse from") + + TODO what if book name in one v11n differs from cannon + special section in mapping for book transformation + */ + vector> mappings; + vector book_mappings; Private() { } @@ -168,7 +180,7 @@ } -void VerseMgr::System::loadFromSBook(const sbook *ot, const sbook *nt, int *chMax) { +void VerseMgr::System::loadFromSBook(const sbook *ot, const sbook *nt, int *chMax, const unsigned char *mappings) { int chap = 0; int book = 0; long offset = 0; // module heading @@ -208,6 +220,25 @@ BMAX[1] = book; // TODO: build offset speed array + + // parse mappings + if (mappings != NULL) { + p->mappings.resize(p->books.size()); + + bool skip = false; + for (const unsigned char *m=mappings; *m != 0; m += 7) { + //if (skip) + // if (strlen(m) < 7) + // skip = false; + //else if (m[1] == 0 && m[2] == 255 && m[3] == 0) { + // p->books[m[0]-1].p->map_book = m[4]; + // skip = true; + //} + //else + //p->books[*m-1].p->mappings.push_back(m); + p->mappings[(*m)-1].push_back(m); + } + } } @@ -360,10 +391,10 @@ } -void VerseMgr::registerVersificationSystem(const char *name, const sbook *ot, const sbook *nt, int *chMax) { +void VerseMgr::registerVersificationSystem(const char *name, const sbook *ot, const sbook *nt, int *chMax, const unsigned char *mappings) { p->systems[name] = name; System &s = p->systems[name]; - s.loadFromSBook(ot, nt, chMax); + s.loadFromSBook(ot, nt, chMax, mappings); } @@ -379,5 +410,87 @@ return retVal; } +void VerseMgr::System::translateVerse(const System *dstSys, const char **book, int *chapter, int *verse, int *verse_end) const { + //printf("translate verse from %s to %s: %s.%i.%i-%i\n",getName(), dstSys->getName(), *book, *chapter, *verse, *verse_end); + if (this == dstSys) + return; + if (!strcmp(getName(),"KJVA") || !strcmp(getName(),"KJV")) { + if (!strcmp(dstSys->getName(),"KJVA") || !strcmp(dstSys->getName(),"KJV")) + return; + // reversed mapping + //printf("Perform reversed mapping.\n"); + const int b = dstSys->getBookNumberByOSISName(*book)-1; + if (b >= (int)dstSys->p->mappings.size()) + return; + const unsigned char *a = NULL; + for (int i=dstSys->p->mappings[b].size()-1; i>=0; --i) { + const unsigned char *m = dstSys->p->mappings[b][i]; + if (m[4] == *chapter && m[5] <= *verse) { + //printf("found mapping %i %i %i %i %i %i\n",m[1],m[2],m[3],m[4],m[5],m[6]); + if (m[5] == *verse || (m[6] >= *verse && m[5] <= *verse)) { + // inside of any mapping range + (*chapter) = m[1]; + (*verse) = m[2]; + (*verse_end) = m[3]; + return; + } + if (a == NULL || (a[5]>a[6]?a[5]:a[6]) < (m[5]>m[6]?m[5]:m[6])) + a = m; + } + } + if (a != NULL) { + //printf("set appropriate: %i %i %i %i %i %i\n",a[1],a[2],a[3],a[4],a[5],a[6]); + (*chapter) = a[1]; + // shift verse + const int d = (a[3]>a[2]?a[3]:a[2])-(a[6]>a[5]?a[6]:a[5]); + if ((*verse) < (*verse_end)) + (*verse_end) += d; + else + (*verse_end) = (*verse) + d; + (*verse) += d; + return; + } + //printf("There is no mapping.\n"); + } + else if (strcmp(dstSys->getName(),"KJVA") && strcmp(dstSys->getName(),"KJV")) { + const System *kjva = getSystemVerseMgr()->getVersificationSystem("KJVA"); + translateVerse(kjva, book, chapter, verse, verse_end); + kjva->translateVerse(dstSys, book, chapter, verse, verse_end); + } + else { + // forward mapping + //printf("Perform forward mapping.\n"); + const int b = getBookNumberByOSISName(*book)-1; + if (b >= (int)p->mappings.size()) + return; + for (int i=p->mappings[b].size()-1; i>=0; --i) { + const unsigned char *m = p->mappings[b][i]; + if (m[1] < *chapter) { + //printf("There is no mapping for this chapter.\n"); + return; + } + if (m[1] == *chapter && m[2] <= *verse) { + //printf("found mapping %i %i %i %i %i %i\n",m[1],m[2],m[3],m[4],m[5],m[6]); + if (m[2] == *verse || (m[3] >= *verse && m[2] <= *verse)) { + (*chapter) = m[4]; + (*verse) = m[5]; + (*verse_end) = m[6]; + } + else { + (*chapter) = m[4]; + // shift verse + const int d = (m[6]>m[5]?m[6]:m[5])-(m[3]>m[2]?m[3]:m[2]); + if ((*verse) < (*verse_end)) + (*verse_end) += d; + else + (*verse_end) = (*verse) + d; + (*verse) += d; + } + return; + } + } + //printf("No mapping.\n"); + } +} SWORD_NAMESPACE_END