#!/usr/bin/env python import re, sys from collections import Counter import datetime if len(sys.argv) < 3: print 'Usage: ' + sys.argv[0] + ' ' print print 'This utility takes a number of canon_*.h-style v11n definitions and' print ' combines them into a single larger v11n system that maximizes the' print ' chapters-per-book and verses-per-chapter present within its' print ' constituent v11ns. Book order is determined by the order in which' print ' the script encounters each Bible book.' print print 'For example, to create the versification system "Max" from the' print ' files contained in the directory ./canon, you might invoke:' print ' ' + sys.argv[0] + ' Max ./canon/canon*.h' print exit() v11n = sys.argv[1] files = sys.argv[2:] bible = dict() NTbookList = list() OTbookList = list() bookName = dict() for fn in files: f = open(fn).readlines() inBooks = False inVm = False vmArray = list() localOTbookList = list() localNTbookList = list() for l in f: # This is not robust. It assumes that [on]tbooks[] precedes vm[] and # that all of the verse counts in vm[] are part of books listed in # [on]tbooks[]. In general, it assumes canon files that look like what # we include in the library and generate from v11nsys.pl. l = re.sub(r'//.*', '', l) l = re.sub(r'\s*$', '', l) if l: if re.search(r'struct sbook otbooks.*?\[\]', l): inBooks = 1 if re.search(r'struct sbook ntbooks.*?\[\]', l): inBooks = 2 elif re.search(r'int vm.*?\[\]', l): inVm = True elif (inVm or inBooks) and re.search(r'};', l): inBooks = False inVm = False elif inBooks: match = re.search(r'{"(.+?)", "(.+?)", ".+?", (\d+)},', l) if match: id = match.group(2) name = match.group(1) if id not in OTbookList and id not in NTbookList: if (inBooks == 1): OTbookList.append(id) else: NTbookList.append(id) bookName[id] = name bible[id] = Counter() if inBooks == 1: localOTbookList.append((id, int(match.group(3)))) else: localNTbookList.append((id, int(match.group(3)))) elif inVm: vmArray.append(re.findall(r'(\d+),?', l)) vmArray = sum(vmArray, []) vmArray = map(int, vmArray) #print localOTbookList #print localNTbookList #print vmArray for book,chapters in localOTbookList + localNTbookList: #print book,chapters for c in range(chapters): # update the master dictionary with the max of its current value # and the verse count for that chapter in the current v11n bible[book][c+1] = max(bible[book][c+1], vmArray.pop(0)) canonMax = open('canon_' + v11n.lower() + '.h', 'w') # print header stuff canonMax.write('/******************************************************************************\n') canonMax.write(' *\n') canonMax.write(' * canon_' + v11n.lower() + '.h - Versification data for the ' + v11n + ' system\n') canonMax.write(' *\n') canonMax.write(' * $Id$\n') canonMax.write(' *\n') canonMax.write(' * Copyright '+str(datetime.date.today().year)+' CrossWire Bible Society (http://www.crosswire.org)\n') canonMax.write(' * CrossWire Bible Society\n') canonMax.write(' * P. O. Box 2528\n') canonMax.write(' * Tempe, AZ 85280-2528\n') canonMax.write(' *\n') canonMax.write(' * This program is free software; you can redistribute it and/or modify it\n') canonMax.write(' * under the terms of the GNU General Public License as published by the\n') canonMax.write(' * Free Software Foundation version 2.\n') canonMax.write(' *\n') canonMax.write(' * This program is distributed in the hope that it will be useful, but\n') canonMax.write(' * WITHOUT ANY WARRANTY; without even the implied warranty of\n') canonMax.write(' * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n') canonMax.write(' * General Public License for more details.\n') canonMax.write(' */\n') canonMax.write('\n') canonMax.write('#ifndef CANON_' + v11n.upper() + '_H\n') canonMax.write('#define CANON_' + v11n.upper() + '_H\n') canonMax.write('\n') canonMax.write('SWORD_NAMESPACE_START\n') canonMax.write('\n') canonMax.write('\n') canonMax.write('// Versification system: ' + v11n + '\n') canonMax.write('// Book order: ' + ' '.join(OTbookList + NTbookList) + '\n') canonMax.write('\n') canonMax.write('\n') # print otbooks and ntbooks canonMax.write('/******************************************************************************\n') canonMax.write(' * [on]tbooks_' + v11n.lower() + ' - initialize static instance for all canonical\n') canonMax.write(' * text names and chapmax\n') canonMax.write(' */\n') if OTbookList: canonMax.write('struct sbook otbooks_' + v11n.lower() + '[] = {\n') for book in OTbookList: canonMax.write(' {"' + bookName[book] + '", "' + book + '", "' + book + '", ' + str(len(bible[book])) + '},\n') canonMax.write(' {"", "", "", 0}\n') canonMax.write('};\n') canonMax.write('\n') if NTbookList: canonMax.write('struct sbook ntbooks_' + v11n.lower() + '[] = {\n') for book in NTbookList: canonMax.write(' {"' + bookName[book] + '", "' + book + '", "' + book + '", ' + str(len(bible[book])) + '},\n') canonMax.write(' {"", "", "", 0}\n') canonMax.write('};\n') canonMax.write('\n') # print vm canonMax.write('/******************************************************************************\n') canonMax.write(' * Maximum verses per chapter\n') canonMax.write(' */\n') canonMax.write('int vm_' + v11n.lower() + '[] = {\n') for book in OTbookList + NTbookList: canonMax.write(' // ' + bookName[book] + '\n') verseCountList = list() for ch in range(1, len(bible[book])+1): verseCountList.append(bible[book][ch]) verseCountString = ', '.join(map(str, verseCountList)) verseCountString = re.sub(r'(([0-9]+, ){9}[0-9]+,) ', r'\1\n ', verseCountString) canonMax.write(' ' + verseCountString + ',\n') canonMax.write('};\n') canonMax.write('\n') # print footer stuff canonMax.write('SWORD_NAMESPACE_END\n') canonMax.write('#endif\n')