diff options
Diffstat (limited to 'src/modules/texts')
30 files changed, 7313 insertions, 0 deletions
diff --git a/src/modules/texts/Makefile b/src/modules/texts/Makefile new file mode 100644 index 0000000..1a2d00d --- /dev/null +++ b/src/modules/texts/Makefile @@ -0,0 +1,5 @@ + +root := ../../.. + +all: + make -C ${root} diff --git a/src/modules/texts/Makefile.am b/src/modules/texts/Makefile.am new file mode 100644 index 0000000..b48d93e --- /dev/null +++ b/src/modules/texts/Makefile.am @@ -0,0 +1,7 @@ +textsdir = $(top_srcdir)/src/modules/texts + +libsword_la_SOURCES += $(textsdir)/swtext.cpp + +include ../src/modules/texts/rawtext/Makefile.am +include ../src/modules/texts/ztext/Makefile.am +include ../src/modules/texts/rawgbf/Makefile.am diff --git a/src/modules/texts/rawgbf/Gbf.c b/src/modules/texts/rawgbf/Gbf.c new file mode 100644 index 0000000..2b7f786 --- /dev/null +++ b/src/modules/texts/rawgbf/Gbf.c @@ -0,0 +1,485 @@ +/* Output from p2c, the Pascal-to-C translator */ +/* From input file "Gbf.pas" */ + + +#include <p2c/p2c.h> + + +typedef enum { + tokNull, tokEOF, tokHeader, tokContent, tokTail, tokStyle, tokWord, + tokSpace, tokSync, tokControl, tokChar, tokFont +} TToken; +typedef enum { + caBold, caSmallCaps, caItalic, caOTQuote, caRed, caSuperscript, caUnderline, + caSubscript +} TCharacterAttribute; +typedef long TCharAttribs; + + + +typedef struct TBookNameRec { + Char Name[256], Abbr[256]; + uchar Num; +} TBookNameRec; + +typedef TBookNameRec TBookAbbr[116]; + + +typedef struct TReadGBF { + /* private*/ + FILE *F; + Char FName[256], TokenLine[256]; + long TokenPos; + boolean fFileIsOpen, fParagraphEnd, fInTitle, fInPsalmBookTitle, + fInHebrewTitle, fInSectionTitle; + + /* public*/ + Char sBook[256], sChapter[256], sVerse[256], sMode[256]; + Char sContext[256]; /*// Last text type (header, body, or tail)*/ + Char sTitle[256]; /*// Title of this book of the Bible*/ + Char sPsalmBookTitle[256]; /*// Title of this Psalm book*/ + Char sHebrewTitle[256]; /*// Psalm Hebrew title*/ + Char sSectionTitle[256]; /*// Section headings*/ + Char sDate[256], sFontName[256]; + long iTotalWords; + Char chJustification, chDirection; + boolean fIndent, fPoetry; + TCharAttribs CharAttribs; + uchar bBk, bChap, bVs, bWd; + /* + function Init({const*/ + /*sFileName: string): boolean; + procedure Done; + function GetToken(var TokenKind: TToken): string; + */ +} TReadGBF; + +typedef struct TWriteGBF { + /* private*/ + FILE *F; + Char FName[256], LineOut[256]; + boolean fFileIsOpen; + uchar bBk, bChap, bVs, bWd; + + /* public*/ + /* + function Init({const*/ + /*sFileName: string): boolean; + function Done: boolean; + procedure Out({const*/ + /*s: string); +*/ +} TWriteGBF; + +/*implementation */ + + +/*//0*/ +/*//1*/ +/*//2*/ +/*//3*/ +/*//4*/ +/*//5*/ +/*//6*/ +/*//7*/ +/*//8*/ +/*//9*/ +/*//10*/ +/*//11*/ +/*//12*/ +/*//13*/ +/*//14*/ +/*//15*/ +/*//16*/ +/*//17*/ +/*//18*/ +/*//19*/ +/*//20*/ +/*//21*/ +/*//22*/ +/*//0*/ +/*//1*/ +/*//2*/ +/*//3*/ +/*//4*/ +/*//5*/ +/*//6*/ +/*//7*/ +/*//8*/ +/*//9*/ +/*//10*/ +/*//11*/ +/*//12*/ +/*//13*/ +/*//14*/ +/*//15*/ +/*//16*/ +/*//17*/ +/*//18*/ +/*//19*/ +/*//20*/ +/*//21*/ +/*//22*/ +/*//23*/ +/*//24*/ +/*//26*/ +/*//27*/ +/*//28*/ +/*//29*/ +/*//30*/ +/*//31*/ +/*//32*/ +/*//33*/ +/*//34*/ +/*//35*/ +/*//36*/ +/*//37*/ +/*//38*/ +/*//39*/ +/*//40*/ +/*//41*/ +/*//42*/ +/*//43*/ +/*//44*/ +/*//45*/ +/*//46*/ +/*//47*/ +/*//48*/ +/*//49*/ +/*//50*/ +/*//51*/ +/*//52*/ +/*//53*/ +/*//54*/ +/*//55*/ +/*//56*/ +/*//57*/ +/*//58*/ +/*//59*/ +/*//60*/ +/*//61*/ +/*//62*/ +/*//63*/ +/*//64*/ +/*//65*/ +/*//66*/ +/*//67*/ +/*//68*/ +/*//69*/ +/*//70*/ +/*//71*/ +/*//72*/ +/*//73*/ +/*//74*/ +/*//75*/ +/*//76*/ +/*//77*/ +/*//78*/ +/*//79*/ +/*//80*/ +/*//81*/ +/*//82*/ +/*//83*/ +/*//84*/ +/*//85*/ +/*//86*/ +/*//87*/ +/*//88*/ +/*//89*/ +/*//90*/ +/*//91*/ +/*//92*/ + +Static TBookAbbr BookAbbr = { + { "1 Chronicles", "1CH", 13 }, + { "1 Corinthians", "1CO", 70 }, + { "1 Esdras", "1E", 52 }, + { "1 John", "1J", 86 }, + { "1 Kings", "1K", 11 }, + { "1 Maccabees", "1M", 50 }, + { "1 Peter", "1P", 84 }, + { "1 Samuel", "1S", 9 }, + { "1 Thessalonians", "1TH", 76 }, + { "1 Timothy", "1TI", 78 }, + { "2 Chronicles", "2CH", 14 }, + { "2 Corinthians", "2CO", 71 }, + { "2 Esdras", "2E", 56 }, + { "2 John", "2J", 87 }, + { "2 Kings", "2K", 12 }, + { "2 Maccabees", "2M", 51 }, + { "2 Peter", "2P", 85 }, + { "2 Samuel", "2S", 10 }, + { "2 Thessalonians", "2TH", 77 }, + { "2 Timothy", "2TI", 79 }, + { "3 John", "3J", 88 }, + { "3 Maccabees", "3M", 55 }, + { "4 Maccabees", "4M", 57 }, + { "1 Chronicles", "1 CH", 13 }, + { "1 Corinthians", "1 CO", 70 }, + { "1 Esdras", "1 E", 52 }, + { "1 John", "1 J", 86 }, + { "1 Kings", "1 K", 11 }, + { "1 Maccabees", "1 M", 50 }, + { "1 Peter", "1 P", 84 }, + { "1 Samuel", "1 S", 9 }, + { "1 Thessalonians", "1 TH", 76 }, + { "1 Timothy", "1 TI", 78 }, + { "2 Chronicles", "2 CH", 14 }, + { "2 Corinthians", "2 CO", 71 }, + { "2 Esdras", "2 E", 56 }, + { "2 John", "2 J", 87 }, + { "2 Kings", "2 K", 12 }, + { "2 Maccabees", "2 M", 51 }, + { "2 Peter", "2 P", 85 }, + { "2 Samuel", "2 S", 10 }, + { "2 Thessalonians", "2 TH", 77 }, + { "2 Timothy", "2 TI", 79 }, + { "3 John", "3 J", 88 }, + { "3 Maccabees", "3 M", 55 }, + { "4 Maccabees", "4 M", 57 }, + { "Acts", "AC", 68 }, + { "Amos", "AM", 30 }, + { "Prayer of Asariah and the Song of the Three Jews", "AZ", 47 }, + { "Baruch", "BA", 45 }, + { "Bel and the Dragon", "BE", 49 }, + { "Colossians", "CO", 75 }, + { "Daniel", "DA", 27 }, + { "Deuteronomy", "DE", 5 }, + { "Deuteronomy", "DT", 5 }, + { "Ecclesiasties", "EC", 21 }, + { "Esther", "ES", 17 }, + { "Exodus", "EX", 2 }, + { "Ezekiel", "EZE", 26 }, + { "Ezra", "EZR", 15 }, + { "Galatians", "GA", 72 }, + { "Genesis", "GE", 1 }, + { "Genesis", "GN", 1 }, + { "Ephesians", "EP", 73 }, + { "Esther (Greek)", "GR", 42 }, + { "Habakkuk", "HAB", 35 }, + { "Haggai", "HAG", 37 }, + { "Hebrews", "HE", 82 }, + { "Hosea", "HO", 28 }, + { "Isaiah", "IS", 23 }, + { "James", "JA", 83 }, + { "Jeremiah", "JE", 24 }, + { "Job", "JOB", 18 }, + { "Joel", "JOE", 29 }, + { "John", "JOH", 67 }, + { "Jonah", "JON", 32 }, + { "Joshua", "JOS", 6 }, + { "Jude", "JUDE", 89 }, + { "Judges", "JUDG", 7 }, + { "Judith", "JUDI", 41 }, + { "Lamentations", "LA", 25 }, + { "Letter of Jeremiah", "LET", 46 }, + { "Leviticus", "LEV", 3 }, + { "Luke", "LK", 66 }, + { "Leviticus", "LV", 3 }, + { "Luke", "LU", 66 }, + { "Malachi", "MAL", 39 }, + { "Prayer of Manasseh", "MAN", 53 }, + { "Mark", "MAR", 65 }, + { "Matthew", "MAT", 64 }, + { "Micah", "MI", 33 }, + { "Nahum", "NA", 34 }, + { "Nehemiah", "NE", 16 }, + { "Numbers", "NU", 4 }, + { "Obadiah", "OB", 31 }, + { "Psalm 151", "P1", 54 }, + { "Philemon", "PHILE", 81 }, + { "Philippians", "PHILI", 74 }, + { "Philemon", "PHM", 81 }, + { "Philippians", "PHP", 74 }, + { "Proverbs", "PR", 20 }, + { "Psalms", "PS", 19 }, + { "Revelation", "RE", 90 }, + { "Romans", "RM", 69 }, + { "Romans", "RO", 69 }, + { "Ruth", "RU", 8 }, + { "Sirach", "SI", 44 }, + { "Song of Solomon", "SOL", 22 }, + { "Song of Solomon", "SON", 22 }, + { "Song of Solomon", "SS", 22 }, + { "Susanna", "SU", 48 }, + { "Titus", "TI", 80 }, + { "Tobit", "TO", 40 }, + { "Wisdom", "WI", 43 }, + { "Zechariah", "ZEC", 38 }, + { "Zephaniah", "ZEP", 36 } +}; + +/*// 0 - 7*/ +/*// 8 - 14*/ +/*// 15-20*/ +/*// 21-26*/ +/*// 27-33*/ +/*// 34-39*/ +/*// 40-45*/ +/*// 46-52*/ +/*// 53-63*/ +/*// 64-70*/ +/*// 71-78*/ +/*// 79-84*/ + +Static Char BookFileName[91][256] = { + "", "Genesis", "Exodus", "Lev", "Num", "Deut", "Joshua", "Judges", "Ruth", + "1Sam", "2Sam", "1Kings", "2Kings", "1Chron", "2Chron", "Ezra", "Nehemiah", + "Esther", "Job", "Psalms", "Proverbs", "Eccl", "Song", "Isaiah", "Jeremiah", + "Lament", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos", "Obadiah", "Jonah", + "Micah", "Nahum", "Habakkuk", "Zeph", "Haggai", "Zech", "Malachi", "Tobit", + "Judith", "Esther", "Wisdom", "Sirach", "Baruch", "Let", "Azar", "Susanna", + "Bel", "1Mac", "2Mac", "1Esdras", "Man", "P1", "3Mac", "2Esdras", "4Mac", + "", "", "", "", "", "", "Matthew", "Mark", "Luke", "John", "Acts", "Romans", + "1Cor", "2Cor", "Gal", "Eph", "Philip", "Col", "1Thes", "2Thes", "1Tim", + "2Tim", "Titus", "Philemon", "Hebrews", "James", "1Peter", "2Peter", + "1John", "2John", "3John", "Jude", "Rev" +/* p2c: Gbf.pas, line 200: + * Note: Line breaker spent 0.0 seconds, 5000 tries on line 336 [251] */ +}; /*// 85-90*/ + + +Static boolean isletter(ch) +Char ch; +{ + /*const*/ + boolean Result; + + if (isupper(ch)) { + Result = true; + return Result; + } + if (islower(ch)) + Result = true; + else + Result = false; + return Result; +} + + +Static boolean isinword(ch) +Char ch; +{ + /*const*/ + boolean Result; + + switch (ch) { + + case '-': + Result = true; + break; + + default: + if (isupper(ch)) + Result = true; + else if (islower(ch)) + Result = true; + else + Result = false; + break; + } + return Result; +} + + +Static boolean IsUpper(ch) +Char ch; +{ + /*const*/ + boolean Result; + + if (isupper(ch)) + Result = true; + else + Result = false; + return Result; +} + + +Static boolean IsDigit(ch) +Char ch; +{ + /*const*/ + boolean Result; + + if (isdigit(ch)) + Result = true; + else + Result = false; + return Result; +} + + +Static boolean MatchAbbrev(sName, sAbbrev) +Char *sName, *sAbbrev; +{ + /*const*/ + long i; + boolean Result; + + if (strlen(sName) < strlen(sAbbrev)) { + Result = false; +/* p2c: Gbf.pas, line 245: Warning: Symbol 'RESULT' is not defined [221] */ + } else + Result = true; + i = 1; + while (i <= strlen(sAbbrev) && Result) { + if (toupper(sName[i - 1]) != sAbbrev[i - 1]) + Result = false; + i++; + } +} + + +Static uchar BookNameToNumber(sBookName) +Char *sBookName; +{ + /*const*/ + long Result; + + Result = 0; +/* p2c: Gbf.pas, line 259: Warning: Symbol 'RESULT' is not defined [221] */ + TRY(try1); + if (IsDigit(sBookName[strlen(sBookName) - 1]) & IsDigit(sBookName[0])) { + Result = StrToInt(sBookName); +/* p2c: Gbf.pas, line 262: + * Warning: Symbol 'STRTOINT' is not defined [221] */ + } + except(); +/* p2c: Gbf.pas, line 264: Warning: Symbol 'EXCEPT' is not defined [221] */ +/* p2c: Gbf.pas, line 264: + * Warning: Expected RECOVER, found 'Result' [227] */ + RECOVER(try1); + ; + ENDTRY(try1); +} + + +main(argc, argv) +int argc; +Char *argv[]; +{ /*// Yuk! Linear search.*/ + Char STR1[256]; + uchar Result; + +/* p2c: Gbf.pas, line 266: Warning: Expected BEGIN, found 'i' [227] */ + PASCAL_MAIN(argc, argv); + if (MatchAbbrev(sBookName, BookAbbr[i].Abbr)) { +/* p2c: Gbf.pas, line 269: + * Warning: Symbol 'SBOOKNAME' is not defined [221] */ +/* p2c: Gbf.pas, line 269: Warning: Mixing non-strings with strings [170] */ +/* p2c: Gbf.pas, line 269: Warning: Symbol 'I' is not defined [221] */ + Result = BookAbbr[i].Num; +/* p2c: Gbf.pas, line 271: Warning: Symbol 'I' is not defined [221] */ +/* p2c: Gbf.pas, line 271: Warning: Symbol 'RESULT' is not defined [221] */ + } +/* p2c: Gbf.pas, line 273: Warning: Symbol 'I' is not defined [221] */ + i++; + exit(EXIT_SUCCESS); +} +/* p2c: Gbf.pas, line 275: + * Warning: Junk at end of input file ignored [277] */ + + + +/* End. */ diff --git a/src/modules/texts/rawgbf/Gbf.pas b/src/modules/texts/rawgbf/Gbf.pas new file mode 100644 index 0000000..13826e3 --- /dev/null +++ b/src/modules/texts/rawgbf/Gbf.pas @@ -0,0 +1,735 @@ +type + TToken = (tokNull, tokEOF, tokHeader, tokContent, tokTail, tokStyle, + tokWord, tokSpace, tokSync, tokControl, tokChar, tokFont); + TCharacterAttribute = (caBold, caSmallCaps, caItalic, caOTQuote, caRed, + caSuperscript, caUnderline, caSubscript); + TCharAttribs = set of TCharacterAttribute; + + + TBookNameRec = record + Name, + Abbr: string; + Num: byte + end; + + TBookAbbr = array[0..115] of TBookNameRec; + +const + BookAbbr: TBookAbbr = ( + (Name: '1 Chronicles'; Abbr: '1CH'; Num: 13), {//0} + (Name: '1 Corinthians'; Abbr: '1CO'; Num: 70), {//1} + (Name: '1 Esdras'; Abbr: '1E'; Num: 52), {//2} + (Name: '1 John'; Abbr: '1J'; Num: 86), {//3} + (Name: '1 Kings'; Abbr: '1K'; Num: 11), {//4} + (Name: '1 Maccabees'; Abbr: '1M'; Num: 50), {//5} + (Name: '1 Peter'; Abbr: '1P'; Num: 84), {//6} + (Name: '1 Samuel'; Abbr: '1S'; Num: 9), {//7} + (Name: '1 Thessalonians'; Abbr: '1TH'; Num: 76), {//8} + (Name: '1 Timothy'; Abbr: '1TI'; Num: 78), {//9} + (Name: '2 Chronicles'; Abbr: '2CH'; Num: 14), {//10} + (Name: '2 Corinthians'; Abbr: '2CO'; Num: 71), {//11} + (Name: '2 Esdras'; Abbr: '2E'; Num: 56), {//12} + (Name: '2 John'; Abbr: '2J'; Num: 87), {//13} + (Name: '2 Kings'; Abbr: '2K'; Num: 12), {//14} + (Name: '2 Maccabees'; Abbr: '2M'; Num: 51), {//15} + (Name: '2 Peter'; Abbr: '2P'; Num: 85), {//16} + (Name: '2 Samuel'; Abbr: '2S'; Num: 10), {//17} + (Name: '2 Thessalonians'; Abbr: '2TH'; Num: 77), {//18} + (Name: '2 Timothy'; Abbr: '2TI'; Num: 79), {//19} + (Name: '3 John'; Abbr: '3J'; Num: 88), {//20} + (Name: '3 Maccabees'; Abbr: '3M'; Num: 55), {//21} + (Name: '4 Maccabees'; Abbr: '4M'; Num: 57), {//22} + (Name: '1 Chronicles'; Abbr: '1 CH'; Num: 13), {//0} + (Name: '1 Corinthians'; Abbr: '1 CO'; Num: 70), {//1} + (Name: '1 Esdras'; Abbr: '1 E'; Num: 52), {//2} + (Name: '1 John'; Abbr: '1 J'; Num: 86), {//3} + (Name: '1 Kings'; Abbr: '1 K'; Num: 11), {//4} + (Name: '1 Maccabees'; Abbr: '1 M'; Num: 50), {//5} + (Name: '1 Peter'; Abbr: '1 P'; Num: 84), {//6} + (Name: '1 Samuel'; Abbr: '1 S'; Num: 9), {//7} + (Name: '1 Thessalonians'; Abbr: '1 TH'; Num: 76), {//8} + (Name: '1 Timothy'; Abbr: '1 TI'; Num: 78), {//9} + (Name: '2 Chronicles'; Abbr: '2 CH'; Num: 14), {//10} + (Name: '2 Corinthians'; Abbr: '2 CO'; Num: 71), {//11} + (Name: '2 Esdras'; Abbr: '2 E'; Num: 56), {//12} + (Name: '2 John'; Abbr: '2 J'; Num: 87), {//13} + (Name: '2 Kings'; Abbr: '2 K'; Num: 12), {//14} + (Name: '2 Maccabees'; Abbr: '2 M'; Num: 51), {//15} + (Name: '2 Peter'; Abbr: '2 P'; Num: 85), {//16} + (Name: '2 Samuel'; Abbr: '2 S'; Num: 10), {//17} + (Name: '2 Thessalonians'; Abbr: '2 TH'; Num: 77), {//18} + (Name: '2 Timothy'; Abbr: '2 TI'; Num: 79), {//19} + (Name: '3 John'; Abbr: '3 J'; Num: 88), {//20} + (Name: '3 Maccabees'; Abbr: '3 M'; Num: 55), {//21} + (Name: '4 Maccabees'; Abbr: '4 M'; Num: 57), {//22} + (Name: 'Acts'; Abbr: 'AC'; Num: 68), {//23} + (Name: 'Amos'; Abbr: 'AM'; Num: 30), {//24} + (Name: 'Prayer of Asariah and the Song of the Three Jews'; Abbr: 'AZ'; Num: 47), + (Name: 'Baruch'; Abbr: 'BA'; Num: 45), {//26} + (Name: 'Bel and the Dragon';Abbr: 'BE'; Num: 49), {//27} + (Name: 'Colossians'; Abbr: 'CO'; Num: 75), {//28} + (Name: 'Daniel'; Abbr: 'DA'; Num: 27), {//29} + (Name: 'Deuteronomy'; Abbr: 'DE'; Num: 5), {//30} + (Name: 'Deuteronomy'; Abbr: 'DT'; Num: 5), {//31} + (Name: 'Ecclesiasties'; Abbr: 'EC'; Num: 21), {//32} + (Name: 'Esther'; Abbr: 'ES'; Num: 17), {//33} + (Name: 'Exodus'; Abbr: 'EX'; Num: 2), {//34} + (Name: 'Ezekiel'; Abbr: 'EZE'; Num: 26), {//35} + (Name: 'Ezra'; Abbr: 'EZR'; Num: 15), {//36} + (Name: 'Galatians'; Abbr: 'GA'; Num: 72), {//37} + (Name: 'Genesis'; Abbr: 'GE'; Num: 1), {//38} + (Name: 'Genesis'; Abbr: 'GN'; Num: 1), {//39} + (Name: 'Ephesians'; Abbr: 'EP'; Num: 73), {//40} + (Name: 'Esther (Greek)'; Abbr: 'GR'; Num: 42), {//41} + (Name: 'Habakkuk'; Abbr: 'HAB'; Num: 35), {//42} + (Name: 'Haggai'; Abbr: 'HAG'; Num: 37), {//43} + (Name: 'Hebrews'; Abbr: 'HE'; Num: 82), {//44} + (Name: 'Hosea'; Abbr: 'HO'; Num: 28), {//45} + (Name: 'Isaiah'; Abbr: 'IS'; Num: 23), {//46} + (Name: 'James'; Abbr: 'JA'; Num: 83), {//47} + (Name: 'Jeremiah'; Abbr: 'JE'; Num: 24), {//48} + (Name: 'Job'; Abbr: 'JOB'; Num: 18), {//49} + (Name: 'Joel'; Abbr: 'JOE'; Num: 29), {//50} + (Name: 'John'; Abbr: 'JOH'; Num: 67), {//51} + (Name: 'Jonah'; Abbr: 'JON'; Num: 32), {//52} + (Name: 'Joshua'; Abbr: 'JOS'; Num: 6), {//53} + (Name: 'Jude'; Abbr: 'JUDE'; Num: 89), {//54} + (Name: 'Judges'; Abbr: 'JUDG'; Num: 7), {//55} + (Name: 'Judith'; Abbr: 'JUDI'; Num: 41), {//56} + (Name: 'Lamentations'; Abbr: 'LA'; Num: 25), {//57} + (Name: 'Letter of Jeremiah';Abbr:'LET'; Num: 46), {//58} + (Name: 'Leviticus'; Abbr: 'LEV'; Num: 3), {//59} + (Name: 'Luke'; Abbr: 'LK'; Num: 66), {//60} + (Name: 'Leviticus'; Abbr: 'LV'; Num: 3), {//61} + (Name: 'Luke'; Abbr: 'LU'; Num: 66), {//62} + (Name: 'Malachi'; Abbr: 'MAL'; Num: 39), {//63} + (Name: 'Prayer of Manasseh';Abbr:'MAN'; Num: 53), {//64} + (Name: 'Mark'; Abbr: 'MAR'; Num: 65), {//65} + (Name: 'Matthew'; Abbr: 'MAT'; Num: 64), {//66} + (Name: 'Micah'; Abbr: 'MI'; Num: 33), {//67} + (Name: 'Nahum'; Abbr: 'NA'; Num: 34), {//68} + (Name: 'Nehemiah'; Abbr: 'NE'; Num: 16), {//69} + (Name: 'Numbers'; Abbr: 'NU'; Num: 4), {//70} + (Name: 'Obadiah'; Abbr: 'OB'; Num: 31), {//71} + (Name: 'Psalm 151'; Abbr: 'P1'; Num: 54), {//72} + (Name: 'Philemon'; Abbr: 'PHILE'; Num: 81), {//73} + (Name: 'Philippians'; Abbr: 'PHILI'; Num: 74), {//74} + (Name: 'Philemon'; Abbr: 'PHM'; Num: 81), {//75} + (Name: 'Philippians'; Abbr: 'PHP'; Num: 74), {//76} + (Name: 'Proverbs'; Abbr: 'PR'; Num: 20), {//77} + (Name: 'Psalms'; Abbr: 'PS'; Num: 19), {//78} + (Name: 'Revelation'; Abbr: 'RE'; Num: 90), {//79} + (Name: 'Romans'; Abbr: 'RM'; Num: 69), {//80} + (Name: 'Romans'; Abbr: 'RO'; Num: 69), {//81} + (Name: 'Ruth'; Abbr: 'RU'; Num: 8), {//82} + (Name: 'Sirach'; Abbr: 'SI'; Num: 44), {//83} + (Name: 'Song of Solomon'; Abbr: 'SOL'; Num: 22), {//84} + (Name: 'Song of Solomon'; Abbr: 'SON'; Num: 22), {//85} + (Name: 'Song of Solomon'; Abbr: 'SS'; Num: 22), {//86} + (Name: 'Susanna'; Abbr: 'SU'; Num: 48), {//87} + (Name: 'Titus'; Abbr: 'TI'; Num: 80), {//88} + (Name: 'Tobit'; Abbr: 'TO'; Num: 40), {//89} + (Name: 'Wisdom'; Abbr: 'WI'; Num: 43), {//90} + (Name: 'Zechariah'; Abbr: 'ZEC'; Num: 38), {//91} + (Name: 'Zephaniah'; Abbr: 'ZEP'; Num: 36) {//92} + ); + + BookFileName: array[0..90] of string = ( + '','Genesis','Exodus','Lev','Num','Deut','Joshua','Judges', {// 0 - 7} + 'Ruth','1Sam','2Sam','1Kings','2Kings','1Chron','2Chron', {// 8 - 14} + 'Ezra','Nehemiah','Esther','Job','Psalms','Proverbs', {// 15-20} + 'Eccl','Song','Isaiah','Jeremiah','Lament','Ezekiel', {// 21-26} + 'Daniel','Hosea','Joel','Amos','Obadiah','Jonah','Micah', {// 27-33} + 'Nahum','Habakkuk','Zeph','Haggai','Zech','Malachi', {// 34-39} + 'Tobit','Judith','Esther','Wisdom','Sirach','Baruch', {// 40-45} + 'Let','Azar','Susanna','Bel','1Mac','2Mac','1Esdras', {// 46-52} + 'Man','P1','3Mac','2Esdras','4Mac','','','','','','', {// 53-63} + 'Matthew','Mark','Luke','John','Acts','Romans','1Cor', {// 64-70} + '2Cor','Gal','Eph','Philip','Col','1Thes','2Thes','1Tim', {// 71-78} + '2Tim','Titus','Philemon','Hebrews','James','1Peter', {// 79-84} + '2Peter','1John','2John','3John','Jude','Rev'); {// 85-90} + +type + TReadGBF = record +{ private} + F: File; + FName, TokenLine: string; + TokenPos: integer; + fFileIsOpen, fParagraphEnd, fInTitle, fInPsalmBookTitle, fInHebrewTitle, + fInSectionTitle: boolean; + +{ public} + sBook, sChapter, sVerse, sMode: string; + sContext, {// Last text type (header, body, or tail)} + sTitle, {// Title of this book of the Bible} + sPsalmBookTitle, {// Title of this Psalm book} + sHebrewTitle, {// Psalm Hebrew title} + sSectionTitle, {// Section headings} + sDate, + sFontName: string; + iTotalWords: integer; + chJustification, + chDirection: char; + fIndent, fPoetry: boolean; + CharAttribs: TCharAttribs; + bBk, bChap, bVs, bWd: byte; +{ + function Init({const}{sFileName: string): boolean; + procedure Done; + function GetToken(var TokenKind: TToken): string; +} + end; + + TWriteGBF = record +{ private} + F: File; + FName, LineOut: string; + fFileIsOpen: boolean; + bBk, bChap, bVs, bWd: byte; + +{ public} +{ + function Init({const}{sFileName: string): boolean; + function Done: boolean; + procedure Out({const}{s: string); +} + end; + +{implementation } + +function isletter({const}ch: char): boolean; +begin + case ch of + 'A'..'Z': isletter := true; + 'a'..'z': isletter := true; + else + isletter := false; + end; +end; + +function isinword({const}ch: char): boolean; +begin + case ch of + '-': isinword := true; + 'A'..'Z': isinword := true; + 'a'..'z': isinword := true; + else + isinword := false; + end; +end; + +function IsUpper({const}ch: char): Boolean; +begin + case ch of + 'A'..'Z': IsUpper := true; + else + IsUpper := false; + end; +end; + +function IsDigit({const}ch: char): Boolean; +begin + case ch of + '0'..'9': IsDigit := true; + else + IsDigit := false; + end; +end; + + +function MatchAbbrev({const}sName, sAbbrev: string): boolean; +var i: integer; +begin + if Length(sName) < Length(sAbbrev) then + Result := false + else + Result := true; + i := 1; + while (i <= Length(sAbbrev)) and Result do + begin + if UpCase(sName[i]) <> sAbbrev[i] then + Result := false; + inc(i); + end; +end; + +function BookNameToNumber({const}sBookName: string): byte; +var i: integer; +begin + Result := 0; + try + if IsDigit(sBookName[Length(sBookName)]) and IsDigit(sBookName[1]) then + Result := StrToInt(sBookName); + except + Result := 0; + end; + i := 0; + while (Result = 0) and (i <= 115) do {// Yuk! Linear search.} + begin + if MatchAbbrev(sBookName,BookAbbr[i].Abbr) then + begin + Result := BookAbbr[i].Num; + end; + inc(i); + end; +end; + +function BookNumberToName({const}bBookNum: byte): string; +begin + if bBookNum <= 115 then + Result := BookAbbr[bBookNum].Name + else + Result := ''; +end; + +function ConformCase({const}sPat, sSrc: string): string; +var i: integer; +begin + Result := sSrc; + if (Length(sPat) > 0) and (Length(sSrc) > 0) then + begin + Result := LowerCase(sSrc); + if IsUpper(sPat[1]) then + Result[1] := UpCase(Result[1]); + if (Length(sPat) > 1) and (Length(sSrc) > 1) then + begin + if IsUpper(sPat[2]) then + begin + for i := 2 to Length(Result) do + Result[i] := UpCase(Result[i]); + end; + end; + end; +end; + +function TReadGBF.Init({const}sFileName: string): boolean; +var s: string; + tok: TToken; +begin + try + fParagraphEnd := false; + bBk := 0; + bChap := 0; + bVs := 0; + bWd := 0; + iTotalWords := 0; + FName := sFileName; + Assign(F, FName); + reset(F); + readln(F, TokenLine); + TokenPos := 1; + fFileIsOpen := true; + repeat + s := GetToken(tok) + until (tok = tokEOF) or ((tok = tokHeader) and (s[3] = '0')); + Init := true; + except + Init := false; + fFileIsOpen := false; + end +end; + +procedure TReadGBF.Done; +begin + if fFileIsOpen then + begin + closefile(F); + fFileIsOpen := false; + end; +end; + +function TReadGBF.GetToken(var TokenKind: TToken): string; +var m: integer; +begin + Result := ''; + TokenKind := tokNull; + if TokenPos = 0 then + begin + if (not fFileIsOpen) or EOF(F) then + TokenKind := tokEOF + else + begin + ReadLn(F,TokenLine); + TokenPos := 1; + end; + end; + if TokenKind <> tokEOF then + begin + m := Length(TokenLine); + if TokenPos > m then + begin + TokenKind := tokSpace; + if fParagraphEnd then + fParagraphEnd := false + else + Result := ' '; + TokenPos := 0; + end + else + begin + if (TokenLine[TokenPos] = '<') then + begin + fParagraphEnd := false; + repeat + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + until (TokenLine[TokenPos] = '>') or (TokenPos > m); + Result := Result + '>'; + inc(TokenPos); + case result[2] of + 'B': begin {// File body text type} + TokenKind := tokContent; + sContext := Result; + end; + 'C': begin {// Special characters} + TokenKind := tokControl; + if (Result[3] = 'M') or (Result[3] = 'L') then + fParagraphEnd := true; + end; + 'D': begin {// Direction} + TokenKind := tokControl; + chDirection := Result[3]; + end; + 'H': begin + TokenKind := tokHeader; + sContext := Result; + end; + 'F': begin {// Font attributes} + TokenKind := tokFont; + case Result[3] of + 'B': CharAttribs := CharAttribs + [caBold]; + 'C': CharAttribs := CharAttribs + [caSmallCaps]; + 'I': CharAttribs := CharAttribs + [caItalic]; + 'N': sFontName := copy(Result,4,Length(Result)-4); + 'O': CharAttribs := CharAttribs + [caOTQuote]; + 'R': CharAttribs := CharAttribs + [caRed]; + 'S': CharAttribs := CharAttribs + [caSuperscript]; + 'U': CharAttribs := CharAttribs + [caUnderline]; + 'V': CharAttribs := CharAttribs + [caSubscript]; + 'b': CharAttribs := CharAttribs - [caBold]; + 'c': CharAttribs := CharAttribs - [caSmallCaps]; + 'i': CharAttribs := CharAttribs - [caItalic]; + 'n': sFontName := ''; + 'o': CharAttribs := CharAttribs - [caOTQuote]; + 'r': CharAttribs := CharAttribs - [caRed]; + 's': CharAttribs := CharAttribs - [caSuperscript]; + 'u': CharAttribs := CharAttribs - [caUnderline]; + 'v': CharAttribs := CharAttribs - [caSubscript]; + + end; + end; + 'J': begin {// Justification} + TokenKind := tokStyle; + chJustification := Result[3]; + end; + 'P': begin {// Poetry/prose, indent} + TokenKind := tokControl; + case Result[3] of + 'I': fIndent := true; + 'P': fPoetry := true; + 'i': fIndent := false; + 'p': fPoetry := false; + end; + end; + 'R': begin {// References and footnotes} + TokenKind := tokControl; + end; + 'S': begin {// sync mark} + TokenKind := TokSync; + case Result[3] of + 'B': begin {// Book} + sBook := system.copy(Result, 4, length(Result)-4); + sPsalmBookTitle := ''; + if sBook = '' then + begin + inc(bBk); + sBook := BookNumberToName(bBk); + end + else + bBk := BookNameToNumber(sBook); + sTitle := sBook; + end; + 'C': begin {//chapter} + sChapter := system.copy(Result, 4, length(Result)-4); + if sChapter = '' then + begin + inc(bChap); + sChapter := IntToStr(bChap); + end + else + begin + try + bChap := StrToInt(sChapter); + except + showmessage('Non-numeric chapter: '+sBook+' '+sChapter); + end; + end; + sHebrewTitle := ''; + end; + 'V': begin {// Verse} + bWd := 0; + sVerse := system.copy(Result, 4, length(Result)-4); + if sVerse = '' then + begin + inc(bVs); + sVerse := IntToStr(bVs); + end + else + begin + try + bVs := StrToInt(sVerse); + except + showmessage('Non-numeric verse: '+sBook+' '+sChapter+':'+sVerse); + end; + end; + end; + 'D': begin {// Date} + sDate := system.copy(Result, 3, length(Result)-4); + end; + end; + end; + 'T': begin {// Titles} + TokenKind := TokContent; + case Result[3] of + 'B': + begin + sPsalmBookTitle := ''; + fInPsalmBookTitle := true; + end; + 'b': fInPsalmBookTitle := true; + 'H': + begin + sHebrewTitle := ''; + fInHebrewTitle := true; + end; + 'h': fInHebrewTitle := false; + 'S': + begin + sSectionTitle := ''; + fInSectionTitle := true; + end; + 's': fInSectionTitle := false; + 'T': + begin + sTitle := ''; + fInTitle := true; + end; + 't': fInTitle := false; + end; + end; + 'Z': begin {// File tail} + TokenKind := tokTail; + sContext := Result; + if Result[3] = 'Z' then + done; + end; + else + TokenKind := TokControl; + + end; + end + else if isletter(TokenLine[TokenPos]) then + begin {Word} + fParagraphEnd := false; + TokenKind := tokWord; + repeat + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + until (TokenPos > m) or (not isinword(TokenLine[TokenPos])); + inc(bWd); + inc(iTotalWords); + end + else if ((TokenLine[TokenPos] = ' ') or (TokenLine[TokenPos] = #9)) then + begin + fParagraphEnd := false; + TokenKind := tokSpace; + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + end + else + begin + fParagraphEnd := false; + TokenKind := tokChar; + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + end + end; + end; + if ((TokenKind = tokWord) or (TokenKind = tokSpace) or + (TokenKind = tokChar)) then + begin + if fInTitle then + sTitle := sTitle + Result + else if fInPsalmBookTitle then + sPsalmBookTitle := sPsalmBookTitle + Result + else if fInHebrewTitle then + sHebrewTitle := sHebrewTitle + Result + else if fInSectionTitle then + sSectionTitle := sSectionTitle + Result; + end; +end; + +function TWriteGBF.Init({const}sFileName: string): boolean; +begin + try + bBk := 0; + bChap := 0; + bVs := 0; + bWd := 0; + LineOut := ''; + FName := sFileName; + Assign(F, FName); + filemode := 1; + rewrite(F); + fFileIsOpen := true; + Init := true; + except + Init := false; + fFileIsOpen := false; + end +end; + +function TWriteGBF.Done: boolean; +begin + try + if fFileIsOpen then + begin + if LineOut <> '' then + begin + WriteLn(F, LineOut); + LineOut := ''; + end; + CloseFile(F); + end; + Done := true; + except + Done := false; + end; +end; + +procedure TWriteGBF.Out({const}s: string); +var sPrint, sSave, sBook, sChapter, sVerse: string; + i: integer; + b: byte; +begin + if (Length(s) > 0) and IsLetter(s[1]) then + begin + inc(bWd); + LineOut := LineOut + s; + end + else if Length(s) > 3 then + begin + if (s[1] = '<') and (s[2] = 'S') then + begin + case s[3] of + 'B': begin {// Book} + sBook := system.copy(s, 4, length(s)-4); + if sBook = '' then + begin + inc(bBk); + LineOut := LineOut + s; + end + else + begin + b := bBk; + bBk := BookNameToNumber(sBook); + if b <> bBk then + LineOut := LineOut + s; + end; + end; + 'C': begin {//chapter} + sChapter := system.copy(s, 4, length(s)-4); + if sChapter = '' then + begin + inc(bChap); + LineOut := LineOut + s; + end + else + begin + try +{// b := bChap;} + bChap := StrToInt(sChapter); +{// if b <> bChap then} + LineOut := LineOut + s; + except + showmessage('Non-numeric chapter: '+sBook+' '+sChapter); + end; + end; + end; + 'V': begin {// Verse} + bWd := 0; + sVerse := system.copy(s, 4, length(s)-4); + if sVerse = '' then + begin + inc(bVs); + LineOut := LineOut + s; + end + else + begin + try +{// b := bVs;} + bVs := StrToInt(sVerse); +{// if b <> bVs then} + LineOut := LineOut + s; + except + showmessage('Non-numeric verse: '+sBook+' '+sChapter+':'+sVerse); + end; + end; + end; + else + LineOut := LineOut + s; + end + end + else + LineOut := LineOut + s; {// Not a sync mark} + end + else {// other token, space, or punctuation} + LineOut := LineOut + s; {// Length <= 3} + if ((s = '<CM>') or (s = '<CL>')) then + begin + if (Length(LineOut) > 78) then + begin + i := 78; + while (i > 0) and (LineOut[i] <> ' ') do + dec(i); + if i < 1 then + begin + WriteLn(F,LineOut); + LineOut := ''; + end + else + begin + sPrint := system.copy(LineOut,1,i-1); + sSave := system.copy(LineOut,i+1,Length(LineOut)-i); + WriteLn(F,sPrint); + WriteLn(F, sSave); + LineOut := ''; + end + end + else + begin + WriteLn(F, LineOut); + LineOut := ''; + end + end + else if (Length(LineOut) > 78) then + begin + i := 78; + while (i > 0) and (LineOut[i] <> ' ') do + dec(i); + if i < 1 then + begin + WriteLn(F,LineOut); + LineOut := ''; + end + else + begin + sPrint := system.copy(LineOut,1,i-1); + sSave := system.copy(LineOut,i+1,Length(LineOut)-i); + WriteLn(F,sPrint); + LineOut := sSave; + end + end +end; + +end. diff --git a/src/modules/texts/rawgbf/Gbfmain.pas b/src/modules/texts/rawgbf/Gbfmain.pas new file mode 100644 index 0000000..4377622 --- /dev/null +++ b/src/modules/texts/rawgbf/Gbfmain.pas @@ -0,0 +1,1267 @@ +unit GBFMain; + +interface + +uses + Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, + Buttons, StdCtrls, ExtCtrls, GBF; + +const + sTitlePar = '\pard\plain \s1\fi432\sb240\sa60\keepn\widctlpar \b\f5\fs28\kerning28 '; + sNormalPar = '\pard\plain \fi432\widctlpar \f4 '; + sNormalQuotePar = '\pard\plain \s20\fi432\li432\widctlpar \f4 '; + sPoetryPar = '\pard\plain \s18\fi-432\li432\widctlpar \f4 '; + sPoetryQuotePar = '\pard\plain \s21\fi-432\li864\widctlpar \f4 '; + sHebrewTitlePar = '\pard\plain \s16\fi432\keep\keepn\widctlpar \f4\fs20 '; + sSelahPar = '\pard\plain \s19\qr\widctlpar \f4 '; + ANSI2OEM: array[0..255] of char = + ( #0, #1, #2, #3, #4, #5, #6, #7, + #8, #9, #10, #11, #12, #13, #14, #15, + #16, #17, #18, #19, #20, #21, #22, #23, + #24, #25, #26, #27, #28, #29, #30, #31, + #32, #33, #34, #35, #36, #37, #38, #39, + #40, #41, #42, #43, #44, #45, #46, #47, + #48, #49, #50, #51, #52, #53, #54, #55, + #56, #57, #58, #59, #60, #61, #62, #63, + #64, #65, #66, #67, #68, #69, #70, #71, + #72, #73, #74, #75, #76, #77, #78, #79, + #80, #81, #82, #83, #84, #85, #86, #87, + #88, #89, #90, #91, #92, #93, #94, #95, + #96, #97, #98, #99,#100,#101,#102,#103, + #104,#105,#106,#107,#108,#109,#110,#111, + #112,#113,#114,#115,#116,#117,#118,#119, + #120,#121,#122,#123,#124,#125,#126,#127, + #128,#129, ',', 'a', '"',#133,#197,#216, + '^', '%', 'S', '<',#140,#141,#142,#143, + #144, #96, #97, '"', '"',#249,#150,#151, + '~',#153, 's', '>',#156,#157,#158, 'Y', + ' ',#173,#155,#156,#232,#157,#124, #21, + #168,#169, 'a',#174,#170, '-',#174, '_', + #167,#241,#253, '3', #39,#230, #20,#254, + ',', '1', 'o',#175,#172,#171,#190,#168, + 'A', 'A', 'A', 'A',#142,#143,#198,#128, + 'E',#144, 'E',#142, 'I', 'I', 'I', 'I', + 'D',#165, 'O', 'O', 'O', 'O',#153, 'x', + '0', 'U', 'U', 'U',#154, 'Y', 'b',#225, + #133,#130,#131, 'a',#132,#134,#230,#135, + #138,#130,#136,#137,#141,#161,#140,#139, + #148,#164,#149,#162,#147, 'o',#148,#246, + 'o',#151,#163,#150,#129, 'y', 'b',#152); + +type + TGBFConverterMainForm = class(TForm) + SourceEdit: TEdit; + Label1: TLabel; + BrowseButton: TButton; + SaveDialog1: TSaveDialog; + OpenDialog1: TOpenDialog; + DestEdit: TEdit; + Label2: TLabel; + BrowseDestButton: TButton; + FormatRadioGroup: TRadioGroup; + GoBitBtn: TBitBtn; + CloseBitBtn: TBitBtn; + Timer1: TTimer; + VerseLabel: TLabel; + ApocryphaCheckBox: TCheckBox; + WdLabel: TLabel; + Label3: TLabel; + Label4: TLabel; + WEBDraftCheckBox: TCheckBox; + QuickButton: TButton; + procedure CloseBitBtnClick(Sender: TObject); + procedure GoBitBtnClick(Sender: TObject); + procedure Timer1Timer(Sender: TObject); + procedure FormShow(Sender: TObject); + procedure FormatRadioGroupClick(Sender: TObject); + procedure QuickConversion; + procedure DoConversion; + procedure QuickButtonClick(Sender: TObject); + procedure FormActivate(Sender: TObject); + private + { Private declarations } + public + { Public declarations } + end; + +var + GBFConverterMainForm: TGBFConverterMainForm; + +implementation + +{$R *.DFM} + +var InFile: TReadGBF; + OutGBF: TWriteGBF; + OutFile: TextFile; + +function ANSIToOEM(s: string): string; +var i, j: integer; +begin + Result := s; + j := 1; + for i := 1 to length(s) do + begin + case s[i] of + #133: + begin + Result[j] := '.'; + inc(j); + Insert('..', Result, j); + inc(j); + end; + #140: + begin + Result[j] := 'O'; + inc(j); + Insert('E', Result, j); + end; + #150: + begin + Result[j] := '-'; + inc(j); + Insert('-', Result, j); + end; + #151: + begin + Result[j] := '-'; + inc(j); + Insert('-', Result, j); + end; + #153: + begin + Result[j] := '('; + inc(j); + Insert('TM)', Result, j); + inc(j,2); + end; + #156: + begin + Result[j] := 'o'; + inc(j); + Insert('e', Result, j); + end; + #169: + begin + Result[j] := '('; + inc(j); + Insert('C)',Result, j); + inc(j); + end; + #174: + begin + Result[j] := '('; + inc(j); + Insert('R)',Result, j); + inc(j); + end; + #198: + begin + Result[j] := 'A'; + inc(j); + Insert('E', Result, j); + end; + #230: + begin + Result[j] := 'a'; + inc(j); + Insert('e', Result, j); + end; + else + Result[j] := ANSI2OEM[ord(s[i])]; + end; + inc(j); + end; +end; + +procedure TGBFConverterMainForm.CloseBitBtnClick(Sender: TObject); +begin + Close; +end; + +procedure TGBFConverterMainForm.DoConversion; +var LastBook, wd, ParagraphAttributes, s, sLine, sPrint, sSave, + OutFileName: string; + LinePos, i, iFileNumber: integer; + tok: TToken; + fInclude, fProse, fSkip, fHTMLisOpen, fRed, fASCIIisOpen: boolean; + bLastBook, bChap: byte; + + procedure CheckEOL; + begin + if Length(sLine) > 65 then + begin + i := 65; + while (i > 0) and (sLine[i] <> ' ') do + dec(i); + if i < 1 then + begin + if fASCIIisOpen then WriteLn(OutFile,sLine); + if fProse then + sLine := '' + else + sLine := ' '; + end + else + begin + sPrint := system.copy(sLine,1,i-1); + if fProse then + sSave := system.copy(sLine,i+1,Length(sLine)-i) + else + sSave := ' '+system.copy(sLine,i+1,Length(sLine)-i); + if fASCIIisOpen then WriteLn(OutFile,sPrint); + sLine := sSave; + end + end; + end; + + procedure StartNewLine; + begin + if fInclude then + begin + CheckEol; + if fASCIIisOpen then WriteLn(OutFile, sLine); + sLine := ''; + end; + end; + + procedure CloseHTML; + begin + if fHTMLisOpen then + begin + WriteLn(OutFile,sLine); + sLine := ''; + WriteLn(OutFile,'</P>'); + WriteLn(OutFile,'<P></P><HR><A HREF="index.htm">[Index]</A> '); + WriteLn(OutFile,'<A HREF="http://www.ebible.net/bible/">[Home]</A>'); + WriteLn(OutFile,'</BODY></HTML>'); + CloseFile(OutFile); + fHTMLisOpen := false; + end; + end; + + procedure CloseASCII; + begin + if fASCIIisOpen then + begin + WriteLn(OutFile,sLine); + sLine := ''; + WriteLn(OutFile); + if WEBDraftCheckBox.Checked then + begin + WriteLn(OutFile,'______________________________________________________________'); + WriteLn(OutFile); + WriteLn(OutFile,'The above is from the public domain World English Bible (WEB).'); + WriteLn(OutFile,'See http://www.ebible.org/bible/WEB for more about this Bible.'); + WriteLn(OutFile,'Please report typos to mpj@ebible.org.'); + end; + CloseFile(OutFile); + fASCIIisOpen := false; + end; + end; + + procedure OpenHTML; + begin + if fHTMLisOpen then CloseHTML; + sLine := ''; + OutFileName := ExtractFilePath(DestEdit.Text)+BookFileName[InFile.bBk]+'.htm'; + AssignFile(OutFile,OutFileName); + Rewrite(OutFile); + WriteLn(OutFile,'<HTML>'); + WriteLn(OutFile,'<HEAD>'); + WriteLn(OutFile,'<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">'); + WriteLn(OutFile,'<META http-equiv="PICS-Label" content=''(PICS-1.1 "http://www.rsac.org/ratingsv01.html"'); + WriteLn(OutFile,' l gen true comment "RSACi North America Server" by "mpj@csn.net" for "http://www.csn.net/~mpj"'); + WriteLn(OutFile,' on "1996.08.29T12:42-0500" r (n 0 s 0 v 0 l 0))''>'); + WriteLn(OutFile,'<META NAME="description" CONTENT="'+InFile.sTitle+' from the World English Bible -- a Public Domain Modern English translation of the Holy Bible.">'); + WriteLn(OutFile,'<META NAME="keywords" CONTENT="'+BookFileName[InFile.bBk]+', '+InFile.sTitle+', Bible, Christian, Holy Bible, Bible search, WEB, World English Bible, Scriptures, Scripture, Bibles, Gospel, Gospels, bible">'); + WriteLn(OutFile,'<TITLE>'+InFile.sTitle+'</TITLE>'); + WriteLn(OutFile,'<LINK REL=Home HREF="http://www.ebible.org/bible">'); + WriteLn(OutFile,'<LINK REL=Glossary HREF="glossary.htm">'); + WriteLn(OutFile,'</HEAD>'); + WriteLn(OutFile,'<BODY BGCOLOR="#80ffff">'); + WriteLn(OutFile,'<H1>'); + WriteLn(OutFile,InFile.sTitle); + WriteLn(OutFile,'</H1><P>'); + fHTMLisOpen := true; + end; + + procedure OpenASCII; + begin + if fASCIIisOpen then CloseASCII; + if fProse then + sLine := ' ' + else + sLine := ''; + OutFileName := ExtractFilePath(DestEdit.Text)+BookFileName[InFile.bBk]+'.txt'; + AssignFile(OutFile,OutFileName); + Rewrite(OutFile); + WriteLn(OutFile); + WriteLn(OutFile,InFile.sTitle); + WriteLn(OutFile); + fASCIIisOpen := true; + end; + + procedure OpenNTChapter; + var s: string; + begin + if InFile.bBk >= 64 then + begin + if fASCIIisOpen then CloseASCII; + inc(iFileNumber); + s := IntToStr(iFileNumber); + if Length(s) < 3 then s := '0'+s; + if Length(s) < 3 then s := '0'+s; + OutFileName := ExtractFilePath(DestEdit.Text)+'n'+s+'.txt'; + AssignFile(OutFile,OutFileName); + Rewrite(OutFile); + WriteLn(OutFile,'Subject: '+BookFileName[InFile.bBk]+' '+InFile.sChapter+', World English Bible'); + if iFileNumber = 260 then + WriteLn(OutFile,'X-Reset: 1'); + WriteLn(OutFile); + WriteLn(OutFile); + WriteLn(OutFile,InFile.sTitle+', Chapter '+InFile.sChapter); + WriteLn(OutFile); + fASCIIisOpen := true; + if fProse then + sLine := ' ' + else + sLine := ''; + end + else + begin + inc(bChap); + if (bLastBook <> Infile.bBk) or ((bChap mod 3) = 1) then + begin + if (bLastBook <> Infile.bBk) then + begin + bLastBook := Infile.bBk; + bChap := 1; + end; + if fASCIIisOpen then CloseASCII; + inc(iFileNumber); + s := IntToStr(iFileNumber); + if Length(s) < 3 then s := '0'+s; + if Length(s) < 3 then s := '0'+s; + OutFileName := ExtractFilePath(DestEdit.Text)+s+'.txt'; + AssignFile(OutFile,OutFileName); + Rewrite(OutFile); + WriteLn(OutFile,'Subject: '+BookFileName[InFile.bBk]+' '+InFile.sChapter+', World English Bible'); + if (Infile.bBk = 39) and (bChap = 4) then + WriteLn(OutFile,'X-Reset: 1'); + WriteLn(OutFile); + WriteLn(OutFile); + WriteLn(OutFile,InFile.sTitle+', starting at chapter '+InFile.sChapter); + WriteLn(OutFile); + fASCIIisOpen := true; + if fProse then + sLine := ' ' + else + sLine := ''; + end; + end; + end; + + procedure CheckHTMLEOL; + begin + if Length(sLine) > 75 then + begin + i := 75; + while (i > 0) and (sLine[i] <> ' ') do + dec(i); + if i < 1 then + begin + if fHTMLisOpen then WriteLn(OutFile,sLine); + sLine := '' + end + else + begin + sPrint := system.copy(sLine,1,i-1); + sSave := system.copy(sLine,i+1,Length(sLine)-i); + if fHTMLisOpen then WriteLn(OutFile,sPrint); + sLine := sSave; + end + end; + end; + + procedure StartNewHTMLLine; + begin + if fInclude then + begin + CheckHTMLEOL; + if fHTMLisOpen then WriteLn(OutFile, sLine+'</P>'); + sLine := '<P>'; + end; + end; + + +begin + QuickButton.Enabled := false; + GoBitBtn.Enabled := false; + fInclude := false; + fSkip := false; + fProse := true; + fRed := false; + LastBook := ''; + ParagraphAttributes := sNormalPar; + try + InFile := TReadGBF.Create; + if InFile.Init(Trim(SourceEdit.Text)) then + begin + LinePos := 0; + case FormatRadioGroup.ItemIndex of + -1: showmessage('No destination format selected!'); + 0: begin + Label3.Caption := 'Converting to ASCII'; + AssignFile(OutFile, DestEdit.Text); + FileMode := 1; + Rewrite(OutFile); + fASCIIisOpen := true; + sLine := ''; + repeat + wd := ANSIToOEM(InFile.GetToken(tok)); + Application.ProcessMessages; + case tok of + tokWord: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokSpace: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokSync: + begin + if fInclude and (length(wd) > 3) then + begin + if wd[3] = 'V' then + begin + sLine := sLine + '{' + InFile.sChapter+':'+ + InFile.sVerse+'} '; + CheckEOL + end + else if (wd[3] = 'C') and (InFile.bBk = 19) then + begin + StartNewLine; + WriteLn(OutFile, 'Psalm '+InFile.sChapter); + WriteLn(OutFile); + end; + if wd[3] = 'B' then + fProse := true; + end; + end; + tokContent: + begin + if wd = '<BO>' then + fInclude := true + else if wd = '<BN>' then + fInclude := true + else if wd = '<BO>' then + fInclude := ApocryphaCheckBox.Checked + end; + tokControl: + begin + if wd = '<CM>' then + begin + StartNewLine; + if fProse then + begin + WriteLn(OutFile); + sLine := ' ' + end + end + else if wd = '<CL>' then + begin + StartNewLine; + sLine := ' '; + end + else if wd = '<Pp>' then + fProse := true + else if wd = '<PP>' then + fProse := false + else if wd = '<RF>' then + fSkip := true + else if wd = '<Rf>' then + fSkip := false + else if wd = '<RN>' then + fSkip := true + else if wd = '<Rn>' then + fSkip := false + else if wd = '<ZZ>' then + fInclude := false + end; + tokChar: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokFont: + begin + if wd = '<FI>' then + begin + if fInclude then + sLine := sLine + '['; + end + else if wd = '<Fi>' then + begin + if fInclude then + sLine := sLine + ']'; + end + end; + end + until tok = tokEOF; + writeln(OutFile, sLine); + CloseFile(OutFile); + fASCIIisOpen := false; + Label3.Caption := ''; + end; + 1: begin + Label3.Caption := 'Converting to ASCII (one file/book)'; + FileMode := 1; + fASCIIisOpen := false; + sLine := ''; + repeat + Application.ProcessMessages; + wd := ANSIToOEM(InFile.GetToken(tok)); + case tok of + tokEOF: + CloseASCII; + tokWord: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokSpace: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokSync: + begin + if fInclude and (length(wd) > 3) then + begin + if wd[3] = 'V' then + begin + sLine := sLine + '{' + InFile.sChapter+':'+ + InFile.sVerse+'} '; + CheckEOL + end + else if (wd[3] = 'C') and (InFile.bBk = 19) then + begin + StartNewLine; + WriteLn(OutFile, 'Psalm '+InFile.sChapter); + WriteLn(OutFile); + end; + if wd[3] = 'B' then + begin + fProse := true; + CloseASCII; + end; + end; + end; + tokContent: + begin + if wd = '<BO>' then + fInclude := true + else if wd = '<BN>' then + fInclude := true + else if wd = '<BO>' then + fInclude := ApocryphaCheckBox.Checked + else if wd = '<Tt>' then + OpenASCII; + end; + tokControl: + begin + if wd = '<CM>' then + begin + StartNewLine; + if fProse then + begin + if fASCIIisOpen then WriteLn(OutFile); + sLine := ' ' + end + end + else if wd = '<CL>' then + begin + StartNewLine; + sLine := ' '; + end + else if wd = '<Pp>' then + fProse := true + else if wd = '<PP>' then + fProse := false + else if wd = '<RF>' then + fSkip := true + else if wd = '<Rf>' then + fSkip := false + else if wd = '<RN>' then + fSkip := true + else if wd = '<Rn>' then + fSkip := false + else if wd = '<ZZ>' then + fInclude := false + end; + tokChar: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokFont: + begin + if wd = '<FI>' then + begin + if fInclude then + sLine := sLine + '['; + end + else if wd = '<Fi>' then + begin + if fInclude then + sLine := sLine + ']'; + end + end; + end + until tok = tokEOF; + if fASCIIisOpen then writeln(OutFile, sLine); + CloseASCII; + Label3.Caption := ''; + end; + 2: begin + Label3.Caption := 'Converting ASCII postings'; + bLastBook := 255; + bChap := 0; + FileMode := 1; + iFileNumber := 0; + fASCIIisOpen := false; + sLine := ''; + repeat + Application.ProcessMessages; + wd := ANSIToOEM(InFile.GetToken(tok)); + case tok of + tokEOF: + CloseASCII; + tokWord: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokSpace: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokSync: + begin + if fInclude and (length(wd) > 3) then + begin + if wd[3] = 'V' then + begin + sLine := sLine + '{' + InFile.sChapter+':'+ + InFile.sVerse+'} '; + CheckEOL + end + else if (wd[3] = 'C') then + begin + OpenNTChapter; + if (InFile.bBk = 19) then + begin + StartNewLine; + if fASCIIisOpen then + begin + WriteLn(OutFile, 'Psalm '+InFile.sChapter); + WriteLn(OutFile); + end; + end; + end; + if wd[3] = 'B' then + begin + fProse := true; + CloseASCII; + end; + end; + end; + tokContent: + begin + if wd = '<BO>' then + fInclude := true + else if wd = '<BN>' then + begin + fInclude := true; + iFileNumber := 0; + end + else if wd = '<BO>' then + fInclude := ApocryphaCheckBox.Checked + end; + tokControl: + begin + if wd = '<CM>' then + begin + StartNewLine; + if fProse then + begin + if fASCIIisOpen then WriteLn(OutFile); + sLine := ' ' + end + end + else if wd = '<CL>' then + begin + StartNewLine; + sLine := ' '; + end + else if wd = '<Pp>' then + fProse := true + else if wd = '<PP>' then + fProse := false + else if wd = '<RF>' then + fSkip := true + else if wd = '<Rf>' then + fSkip := false + else if wd = '<RN>' then + fSkip := true + else if wd = '<Rn>' then + fSkip := false + else if wd = '<ZZ>' then + fInclude := false + end; + tokChar: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckEOL; + end; + end; + tokFont: + begin + if wd = '<FI>' then + begin + if fInclude then + sLine := sLine + '['; + end + else if wd = '<Fi>' then + begin + if fInclude then + sLine := sLine + ']'; + end + end; + end + until tok = tokEOF; + if fASCIIisOpen then writeln(OutFile, sLine); + CloseASCII; + Label3.Caption := ''; + end; + 3: begin + Label3.Caption := 'Converting to RTF'; + AssignFile(OutFile, DestEdit.Text); + FileMode := 1; + Rewrite(OutFile); + repeat + Application.ProcessMessages; + wd := InFile.GetToken(tok); + case tok of + tokWord: + begin + if fInclude then + begin + LinePos := LinePos + Length(wd); + write(OutFile,wd); + end; + end; + tokSpace: + begin + if fInclude then + begin + LinePos := LinePos + Length(wd); + if LinePos > 78 then + begin + WriteLn(OutFile,wd); + LinePos := 0; + end + else + write(OutFile,wd); + end + end; + tokSync: + begin + if length(wd) > 1 then + begin + case wd[2] of + 'B': begin + if InFile.sBook <> LastBook then + begin + LastBook := InFile.sBook; + WriteLn(OutFile,'\par '+sTitlePar+ + LastBook+'\par '+ParagraphAttributes); + LinePos := 0; + end; + end; + 'V': begin + s := '{\f5\super '+InFile.sChapter+':'+ + InFile.sVerse+'}'; + Write(OutFile,s); + LinePos := LinePos+Length(s); + end; + end; + end; + end; + tokControl: + begin + if length(wd) > 1 then + begin + case wd[2] of + 'A': fInclude := false; + 'E': begin + Write(OutFile,'{\b\cf1 '); + LinePos := LinePos + 8; + end; + 'F': fInclude := false; + 'H': begin + fInclude := true; + ParagraphAttributes := sHebrewTitlePar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'I' : begin + Write(OutFile,'{\i\cf1 '); + LinePos := LinePos + 7; + end; + 'J' : begin + Write(OutFile,'{\scaps '); + LinePos := LinePos + 8; + end; + 'K': fInclude := false; + 'M': begin + if fInclude then + begin + writeln(OutFile); + write(OutFile,'\par '+ParagraphAttributes); + LinePos := Length(ParagraphAttributes) + 5; + end; + end; + 'N': begin + fInclude := true; + ParagraphAttributes := sNormalPar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'P': begin + fInclude := true; + ParagraphAttributes := sPoetryPar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'Q': begin + fInclude := true; + ParagraphAttributes := sTitlePar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'R' : begin + Write(OutFile,'\cf6 '); + LinePos := LinePos + 4; + end; + 'S': begin + fInclude := true; + ParagraphAttributes := sSelahPar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'T': begin + fInclude := true; + ParagraphAttributes := sTitlePar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'U' : begin + Write(OutFile,'{\ul '); + LinePos := LinePos + 4; + end; + 'W': begin + fInclude := true; + ParagraphAttributes := sNormalQuotePar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'X': fInclude := false; + 'Y': begin + fInclude := true; + ParagraphAttributes := sPoetryQuotePar; + Write(OutFile,ParagraphAttributes); + LinePos := LinePos + Length(ParagraphAttributes); + end; + 'Z': fInclude := false; + 'a': fInclude := false; + 'c': fInclude := false; + 'e': begin + Write(OutFile,'}'); + inc(LinePos); + end; + 'h': fInclude := false; + 'i': begin + Write(OutFile,'}'); + inc(LinePos); + end; + 'j': begin + Write(OutFile,'}'); + inc(LinePos); + end; + 'n': fInclude := false; + 'p': fInclude := false; + 'r': begin + Write(OutFile,'}'); + inc(LinePos); + end; + 'u': begin + Write(OutFile,'}'); + inc(LinePos); + end; + + end; + end; + end; + tokChar: + begin + if fInclude then + begin + write(OutFile,wd); + LinePos := LinePos + length(wd); + end; + end; + end; + until tok = tokEOF; + writeln(OutFile,'\par }'); + CloseFile(OutFile); + Label3.Caption := ''; + end; + 4: begin // GBF + Label3.Caption := 'Converting to GBF'; + OutGBF := TWriteGBF.Create; + OutGBF.Init(Trim(DestEdit.Text)); + OutGBF.Out('<H000>'); + repeat + Application.ProcessMessages; + wd := InFile.GetToken(tok); + if tok <> tokEOF then OutGBF.Out(wd); + until tok = tokEOF; + OutGBF.Done; + OutGBF.Free; + Label3.Caption := ''; + end; + 5: begin // HTML + Label3.Caption := 'Converting to HTML'; + fHTMLisOpen := false; + repeat + Application.ProcessMessages; + wd := Infile.GetToken(tok); + case tok of + tokEOF: + CloseHTML; + tokWord: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckHTMLEOL; + end; + end; + tokSpace: + begin + if fInclude and (not fSkip) then + begin + sLine := sLine + wd; + CheckHTMLEOL; + end; + end; + tokSync: + begin + if fInclude and (length(wd) > 3) then + begin + if wd[3] = 'V' then + begin + if fRed then + sLine := sLine + '</FONT>'; + sLine := sLine + '<FONT COLOR="#0000ff"><FONT SIZE=-1><SUP>'+ + InFile.sChapter+':'+ + InFile.sVerse+'</SUP></FONT></FONT>'; + if fRed then + sLine := sLine + '<FONT COLOR="#ff0000">'; + CheckHTMLEOL + end + else if (wd[3] = 'C') and (InFile.bBk = 19) then + begin + StartNewHTMLLine; + if fHTMLisOpen then + begin + WriteLn(OutFile, '<P><H2>Psalm '+ + InFile.sChapter+'</H2>'); + WriteLn(OutFile); + end; + end; + if wd[3] = 'B' then + begin + fProse := true; + CloseHTML; + end; + end; + end; + tokContent: + begin + if wd = '<BO>' then + fInclude := true + else if wd = '<BN>' then + fInclude := true + else if wd = '<BO>' then + fInclude := ApocryphaCheckBox.Checked + else if wd = '<Tt>' then + OpenHTML; + end; + tokControl: + begin + if wd = '<CM>' then + begin + StartNewHTMLLine; + if not fProse then + begin + sLine := sLine + ' '; + end + end + else if wd = '<CL>' then + begin + StartNewHTMLLine; + sLine := sLine + ' ' + end + else if wd = '<Pp>' then + fProse := true + else if wd = '<PP>' then + fProse := false + else if wd = '<RF>' then + fSkip := true + else if wd = '<Rf>' then + fSkip := false + else if wd = '<RN>' then + fSkip := true + else if wd = '<Rn>' then + fSkip := false + else if wd = '<ZZ>' then + fInclude := false + end; + tokChar: + begin + if fInclude and (not fSkip) then + begin + if wd = '"' then + sLine := sLine + '"' + else + sLine := sLine + wd; + CheckHTMLEOL; + end; + end; + tokFont: + begin + if fInclude then + begin + if wd = '<FI>' then + sLine := sLine + '<I>' + else if wd = '<Fi>' then + sLine := sLine + '</I>' + else if wd = '<FR>' then + begin + if not fRed then + begin + sLine := sLine + '<FONT COLOR="#ff0000">'; + fRed := true + end + end + else if wd = '<Fr>' then + begin + if fRed then + begin + sLine := sLine + '</FONT>'; + fRed := false + end + end + end; + end; + end; + until tok = tokEOF; + Label3.Caption := ''; + end; + end; + InFile.Done; + end; + InFile.Free; + except + showmessage('Error!'); + end; + GoBitBtn.Enabled := true; + QuickButton.Enabled := true; +end; + +procedure TGBFConverterMainForm.GoBitBtnClick(Sender: TObject); +begin + DoConversion; +end; + +procedure TGBFConverterMainForm.Timer1Timer(Sender: TObject); +begin + If InFile <> nil then + VerseLabel.Caption := InFile.sBook+' ['+IntToStr(InFile.bBk)+'] '+ + InFile.sChapter+':'+InFile.sVerse + else + VerseLabel.Caption := ''; +end; + +procedure TGBFConverterMainForm.QuickConversion; +begin + FormatRadioGroup.ItemIndex := 1; + DoConversion; + FormatRadioGroup.ItemIndex := 2; + DoConversion; + FormatRadioGroup.ItemIndex := 5; + DoConversion; +end; + +procedure TGBFConverterMainForm.FormShow(Sender: TObject); +begin + VerseLabel.Caption := ''; + WdLabel.Caption := ''; +end; + +(* +procedure TGBFConverterMainForm.TransformButtonClick(Sender: TObject); +var apoc: textfile; + last, s, sBook, sChap, sVs: string; + blankcount, i: integer; +begin + TransformButton.Enabled := false; + blankcount := 0; + assignfile(apoc, trim(sourceedit.text)); + reset(apoc); + assignfile(outfile, trim(destedit.text)); + rewrite(outfile); + last := ''; + while not eof(apoc) do + begin + readln(apoc, s); + if s = '' then + begin + inc(blankcount); + if last <> '' then + begin + writeln(outfile, last, '~M'); + last := ''; + end; + end + else + begin + if blankcount >= 2 then + writeln(outfile, '~T',s,'~N~M') // book title + else if blankcount = 1 then + begin + sBook := ''; + sChap := ''; + sVs := ''; + i := 1; + while (s[i] <> ' ') and (i <= Length(s)) do + begin + sBook := sBook + s[i]; + inc(i); + end; + while (s[i] = ' ') and (i <= Length(s)) do + inc(i); + while (s[i] <> ':') and (i <= Length(s)) do + begin + sChap := sChap + s[i]; + inc(i); + end; + inc(i); + while IsDigit(s[i]) and (i <= Length(s)) do + begin + sVs := sVs + s[i]; + inc(i); + end; + write(outfile, '~B'+sBook+';~C'+sChap+';'); + if sVs <> '' then + write(outfile, '~V'+sVs+';'); + end + else + begin + if last <> '' then + begin + writeln(outfile, last); + end; + last := s; + end; + blankcount := 0; + end; + end; + if last <> '' then + begin + writeln(outfile, last); + last := s; + end; + closefile(outfile); + closefile(apoc); + TransformButton.Enabled := true; +end; +*) + +procedure TGBFConverterMainForm.FormatRadioGroupClick(Sender: TObject); +begin + Case FormatRadioGroup.ItemIndex of + 0: // Plain ASCII (one file) + DestEdit.Text := 'pub\web.txt'; + 1: // Plain ASCII (one file per book) + DestEdit.Text := 'pub\web.htm'; + 2: // Daily posts + DestEdit.Text := 'pub\queue\web.txt'; + 3: // RTF + DestEdit.Text := 'pub\web.rtf'; + 4: // GBF + DestEdit.Text := 'pub\web.gbf'; + 5: // HTML + DestEdit.Text := 'pub\htm\web.htm'; + end; +end; + +procedure TGBFConverterMainForm.QuickButtonClick(Sender: TObject); +begin + QuickConversion; +end; + +procedure TGBFConverterMainForm.FormActivate(Sender: TObject); +begin + if ParamCount > 0 then + if ParamStr(1) = 'quick' then + begin + QuickConversion; + close; + end; +end; + +end. diff --git a/src/modules/texts/rawgbf/Makefile b/src/modules/texts/rawgbf/Makefile new file mode 100644 index 0000000..35d6648 --- /dev/null +++ b/src/modules/texts/rawgbf/Makefile @@ -0,0 +1,5 @@ + +root := ../../../.. + +all: + make -C ${root} diff --git a/src/modules/texts/rawgbf/Makefile.am b/src/modules/texts/rawgbf/Makefile.am new file mode 100644 index 0000000..ab6aa2e --- /dev/null +++ b/src/modules/texts/rawgbf/Makefile.am @@ -0,0 +1,4 @@ +rawgbfdir = $(top_srcdir)/src/modules/texts/rawgbf + +libsword_la_SOURCES += $(rawgbfdir)/rawgbf.cpp + diff --git a/src/modules/texts/rawgbf/gbf.cpp b/src/modules/texts/rawgbf/gbf.cpp new file mode 100644 index 0000000..dc67a1c --- /dev/null +++ b/src/modules/texts/rawgbf/gbf.cpp @@ -0,0 +1,735 @@ +enum TToken { +tokNull, tokEOF, tokHeader, tokContent, tokTail, tokStyle, + tokWord, tokSpace, tokSync, tokControl, tokChar, tokFont}; + +enum TCharacterAttribute { caBold, caSmallCaps, caItalic, caOTQuote, caRed, + caSuperscript, caUnderline, caSubscript}; + +// TCharAttribs = set of TCharacterAttribute; + + +struct TBookNameRec { + string Name, Abbr; + char Num; +} + +const struct TBookNameRec TBookAbbr[116] = { + {"1 Chronicles", "1CH", 13}, //0 + {"1 Corinthians", "1CO", 70}, //1 + {"1 Esdras", "1E", 52}, //2 + {"1 John", "1J", 86}, //3 + {"1 Kings", "1K", 11}, //4 + {"1 Maccabees", "1M", 50}, //5 + {"1 Peter", "1P", 84}, //6 + {"1 Samuel", "1S", 9}, //7 + {"1 Thessalonians", "1TH", 76}, //8 + {"1 Timothy", "1TI", 78}, //9 + {"2 Chronicles", "2CH", 14}, //10 + {"2 Corinthians", "2CO", 71}, //11 + {"2 Esdras", "2E", 56}, //12 + {"2 John", "2J", 87}, //13 + {"2 Kings", "2K", 12}, //14 + {"2 Maccabees", "2M", 51}, //15 + {"2 Peter", "2P", 85}, //16 + {"2 Samuel", "2S", 10}, //17 + {"2 Thessalonians", "2TH", 77}, //18 + {"2 Timothy", "2TI", 79}, //19 + {"3 John", "3J", 88}, //20 + {"3 Maccabees", "3M", 55}, //21 + {"4 Maccabees", "4M", 57}, //22 + {"1 Chronicles", "1 CH", 13}, //0 + {"1 Corinthians", "1 CO", 70}, //1 + {"1 Esdras", "1 E", 52}, //2 + {"1 John", "1 J", 86}, //3 + {"1 Kings", "1 K", 11}, //4 + {"1 Maccabees", "1 M", 50}, //5 + {"1 Peter", "1 P", 84}, //6 + {"1 Samuel", "1 S", 9}, //7 + {"1 Thessalonians", "1 TH", 76}, //8 + {"1 Timothy", "1 TI", 78}, //9 + {"2 Chronicles", "2 CH", 14}, //10 + {"2 Corinthians", "2 CO", 71}, //11 + {"2 Esdras", "2 E", 56}, //12 + {"2 John", "2 J", 87}, //13 + {"2 Kings", "2 K", 12}, //14 + {"2 Maccabees", "2 M", 51}, //15 + {"2 Peter", "2 P", 85}, //16 + {"2 Samuel", "2 S", 10}, //17 + {"2 Thessalonians", "2 TH", 77}, //18 + {"2 Timothy", "2 TI", 79}, //19 + {"3 John", "3 J", 88}, //20 + {"3 Maccabees", "3 M", 55}, //21 + {"4 Maccabees", "4 M", 57}, //22 + {"Acts", "AC", 68}, //23 + {"Amos", "AM", 30}, //24 + {"Prayer of Asariah and the Song of the Three Jews", "AZ", 47}, + {"Baruch", "BA", 45}, //26 + {"Bel and the Dragon","BE", 49}, //27 + {"Colossians", "CO", 75}, //28 + {"Daniel", "DA", 27}, //29 + {"Deuteronomy", "DE", 5}, //30 + {"Deuteronomy", "DT", 5}, //31 + {"Ecclesiasties", "EC", 21}, //32 + {"Esther", "ES", 17}, //33 + {"Exodus", "EX", 2}, //34 + {"Ezekiel", "EZE", 26}, //35 + {"Ezra", "EZR", 15}, //36 + {"Galatians", "GA", 72}, //37 + {"Genesis", "GE", 1}, //38 + {"Genesis", "GN", 1}, //39 + {"Ephesians", "EP", 73}, //40 + {"Esther (Greek}", "GR", 42), //41 + {"Habakkuk", "HAB", 35}, //42 + {"Haggai", "HAG", 37}, //43 + {"Hebrews", "HE", 82}, //44 + {"Hosea", "HO", 28}, //45 + {"Isaiah", "IS", 23}, //46 + {"James", "JA", 83}, //47 + {"Jeremiah", "JE", 24}, //48 + {"Job", "JOB", 18}, //49 + {"Joel", "JOE", 29}, //50 + {"John", "JOH", 67}, //51 + {"Jonah", "JON", 32}, //52 + {"Joshua", "JOS", 6}, //53 + {"Jude", "JUDE", 89}, //54 + {"Judges", "JUDG", 7}, //55 + {"Judith", "JUDI", 41}, //56 + {"Lamentations", "LA", 25}, //57 + {"Letter of Jeremiah",Abbr:"LET", 46}, //58 + {"Leviticus", "LEV", 3}, //59 + {"Luke", "LK", 66}, //60 + {"Leviticus", "LV", 3}, //61 + {"Luke", "LU", 66}, //62 + {"Malachi", "MAL", 39}, //63 + {"Prayer of Manasseh",Abbr:"MAN", 53}, //64 + {"Mark", "MAR", 65}, //65 + {"Matthew", "MAT", 64}, //66 + {"Micah", "MI", 33}, //67 + {"Nahum", "NA", 34}, //68 + {"Nehemiah", "NE", 16}, //69 + {"Numbers", "NU", 4}, //70 + {"Obadiah", "OB", 31}, //71 + {"Psalm 151", "P1", 54}, //72 + {"Philemon", "PHILE", 81}, //73 + {"Philippians", "PHILI", 74}, //74 + {"Philemon", "PHM", 81}, //75 + {"Philippians", "PHP", 74}, //76 + {"Proverbs", "PR", 20}, //77 + {"Psalms", "PS", 19}, //78 + {"Revelation", "RE", 90}, //79 + {"Romans", "RM", 69}, //80 + {"Romans", "RO", 69}, //81 + {"Ruth", "RU", 8}, //82 + {"Sirach", "SI", 44}, //83 + {"Song of Solomon", "SOL", 22}, //84 + {"Song of Solomon", "SON", 22}, //85 + {"Song of Solomon", "SS", 22}, //86 + {"Susanna", "SU", 48}, //87 + {"Titus", "TI", 80}, //88 + {"Tobit", "TO", 40}, //89 + {"Wisdom", "WI", 43}, //90 + {"Zechariah", "ZEC", 38}, //91 + {"Zephaniah", "ZEP", 36} //92 + }, + +string BookFileName[91] = { + "","Genesis","Exodus","Lev","Num","Deut","Joshua","Judges", // 0 - 7 + "Ruth","1Sam","2Sam","1Kings","2Kings","1Chron","2Chron", // 8 - 14 + "Ezra","Nehemiah","Esther","Job","Psalms","Proverbs", // 15-20 + "Eccl","Song","Isaiah","Jeremiah","Lament","Ezekiel", // 21-26 + "Daniel","Hosea","Joel","Amos","Obadiah","Jonah","Micah", // 27-33 + "Nahum","Habakkuk","Zeph","Haggai","Zech","Malachi", // 34-39 + "Tobit","Judith","Esther","Wisdom","Sirach","Baruch", // 40-45 + "Let","Azar","Susanna","Bel","1Mac","2Mac","1Esdras", // 46-52 + "Man","P1","3Mac","2Esdras","4Mac","","","","","","", // 53-63 + "Matthew","Mark","Luke","John","Acts","Romans","1Cor", // 64-70 + "2Cor","Gal","Eph","Philip","Col","1Thes","2Thes","1Tim", // 71-78 + "2Tim","Titus","Philemon","Hebrews","James","1Peter", // 79-84 + "2Peter","1John","2John","3John","Jude","Rev"}; // 85-90 + +class TReadGBF { +private: + FILE *fp; + string FName, TokenLine; + int TokenPos; + bool fFileIsOpen, fParagraphEnd, fInTitle, fInPsalmBookTitle, fInHebrewTitle, fInSectionTitle; + +public: + string sBook, sChapter, sVerse, sMode; + string sContext; // Last text type (header, body, or tail) + string sTitle; // Title of this book of the Bible + string sPsalmBookTitle; // Title of this Psalm book + string sHebrewTitle; // Psalm Hebrew title + string sSectionTitle; // Section headings + string sDate; + string sFontName; + int iTotalWords; + char chJustification, chDirection; + bool fIndent, fPoetry; + int CharAttribs; + char bBk, bChap, bVs, bWd; + + bool Init(const string sFileName); + void Done(); + string GetToken(TToken &TokenKind); + end; + +class TWriteGBF { + private: + F: TextFile; + FName, LineOut: string; + fFileIsOpen: boolean; + bBk, bChap, bVs, bWd: byte; + + public + + function Init(const sFileName: string): boolean; + function Done: boolean; + procedure Out(const s: string); + end; + +function isletter(const ch: char): boolean; +function isinword(const ch: char): boolean; +function IsDigit(const ch: char): Boolean; +function IsUpper(const ch: char): Boolean; +function ConformCase(const sPat, sSrc: string): string; +function BookNameToNumber(const sBookName: string): byte; + +implementation + +function isletter(const ch: char): boolean; +begin + case ch of + 'A'..'Z': isletter := true; + 'a'..'z': isletter := true; + else + isletter := false; + end; +end; + +function isinword(const ch: char): boolean; +begin + case ch of + '-': isinword := true; + 'A'..'Z': isinword := true; + 'a'..'z': isinword := true; + else + isinword := false; + end; +end; + +function IsUpper(const ch: char): Boolean; +begin + case ch of + 'A'..'Z': IsUpper := true; + else + IsUpper := false; + end; +end; + +function IsDigit(const ch: char): Boolean; +begin + case ch of + '0'..'9': IsDigit := true; + else + IsDigit := false; + end; +end; + + +function MatchAbbrev(const sName, sAbbrev: string): boolean; +var i: integer; +begin + if Length(sName) < Length(sAbbrev) then + Result := false + else + Result := true; + i := 1; + while (i <= Length(sAbbrev)) and Result do + begin + if UpCase(sName[i]) <> sAbbrev[i] then + Result := false; + inc(i); + end; +end; + +function BookNameToNumber(const sBookName: string): byte; +var i: integer; +begin + Result := 0; + try + if IsDigit(sBookName[Length(sBookName)]) and IsDigit(sBookName[1]) then + Result := StrToInt(sBookName); + except + Result := 0; + end; + i := 0; + while (Result = 0) and (i <= 115) do // Yuk! Linear search. + begin + if MatchAbbrev(sBookName,BookAbbr[i].Abbr) then + begin + Result := BookAbbr[i].Num; + end; + inc(i); + end; +end; + +function BookNumberToName(const bBookNum: byte): string; +begin + if bBookNum <= 115 then + Result := BookAbbr[bBookNum].Name + else + Result := ''; +end; + +function ConformCase(const sPat, sSrc: string): string; +var i: integer; +begin + Result := sSrc; + if (Length(sPat) > 0) and (Length(sSrc) > 0) then + begin + Result := LowerCase(sSrc); + if IsUpper(sPat[1]) then + Result[1] := UpCase(Result[1]); + if (Length(sPat) > 1) and (Length(sSrc) > 1) then + begin + if IsUpper(sPat[2]) then + begin + for i := 2 to Length(Result) do + Result[i] := UpCase(Result[i]); + end; + end; + end; +end; + +function TReadGBF.Init(const sFileName: string): boolean; +var s: string; + tok: TToken; +begin + try + fParagraphEnd := false; + bBk := 0; + bChap := 0; + bVs := 0; + bWd := 0; + iTotalWords := 0; + FName := sFileName; + Assign(F, FName); + reset(F); + readln(F, TokenLine); + TokenPos := 1; + fFileIsOpen := true; + repeat + s := GetToken(tok) + until (tok = tokEOF) or ((tok = tokHeader) and (s[3] = '0')); + Init := true; + except + Init := false; + fFileIsOpen := false; + end +end; + +procedure TReadGBF.Done; +begin + if fFileIsOpen then + begin + closefile(F); + fFileIsOpen := false; + end; +end; + +function TReadGBF.GetToken(var TokenKind: TToken): string; +var m: integer; +begin + Result := ''; + TokenKind := tokNull; + if TokenPos = 0 then + begin + if (not fFileIsOpen) or EOF(F) then + TokenKind := tokEOF + else + begin + ReadLn(F,TokenLine); + TokenPos := 1; + end; + end; + if TokenKind <> tokEOF then + begin + m := Length(TokenLine); + if TokenPos > m then + begin + TokenKind := tokSpace; + if fParagraphEnd then + fParagraphEnd := false + else + Result := ' '; + TokenPos := 0; + end + else + begin + if (TokenLine[TokenPos] = '<') then + begin + fParagraphEnd := false; + repeat + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + until (TokenLine[TokenPos] = '>') or (TokenPos > m); + Result := Result + '>'; + inc(TokenPos); + case result[2] of + 'B': begin // File body text type + TokenKind := tokContent; + sContext := Result; + end; + 'C': begin // Special characters + TokenKind := tokControl; + if (Result[3] = 'M') or (Result[3] = 'L') then + fParagraphEnd := true; + end; + 'D': begin // Direction + TokenKind := tokControl; + chDirection := Result[3]; + end; + 'H': begin + TokenKind := tokHeader; + sContext := Result; + end; + 'F': begin // Font attributes + TokenKind := tokFont; + case Result[3] of + 'B': CharAttribs := CharAttribs + [caBold]; + 'C': CharAttribs := CharAttribs + [caSmallCaps]; + 'I': CharAttribs := CharAttribs + [caItalic]; + 'N': sFontName := copy(Result,4,Length(Result)-4); + 'O': CharAttribs := CharAttribs + [caOTQuote]; + 'R': CharAttribs := CharAttribs + [caRed]; + 'S': CharAttribs := CharAttribs + [caSuperscript]; + 'U': CharAttribs := CharAttribs + [caUnderline]; + 'V': CharAttribs := CharAttribs + [caSubscript]; + 'b': CharAttribs := CharAttribs - [caBold]; + 'c': CharAttribs := CharAttribs - [caSmallCaps]; + 'i': CharAttribs := CharAttribs - [caItalic]; + 'n': sFontName := ''; + 'o': CharAttribs := CharAttribs - [caOTQuote]; + 'r': CharAttribs := CharAttribs - [caRed]; + 's': CharAttribs := CharAttribs - [caSuperscript]; + 'u': CharAttribs := CharAttribs - [caUnderline]; + 'v': CharAttribs := CharAttribs - [caSubscript]; + + end; + end; + 'J': begin // Justification + TokenKind := tokStyle; + chJustification := Result[3]; + end; + 'P': begin // Poetry/prose, indent + TokenKind := tokControl; + case Result[3] of + 'I': fIndent := true; + 'P': fPoetry := true; + 'i': fIndent := false; + 'p': fPoetry := false; + end; + end; + 'R': begin // References and footnotes + TokenKind := tokControl; + end; + 'S': begin // sync mark + TokenKind := TokSync; + case Result[3] of + 'B': begin // Book + sBook := system.copy(Result, 4, length(Result)-4); + sPsalmBookTitle := ''; + if sBook = '' then + begin + inc(bBk); + sBook := BookNumberToName(bBk); + end + else + bBk := BookNameToNumber(sBook); + sTitle := sBook; + end; + 'C': begin //chapter + sChapter := system.copy(Result, 4, length(Result)-4); + if sChapter = '' then + begin + inc(bChap); + sChapter := IntToStr(bChap); + end + else + begin + try + bChap := StrToInt(sChapter); + except + showmessage('Non-numeric chapter: '+sBook+' '+sChapter); + end; + end; + sHebrewTitle := ''; + end; + 'V': begin // Verse + bWd := 0; + sVerse := system.copy(Result, 4, length(Result)-4); + if sVerse = '' then + begin + inc(bVs); + sVerse := IntToStr(bVs); + end + else + begin + try + bVs := StrToInt(sVerse); + except + showmessage('Non-numeric verse: '+sBook+' '+sChapter+':'+sVerse); + end; + end; + end; + 'D': begin // Date + sDate := system.copy(Result, 3, length(Result)-4); + end; + end; + end; + 'T': begin // Titles + TokenKind := TokContent; + case Result[3] of + 'B': + begin + sPsalmBookTitle := ''; + fInPsalmBookTitle := true; + end; + 'b': fInPsalmBookTitle := true; + 'H': + begin + sHebrewTitle := ''; + fInHebrewTitle := true; + end; + 'h': fInHebrewTitle := false; + 'S': + begin + sSectionTitle := ''; + fInSectionTitle := true; + end; + 's': fInSectionTitle := false; + 'T': + begin + sTitle := ''; + fInTitle := true; + end; + 't': fInTitle := false; + end; + end; + 'Z': begin // File tail + TokenKind := tokTail; + sContext := Result; + if Result[3] = 'Z' then + done; + end; + else + TokenKind := TokControl; + + end; + end + else if isletter(TokenLine[TokenPos]) then + begin {Word} + fParagraphEnd := false; + TokenKind := tokWord; + repeat + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + until (TokenPos > m) or (not isinword(TokenLine[TokenPos])); + inc(bWd); + inc(iTotalWords); + end + else if ((TokenLine[TokenPos] = ' ') or (TokenLine[TokenPos] = #9)) then + begin + fParagraphEnd := false; + TokenKind := tokSpace; + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + end + else + begin + fParagraphEnd := false; + TokenKind := tokChar; + Result := Result + TokenLine[TokenPos]; + inc(TokenPos); + end + end; + end; + if ((TokenKind = tokWord) or (TokenKind = tokSpace) or + (TokenKind = tokChar)) then + begin + if fInTitle then + sTitle := sTitle + Result + else if fInPsalmBookTitle then + sPsalmBookTitle := sPsalmBookTitle + Result + else if fInHebrewTitle then + sHebrewTitle := sHebrewTitle + Result + else if fInSectionTitle then + sSectionTitle := sSectionTitle + Result; + end; +end; + +function TWriteGBF.Init(const sFileName: string): boolean; +begin + try + bBk := 0; + bChap := 0; + bVs := 0; + bWd := 0; + LineOut := ''; + FName := sFileName; + Assign(F, FName); + filemode := 1; + rewrite(F); + fFileIsOpen := true; + Init := true; + except + Init := false; + fFileIsOpen := false; + end +end; + +function TWriteGBF.Done: boolean; +begin + try + if fFileIsOpen then + begin + if LineOut <> '' then + begin + WriteLn(F, LineOut); + LineOut := ''; + end; + CloseFile(F); + end; + Done := true; + except + Done := false; + end; +end; + +procedure TWriteGBF.Out(const s: string); +var sPrint, sSave, sBook, sChapter, sVerse: string; + i: integer; + b: byte; +begin + if (Length(s) > 0) and IsLetter(s[1]) then + begin + inc(bWd); + LineOut := LineOut + s; + end + else if Length(s) > 3 then + begin + if (s[1] = '<') and (s[2] = 'S') then + begin + case s[3] of + 'B': begin // Book + sBook := system.copy(s, 4, length(s)-4); + if sBook = '' then + begin + inc(bBk); + LineOut := LineOut + s; + end + else + begin + b := bBk; + bBk := BookNameToNumber(sBook); + if b <> bBk then + LineOut := LineOut + s; + end; + end; + 'C': begin //chapter + sChapter := system.copy(s, 4, length(s)-4); + if sChapter = '' then + begin + inc(bChap); + LineOut := LineOut + s; + end + else + begin + try +// b := bChap; + bChap := StrToInt(sChapter); +// if b <> bChap then + LineOut := LineOut + s; + except + showmessage('Non-numeric chapter: '+sBook+' '+sChapter); + end; + end; + end; + 'V': begin // Verse + bWd := 0; + sVerse := system.copy(s, 4, length(s)-4); + if sVerse = '' then + begin + inc(bVs); + LineOut := LineOut + s; + end + else + begin + try +// b := bVs; + bVs := StrToInt(sVerse); +// if b <> bVs then + LineOut := LineOut + s; + except + showmessage('Non-numeric verse: '+sBook+' '+sChapter+':'+sVerse); + end; + end; + end; + else + LineOut := LineOut + s; + end + end + else + LineOut := LineOut + s; // Not a sync mark + end + else // other token, space, or punctuation + LineOut := LineOut + s; // Length <= 3 + if ((s = '<CM>') or (s = '<CL>')) then + begin + if (Length(LineOut) > 78) then + begin + i := 78; + while (i > 0) and (LineOut[i] <> ' ') do + dec(i); + if i < 1 then + begin + WriteLn(F,LineOut); + LineOut := ''; + end + else + begin + sPrint := system.copy(LineOut,1,i-1); + sSave := system.copy(LineOut,i+1,Length(LineOut)-i); + WriteLn(F,sPrint); + WriteLn(F, sSave); + LineOut := ''; + end + end + else + begin + WriteLn(F, LineOut); + LineOut := ''; + end + end + else if (Length(LineOut) > 78) then + begin + i := 78; + while (i > 0) and (LineOut[i] <> ' ') do + dec(i); + if i < 1 then + begin + WriteLn(F,LineOut); + LineOut := ''; + end + else + begin + sPrint := system.copy(LineOut,1,i-1); + sSave := system.copy(LineOut,i+1,Length(LineOut)-i); + WriteLn(F,sPrint); + LineOut := sSave; + end + end +end; + +end. diff --git a/src/modules/texts/rawgbf/gbf.h b/src/modules/texts/rawgbf/gbf.h new file mode 100644 index 0000000..b695759 --- /dev/null +++ b/src/modules/texts/rawgbf/gbf.h @@ -0,0 +1,67 @@ +/* Header for module GBF, generated by p2c */ +#ifndef GBF_H +#define GBF_H +/* p2c: Gbf.pas, line 5: Warning: Could not find module SYSUTILS [271] */ + + +#include "sysutils.h" +/* p2c: Gbf.pas, line 5: Warning: Could not find module DIALOGS [271] */ +#include "dialogs.h" + + +#ifdef GBF_G +# define vextern +#else +# define vextern extern +#endif + + + +typedef enum { + tokNull, tokEOF, tokHeader, tokContent, tokTail, tokStyle, tokWord, + tokSpace, tokSync, tokControl, tokChar, tokFont +} TToken; +typedef enum { + caBold, caSmallCaps, caItalic, caOTQuote, caRed, caSuperscript, caUnderline, + caSubscript +} TCharacterAttribute; +typedef long TCharAttribs; + + + +typedef struct TBookNameRec { + Char Name[256], Abbr[256]; + uchar Num; +} TBookNameRec; + +typedef TBookNameRec TBookAbbr[116]; +/* p2c: Gbf.pas, line 25: + * Warning: Expected an expression, found a '/' [227] */ +/* p2c: Gbf.pas, line 25: + * Warning: Expected an expression, found a '/' [227] */ +/* p2c: Gbf.pas, line 25: Warning: Division by zero [163] */ +/* p2c: Gbf.pas, line 26: Warning: Division by zero [163] */ +/* p2c: Gbf.pas, line 26: Warning: Expected a ')', found a '(' [227] */ +/* p2c: Gbf.pas, line 144: + * Warning: Expected an expression, found a '/' [227] */ +/* p2c: Gbf.pas, line 144: + * Warning: Expected an expression, found a '/' [227] */ +/* p2c: Gbf.pas, line 144: Warning: Division by zero [163] */ +/* p2c: Gbf.pas, line 144: Warning: Division by zero [163] */ +/* p2c: Gbf.pas, line 145: Warning: Mixing non-strings with strings [170] */ +/* p2c: Gbf.pas, line 145: + * Warning: Expected a ')', found a string literal [227] */ + + +extern TBookAbbr BookAbbr; + +extern Char BookFileName[91][256]; + +vextern Char STR1[256]; + + +#undef vextern + +#endif /*GBF_H*/ + +/* End. */ diff --git a/src/modules/texts/rawgbf/gbfidx.cpp b/src/modules/texts/rawgbf/gbfidx.cpp new file mode 100644 index 0000000..8337d62 --- /dev/null +++ b/src/modules/texts/rawgbf/gbfidx.cpp @@ -0,0 +1,294 @@ +/***************************************************************************** + * + * This code wreaks but works (at least for WEB). Good luck! + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + +#include <fcntl.h> +#include <versekey.h> + + +void writeidx(VerseKey &key1, VerseKey &key2, VerseKey &key3, long offset, short size); +char findbreak(int fp, long *offset, int *num1, int *num2, int *rangemax, short *size); +void openfiles(char *fname); +void checkparams(int argc, char **argv); + + +VerseKey key1, key2, key3; +int fp, vfp, cfp, bfp; +long chapoffset; +short chapsize; +char testmnt; + + +main(int argc, char **argv) +{ + long pos, offset; + int num1, num2, rangemax, curbook = 0, curchap = 0, curverse = 0; + char buf[127], startflag = 0; + short size, tmp; + + checkparams(argc, argv); + + openfiles(argv[1]); + + testmnt = key1.Testament(); + num1 = key1.Chapter(); + num2 = key1.Verse(); + pos = 0; + write(bfp, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfp, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfp, &pos, 4); /* Module intro */ + write(vfp, &size, 2); + write(vfp, &pos, 4); /* Testament intro */ + write(vfp, &size, 2); + + while(!findbreak(fp, &offset, &num1, &num2, &rangemax, &size)) { + if (!startflag) { + startflag = 1; + } + else { + if (num2 < key2.Verse()) { // new chapter + if (num1 <= key2.Chapter()) { // new book + key2.Verse(1); + key2.Chapter(1); + key2.Book(key2.Book()+1); + } + printf("Found Chapter Break: %d ('%s')\n", num1, (const char *)key2); + chapoffset = offset; + chapsize = size; +// continue; + } + } + key2.Verse(1); + key2.Chapter(num1); + key2.Verse(num2); + + key3 = key2; +// key3 += (rangemax - key3.Verse()); + + writeidx(key1, key2, key3, offset, size); + } + close(vfp); + close(cfp); + close(bfp); + close(fp); +} + + +/************************************************************************** + * ENT: key1 - current location of index + * key2 - minimum keyval for which this offset is valid + * key3 - maximum keyval for which this offset is valid + */ + +void writeidx(VerseKey &key1, VerseKey &key2, VerseKey &key3, long offset, short size) +{ + long pos; + short tmp; + + for (; ((key1 <= key3) && (key1.Error() != KEYERR_OUTOFBOUNDS) && (key1.Testament() == testmnt)); key1+=1) { + if (key1.Verse() == 1) { // new chapter + if (key1.Chapter() == 1) { // new book + pos = lseek(cfp, 0, SEEK_CUR); + write(bfp, &pos, 4); + pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfp, &pos, 4); + write(vfp, &chapoffset, 4); /* Book intro (vss) set to same as chap for now(it should be chap 1 which usually contains the book into anyway)*/ + write(vfp, &chapsize, 2); + } + pos = lseek(vfp, 0, SEEK_CUR); + write(cfp, &pos, 4); + write(vfp, &chapoffset, 4); /* Chapter intro */ + write(vfp, &chapsize, 2); + } + if (key1 >= key2) { + write(vfp, &offset, 4); + write(vfp, &size, 2); + } + else { + pos = 0; + tmp = 0; + write(vfp, &pos, 4); + write(vfp, &tmp, 2); + } + } +} + + +char startchap(char *buf) +{ + char loop; + + if (buf[0] != '<') + return 0; + if (buf[1] != 'S') + return 0; + if (buf[2] != 'C') + return 0; +/* + if (!isdigit(buf[2])) + return 0; + for (loop = 3; loop < 7; loop++) { + if (buf[loop] == ' ') + break; + if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-')) + return 0; + } +*/ + return 1; +} + + +char startentry(char *buf) +{ + char loop; + + if (buf[0] != '<') + return 0; + if (buf[1] != 'S') + return 0; + if (buf[2] != 'V') + return 0; +/* + if (!isdigit(buf[2])) + return 0; + for (loop = 3; loop < 7; loop++) { + if (buf[loop] == ' ') + break; + if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-')) + return 0; + } +*/ + return 1; +} + + +char findbreak(int fp, long *offset, int *num1, int *num2, int *rangemax, short *size) +{ + char buf[7]; + char buf2[20]; + char ch; + char loop; + long offset2; + int ch2, vs2, rm2; + bool flag; + long chapstart = 0; + + memset(buf, ' ', 7); + + while (1) { + if (startchap(buf)) { + chapstart = lseek(fp, 0, SEEK_CUR) - 7; + memset(buf, ' ', 3); + flag = false; + for (loop = 3; loop < 6; loop++) { + if (isdigit(buf[loop])) + flag = true; + else { + buf[loop] = 0; + break; + } + } + if (flag) + *num1 = atoi(buf); + else (*num1)++; + } + if (startentry(buf)) { + memset(buf, ' ', 3); + flag = false; + for (loop = 3; loop < 6; loop++) { + if (isdigit(buf[loop])) + flag = true; + else { + buf[loop] = 0; + break; + } + if (flag) + *num2 = atoi(buf); + else (*num2)++; + } + loop++; + if (size) + *offset = lseek(fp, 0, SEEK_CUR) - (7 - loop); + else *offset = (chapstart) ? chapstart : lseek(fp, 0, SEEK_CUR) - 7; + if (size) { + ch2 = *num1; + vs2 = *num2; + if (findbreak(fp, &offset2, &ch2, &vs2, &rm2, 0)) { + *size = (short) (lseek(fp, 0, SEEK_END) - (*offset)); + } + else { + if (vs2) { + *size = (offset2 - (*offset)); + } + } + lseek(fp, *offset, SEEK_SET); + } + return 0; + } + memmove(buf, &buf[1], 6); + if (read(fp, &buf[6], 1) != 1) + return 1; + } +} + + +void openfiles(char *fname) +{ +#ifndef O_BINARY // O_BINARY is needed in Borland C++ 4.53 +#define O_BINARY 0 // If it hasn't been defined than we probably +#endif // don't need it. + char buf[255]; + + if ((fp = open(fname, O_RDONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", fname); + exit(1); + } + + sprintf(buf, "%s.vss", fname); + if ((vfp = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", fname); + if ((cfp = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", fname); + if ((bfp = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } +} + + +void checkparams(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "usage: %s <file to process> [nt - for new testmt file]\n", argv[0]); + exit(1); + } + if (argc == 3) + key1 = key2 = key3 = "Matthew 1:1"; + else key1 = key2 = key3 = "Genesis 1:1"; +} diff --git a/src/modules/texts/rawgbf/rawgbf.cpp b/src/modules/texts/rawgbf/rawgbf.cpp new file mode 100644 index 0000000..dd2fd47 --- /dev/null +++ b/src/modules/texts/rawgbf/rawgbf.cpp @@ -0,0 +1,84 @@ +/****************************************************************************** + * rawgbf.cpp - code for class 'RawGBF'- a module that reads raw text files: + * ot and nt using indexs ??.bks ??.cps ??.vss + */ + + +#include <ctype.h> +#include <stdio.h> +#include <fcntl.h> + +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + +#include <string.h> +#include <utilfuns.h> +#include <rawverse.h> +#include <rawgbf.h> + + +/****************************************************************************** + * RawGBF Constructor - Initializes data for instance of RawGBF + * + * ENT: iname - Internal name for module + * idesc - Name to display to user for module + * idisp - Display object to use for displaying + */ + +RawGBF::RawGBF(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp) : SWText(iname, idesc, idisp), RawVerse(ipath) +{ +} + + +/****************************************************************************** + * RawGBF Destructor - Cleans up instance of RawGBF + */ + +RawGBF::~RawGBF() +{ +} + + +/****************************************************************************** + * RawGBF::operator char * - Returns the correct verse when char * cast + * is requested + * + * RET: string buffer with verse + */ + +RawGBF::operator char*() +{ + long start; + unsigned short size; + VerseKey *key = 0; + +#ifndef _WIN32_WCE + try { +#endif + key = SWDYNAMIC_CAST(VerseKey, this->key); +#ifndef _WIN32_WCE + } + catch ( ... ) {} +#endif + if (!key) + key = new VerseKey(this->key); + + + findoffset(key->Testament(), key->Index(), &start, &size); + + if (entrybuf) + delete [] entrybuf; + entrybuf = new char [ size * 3 ]; // extra for conversion to RTF or other. + + readtext(key->Testament(), start, size + 1, entrybuf); + preptext(entrybuf); + RenderText(entrybuf, size * 3); + + if (key != this->key) + delete key; + + return entrybuf; +} diff --git a/src/modules/texts/rawtext/Makefile b/src/modules/texts/rawtext/Makefile new file mode 100644 index 0000000..35d6648 --- /dev/null +++ b/src/modules/texts/rawtext/Makefile @@ -0,0 +1,5 @@ + +root := ../../../.. + +all: + make -C ${root} diff --git a/src/modules/texts/rawtext/Makefile.am b/src/modules/texts/rawtext/Makefile.am new file mode 100644 index 0000000..d0e1d7e --- /dev/null +++ b/src/modules/texts/rawtext/Makefile.am @@ -0,0 +1,4 @@ +rawtextdir = $(top_srcdir)/src/modules/texts/rawtext + +libsword_la_SOURCES += $(rawtextdir)/rawtext.cpp + diff --git a/src/modules/texts/rawtext/kjvidx.cpp b/src/modules/texts/rawtext/kjvidx.cpp new file mode 100644 index 0000000..708a9e6 --- /dev/null +++ b/src/modules/texts/rawtext/kjvidx.cpp @@ -0,0 +1,169 @@ +#include <stdio.h> +#include <fcntl.h> +#include <versekey.h> + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size); + + +main(int argc, char **argv) +{ + int fp, vfp, cfp, bfp; + long pos; + short size, tmp; + int num1, num2, offset, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + VerseKey mykey; + + if ((argc < 2) || (argc > 3)) { + fprintf(stderr, "usage: %s <file to process> [nt]\n", argv[0]); + exit(1); + } + + if ((fp = open(argv[1], O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", argv[1]); + exit(1); + } + + sprintf(buf, "%s.vss", argv[1]); + if ((vfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + pos = 0; + write(bfp, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfp, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfp, &pos, 4); /* Module intro */ + write(vfp, &size, 2); + write(vfp, &pos, 4); /* Testament intro */ + write(vfp, &size, 2); + + mykey = (argc == 3) ? "Matthew 1:1" : "Genesis 1:1"; + + while (!findbreak(fp, &offset, &num1, &num2, &size)) { + num1 = mykey.Chapter(); + num2 = mykey.Verse(); + if (num2 == 1) { /* if we're at a new chapter */ + if (num1 == 1) { /* if we're at a new book */ + pos = lseek(cfp, 0, SEEK_CUR); + write(bfp, &pos, 4); + pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfp, &pos, 4); + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Book intro (vss) */ + write(vfp, &tmp, 2); + curbook++; + curchap = 0; + } + pos = lseek(vfp, 0, SEEK_CUR); + write(cfp, &pos, 4); + curverse = 1; + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Chapter intro */ + write(vfp, &tmp, 2); + curchap++; + } + else curverse++; + + printf("%2d:%3d:%3d found at offset: %7d\n", curbook, num1, num2, offset); + + if (num1 != curchap) { + fprintf(stderr, "Error: Found chaptures out of sequence\n"); + break; + } + if (num2 != curverse) { + fprintf(stderr, "Error: Found verses out of sequence\n"); + break; + } + write(vfp, &offset, 4); + write(vfp, &size, 2); + mykey++; + } + + close(vfp); + close(cfp); + close(bfp); + close(fp); +} + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size) +{ + char buf[17]; + char buf2[7]; + char loop; + char offadj, inquotes, sizeadj; + int offset2, ch2, vs2; + + memset(buf, ' ', 17); + + while (1) { + offadj = -10; + inquotes = 0; + sizeadj = 0; + if ((!memcmp(buf, "\\widctlpar {\\b\\f0\\cf2 ", 16)) && (!size)) { + offadj = -1; +// inquotes = 1; + sizeadj = -18; + } + if (!memcmp(&buf[1], "\\f0\\fs16\\cf2\\up6", 15)) { + offadj = 0; + inquotes = 1; + sizeadj = (*buf == 10) ? -18:-17; + } + if (!memcmp(buf, "\\fi200\\widctlpar", 16)) { + offadj = -1; +// inquotes = 1; + sizeadj = -18; + } + if (offadj > -10) { + *offset = lseek(fp, 0, SEEK_CUR) + offadj; + if (size) { + (*offset)++; + while (inquotes) { + while (read(fp, buf2, 1) == 1) { + if (*buf2 == '}') + break; + (*offset)++; + } + inquotes--; + } + if (findbreak(fp, &offset2, &ch2, &vs2, 0)) { + *size = (short) (lseek(fp, 0, SEEK_END) - (*offset)); + } + else { + sprintf(buf2, "%d:%d", ch2, vs2); + *size = (offset2 - (*offset)); + } + lseek(fp, *offset+17, SEEK_SET); + } + else (*offset) += sizeadj; + return 0; + } + memmove(buf, &buf[1], 16); + if (read(fp, &buf[16], 1) != 1) + return 1; + } +} + diff --git a/src/modules/texts/rawtext/makebnds.c b/src/modules/texts/rawtext/makebnds.c new file mode 100644 index 0000000..44da447 --- /dev/null +++ b/src/modules/texts/rawtext/makebnds.c @@ -0,0 +1,86 @@ +#include <stdio.h> +#include <fcntl.h> + + +char *bnames[] = { + "Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", + "Joshua", "Judges", "Ruth", "I Samual", "II Samuel", + "I Kings", "II Kings", "I Chronicles", "II Chronicles", "Ezra", + "Nehemiah", "Esther", "Job", "Psalms", "Proverbs", + "Ecclesiastes", "Song of Solomon", "Isaiah", "Jeremiah", "Lamentations", + "Ezekiel", "Daniel", "Hosea", "Joel", "Amos", + "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", + "Zephaniah", "Haggai", "Zechariah", "Malachi", + "Matthew", "Mark", "Luke", "John", "Acts", + "Romans", "I Corinthians", "II Corinthians", "Galatians", "Ephesians", + "Philippians", "Colossians", "I Thessalonians", "II Thessalonians", "I Timothy", + "II Timothy", "Titus", "Philemon", "Hebrews", "James", + "I Peter", "II Peter", "I John", "II John", "III John", + "Jude", "Revelation of John"}; + + + +main(int argc, char **argv) +{ + int fp, vfp, cfp, bfp; + long pos; + int num1, num2, offset, offset2, chapmax, chapoff, chapoff2, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + + if (argc > 3) { + fprintf(stderr, "usage: %s <file to process> [NT?]\n", argv[0]); + exit(1); + } + + if (argc > 2) + curbook = 39; + sprintf(buf, "%s.vss", argv[1]); + if ((vfp = open(buf, O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfp = open(buf, O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfp = open(buf, O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + read(bfp, &offset2, sizeof(offset2)); + read(cfp, &chapoff2, sizeof(chapoff2)); + while (read(bfp, &offset, sizeof(offset)) == sizeof(offset)) { + chapmax = (offset - offset2) / sizeof(offset); + printf("\n\{\"%s\", %d}, \n// %s\n", bnames[curbook], chapmax, bnames[curbook]); + curbook++; + for (curchap = 0; curchap < chapmax; curchap++) { + read(cfp, &chapoff, sizeof(chapoff)); + printf("%d, ", (chapoff - chapoff2) / sizeof(chapoff)); + chapoff2 = chapoff; + } + offset2 = offset; + } + pos = lseek(cfp, 0, SEEK_CUR); + offset = (int) lseek(cfp, 0, SEEK_END); + chapmax = (offset - offset2) / sizeof(offset); + printf("\n\{\"%s\", %d}, \n// %s\n", bnames[curbook], chapmax, bnames[curbook]); + curbook++; + lseek(cfp, pos, SEEK_SET); + for (curchap = 0; curchap < chapmax - 1; curchap++) { + read(cfp, &chapoff, sizeof(chapoff)); + printf("%d, ", (chapoff - chapoff2) / sizeof(chapoff)); + chapoff2 = chapoff; + } + chapoff = (int) lseek(vfp, 0, SEEK_END); + printf("%d, ", (chapoff - chapoff2) / sizeof(chapoff)); + + close(vfp); + close(cfp); + close(bfp); + close(fp); +} diff --git a/src/modules/texts/rawtext/nuidx.cpp b/src/modules/texts/rawtext/nuidx.cpp new file mode 100644 index 0000000..edf298d --- /dev/null +++ b/src/modules/texts/rawtext/nuidx.cpp @@ -0,0 +1,238 @@ +/***************************************************************************** + * + * This code wreaks but works (at least for MHC). Good luck! + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + +#include <fcntl.h> +#include <versekey.h> + + +void writeidx(VerseKey &key1, VerseKey &key2, VerseKey &key3, long offset, short size); +char findbreak(int fp, long *offset, int *num1, int *num2, int *rangemax, short *size); +void openfiles(char *fname); +void checkparams(int argc, char **argv); + + +VerseKey key1, key2, key3; +int fp, vfp, cfp, bfp; +long chapoffset; +short chapsize; +char testmnt; + + +main(int argc, char **argv) +{ + long pos, offset; + int num1, num2, rangemax, curbook = 0, curchap = 0, curverse = 0; + char buf[127], startflag = 0; + short size, tmp; + + checkparams(argc, argv); + + openfiles(argv[1]); + + testmnt = key1.Testament(); + num1 = key1.Chapter(); + num2 = key1.Verse(); + pos = 0; + write(bfp, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfp, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfp, &pos, 4); /* Module intro */ + write(vfp, &size, 2); + write(vfp, &pos, 4); /* Testament intro */ + write(vfp, &size, 2); + + while(!findbreak(fp, &offset, &num1, &num2, &rangemax, &size)) { + writeidx(key1, key2, key3, offset, size); + key2++; + key3 = key2; + } + close(vfp); + close(cfp); + close(bfp); + close(fp); +} + + +/************************************************************************** + * ENT: key1 - current location of index + * key2 - minimum keyval for which this offset is valid + * key3 - maximum keyval for which this offset is valid + */ + +void writeidx(VerseKey &key1, VerseKey &key2, VerseKey &key3, long offset, short size) +{ + long pos; + short tmp; + + for (; ((key1 <= key3) && (key1.Error() != KEYERR_OUTOFBOUNDS) && (key1.Testament() == testmnt)); key1+=1) { + if (key1.Verse() == 1) { // new chapter + if (key1.Chapter() == 1) { // new book + pos = lseek(cfp, 0, SEEK_CUR); + write(bfp, &pos, 4); + pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfp, &pos, 4); + write(vfp, &chapoffset, 4); /* Book intro (vss) set to same as chap for now(it should be chap 1 which usually contains the book into anyway)*/ + write(vfp, &chapsize, 2); + } + pos = lseek(vfp, 0, SEEK_CUR); + write(cfp, &pos, 4); + write(vfp, &chapoffset, 4); /* Chapter intro */ + write(vfp, &chapsize, 2); + } + if (key1 >= key2) { + write(vfp, &offset, 4); + write(vfp, &size, 2); + } + else { + pos = 0; + tmp = 0; + write(vfp, &pos, 4); + write(vfp, &tmp, 2); + } + } +} + + +char startchap(char *buf) +{ + char loop; + + if (buf[0] != '<') + return 0; + if (buf[1] != 'S') + return 0; + if (buf[2] != 'C') + return 0; +/* + if (!isdigit(buf[2])) + return 0; + for (loop = 3; loop < 7; loop++) { + if (buf[loop] == ' ') + break; + if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-')) + return 0; + } +*/ + return 1; +} + + +char startentry(char *buf) +{ + char loop; + + if (buf[0] != '<') + return 0; + if (buf[1] != 'S') + return 0; + if (buf[2] != 'V') + return 0; +/* + if (!isdigit(buf[2])) + return 0; + for (loop = 3; loop < 7; loop++) { + if (buf[loop] == ' ') + break; + if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-')) + return 0; + } +*/ + return 1; +} + + +char findbreak(int fp, long *offset, int *num1, int *num2, int *rangemax, short *size) +{ + char buf[7]; + char buf2[20]; + char ch; + char loop; + long offset2; + int ch2, vs2, rm2; + bool flag; + long chapstart = 0; + + memset(buf, ' ', 7); + + while (1) { + if (startentry(buf)) { + if (size) + *offset = lseek(fp, 0, SEEK_CUR) - 3; + else *offset = lseek(fp, 0, SEEK_CUR) - 7; + if (size) { + ch2 = *num1; + vs2 = *num2; + if (findbreak(fp, &offset2, &ch2, &vs2, &rm2, 0)) { + *size = (short) (lseek(fp, 0, SEEK_END) - (*offset)); + } + else { + *size = (offset2 - (*offset)); + } + lseek(fp, *offset, SEEK_SET); + } + return 0; + } + memmove(buf, &buf[1], 6); + if (read(fp, &buf[6], 1) != 1) + return 1; + } +} + + +void openfiles(char *fname) +{ + char buf[255]; + + if ((fp = open(fname, O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", fname); + exit(1); + } + + sprintf(buf, "%s.vss", fname); + if ((vfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", fname); + if ((cfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", fname); + if ((bfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } +} + + +void checkparams(int argc, char **argv) +{ + if (argc < 2) { + fprintf(stderr, "usage: %s <file to process> [nt - for new testmt file]\n", argv[0]); + exit(1); + } + if (argc == 3) + key1 = key2 = key3 = "Matthew 1:1"; + else key1 = key2 = key3 = "Genesis 1:1"; +} diff --git a/src/modules/texts/rawtext/ojbtxidx.c b/src/modules/texts/rawtext/ojbtxidx.c new file mode 100644 index 0000000..f70cc01 --- /dev/null +++ b/src/modules/texts/rawtext/ojbtxidx.c @@ -0,0 +1,166 @@ +#include <stdio.h> +#include <fcntl.h> +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + + +char findbreak(int fd, long *offset, int *num1, int *num2, short *size); + + +main(int argc, char **argv) +{ + int fd, vfd, cfd, bfd; + long pos, offset; + short size, tmp; + int num1, num2, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + + if (argc != 2) { + fprintf(stderr, "usage: %s <file to process>\n", argv[0]); + exit(1); + } +#ifndef O_BINARY // O_BINARY is for Borland to be happy. If we're in GNU, just define it to a NULL mask +#define O_BINARY 0 +#endif + if ((fd = open(argv[1], O_RDONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", argv[1]); + exit(1); + } + + sprintf(buf, "%s.vss", argv[1]); + if ((vfd = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfd = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfd = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + pos = 0; + write(bfd, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfd, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfd, &pos, 4); /* Module intro */ + write(vfd, &size, 2); + write(vfd, &pos, 4); /* Testament intro */ + write(vfd, &size, 2); + + while (!findbreak(fd, &offset, &num1, &num2, &size)) { + + if (num2 == 1) { /* if we're at a new chapter */ + if (num1 == 1) { /* if we're at a new book */ + pos = lseek(cfd, 0, SEEK_CUR); + write(bfd, &pos, 4); + pos = lseek(vfd, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfd, &pos, 4); + pos = 0; + tmp = 0; + write(vfd, &pos, 4); /* Book intro (vss) */ + write(vfd, &tmp, 2); + curbook++; + curchap = 0; + } + pos = lseek(vfd, 0, SEEK_CUR); + write(cfd, &pos, 4); + curverse = 1; + pos = 0; + tmp = 0; + write(vfd, &pos, 4); /* Chapter intro */ + write(vfd, &tmp, 2); + curchap++; + } + else curverse++; + + printf("%2d:%3d:%3d found at offset: %7ld\n", curbook, num1, num2, offset); + + if (num1 != curchap) { + fprintf(stderr, "Error: Found chaptures out of sequence (%2d:%3d:%3d)\n", curbook, num1-1, num2); + curchap = num1; +// break; + } + if (num2 != curverse) { + fprintf(stderr, "Error: Found verses out of sequence (%2d:%3d:%3d)\n", curbook, num1, num2-1); +// break; + tmp = 0; + curverse = num2; + write(vfd, &offset, 4); + write(vfd, &tmp, 2); + } + write(vfd, &offset, 4); + write(vfd, &size, 2); + } + + close(vfd); + close(cfd); + close(bfd); + close(fd); + return 0; +} + + +char findbreak(int fd, long *offset, int *num1, int *num2, short *size) +{ + char buf[8]; + char buf2[7]; + char loop, len, star; + + memset(buf, ' ', 7); + buf[7] = 0; + + while (1) { + + memmove(buf, &buf[1], 6); + if (read(fd, &buf[6], 1) != 1) + return 1; + + if ((buf[0] == 10) && ((buf[2] == '*') || (buf[3] == '*') || (buf[4] == '*'))) { + star = 0; + for (loop = 0; loop < 7; loop++) { + if (buf[loop] == '*') + star = 1; + if (isdigit(buf[loop])&&star) + break; + else buf[loop] = ' '; + } + if (loop < 7) { + sscanf(buf, "%d", num1); + continue; + } + } + + if ((buf[0] == '|') && (isdigit(buf[1]))) { + sscanf(&buf[1], "%d", num2); + sprintf(buf, "%d", *num2); + (*offset) = lseek(fd, 0, SEEK_CUR); + (*offset) -= (4-strlen(buf)); + + for (len = 1; len == 1; len = read(fd, &loop, 1)) { + if (loop == '|') + break; + } + + *size = (short)(lseek(fd, 0, SEEK_CUR) - *offset) - 1; + lseek(fd, -1, SEEK_CUR); + break; + } + } + return 0; +} + diff --git a/src/modules/texts/rawtext/rawtext.cpp b/src/modules/texts/rawtext/rawtext.cpp new file mode 100644 index 0000000..c2214f8 --- /dev/null +++ b/src/modules/texts/rawtext/rawtext.cpp @@ -0,0 +1,580 @@ +/****************************************************************************** + * rawtext.cpp - code for class 'RawText'- a module that reads raw text files: + * ot and nt using indexs ??.bks ??.cps ??.vss + */ + + +#include <stdio.h> +#include <fcntl.h> + +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + +#include <string.h> +#include <utilfuns.h> +#include <rawverse.h> +#include <rawtext.h> + +#include <map> +#include <list> +#include <algorithm> +#include <regex.h> // GNU + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/****************************************************************************** + * RawText Constructor - Initializes data for instance of RawText + * + * ENT: iname - Internal name for module + * idesc - Name to display to user for module + * idisp - Display object to use for displaying + */ + +RawText::RawText(const char *ipath, const char *iname, const char *idesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang) + : SWText(iname, idesc, idisp, enc, dir, mark, ilang), + RawVerse(ipath) { + + string fname; + fname = path; + char ch = fname.c_str()[strlen(fname.c_str())-1]; + if ((ch != '/') && (ch != '\\')) + fname += "/"; + + for (int loop = 0; loop < 2; loop++) { + fastSearch[loop] = 0; + string fastidxname =(fname + ((loop)?"ntwords.dat":"otwords.dat")); + if (!access(fastidxname.c_str(), 04)) { + fastidxname = (fname + ((loop)?"ntwords.idx":"otwords.idx")); + if (!access(fastidxname.c_str(), 04)) + fastSearch[loop] = new RawStr((fname + ((loop)?"ntwords":"otwords")).c_str()); + } + } +} + + +/****************************************************************************** + * RawText Destructor - Cleans up instance of RawText + */ + +RawText::~RawText() +{ + if (fastSearch[0]) + delete fastSearch[0]; + + if (fastSearch[1]) + delete fastSearch[1]; +} + + +/****************************************************************************** + * RawText::getRawEntry - Returns the correct verse when char * cast + * is requested + * + * RET: string buffer with verse + */ + +char *RawText::getRawEntry() { + long start = 0; + unsigned short size = 0; + VerseKey *key = 0; + + // see if we have a VerseKey * or decendant + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) { } + // if we don't have a VerseKey * decendant, create our own + if (!key) + key = new VerseKey(this->key); + + findoffset(key->Testament(), key->Index(), &start, &size); + entrySize = size; // support getEntrySize call + + unsigned long newsize = (size + 2) * FILTERPAD; + if (newsize > entrybufallocsize) { + if (entrybuf) + delete [] entrybuf; + entrybuf = new char [ newsize ]; + entrybufallocsize = newsize; + } + *entrybuf = 0; + + readtext(key->Testament(), start, (size + 2), entrybuf); + + rawFilter(entrybuf, size, key); + + if (!isUnicode()) + preptext(entrybuf); + + if (this->key != key) // free our key if we created a VerseKey + delete key; + + return entrybuf; +} + + +signed char RawText::createSearchFramework() { + SWKey *savekey = 0; + SWKey *searchkey = 0; + SWKey textkey; + char *word = 0; + char *wordBuf = 0; + + // dictionary holds words associated with a list + // containing every module position that contains + // the word. [0] Old Testament; [1] NT + map < string, list<long> > dictionary[2]; + + + // save key information so as not to disrupt original + // module position + if (!key->Persist()) { + savekey = CreateKey(); + *savekey = *key; + } + else savekey = key; + + searchkey = (key->Persist())?key->clone():0; + if (searchkey) { + searchkey->Persist(1); + SetKey(*searchkey); + } + + // position module at the beginning + *this = TOP; + + VerseKey *lkey = (VerseKey *)key; + + // iterate thru each entry in module + while (!Error()) { + long index = lkey->Index(); + wordBuf = (char *)calloc(sizeof(char), strlen(StripText()) + 1); + strcpy(wordBuf, StripText()); + + // grab each word from the text + word = strtok(wordBuf, " !.,?;:()-=+/\\|{}[]\"<>"); + while (word) { + + // make word upper case + toupperstr(word); + + // lookup word in dictionary (or make entry in dictionary + // for this word) and add this module position (index) to + // the word's associated list of module positions + dictionary[lkey->Testament()-1][word].push_back(index); + word = strtok(NULL, " !.,?;:()-=+/\\|{}[]\"<>"); + } + free(wordBuf); + (*this)++; + } + + // reposition module back to where it was before we were called + SetKey(*savekey); + + if (!savekey->Persist()) + delete savekey; + + if (searchkey) + delete searchkey; + + + // --------- Let's output an index from our dictionary ----------- + int datfd; + int idxfd; + map < string, list<long> >::iterator it; + list<long>::iterator it2; + unsigned long offset, entryoff; + unsigned short size; + + string fname; + fname = path; + char ch = fname.c_str()[strlen(fname.c_str())-1]; + if ((ch != '/') && (ch != '\\')) + fname += "/"; + + // for old and new testament do... + for (int loop = 0; loop < 2; loop++) { + if ((datfd = open((fname + ((loop)?"ntwords.dat":"otwords.dat")).c_str(), O_CREAT|O_WRONLY|O_BINARY, 00644 )) == -1) + return -1; + if ((idxfd = open((fname + ((loop)?"ntwords.idx":"otwords.idx")).c_str(), O_CREAT|O_WRONLY|O_BINARY, 00644 )) == -1) { + close(datfd); + return -1; + } + + // iterate thru each word in the dictionary + for (it = dictionary[loop].begin(); it != dictionary[loop].end(); it++) { + printf("%s: ", it->first.c_str()); + + // get our current offset in our word.dat file and write this as the start + // of the next entry in our database + offset = lseek(datfd, 0, SEEK_CUR); + write(idxfd, &offset, 4); + + // write our word out to the word.dat file, delineating with a \n + write(datfd, it->first.c_str(), strlen(it->first.c_str())); + write(datfd, "\n", 1); + + // force our mod position list for this word to be unique (remove + // duplicates that may exist if the word was found more than once + // in the verse + it->second.unique(); + + // iterate thru each mod position for this word and output it to + // our database + unsigned short count = 0; + for (it2 = it->second.begin(); it2 != it->second.end(); it2++) { + entryoff= *it2; + write(datfd, &entryoff, 4); + count++; + } + + // now see what our new position is in our word.dat file and + // determine the size of this database entry + size = lseek(datfd, 0, SEEK_CUR) - offset; + + // store the size of this database entry + write(idxfd, &size, 2); + printf("%d entries (size: %d)\n", count, size); + } + close(datfd); + close(idxfd); + } + return 0; +} + + +/****************************************************************************** + * SWModule::Search - Searches a module for a string + * + * ENT: istr - string for which to search + * searchType - type of search to perform + * >=0 - regex + * -1 - phrase + * -2 - multiword + * flags - options flags for search + * justCheckIfSupported - if set, don't search, only tell if this + * function supports requested search. + * + * RET: listkey set to verses that contain istr + */ + +ListKey &RawText::Search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData) +{ + listkey.ClearList(); + + if ((fastSearch[0]) && (fastSearch[1])) { + + switch (searchType) { + case -2: { + + if ((flags & REG_ICASE) != REG_ICASE) // if haven't chosen to + // ignore case + break; // can't handle fast case sensitive searches + + // test to see if our scope for this search is bounded by a + // VerseKey + VerseKey *testKeyType = 0; + try { + testKeyType = SWDYNAMIC_CAST(VerseKey, ((scope)?scope:key)); + } + catch ( ... ) {} + // if we don't have a VerseKey * decendant we can't handle + // because of scope. + // In the future, add bool SWKey::isValid(const char *tryString); + if (!testKeyType) + break; + + + // check if we just want to see if search is supported. + // If we've gotten this far, then it is supported. + if (justCheckIfSupported) { + *justCheckIfSupported = true; + return listkey; + } + + SWKey saveKey = *testKeyType; // save current place + + char error = 0; + char **words = 0; + char *wordBuf = 0; + int wordCount = 0; + long start; + unsigned short size; + char *idxbuf = 0; + char *datbuf = 0; + list <long> indexes; + list <long> indexes2; + VerseKey vk; + vk = TOP; + + (*percent)(10, percentUserData); + + // toupper our copy of search string + stdstr(&wordBuf, istr); + toupperstr(wordBuf); + + // get list of individual words + words = (char **)calloc(sizeof(char *), 10); + int allocWords = 10; + words[wordCount] = strtok(wordBuf, " "); + while (words[wordCount]) { + wordCount++; + if (wordCount == allocWords) { + allocWords+=10; + words = (char **)realloc(words, sizeof(char *)*allocWords); + } + words[wordCount] = strtok(NULL, " "); + } + + (*percent)(20, percentUserData); + + // clear our result set + indexes.erase(indexes.begin(), indexes.end()); + + // search both old and new testament indexes + for (int j = 0; j < 2; j++) { + // iterate thru each word the user passed to us. + for (int i = 0; i < wordCount; i++) { + + // clear this word's result set + indexes2.erase(indexes2.begin(), indexes2.end()); + error = 0; + + // iterate thru every word in the database that starts + // with our search word + for (int away = 0; !error; away++) { + idxbuf = 0; + + // find our word in the database and jump ahead _away_ + error = fastSearch[j]->findoffset(words[i], &start, &size, away); + + // get the word from the database + fastSearch[j]->getidxbufdat(start, &idxbuf); + + // check to see if it starts with our target word + if (strlen(idxbuf) > strlen(words[i])) + idxbuf[strlen(words[i])] = 0; +// else words[i][strlen(idxbuf)] = 0; + if (!strcmp(idxbuf, words[i])) { + + // get data for this word from database + free(idxbuf); + idxbuf = 0; + datbuf = 0; + fastSearch[j]->readtext(start, &size, &idxbuf, &datbuf); + + // we know that the data consists of sizof(long) + // records each a valid module position that constains + // this word + // + // iterate thru each of these module positions + long *keyindex = (long *)datbuf; + while (keyindex < (long *)(datbuf + size - (strlen(idxbuf) + 1))) { + if (i) { // if we're not on our first word + + // check to see if this word is already in the result set. + // This is our AND functionality + if (find(indexes.begin(), indexes.end(), *keyindex) != indexes.end()) + // add to new result set + indexes2.push_back(*keyindex); + } + else indexes2.push_back(*keyindex); + keyindex++; + } + free(datbuf); + } + else error = 1; // no more matches + free(idxbuf); + } + + // make new result set final result set + indexes = indexes2; + + percent((char)(20 + (float)((j*wordCount)+i)/(wordCount * 2) * 78), percentUserData); + } + + // indexes contains our good verses, lets return them in a listkey + indexes.sort(); + + // iterate thru each good module position that meets the search + for (list <long>::iterator it = indexes.begin(); it != indexes.end(); it++) { + + // set a temporary verse key to this module position + vk.Testament(j+1); + vk.Error(); + vk.Index(*it); + + // check scope + // Try to set our scope key to this verse key + if (scope) { + *testKeyType = vk; + + // check to see if it set ok and if so, add to our return list + if (*testKeyType == vk) + listkey << (const char *) vk; + } + else listkey << (const char*) vk; + } + } + (*percent)(98, percentUserData); + + free(words); + free(wordBuf); + + *testKeyType = saveKey; // set current place back to original + + listkey = TOP; + (*percent)(100, percentUserData); + return listkey; + } + + default: + break; + } + } + + // check if we just want to see if search is supported + if (justCheckIfSupported) { + *justCheckIfSupported = false; + return listkey; + } + + // if we don't support this search, fall back to base class + return SWModule::Search(istr, searchType, flags, scope, justCheckIfSupported, percent, percentUserData); +} + + +void RawText::setEntry(const char *inbuf, long len) { + VerseKey *key = 0; + // see if we have a VerseKey * or decendant + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + // if we don't have a VerseKey * decendant, create our own + if (!key) + key = new VerseKey(this->key); + + settext(key->Testament(), key->Index(), inbuf, len); + + if (this->key != key) // free our key if we created a VerseKey + delete key; +} + + +void RawText::linkEntry(const SWKey *inkey) { + VerseKey *destkey = 0; + const VerseKey *srckey = 0; + // see if we have a VerseKey * or decendant + try { + destkey = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + // if we don't have a VerseKey * decendant, create our own + if (!destkey) + destkey = new VerseKey(this->key); + + // see if we have a VerseKey * or decendant + try { + srckey = SWDYNAMIC_CAST(VerseKey, inkey); + } + catch ( ... ) {} + // if we don't have a VerseKey * decendant, create our own + if (!srckey) + srckey = new VerseKey(inkey); + + linkentry(destkey->Testament(), destkey->Index(), srckey->Index()); + + if (this->key != destkey) // free our key if we created a VerseKey + delete destkey; + + if (inkey != srckey) // free our key if we created a VerseKey + delete srckey; +} + + +/****************************************************************************** + * RawText::deleteEntry - deletes this entry + * + * RET: *this + */ + +void RawText::deleteEntry() { + + VerseKey *key = 0; + + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + if (!key) + key = new VerseKey(this->key); + + settext(key->Testament(), key->Index(), ""); + + if (key != this->key) + delete key; +} + +/****************************************************************************** + * RawText::increment - Increments module key a number of entries + * + * ENT: increment - Number of entries to jump forward + * + * RET: *this + */ + +void RawText::increment(int steps) { + long start; + unsigned short size; + VerseKey *tmpkey = 0; + + try { + tmpkey = SWDYNAMIC_CAST(VerseKey, key); + } + catch ( ... ) {} + if (!tmpkey) + tmpkey = new VerseKey(key); + + findoffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); + + SWKey lastgood = *tmpkey; + while (steps) { + long laststart = start; + unsigned short lastsize = size; + SWKey lasttry = *tmpkey; + (steps > 0) ? (*key)++ : (*key)--; + if (tmpkey != key) + delete tmpkey; + tmpkey = 0; + try { + tmpkey = SWDYNAMIC_CAST(VerseKey, key); + } + catch ( ... ) {} + if (!tmpkey) + tmpkey = new VerseKey(key); + + if ((error = key->Error())) { + *key = lastgood; + break; + } + long index = tmpkey->Index(); + findoffset(tmpkey->Testament(), index, &start, &size); + if ( + (((laststart != start) || (lastsize != size)) // we're a different entry + && (start > 0) && (size)) // and we actually have a size + ||(!skipConsecutiveLinks)) { // or we don't want to skip consecutive links + steps += (steps < 0) ? 1 : -1; + lastgood = *tmpkey; + } + } + error = (error) ? KEYERR_OUTOFBOUNDS : 0; + + if (tmpkey != key) + delete tmpkey; +} diff --git a/src/modules/texts/rawtext/rawtxidx.c b/src/modules/texts/rawtext/rawtxidx.c new file mode 100644 index 0000000..311103e --- /dev/null +++ b/src/modules/texts/rawtext/rawtxidx.c @@ -0,0 +1,146 @@ +#include <stdio.h> +#include <fcntl.h> + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size); + + +main(int argc, char **argv) +{ + int fp, vfp, cfp, bfp; + long pos; + short size, tmp; + int num1, num2, offset, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + + if (argc != 2) { + fprintf(stderr, "usage: %s <file to process>\n", argv[0]); + exit(1); + } + + if ((fp = open(argv[1], O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", argv[1]); + exit(1); + } + + sprintf(buf, "%s.vss", argv[1]); + if ((vfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + pos = 0; + write(bfp, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfp, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfp, &pos, 4); /* Module intro */ + write(vfp, &size, 2); + write(vfp, &pos, 4); /* Testament intro */ + write(vfp, &size, 2); + + while (!findbreak(fp, &offset, &num1, &num2, &size)) { + + if (num2 == 1) { /* if we're at a new chapter */ + if (num1 == 1) { /* if we're at a new book */ + pos = lseek(cfp, 0, SEEK_CUR); + write(bfp, &pos, 4); + pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfp, &pos, 4); + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Book intro (vss) */ + write(vfp, &tmp, 2); + curbook++; + curchap = 0; + } + pos = lseek(vfp, 0, SEEK_CUR); + write(cfp, &pos, 4); + curverse = 1; + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Chapter intro */ + write(vfp, &tmp, 2); + curchap++; + } + else curverse++; + + printf("%2d:%3d:%3d found at offset: %7d\n", curbook, num1, num2, offset); + + if (num1 != curchap) { + fprintf(stderr, "Error: Found chaptures out of sequence\n", buf); + break; + } + if (num2 != curverse) { + fprintf(stderr, "Error: Found verses out of sequence\n", buf); + break; + } + write(vfp, &offset, 4); + write(vfp, &size, 2); + } + + close(vfp); + close(cfp); + close(bfp); + close(fp); +} + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size) +{ + char buf[7]; + char buf2[7]; + char loop; + int offset2, ch2, vs2; + + memset(buf, ' ', 7); + + while (1) { + if (buf[3] == ':') { + memcpy(buf2, buf, 7); + for (loop = 0; loop < 7; loop++) { + if (!isdigit(buf2[loop])) + buf2[loop] = ' '; + } + buf2[3] = 0; + *num1 = atoi(buf2); + *num2 = atoi(&buf2[4]); + if (*num1 && *num2) { + *offset = lseek(fp, 0, SEEK_CUR); + sprintf(buf2, "%d", *num2); + *offset -= 2 - strlen(buf2); + if (size) { + if (findbreak(fp, &offset2, &ch2, &vs2, 0)) { + *size = (short) (lseek(fp, 0, SEEK_END) - (*offset)); + } + else { + sprintf(buf2, "%d:%d", ch2, vs2); + *size = (offset2 - (*offset)) - (strlen(buf2) + 2); + } + lseek(fp, *offset, SEEK_SET); + } + return 0; + } + } + memmove(buf, &buf[1], 6); + if (read(fp, &buf[6], 1) != 1) + return 1; + } +} + diff --git a/src/modules/texts/rawtext/rtfidx.cpp b/src/modules/texts/rawtext/rtfidx.cpp new file mode 100644 index 0000000..9fdb305 --- /dev/null +++ b/src/modules/texts/rawtext/rtfidx.cpp @@ -0,0 +1,164 @@ +#include <stdio.h> +#include <fcntl.h> +#include <versekey.h> + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size); + + +main(int argc, char **argv) +{ + int fp, vfp, cfp, bfp; + long pos; + short size, tmp; + int num1, num2, offset, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + VerseKey mykey; + + if ((argc < 2) || (argc > 3)) { + fprintf(stderr, "usage: %s <file to process> [nt]\n", argv[0]); + exit(1); + } + + if ((fp = open(argv[1], O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", argv[1]); + exit(1); + } + + sprintf(buf, "%s.vss", argv[1]); + if ((vfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + pos = 0; + write(bfp, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfp, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfp, &pos, 4); /* Module intro */ + write(vfp, &size, 2); + write(vfp, &pos, 4); /* Testament intro */ + write(vfp, &size, 2); + + mykey = (argc == 3) ? "Matthew 1:1" : "Genesis 1:1"; + + while (!findbreak(fp, &offset, &num1, &num2, &size)) { + num1 = mykey.Chapter(); + num2 = mykey.Verse(); + if (num2 == 1) { /* if we're at a new chapter */ + if (num1 == 1) { /* if we're at a new book */ + pos = lseek(cfp, 0, SEEK_CUR); + write(bfp, &pos, 4); + pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfp, &pos, 4); + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Book intro (vss) */ + write(vfp, &tmp, 2); + curbook++; + curchap = 0; + } + pos = lseek(vfp, 0, SEEK_CUR); + write(cfp, &pos, 4); + curverse = 1; + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Chapter intro */ + write(vfp, &tmp, 2); + curchap++; + } + else curverse++; + + printf("%2d:%3d:%3d found at offset: %7d\n", curbook, num1, num2, offset); + + if (num1 != curchap) { + fprintf(stderr, "Error: Found chaptures out of sequence\n"); + break; + } + if (num2 != curverse) { + fprintf(stderr, "Error: Found verses out of sequence\n"); + break; + } + write(vfp, &offset, 4); + write(vfp, &size, 2); + mykey++; + } + + close(vfp); + close(cfp); + close(bfp); + close(fp); +} + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size) +{ + char buf[17]; + char buf2[7]; + char loop; + char offadj, inquotes, sizeadj; + int offset2, ch2, vs2; + + memset(buf, ' ', 17); + + while (1) { + offadj = -10; + inquotes = 0; + sizeadj = 0; + if (!memcmp(&buf[1], "\\f0\\fs16\\cf2\\up6", 15)) { + offadj = 0; + inquotes = 1; + sizeadj = (*buf == 10) ? -19:-17; + } + if (!memcmp(buf, "\\fi200\\widctlpar", 16)) { + offadj = -1; +// inquotes = 1; + sizeadj = -18; + } + if (offadj > -10) { + *offset = lseek(fp, 0, SEEK_CUR) + offadj; + if (size) { + (*offset)++; + while (inquotes) { + while (read(fp, buf2, 1) == 1) { + if (*buf2 == '}') + break; + (*offset)++; + } + inquotes--; + } + if (findbreak(fp, &offset2, &ch2, &vs2, 0)) { + *size = (short) (lseek(fp, 0, SEEK_END) - (*offset)); + } + else { + sprintf(buf2, "%d:%d", ch2, vs2); + *size = (offset2 - (*offset)); + } + lseek(fp, *offset+17, SEEK_SET); + } + else (*offset) += sizeadj; + return 0; + } + memmove(buf, &buf[1], 16); + if (read(fp, &buf[16], 1) != 1) + return 1; + } +} + diff --git a/src/modules/texts/rawtext/svetxidx.c b/src/modules/texts/rawtext/svetxidx.c new file mode 100644 index 0000000..26e67fd --- /dev/null +++ b/src/modules/texts/rawtext/svetxidx.c @@ -0,0 +1,153 @@ +#include <stdio.h> +#include <fcntl.h> +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + + +char findbreak(int fd, long *offset, int *num1, int *num2, short *size); + + +main(int argc, char **argv) +{ + int fd, vfd, cfd, bfd; + long pos, offset; + short size, tmp; + int num1, num2, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + + if (argc != 2) { + fprintf(stderr, "usage: %s <file to process>\n", argv[0]); + exit(1); + } +#ifndef O_BINARY // O_BINARY is for Borland to be happy. If we're in GNU, just define it to a NULL mask +#define O_BINARY 0 +#endif + if ((fd = open(argv[1], O_RDONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", argv[1]); + exit(1); + } + + sprintf(buf, "%s.vss", argv[1]); + if ((vfd = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfd = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfd = open(buf, O_CREAT|O_WRONLY|O_BINARY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + pos = 0; + write(bfd, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfd, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfd, &pos, 4); /* Module intro */ + write(vfd, &size, 2); + write(vfd, &pos, 4); /* Testament intro */ + write(vfd, &size, 2); + + while (!findbreak(fd, &offset, &num1, &num2, &size)) { + + if (num2 == 1) { /* if we're at a new chapter */ + if (num1 == 1) { /* if we're at a new book */ + pos = lseek(cfd, 0, SEEK_CUR); + write(bfd, &pos, 4); + pos = lseek(vfd, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfd, &pos, 4); + pos = 0; + tmp = 0; + write(vfd, &pos, 4); /* Book intro (vss) */ + write(vfd, &tmp, 2); + curbook++; + curchap = 0; + } + pos = lseek(vfd, 0, SEEK_CUR); + write(cfd, &pos, 4); + curverse = 1; + pos = 0; + tmp = 0; + write(vfd, &pos, 4); /* Chapter intro */ + write(vfd, &tmp, 2); + curchap++; + } + else curverse++; + + printf("%2d:%3d:%3d found at offset: %7ld\n", curbook, num1, num2, offset); + + if (num1 != curchap) { + fprintf(stderr, "Error: Found chaptures out of sequence (%2d:%3d:%3d)\n", curbook, num1-1, num2); + curchap = num1; +// break; + } + if (num2 != curverse) { + fprintf(stderr, "Error: Found verses out of sequence (%2d:%3d:%3d)\n", curbook, num1, num2-1); +// break; + tmp = 0; + curverse = num2; + write(vfd, &offset, 4); + write(vfd, &tmp, 2); + } + write(vfd, &offset, 4); + write(vfd, &size, 2); + } + + close(vfd); + close(cfd); + close(bfd); + close(fd); +} + + +char findbreak(int fd, long *offset, int *num1, int *num2, short *size) +{ + char buf[8]; + char buf2[7]; + char loop, len; + + memset(buf, ' ', 7); + buf[7] = 0; + + while (1) { + + memmove(buf, &buf[1], 6); + if (read(fd, &buf[6], 1) != 1) + return 1; + + if ((buf[0] == 10) && (isdigit(buf[1]))) { + sscanf(buf, "%d %s", num2, buf2); + if (!strncmp(buf2, "KAP", 3)) { + *num1 = *num2; + continue; + } + sprintf(buf, "%d", *num2); + (*offset) = lseek(fd, 0, SEEK_CUR); + (*offset) -= (5-strlen(buf)); + for (len = 1; len == 1; len = read(fd, &loop, 1)) { + if ((loop == 10) || (loop == 13)) + break; + } + + *size = (short)(lseek(fd, 0, SEEK_CUR) - *offset) - 1; + lseek(fd, -1, SEEK_CUR); + break; + } + } + return 0; +} + diff --git a/src/modules/texts/rawtext/vntidx.cpp b/src/modules/texts/rawtext/vntidx.cpp new file mode 100644 index 0000000..bbb4a9e --- /dev/null +++ b/src/modules/texts/rawtext/vntidx.cpp @@ -0,0 +1,185 @@ +#include <stdio.h> +#include <fcntl.h> +#include <versekey.h> + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size); + + +main(int argc, char **argv) +{ + int fp, vfp, cfp, bfp; + long pos; + short size, tmp; + int num1, num2, offset, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + VerseKey mykey; + + if ((argc < 2) || (argc > 3)) { + fprintf(stderr, "usage: %s <file to process> [nt]\n", argv[0]); + exit(1); + } + + if ((fp = open(argv[1], O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", argv[1]); + exit(1); + } + + sprintf(buf, "%s.vss", argv[1]); + if ((vfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + pos = 0; + write(bfp, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfp, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfp, &pos, 4); /* Module intro */ + write(vfp, &size, 2); + write(vfp, &pos, 4); /* Testament intro */ + write(vfp, &size, 2); + + mykey = (argc == 3) ? "Matthew 1:1" : "Genesis 1:1"; + + while (!findbreak(fp, &offset, &num1, &num2, &size)) { + num1 = mykey.Chapter(); + num2 = mykey.Verse(); + if (num2 == 1) { /* if we're at a new chapter */ + if (num1 == 1) { /* if we're at a new book */ + pos = lseek(cfp, 0, SEEK_CUR); + write(bfp, &pos, 4); + pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfp, &pos, 4); + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Book intro (vss) */ + write(vfp, &tmp, 2); + curbook++; + curchap = 0; + } + pos = lseek(vfp, 0, SEEK_CUR); + write(cfp, &pos, 4); + curverse = 1; + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Chapter intro */ + write(vfp, &tmp, 2); + curchap++; + } + else curverse++; + + printf("%2d:%3d:%3d found at offset: %7d\n", curbook, num1, num2, offset); + + if (num1 != curchap) { + fprintf(stderr, "Error: Found chaptures out of sequence\n"); + break; + } + if (num2 != curverse) { + fprintf(stderr, "Error: Found verses out of sequence\n"); + break; + } + write(vfp, &offset, 4); + write(vfp, &size, 2); + mykey++; + } + + close(vfp); + close(cfp); + close(bfp); + close(fp); +} + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size) +{ + char buf[17]; + char buf2[7]; + char buf3[7]; + char loop; + char offadj, inquotes, sizeadj; + int offset2, ch2, vs2; + + strcpy (buf3, "\\par "); + buf3[5] = 10; + memset(buf, ' ', 17); + + while (1) { + offadj = -100; + inquotes = 0; + sizeadj = 0; + if (!memcmp(buf, "\\par FIN DEL NUEVO TESTAMENTO", 16)) { + offadj = -11; +// inquotes = 1; + sizeadj = -7; + } + + if ((!memcmp(buf, buf3, 6)) && (!size)) { + offadj = -11; +// inquotes = 1; + sizeadj = -7; + } + if (!memcmp(buf, "\\par ", 6)) { + if (isdigit(buf[6])) { + for (loop = 7; loop < 10; loop++) { + if (!isdigit(buf[loop])) + break; + } + offadj = -(11 - (loop - 6)); + // inquotes = 1; + sizeadj = -7; + } + } +/* + if (!memcmp(buf, "\\fi200\\widctlpar", 16)) { + offadj = -1; +// inquotes = 1; + sizeadj = -18; + } +*/ + if (offadj > -100) { + *offset = lseek(fp, 0, SEEK_CUR) + offadj; + if (size) { + (*offset)++; + while (inquotes) { + while (read(fp, buf2, 1) == 1) { + if (*buf2 == '}') + break; + (*offset)++; + } + inquotes--; + } + if (findbreak(fp, &offset2, &ch2, &vs2, 0)) { + *size = (short) (lseek(fp, 0, SEEK_END) - (*offset)); + } + else { + *size = (offset2 - (*offset)); + } + lseek(fp, *offset-sizeadj, SEEK_SET); + } + else (*offset) += sizeadj; + return 0; + } + memmove(buf, &buf[1], 16); + if (read(fp, &buf[16], 1) != 1) + return 1; + } +} + diff --git a/src/modules/texts/swtext.cpp b/src/modules/texts/swtext.cpp new file mode 100644 index 0000000..5f6b424 --- /dev/null +++ b/src/modules/texts/swtext.cpp @@ -0,0 +1,40 @@ +/****************************************************************************** + * swtext.cpp - code for base class 'SWText'- The basis for all text modules + */ + +#include <swtext.h> +#include <listkey.h> + + +/****************************************************************************** + * SWText Constructor - Initializes data for instance of SWText + * + * ENT: imodname - Internal name for module + * imoddesc - Name to display to user for module + * idisp - Display object to use for displaying + */ + +SWText::SWText(const char *imodname, const char *imoddesc, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang): SWModule(imodname, imoddesc, idisp, "Biblical Texts", enc, dir, mark, ilang) +{ + delete key; + key = CreateKey(); + skipConsecutiveLinks = false; +} + + +/****************************************************************************** + * SWText Destructor - Cleans up instance of SWText + */ + +SWText::~SWText() { +} + + +/****************************************************************************** + * SWText CreateKey - Create the correct key (VerseKey) for use with SWText + */ + +SWKey *SWText::CreateKey() +{ + return new VerseKey(); +} diff --git a/src/modules/texts/ztext/Makefile b/src/modules/texts/ztext/Makefile new file mode 100644 index 0000000..35d6648 --- /dev/null +++ b/src/modules/texts/ztext/Makefile @@ -0,0 +1,5 @@ + +root := ../../../.. + +all: + make -C ${root} diff --git a/src/modules/texts/ztext/Makefile.am b/src/modules/texts/ztext/Makefile.am new file mode 100644 index 0000000..2b78db6 --- /dev/null +++ b/src/modules/texts/ztext/Makefile.am @@ -0,0 +1,4 @@ +ztextdir = $(top_srcdir)/src/modules/texts/ztext + +libsword_la_SOURCES += $(ztextdir)/ztext.cpp + diff --git a/src/modules/texts/ztext/gbfidx.cpp b/src/modules/texts/ztext/gbfidx.cpp new file mode 100644 index 0000000..e7a9530 --- /dev/null +++ b/src/modules/texts/ztext/gbfidx.cpp @@ -0,0 +1,661 @@ +/*****************************************************************************
+ *
+ * This code reeks but works (sometimes). Good luck!
+ * Modified for zText purposes
+ */
+
+//#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+//#ifndef __GNUC__
+#include <io.h>
+//#else
+//#include <unistd.h>
+//#endif
+
+#include <fcntl.h>
+#include <versekey.h>
+
+
+void writeidx(VerseKey &key1, VerseKey &key2, VerseKey &key3, long offset, short size);
+char findbreak(int fp, long *offset, int *num1, int *num2, int *rangemax, unsigned short *size);
+void openfiles(char *fname);
+void checkparams(int argc, char **argv);
+
+
+VerseKey key1, key2, key3;
+int fp=0, vfp=0, cfp=0, bfp=0;
+long chapoffset=0;
+unsigned short chapsize=0;
+long bookoffset=0;
+unsigned short booksize=0;
+long testoffset=0;
+unsigned short testsize=0;
+long verseoffset=0;
+unsigned short versesize=0;
+long nextoffset=0;
+char testmnt=0;
+int deadcount = 0;
+int chapmark=-4, bookmark=-1;
+ofstream cfile;
+
+
+int main(int argc, char **argv)
+{
+ long pos, offset;
+ int num1, num2, rangemax;//, curbook = 0, curchap = 0, curverse = 0;
+ //char buf[127],
+ char startflag = 0;
+ unsigned short size;//, tmp;
+
+ checkparams(argc, argv);
+
+ openfiles(argv[1]);
+ //key1 = "Matthew 1:1";
+ //key2 = "Matthew 1:1";
+ //key3 = "Matthew 1:1";
+
+ testmnt = key1.Testament();
+ cfile << "testament" << (int) testmnt << "\n";
+ num1 = key1.Chapter();
+ num2 = key1.Verse();
+ pos = 0;
+ write(bfp, &pos, 4); /* Book offset for testament intros */
+ pos = 4;
+ write(cfp, &pos, 4); /* Chapter offset for testament intro */
+
+
+/* Right now just zero out intros until parsing correctly */
+ /*pos = 0;
+ size = 0;
+ write(vfp, &pos, 4); // Module intro
+ write(vfp, &size, 2);
+ cfile << "modintro pos{" << pos << "} size{" << size << "}\n";
+ write(vfp, &pos, 4); // Testament intro
+ write(vfp, &size, 2);
+ cfile << "test intro pos{" << pos << "} size{" << size << "}\n";
+ */
+ cout << "GBFIDX Running\n";
+ cout.flush();
+ while(!findbreak(fp, &offset, &num1, &num2, &rangemax, &size)) {
+ if (!startflag) {
+ startflag = 1;
+ }
+ else {
+ if (num2 < key2.Verse()) { // new chapter
+ if (num1 <= key2.Chapter()) { // new book
+ key2.Verse(1);
+ key2.Chapter(1);
+ key2.Book(key2.Book()+1);
+ }
+ cfile << "Found Chapter Break: " << num1 << " ('" << (const char *)key2 << "')\n";
+ //chapoffset = offset;
+ //chapsize = chapsize - size;
+// continue;
+ }
+ }
+ key2.Verse(1);
+ key2.Chapter(num1);
+ key2.Verse(num2);
+
+ key3 = key2;
+// key3 += (rangemax - key3.Verse());
+
+ writeidx(key1, key2, key3, offset, size);
+ }
+ close(vfp);
+ close(cfp);
+ close(bfp);
+ close(fp);
+
+ return 1;
+}
+
+
+/**************************************************************************
+ * writeidx: key1 - current location of index
+ * key2 - minimum keyval for which this offset is valid
+ * key3 - maximum keyval for which this offset is valid
+ */
+
+void writeidx(VerseKey &key1, VerseKey &key2, VerseKey &key3, long offset, short size)
+{
+ long pos;
+ unsigned short tmp;
+
+ for (; ((key1 <= key3) && (key1.Error() != KEYERR_OUTOFBOUNDS) && (key1.Testament() == testmnt)); key1+=1) {
+ if (chapmark>=2)
+ {
+ if (bookmark==2)
+ {
+ //booksize = booksize - chapsize + 7;
+ cfile << "versesize " << versesize << " booksize " << booksize << " chapsize " << chapsize << " size " << size << "\n";
+ //cfile.flush();
+ //assert(chapsize < size);
+ //if (chapsize > size) // At start of Psalms gets chapsize rather than chapsize+size ???
+ //{
+ // versesize = versesize - (booksize - (chapsize - size) + 7);
+ //}
+ //else
+ //{
+ versesize = versesize - (booksize - (chapsize) + 7);
+ //}
+ cfile << "Last verse in book\n";
+ }
+ //chapsize = chapsize - size;
+ cfile << "versesize " << versesize << " chapsize " << chapsize << " size " << size<< "\n";
+ cfile.flush();
+ //assert(chapsize > size);
+ //if (chapsize > size) // At start of Psalms gets chapsize rather than chapsize+size ???
+ //{
+ // versesize = versesize - (chapsize - size);
+ //}
+ //else
+ //{
+ versesize = versesize - (chapsize);
+ //}
+ cfile << "Last verse in chapter\n";
+ }
+ if (chapmark>=2 && bookmark!=1)
+ {
+ cfile << "prev verse pos{" << verseoffset << "} size{" << versesize << "} nextoffset{" << nextoffset << "}\n";
+ cfile.flush();
+ assert(verseoffset==nextoffset);
+ write(vfp, &verseoffset, 4);
+ write(vfp, &versesize, 2);
+ nextoffset = verseoffset+versesize;
+ bookmark = 0;
+ chapmark = 0;
+ }
+ if (key1.Verse() == 1) { // new chapter
+ cfile << "size??? " << size << "\n";
+ cfile.flush();
+ //assert(chapsize > size || key1.Chapter()==1);
+ //assert(chapsize > size);
+ //if (chapsize > size) // At start of books gets chapsize rather than chapsize+size
+ //{
+ // chapsize = chapsize - size;
+ //}
+ if (key1.Chapter() == 1) { // new book
+ booksize = booksize - chapsize + 7;
+ if (key1.Book() == 1)
+ {
+ pos = 0;
+ //tmp = testoffset;
+ tmp = 0; // better just remember that it goes up to the testament intro to avoid 64k limit
+ // AV exceeds that anyway!
+ write(vfp, &pos, 4); /* Module intro */
+ write(vfp, &tmp, 2);
+ assert(nextoffset==0);
+ cfile << "modintro pos{" << pos << "} size{" << tmp << "}\n";
+ testsize = testsize - booksize - chapsize + 7;
+ if (testsize > 10000)
+ {
+ cerr << "Error: testament too big " << testsize << "\n";
+ exit(-1);
+ }
+ //assert(testoffset==nextoffset);
+ write(vfp, &testoffset, 4); /* Testament intro (vss) */
+ write(vfp, &testsize, 2);
+ nextoffset = testoffset+testsize;
+ cfile << "test intro pos{" << testoffset << "} size{" << testsize << "}\n";
+ }
+ pos = lseek(cfp, 0, SEEK_CUR);
+ write(bfp, &pos, 4);
+ pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */
+ write(cfp, &pos, 4);
+ if (booksize > 10000)
+ {
+ cerr << "Error: book too big " << booksize << "\n";
+ exit(-1);
+ }
+ assert(bookoffset==nextoffset);
+ write(vfp, &bookoffset, 4); /* Book intro (vss) */
+ write(vfp, &booksize, 2);
+ nextoffset = bookoffset+booksize;
+ cfile << "book intro pos{" << bookoffset << "} size{" << booksize << "}\n";
+ //offset += booksize;
+ //bookmark = false;
+ }
+ pos = lseek(vfp, 0, SEEK_CUR);
+ write(cfp, &pos, 4);
+ assert(chapsize < 10000);
+ write(vfp, &chapoffset, 4); /* Chapter intro */
+ write(vfp, &chapsize, 2);
+ nextoffset = chapoffset+chapsize;
+ cfile << "chapter intro pos{" << chapoffset << "} size{" << chapsize << "}\n";
+ //offset += chapsize;
+ //size -= chapsize;
+ //chapmark = false;
+ }
+ if (key1 >= key2) {
+ if (size > 10000)
+ {
+ cerr << "Error: verse too big " << size << "\n";
+ exit(-1);
+ }
+ if (!chapmark && !bookmark)
+ {
+ write(vfp, &offset, 4);
+ write(vfp, &size, 2);
+ cfile << "verse pos{" << offset << "} size{" << size << "}\n";
+ cfile.flush();
+ assert(offset==nextoffset);
+ nextoffset = offset+size;
+ //cfile << "bookmark " << bookmark << " chapmark " << chapmark << "\n";
+ }
+ else
+ {
+ verseoffset = offset;
+ versesize = size;
+ cfile << "saving verse pos{" << offset << "} size{" << size << "}\n";
+ cfile << "bookmark " << bookmark << " chapmark " << chapmark << "\n";
+ }
+ }
+ else {
+ pos = 0;
+ tmp = 0;
+ write(vfp, &pos, 4);
+ write(vfp, &tmp, 2);
+ cfile << "blank pos{" << pos << "} size{" << tmp << "}\n";
+ }
+ }
+}
+
+char startmod(char *buf)
+{
+ //char loop;
+
+ if (buf[0] != '<')
+ return 0;
+ if (buf[1] != 'H')
+ return 0;
+ if (buf[2] != '0')
+ return 0;
+/*
+ if (!isdigit(buf[2]))
+ return 0;
+ for (loop = 3; loop < 7; loop++) {
+ if (buf[loop] == ' ')
+ break;
+ if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-'))
+ return 0;
+ }
+*/
+ return 1;
+}
+
+
+char starttest(char *buf)
+{
+ //char loop;
+
+ if (buf[0] != '<')
+ return 0;
+ if (buf[1] != 'B')
+ return 0;
+ if (testmnt==2)
+ {
+ if (buf[2] != 'N')
+ return 0;
+ }
+ else
+ {
+ if (buf[2] != 'O')
+ return 0;
+ }
+ //if (buf[3] != '>')
+ // return 0;
+/*
+ if (!isdigit(buf[2]))
+ return 0;
+ for (loop = 3; loop < 7; loop++) {
+ if (buf[loop] == ' ')
+ break;
+ if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-'))
+ return 0;
+ }
+*/
+ return 1;
+}
+
+
+char startbook(char *buf)
+{
+ //char loop;
+
+ if (buf[0] != '<')
+ return 0;
+ if (buf[1] != 'S')
+ return 0;
+ if (buf[2] != 'B')
+ return 0;
+/*
+ if (!isdigit(buf[2]))
+ return 0;
+ for (loop = 3; loop < 7; loop++) {
+ if (buf[loop] == ' ')
+ break;
+ if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-'))
+ return 0;
+ }
+*/
+ return 1;
+}
+
+
+char startchap(char *buf)
+{
+ //char loop;
+
+ if (buf[0] != '<')
+ return 0;
+ if (buf[1] != 'S')
+ return 0;
+ if (buf[2] != 'C')
+ return 0;
+/*
+ if (!isdigit(buf[2]))
+ return 0;
+ for (loop = 3; loop < 7; loop++) {
+ if (buf[loop] == ' ')
+ break;
+ if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-'))
+ return 0;
+ }
+*/
+ return 1;
+}
+
+
+char startentry(char *buf)
+{
+ //char loop;
+ //cfile << "{SV}";
+
+ if (buf[0] != '<')
+ {
+ //cfile << "{no<}";
+ return 0;
+ }
+ if (buf[1] != 'S')
+ {
+ //cfile << "\n{noS}\n";
+ return 0;
+ }
+ if (buf[2] != 'V')
+ {
+ //cfile << "\n{noV}\n";
+ return 0;
+ }
+/*
+ if (!isdigit(buf[2]))
+ return 0;
+ for (loop = 3; loop < 7; loop++) {
+ if (buf[loop] == ' ')
+ break;
+ if ((!isdigit(buf[loop])) && (buf[loop] != ',') && (buf[loop] != '-'))
+ return 0;
+ }
+*/
+ return 1;
+}
+
+
+char findbreak(int fp, long *offset, int *num1, int *num2, int *rangemax, unsigned short *size)
+{
+ char buf[8];
+ //char buf2[20];
+ //char ch;
+ char loop=0;
+ long offset2;
+ int ch2, vs2, rm2;
+ bool flag;
+ long versestart = 0;
+ long chapstart = 0;
+ long bookstart = 0;
+ long teststart = 0;
+
+ memset(buf, ' ', 8);
+
+ while (1) {
+ //cfile << "#" << buf << "#";
+ //if (lseek(fp, 0, SEEK_CUR) > 2000000)
+ //{
+ // cfile << lseek(fp, 0, SEEK_CUR) << "\n";
+ //}
+ if (starttest(buf)) {
+ cfile << "\n{start of testament}\n";
+ //chapstart = lseek(fp, 0, SEEK_CUR) - 7;
+ teststart = lseek(fp, 0, SEEK_CUR) - 7;
+ testoffset = teststart;
+ memset(buf, ' ', 3);
+ flag = false;
+ for (loop = 3; loop < 6; loop++) {
+ if (buf[loop]!='>')
+ flag = true;
+ else {
+ buf[loop] = 0;
+ break;
+ }
+ }
+ ch2 = *num1;
+ vs2 = 1;
+ if (size) {
+ if (findbreak(fp, &offset2, &ch2, &vs2, &rm2, 0)) {
+ testsize = (unsigned short) (lseek(fp, 0, SEEK_END) - teststart-7);
+ }
+ else {
+ if (vs2) {
+ testsize = (offset2 - teststart - 7);
+ }
+ }
+ lseek(fp, teststart+7, SEEK_SET);
+ cfile << "\nGot testsize " << testsize << "\n";
+ }
+ }
+
+
+ if (startbook(buf)) {
+ cfile << "\n{start of book}\n";
+ bookmark++;
+ //chapstart = lseek(fp, 0, SEEK_CUR) - 7;
+ bookstart = lseek(fp, 0, SEEK_CUR) - 7;
+ bookoffset = bookstart;
+ memset(buf, ' ', 3);
+ flag = false;
+ for (loop = 3; loop < 6; loop++) {
+ if (buf[loop]!='>')
+ flag = true;
+ else {
+ buf[loop] = 0;
+ break;
+ }
+ }
+ if (size) {
+ ch2 = *num1;
+ vs2 = 1;
+ if (findbreak(fp, &offset2, &ch2, &vs2, &rm2, 0)) {
+ booksize = (unsigned short) (lseek(fp, 0, SEEK_END) - bookstart - 7);
+ }
+ else {
+ if (vs2) {
+ booksize = (offset2 - bookstart - 7);
+ }
+ }
+ lseek(fp, bookstart+7, SEEK_SET);
+ cfile << "\nGot booksize " << booksize << "\n";
+ }
+ }
+
+ if (startchap(buf)) {
+ cfile << "{start of chapter}";
+ chapmark++;
+ //chapstart = lseek(fp, 0, SEEK_CUR) - 7;
+ chapstart = lseek(fp, 0, SEEK_CUR) - 7;
+ chapoffset = chapstart;
+ memset(buf, ' ', 3);
+ flag = false;
+ for (loop = 3; loop < 6; loop++) {
+ if (isdigit(buf[loop]))
+ flag = true;
+ else {
+ buf[loop] = 0;
+ break;
+ }
+ }
+ if (flag)
+ *num1 = atoi(buf);
+ else (*num1)++;
+
+ if (size) {
+ ch2 = *num1;
+ vs2 = 1;
+ lseek(fp, chapstart, SEEK_SET);
+ if (findbreak(fp, &offset2, &ch2, &vs2, &rm2, 0)) {
+ chapsize = (unsigned short) (lseek(fp, 0, SEEK_END) - chapstart);
+ cfile << "getting chapsizeend{" << chapsize << "} = " << lseek(fp, 0, SEEK_END) << " - " << chapstart << "\n";
+ }
+ else {
+ if (vs2) {
+ chapsize = (offset2 - chapstart);
+ cfile << "getting chapsize{" << chapsize << "} = " << offset2 << " - " << chapstart << "\n";
+ }
+ }
+ lseek(fp, chapstart + 7, SEEK_SET);
+ cfile << "\nGot chapsize " << chapsize << " loop{" << (int) loop << "}\n";
+ }
+ //return 0;
+
+ }
+ if (startentry(buf)) {
+ //cfile << "{start of verse}";
+ memset(buf, ' ', 3);
+ flag = false;
+ for (loop = 3; loop < 6; loop++) {
+ if (isdigit(buf[loop]))
+ flag = true;
+ else {
+ buf[loop] = 0;
+ break;
+ }
+ if (flag)
+ *num2 = atoi(buf);
+ else (*num2)++;
+ }
+ loop++;
+ /*
+ if (size)
+ {
+ // *offset = lseek(fp, 0, SEEK_CUR) - (7 - loop);
+ *offset = lseek(fp, 0, SEEK_CUR) - 7;
+ }
+ //else *offset = (chapstart) ? chapstart : lseek(fp, 0, SEEK_CUR) - 7;
+ else *offset = (chapstart) ? chapstart : lseek(fp, 0, SEEK_CUR) - 7;
+ */
+ /*if (chapstart)
+ {
+ chapsize = *offset-chapstart;
+ }
+ else
+ {
+ chapsize = 0;
+ }*/
+ *offset = lseek(fp, 0, SEEK_CUR) - 7;
+ versestart = *offset;
+ if (size) {
+ ch2 = *num1;
+ vs2 = *num2;
+ if (findbreak(fp, &offset2, &ch2, &vs2, &rm2, 0)) {
+ *size = (unsigned short) (lseek(fp, 0, SEEK_END) - versestart);
+ cfile << "getting sizeend{" << *size << "} = " << lseek(fp, 0, SEEK_END) << " - " << versestart << "\n";
+ }
+ else {
+ if (vs2) {
+ *size = (offset2 - versestart);
+ cfile << "getting size{" << *size << "} = " << offset2 << " - " << versestart << "\n";
+ }
+ }
+ lseek(fp, *offset+1, SEEK_SET);
+ }
+ else
+ {
+ cfile << "got offset{" << *offset << "}\n";
+ }
+ return 0;
+ }
+ //cfile << "{ng}";
+ //deadcount++;
+ //if (deadcount==1000) exit(-1);
+ //if (!size)
+ //{
+ // cfile << "not bound offset{" << *offset << "}\n";
+ //}
+ memmove(buf, &buf[1], 6);
+ if (read(fp, &buf[6], 1) != 1)
+ return 1;
+ }
+}
+
+
+void openfiles(char *fname)
+{
+#ifndef O_BINARY // O_BINARY is needed in Borland C++ 4.53
+#define O_BINARY 0 // If it hasn't been defined than we probably
+#endif // don't need it.
+ char buf[255];
+
+ if ((fp = open(fname, O_RDONLY|O_BINARY)) == -1) {
+ fprintf(stderr, "Couldn't open file: %s\n", fname);
+ exit(1);
+ }
+
+ sprintf(buf, "%s.vss", fname);
+ if ((vfp = open(buf, O_CREAT|O_WRONLY|O_BINARY|O_TRUNC)) == -1) {
+ fprintf(stderr, "Couldn't open file: %s\n", buf);
+ exit(1);
+ }
+
+ sprintf(buf, "%s.cps", fname);
+ if ((cfp = open(buf, O_CREAT|O_WRONLY|O_BINARY|O_TRUNC)) == -1) {
+ fprintf(stderr, "Couldn't open file: %s\n", buf);
+ exit(1);
+ }
+
+ sprintf(buf, "%s.bks", fname);
+ if ((bfp = open(buf, O_CREAT|O_WRONLY|O_BINARY|O_TRUNC)) == -1) {
+ fprintf(stderr, "Couldn't open file: %s\n", buf);
+ exit(1);
+ }
+ cfile.open("gbfidx.log", ios::out);
+ if (!cfile.is_open())
+ {
+ cerr << "Failed to open log file\n";
+ exit(-1);
+ }
+}
+
+
+void checkparams(int argc, char **argv)
+{
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <file to process> [nt - for new testmt file]\n", argv[0]);
+ exit(1);
+ }
+ if (!strcmp(argv[1], "nt"))
+ key1 = key2 = key3 = "Matthew 1:1";
+ else if (!strcmp(argv[1], "ot"))
+ {
+ key1 = key2 = key3 = "Genesis 1:1";
+ }
+ else
+ {
+ cerr << "File must be ot or nt\n";
+ exit(-1);
+ }
+}
diff --git a/src/modules/texts/ztext/makeidx.c b/src/modules/texts/ztext/makeidx.c new file mode 100644 index 0000000..311103e --- /dev/null +++ b/src/modules/texts/ztext/makeidx.c @@ -0,0 +1,146 @@ +#include <stdio.h> +#include <fcntl.h> + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size); + + +main(int argc, char **argv) +{ + int fp, vfp, cfp, bfp; + long pos; + short size, tmp; + int num1, num2, offset, curbook = 0, curchap = 0, curverse = 0; + char buf[127]; + + if (argc != 2) { + fprintf(stderr, "usage: %s <file to process>\n", argv[0]); + exit(1); + } + + if ((fp = open(argv[1], O_RDONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", argv[1]); + exit(1); + } + + sprintf(buf, "%s.vss", argv[1]); + if ((vfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.cps", argv[1]); + if ((cfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + sprintf(buf, "%s.bks", argv[1]); + if ((bfp = open(buf, O_CREAT|O_WRONLY)) == -1) { + fprintf(stderr, "Couldn't open file: %s\n", buf); + exit(1); + } + + pos = 0; + write(bfp, &pos, 4); /* Book offset for testament intros */ + pos = 4; + write(cfp, &pos, 4); /* Chapter offset for testament intro */ + + +/* Right now just zero out intros until parsing correctly */ + pos = 0; + size = 0; + write(vfp, &pos, 4); /* Module intro */ + write(vfp, &size, 2); + write(vfp, &pos, 4); /* Testament intro */ + write(vfp, &size, 2); + + while (!findbreak(fp, &offset, &num1, &num2, &size)) { + + if (num2 == 1) { /* if we're at a new chapter */ + if (num1 == 1) { /* if we're at a new book */ + pos = lseek(cfp, 0, SEEK_CUR); + write(bfp, &pos, 4); + pos = lseek(vfp, 0, SEEK_CUR); /* Book intro (cps) */ + write(cfp, &pos, 4); + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Book intro (vss) */ + write(vfp, &tmp, 2); + curbook++; + curchap = 0; + } + pos = lseek(vfp, 0, SEEK_CUR); + write(cfp, &pos, 4); + curverse = 1; + pos = 0; + tmp = 0; + write(vfp, &pos, 4); /* Chapter intro */ + write(vfp, &tmp, 2); + curchap++; + } + else curverse++; + + printf("%2d:%3d:%3d found at offset: %7d\n", curbook, num1, num2, offset); + + if (num1 != curchap) { + fprintf(stderr, "Error: Found chaptures out of sequence\n", buf); + break; + } + if (num2 != curverse) { + fprintf(stderr, "Error: Found verses out of sequence\n", buf); + break; + } + write(vfp, &offset, 4); + write(vfp, &size, 2); + } + + close(vfp); + close(cfp); + close(bfp); + close(fp); +} + + +char findbreak(int fp, int *offset, int *num1, int *num2, short *size) +{ + char buf[7]; + char buf2[7]; + char loop; + int offset2, ch2, vs2; + + memset(buf, ' ', 7); + + while (1) { + if (buf[3] == ':') { + memcpy(buf2, buf, 7); + for (loop = 0; loop < 7; loop++) { + if (!isdigit(buf2[loop])) + buf2[loop] = ' '; + } + buf2[3] = 0; + *num1 = atoi(buf2); + *num2 = atoi(&buf2[4]); + if (*num1 && *num2) { + *offset = lseek(fp, 0, SEEK_CUR); + sprintf(buf2, "%d", *num2); + *offset -= 2 - strlen(buf2); + if (size) { + if (findbreak(fp, &offset2, &ch2, &vs2, 0)) { + *size = (short) (lseek(fp, 0, SEEK_END) - (*offset)); + } + else { + sprintf(buf2, "%d:%d", ch2, vs2); + *size = (offset2 - (*offset)) - (strlen(buf2) + 2); + } + lseek(fp, *offset, SEEK_SET); + } + return 0; + } + } + memmove(buf, &buf[1], 6); + if (read(fp, &buf[6], 1) != 1) + return 1; + } +} + diff --git a/src/modules/texts/ztext/nasb.cpp b/src/modules/texts/ztext/nasb.cpp new file mode 100644 index 0000000..51e08b4 --- /dev/null +++ b/src/modules/texts/ztext/nasb.cpp @@ -0,0 +1,107 @@ + + +#include <ctype.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> + +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + +#include <swcomprs.h> + +class FileCompress: public SWCompress { + int ifd; + int ofd; + int ufd; + int zfd; +public: + FileCompress(char *); + ~FileCompress(); + int GetChars(char *, int len); + int SendChars(char *, int len); + void Encode(); + void Decode(); +}; + + +FileCompress::FileCompress(char *fname) +{ + char buf[256]; + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + + ufd = open(fname, O_RDWR|O_CREAT|O_BINARY); + + sprintf(buf, "%s.zzz", fname); + zfd = open(buf, O_RDWR|O_CREAT|O_BINARY); +} + + +FileCompress::~FileCompress(char *fname) +{ + close(ufd); + close(zfd); +} + + +int FileCompress::GetChars(char *buf, int len) +{ + return read(ifd, buf, len); +} + + +int FileCompress::SendChars(char *buf, int len) +{ + return write(ofd, buf, len); +} + + +void FileCompress::Encode() +{ + ifd = ufd; + ofd = zfd; + + SWCompress::Encode(); +} + + +void FileCompress::Decode() +{ + ifd = zfd; + ofd = ufd; + + SWCompress::Decode(); +} + + +main(int argc, char **argv) +{ + int decomp = 0; + SWCompress *fobj; + + if (argc != 2) { + fprintf(stderr, "usage: %s <filename|filename.zzz>\n", argv[0]); + exit(1); + } + + if (strlen(argv[1]) > 4) { + if (!strcmp(&argv[1][strlen(argv[1])-4], ".zzz")) { + argv[1][strlen(argv[1])-4] = 0; + decomp = 1; + } + } + + fobj = new FileCompress(argv[1]); + + if (decomp) + fobj->Decode(); + else fobj->Encode(); + + delete fobj; +} diff --git a/src/modules/texts/ztext/rawtxt2z.cpp b/src/modules/texts/ztext/rawtxt2z.cpp new file mode 100644 index 0000000..7eafe2a --- /dev/null +++ b/src/modules/texts/ztext/rawtxt2z.cpp @@ -0,0 +1,457 @@ +// Compression on variable granularity
+
+#include <fcntl.h>
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#ifndef __GNUC__
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <zlib.h>
+#include <versekey.h>
+
+int iBufSize, ulBuffNum;
+ofstream cfile;
+ofstream cfile2;
+
+int ofd[2], oxfd[2], ovxfd[2];
+int ifd[2], ixfd[2];
+int itestfd[2], itestxfd[2];
+unsigned long ulIOff=0, ulCOff=0, ulFOff=0, ulNone=0;
+string currbuff="";
+
+
+int openreadfile(char *buffer, char *path, const char *filename)
+{
+ int filenum;
+ sprintf(buffer, "%s/%s", path, filename);
+ cfile << buffer << "\n";
+ filenum = open(buffer, O_RDONLY|O_BINARY);
+ if (filenum > 0)
+ {
+ return filenum;
+ }
+ else
+ {
+ cerr << "failed to open file to read\n";
+ exit(-1);
+ }
+}
+
+int openwritefile(char *buffer, char *path, const char *filename)
+{
+ int filenum;
+ sprintf(buffer, "%s/%s", path, filename);
+ cfile << buffer << "\n";
+ filenum = open(buffer, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC);
+ if (filenum > 0)
+ {
+ return filenum;
+ }
+ else
+ {
+ cerr << "failed to open file to read\n";
+ exit(-1);
+ }
+}
+
+int bytebound(unsigned long offset, VerseKey &thekey)
+{
+ unsigned long bufferoff;
+ cfile << "byteboundtest " << thekey << "\n";
+ bufferoff = iBufSize * (ulBuffNum+1);
+ if (offset > bufferoff)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int versebound(unsigned long offset, VerseKey &thekey)
+{
+ cfile << "verseboundtest " << thekey << "\n";
+ return 1;
+}
+
+int chapterbound(unsigned long offset, VerseKey &thekey)
+{
+ VerseKey testkey;
+ testkey = thekey;
+ testkey++;
+ //cfile << "chapterboundtest " << testkey;
+ if (testkey.Verse()==1 || (!thekey.compare("Revelation of John 22:21")))
+ {
+ //cfile << " 1\n";
+ return 1;
+ }
+ else
+ {
+ //cfile << " 0\n";
+ return 0;
+ }
+}
+
+int bookbound(unsigned long offset, VerseKey &thekey)
+{
+ VerseKey testkey;
+ testkey = thekey;
+ cfile << "bookboundtest " << testkey << "\n";
+ testkey++;
+ if (testkey.Chapter()==1 || (!thekey.compare("Revelation of John 22:21")))
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+typedef int (*boundfunc)(unsigned long offset, VerseKey &thekey);
+
+int writeblock(int i)
+{
+ char *destbuff=NULL;
+ unsigned long compsize = 0, buffsize=0;
+
+ cfile << "compressing block\n";
+ // compress current buffer
+ buffsize = currbuff.length();
+ write(itestfd[i], currbuff.c_str(), buffsize);
+ compsize = (unsigned long) (buffsize*1.01)+20; // at least 1% bigger than buffer + 12 bytes
+ //cfile << "{" << compsize << "}";
+ //destbuff = (char *) calloc(compsize + 1, 1);
+ destbuff = new char[compsize];
+ if (compress((Bytef*)destbuff, &compsize, (const Bytef*)currbuff.c_str(), buffsize)!=Z_OK)
+ {
+ cerr << "Could not compress buffer: exiting\n";
+ delete[] destbuff;
+ exit(-1);
+ }
+ //cout << "Compressed buffer{" << compsize << "}\n" << destbuff << "\n";
+ //cout.flush();
+ // write to compressed file index
+ ulCOff = lseek(ofd[i], 0, SEEK_END);
+ write(oxfd[i], &ulCOff, 4); // offset in compressed file
+ write(oxfd[i], &compsize, 4); // compressed size
+ write(oxfd[i], &buffsize, 4); // uncompressed size
+ cfile << buffsize << " -> " << compsize << "\n";
+ cfile2 << "Compressed{" << compsize << "}\n" << destbuff << "\n";
+ cfile2.flush();
+
+ //write compressed buffer to file
+ write(ofd[i], destbuff, compsize);
+
+ //free(destbuff);
+ delete[] destbuff;
+
+ currbuff = "";
+ ulBuffNum++;
+ ulIOff = 0;
+ return 1;
+}
+
+
+
+int main(int argc, char **argv)
+{
+ VerseKey key1, key2, key3;
+ int i;
+ char xbuff[64];
+ unsigned long offset;
+ unsigned short size=0;
+ unsigned long ulsize=0;
+ char *tmpbuf=NULL;
+ int iType;
+ boundfunc blockbound[4] = {bytebound, versebound, chapterbound, bookbound};
+ bool newbook=true, newchapter=true, newtestament = true, newmodule = true, lasttodo=true;
+
+ if ((argc < 2) || (argc > 4)) {
+ cerr << "usage: " << argv[0] << " datapath [compression type [buffer size]]\n";
+ exit(1);
+ }
+
+ if (argc>2)
+ {
+ iType = atoi(argv[2]);
+ if (argc==4)
+ {
+ iBufSize = atoi(argv[3]);
+ }
+ else
+ {
+ iBufSize = 1;
+ }
+ }
+ else
+ {
+ iType = 2;
+ iBufSize = 1;
+ }
+
+ cfile.open("raw2z.log", ios::out);
+ if (!cfile.is_open())
+ {
+ cerr << "Failed to open log file\n";
+ exit(-1);
+ }
+ cfile2.open("raw2z.lg2", ios::out);
+ if (!cfile2.is_open())
+ {
+ cerr << "Failed to open log file\n";
+ exit(-1);
+ }
+ cfile << iType << " " << iBufSize << "\n";
+
+ if ((iType<=0) || (iType > 4) || !iBufSize || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "/?") || !strcmp(argv[1], "-help"))
+ {
+ cfile << argv[0] << " - a tool to create compressed Sword modules\n";
+ cfile << "version 0.1\n\n";
+ cfile << "usage: "<< argv[0] << " datapath [compression type [buffer size]]\n\n";
+ cfile << "datapath: the directory in which to find the raw module\n";
+ cfile << "compression type: (default 2)\n" << " 1 - bytes\n" << " 2 - verses\n" << " 3 - chapters\n" << " 4 - books\n";
+ cfile << "buffer size (default 1): the number of the compression type in each block\n";
+ exit(1);
+ }
+
+ //zobj = new SWCompress();
+ //rawdrv = new RawVerse(argv[1]);
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+ cfile << "opening files\n";
+
+ tmpbuf = new char [ strlen(argv[1]) + 11 ];
+
+ //original files
+ ifd[0] = openreadfile(tmpbuf, argv[1], "ot");
+ ixfd[0] = openreadfile(tmpbuf, argv[1], "ot.vss");
+ ifd[1] = openreadfile(tmpbuf, argv[1], "nt");
+ ixfd[1] = openreadfile(tmpbuf, argv[1], "nt.vss");
+
+switch ( iType) {
+ case 1 :
+ ofd[0] = openwritefile(tmpbuf, argv[1], "ot.rzz");
+ oxfd[0] = openwritefile(tmpbuf, argv[1], "ot.rzs");
+ ovxfd[0] = openwritefile(tmpbuf, argv[1], "ot.rzv");
+ ofd[1] = openwritefile(tmpbuf, argv[1], "nt.rzz");
+ oxfd[1] = openwritefile(tmpbuf, argv[1], "nt.rzs");
+ ovxfd[1] = openwritefile(tmpbuf, argv[1], "nt.rzv");
+ //boundfunc = bytebound;
+ break;
+ case 2 :
+ ofd[0] = openwritefile(tmpbuf, argv[1], "ot.vzz");
+ oxfd[0] = openwritefile(tmpbuf, argv[1], "ot.vzs");
+ ovxfd[0] = openwritefile(tmpbuf, argv[1], "ot.vzv");
+ ofd[1] = openwritefile(tmpbuf, argv[1], "nt.vzz");
+ oxfd[1] = openwritefile(tmpbuf, argv[1], "nt.vzs");
+ ovxfd[1] = openwritefile(tmpbuf, argv[1], "nt.vzv");
+ break;
+ case 3 :
+ ofd[0] = openwritefile(tmpbuf, argv[1], "ot.czz");
+ oxfd[0] = openwritefile(tmpbuf, argv[1], "ot.czs");
+ ovxfd[0] = openwritefile(tmpbuf, argv[1], "ot.czv");
+ ofd[1] = openwritefile(tmpbuf, argv[1], "nt.czz");
+ oxfd[1] = openwritefile(tmpbuf, argv[1], "nt.czs");
+ ovxfd[1] = openwritefile(tmpbuf, argv[1], "nt.czv");
+ break;
+ case 4 :
+ ofd[0] = openwritefile(tmpbuf, argv[1], "ot.bzz");
+ oxfd[0] = openwritefile(tmpbuf, argv[1], "ot.bzs");
+ ovxfd[0] = openwritefile(tmpbuf, argv[1], "ot.bzv");
+ ofd[1] = openwritefile(tmpbuf, argv[1], "nt.bzz");
+ oxfd[1] = openwritefile(tmpbuf, argv[1], "nt.bzs");
+ ovxfd[1] = openwritefile(tmpbuf, argv[1], "nt.bzv");
+ break;
+ default:
+ cerr << "Unknown compression type\n";
+ exit(-1);
+}
+ itestfd[0] = openwritefile(tmpbuf, argv[1], "ot.tst");
+ itestfd[1] = openwritefile(tmpbuf, argv[1], "nt.tst");
+ itestxfd[0] = openwritefile(tmpbuf, argv[1], "ot.tdx");
+ itestxfd[1] = openwritefile(tmpbuf, argv[1], "nt.tdx");
+
+
+ delete [] tmpbuf;
+
+ //cfile << "about to start\n";
+
+for ( i=0; i<2; i++)
+{
+ ulIOff=0, ulBuffNum=0;
+ currbuff = "";
+ key1 = (i == 1) ? "Matthew 1:1" : "Genesis 1:1";
+ key2 = key3 = key1;
+ newtestament = true;
+
+ cfile << "key: " << key1 << " Testament {" << key1.Testament()-1 << "}\n";
+ //cfile << "Chapter {" << key.Chapter() << "}\n";
+ //cfile << "Verse {" << key.Verse() << "}\n";
+ //cfile << key.compare("Revelation of John 22:21") << "\n";
+ //cfile << key.compare("Genesis 1:1") << "\n";
+ do
+ {
+ //cfile << "ok";
+ // read current verse offset
+ if (read(ixfd[i], &offset, 4) != 4)
+ {
+ cfile << "Failed to read input verse offsets?\n";
+ break;
+ }
+ if (read(ixfd[i], &size, 2) != 2)
+ {
+ cfile << "Failed to read input verse sizes?\n";
+ break;
+ }
+ cfile << "key:" << key1 << " offset:" << offset << " size:" << size << "\n";
+ sprintf(xbuff, "key{%s} offset{%ld} size{%d}\n", (const char *)key1, offset, size);
+ write(itestxfd[i], &xbuff, strlen(xbuff));
+ ulsize = size;
+ if (!offset && !size)
+ {
+ //Check for module header
+ if (read(ixfd[i], &ulIOff, 4) != 4)
+ {
+ cfile << "Failed to read input verse offsets?\n";
+ break;
+ }
+ ulsize = ulIOff;
+ ulIOff = 0;
+ lseek(ixfd[i], 6, SEEK_SET);
+ }
+
+ if (ulsize)
+ {
+ // read current verse and add to current buffer
+ tmpbuf = (char *) calloc(ulsize + 1, 1);
+ lseek(ifd[i], offset, SEEK_SET);
+ read(ifd[i], tmpbuf, ulsize);
+ currbuff += tmpbuf;
+ //cfile << currbuff << "\n";
+
+ // write to verse index into compressed
+ write(ovxfd[i], &ulBuffNum, 4); // current buffer number
+ write(ovxfd[i], &ulIOff, 4); // offset within the buffer
+ write(ovxfd[i], &size, 2); // verse size
+
+ ulFOff = lseek(ofd[i], 0, SEEK_CUR) + size;
+ if (key1.compare("Revelation of John 22:21")!=-1)
+ {
+ lasttodo = false;
+ }
+ if (blockbound[iType-1](ulFOff, key1)/*at block boudary*/)
+ {
+ writeblock(i);
+ /*
+ cfile << "compressing block\n";
+ // compress current buffer
+ buffsize = currbuff.length();
+ write(itestfd[i], currbuff.c_str(), buffsize);
+ compsize = (unsigned long) (buffsize*1.01)+20; // at least 1% bigger than buffer + 12 bytes
+ //cfile << "{" << compsize << "}";
+ //destbuff = (char *) calloc(compsize + 1, 1);
+ destbuff = new char[compsize];
+ if (compress((Bytef*)destbuff, &compsize, (const Bytef*)currbuff.c_str(), buffsize)!=Z_OK)
+ {
+ cerr << "Could not compress buffer: exiting\n";
+ delete[] destbuff;
+ exit(-1);
+ }
+ //cout << "Compressed buffer{" << compsize << "}\n" << destbuff << "\n";
+ //cout.flush();
+ // write to compressed file index
+ ulCOff = lseek(ofd[i], 0, SEEK_END);
+ write(oxfd[i], &ulCOff, 4); // offset in compressed file
+ write(oxfd[i], &compsize, 4); // compressed size
+ write(oxfd[i], &buffsize, 4); // uncompressed size
+ cfile << buffsize << " -> " << compsize << "\n";
+ cfile2 << "Compressed{" << compsize << "}\n" << destbuff << "\n";
+ cfile2.flush();
+
+ //write compressed buffer to file
+ write(ofd[i], destbuff, compsize);
+
+ //free(destbuff);
+ delete[] destbuff;
+
+ currbuff = "";
+ ulBuffNum++;
+ ulIOff = 0;
+ */
+ }
+ else
+ {
+ ulIOff += ulsize;
+ }
+ free(tmpbuf);
+
+ if (newmodule)
+ {
+ newmodule = false;
+ cfile << "had a new module " << (const char *) key1 << "{" << offset << "}\n";
+ writeblock(i);
+ }
+ else if (newtestament)
+ {
+ newtestament = false;
+ cfile << "had a new testament " << (const char *) key1 << "{" << offset << "}\n";
+ }
+ else if (newbook)
+ {
+ newbook = false;
+ cfile << "had a new book " << (const char *) key1 << "{" << offset << "}\n";
+ }
+ else if (newchapter)
+ {
+ newchapter = false;
+ cfile << "had a new chapter " << (const char *) key1 << "{" << offset << "}\n";
+ }
+ else
+ {
+ key1++;
+ }
+
+ if (key1.Chapter()!=key2.Chapter() || (key1.Book()!=key2.Book()))
+ {
+ newchapter = true;
+ cfile << "got a new chapter " << (const char *) key1 << "\n";
+ }
+ if (key1.Book()!=key2.Book())
+ {
+ newbook = true;
+ cfile << "got a new book " << (const char *) key1 << "\n";
+ }
+ key2 = key1;
+
+ }
+ else
+ {
+ cfile << "empty offset\n";
+ // write to verse index into compressed
+ write(ovxfd[i], &ulNone, 4); // current buffer number
+ write(ovxfd[i], &size, 2); // verse size
+ write(ovxfd[i], &ulNone, 4); // offset within the buffer
+ }
+ }
+ while ( (key1.Testament()==i+1) && ((key1.compare("Revelation of John 22:21")==-1) || (lasttodo)));
+
+ close(ifd[i]);
+ close(ofd[i]);
+ close(ixfd[i]);
+ close(oxfd[i]);
+ close(ovxfd[i]);
+ close(itestfd[i]);
+ close(itestxfd[i]);
+}
+ return 1;
+}
diff --git a/src/modules/texts/ztext/ztext.cpp b/src/modules/texts/ztext/ztext.cpp new file mode 100644 index 0000000..c774693 --- /dev/null +++ b/src/modules/texts/ztext/ztext.cpp @@ -0,0 +1,309 @@ +/****************************************************************************** + * ztext.cpp - code for class 'zText'- a module that reads compressed text + * files: ot and nt using indexs ??.vss + */ + + +#include <ctype.h> +#include <stdio.h> +#include <fcntl.h> + +#ifndef __GNUC__ +#include <io.h> +#else +#include <unistd.h> +#endif + +#include <string.h> +#include <utilfuns.h> +//#include <rawverse.h> +#include <ztext.h> +//#include <zlib.h> + + +/****************************************************************************** + * zText Constructor - Initializes data for instance of zText + * + * ENT: ipath - path to data files + * iname - Internal name for module + * idesc - Name to display to user for module + * iblockType - verse, chapter, book, etc. of index chunks + * icomp - Compressor object + * idisp - Display object to use for displaying + */ + +zText::zText(const char *ipath, const char *iname, const char *idesc, int iblockType, SWCompress *icomp, SWDisplay *idisp, SWTextEncoding enc, SWTextDirection dir, SWTextMarkup mark, const char* ilang) : zVerse(ipath, -1, iblockType, icomp), SWText(iname, idesc, idisp, enc, dir, mark, ilang)/*, SWCompress()*/ +{ + blockType = iblockType; + lastWriteKey = 0; +} + + +/****************************************************************************** + * zText Destructor - Cleans up instance of zText + */ + +zText::~zText() +{ + flushCache(); + + if (lastWriteKey) + delete lastWriteKey; +} + + +/****************************************************************************** + * zText::getRawEntry - Returns the current verse buffer + * + * RET: buffer with verse + */ + +char *zText::getRawEntry() +{ +/* + long start; + unsigned long size; + unsigned long destsize; + char *tmpbuf; + char *dest; + VerseKey *lkey = (VerseKey *) SWModule::key; + char sizebuf[3]; + + lkey->Verse(0); + if (chapcache != lkey->Index()) { + findoffset(lkey->Testament(), lkey->Index(), &start, &((unsigned short) size)); + readtext(lkey->Testament(), start, 3, sizebuf); + memcpy(&size, sizebuf, 2); + tmpbuf = new char [ size + 1 ]; + readtext(lkey->Testament(), start + 2, size + 1 , tmpbuf); + //zBuf(&size, tmpbuf); + dest = new char [ (size*4) + 1 ]; + uncompress((Bytef *)dest, &destsize, (Bytef *) tmpbuf, size); + chapcache = lkey->Index(); + delete [] tmpbuf; + } + + //findoffset(key->Testament(), key->Index(), &start, &size); + findoffset(lkey->Testament(), lkey->Index(), &start, &((unsigned short) size)); + + if (versebuf) + delete [] versebuf; + versebuf = new char [ size + 1 ]; + //memcpy(versebuf, Buf(), size); + memcpy(versebuf, dest, destsize); + delete [] dest; + + preptext(versebuf); + + return versebuf; +*/ + + long start = 0; + unsigned short size = 0; + VerseKey *key = 0; + + //printf ("zText char *\n"); + + // see if we have a VerseKey * or decendant + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + // if we don't have a VerseKey * decendant, create our own + if (!key) + key = new VerseKey(this->key); + + //printf ("checking cache\n"); + //printf ("finding offset\n"); + findoffset(key->Testament(), key->Index(), &start, &size); + entrySize = size; // support getEntrySize call + + //printf ("deleting previous buffer\n"); + unsigned long newsize = (size + 2) * FILTERPAD; + if (newsize > entrybufallocsize) { + if (entrybuf) + delete [] entrybuf; + entrybuf = new char [ newsize ]; + entrybufallocsize = newsize; + } + *entrybuf = 0; + + //printf ("getting text\n"); + zreadtext(key->Testament(), start, (size + 2), entrybuf); + //printf ("got text\n"); + + rawFilter(entrybuf, size, key); + + //printf ("preparing text\n"); + if (!isUnicode()) + preptext(entrybuf); + + if (this->key != key) // free our key if we created a VerseKey + delete key; + + //printf ("returning text\n"); + return entrybuf; + +} + + +bool zText::sameBlock(VerseKey *k1, VerseKey *k2) { + if (k1->Testament() != k2->Testament()) + return false; + + switch (blockType) { + case VERSEBLOCKS: + if (k1->Verse() != k2->Verse()) + return false; + case CHAPTERBLOCKS: + if (k1->Chapter() != k2->Chapter()) + return false; + case BOOKBLOCKS: + if (k1->Book() != k2->Book()) + return false; + } + return true; +} + + +void zText::setEntry(const char *inbuf, long len) { + VerseKey *key = 0; + // see if we have a VerseKey * or decendant + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + // if we don't have a VerseKey * decendant, create our own + if (!key) + key = new VerseKey(this->key); + + + // see if we've jumped across blocks since last write + if (lastWriteKey) { + if (!sameBlock(lastWriteKey, key)) { + flushCache(); + } + delete lastWriteKey; + } + + settext(key->Testament(), key->Index(), inbuf, len); + + lastWriteKey = (VerseKey *)key->clone(); // must delete + + if (this->key != key) // free our key if we created a VerseKey + delete key; +} + + +void zText::linkEntry(const SWKey *inkey) { + VerseKey *destkey = 0; + const VerseKey *srckey = 0; + // see if we have a VerseKey * or decendant + try { + destkey = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + // if we don't have a VerseKey * decendant, create our own + if (!destkey) + destkey = new VerseKey(this->key); + + // see if we have a VerseKey * or decendant + try { + srckey = (const VerseKey *) SWDYNAMIC_CAST(VerseKey, inkey); + } + catch ( ... ) { + } + // if we don't have a VerseKey * decendant, create our own + if (!srckey) + srckey = new VerseKey(inkey); + + linkentry(destkey->Testament(), destkey->Index(), srckey->Index()); + + if (this->key != destkey) // free our key if we created a VerseKey + delete destkey; + + if (inkey != srckey) // free our key if we created a VerseKey + delete srckey; +} + + +/****************************************************************************** + * zFiles::deleteEntry - deletes this entry + * + */ + +void zText::deleteEntry() { + + VerseKey *key = 0; + + try { + key = SWDYNAMIC_CAST(VerseKey, this->key); + } + catch ( ... ) {} + if (!key) + key = new VerseKey(this->key); + + settext(key->Testament(), key->Index(), ""); + + if (key != this->key) + delete key; +} + + +/****************************************************************************** + * zText::increment - Increments module key a number of entries + * + * ENT: increment - Number of entries to jump forward + * + */ + +void zText::increment(int steps) { + long start; + unsigned short size; + VerseKey *tmpkey = 0; + + try { + tmpkey = SWDYNAMIC_CAST(VerseKey, key); + } + catch ( ... ) {} + if (!tmpkey) + tmpkey = new VerseKey(key); + + findoffset(tmpkey->Testament(), tmpkey->Index(), &start, &size); + + SWKey lastgood = *tmpkey; + while (steps) { + long laststart = start; + unsigned short lastsize = size; + SWKey lasttry = *tmpkey; + (steps > 0) ? (*key)++ : (*key)--; + if (tmpkey != key) + delete tmpkey; + tmpkey = 0; + try { + tmpkey = SWDYNAMIC_CAST(VerseKey, key); + } + catch ( ... ) {} + if (!tmpkey) + tmpkey = new VerseKey(key); + + if ((error = key->Error())) { + *key = lastgood; + break; + } + long index = tmpkey->Index(); + findoffset(tmpkey->Testament(), index, &start, &size); + + if ( + (((laststart != start) || (lastsize != size)) // we're a different entry + && (start > 0) && (size)) // and we actually have a size + ||(!skipConsecutiveLinks)) { // or we don't want to skip consecutive links + steps += (steps < 0) ? 1 : -1; + lastgood = *tmpkey; + } + } + error = (error) ? KEYERR_OUTOFBOUNDS : 0; + + if (tmpkey != key) + delete tmpkey; +} |