gor.awk (5062B)
1 BEGIN { 2 # $1 Book name 3 # $2 Book abbreviation 4 # $3 Book number 5 # $4 Stephanus page 6 # $5 Section (1=a, 2=b, 3=c, 4=d, 5=e) 7 # $6 Text 8 FS = "\t" 9 10 MAX_WIDTH = 80 11 if (ENVIRON["GOR_MAX_WIDTH"] ~ /^[0-9]+$/) { 12 if (int(ENVIRON["GOR_MAX_WIDTH"]) < MAX_WIDTH) { 13 MAX_WIDTH = int(ENVIRON["GOR_MAX_WIDTH"]) 14 } 15 } 16 17 split("a,b,c,d,e", letters, ",") 18 19 if (cmd == "ref") { 20 mode = parseref(ref, p) 21 p["book"] = cleanbook(p["book"]) 22 } 23 } 24 25 cmd == "list" { 26 if (!($2 in seen_books)) { 27 printf("%s (%s)\n", $1, $2) 28 seen_books[$2] = 1 29 } 30 } 31 32 function letterval(c) { 33 if (c == "a") return 1 34 if (c == "b") return 2 35 if (c == "c") return 3 36 if (c == "d") return 4 37 if (c == "e") return 5 38 return 0 39 } 40 41 function parseref(ref, arr) { 42 # Stephanus reference formats: 43 # 1. <book> 44 # 2. <book> <page> (e.g., Gor 447) 45 # 3. <book> <page><letter> (e.g., Gor 447a) 46 # 4. <book> <page>-<page> (e.g., Gor 447-449) 47 # 5. <book> <page><l>-<page><l> (e.g., Gor 447a-449c) 48 # 6. <book> <page><l>-<l> (e.g., Gor 447a-c) 49 # 7. /<search> 50 # 8. <book>/<search> 51 # 9. <book> <page>/<search> 52 53 if (match(ref, "^[1-9]?[a-zA-Z ]+")) { 54 arr["book"] = substr(ref, 1, RLENGTH) 55 ref = substr(ref, RLENGTH + 1) 56 } else if (match(ref, "^/")) { 57 arr["search"] = substr(ref, 2) 58 return "search" 59 } else { 60 return "unknown" 61 } 62 63 # Parse optional page number 64 if (match(ref, "^:?[0-9]+")) { 65 if (sub("^:", "", ref)) { 66 arr["chapter"] = int(substr(ref, 1, RLENGTH - 1)) 67 ref = substr(ref, RLENGTH) 68 } else { 69 arr["chapter"] = int(substr(ref, 1, RLENGTH)) 70 ref = substr(ref, RLENGTH + 1) 71 } 72 } else if (match(ref, "^/")) { 73 arr["search"] = substr(ref, 2) 74 return "search" 75 } else if (ref == "") { 76 return "exact" 77 } else { 78 return "unknown" 79 } 80 81 # Parse optional letter (a-e) 82 if (match(ref, "^[a-e]")) { 83 arr["verse"] = letterval(substr(ref, 1, 1)) 84 ref = substr(ref, 2) 85 } else if (match(ref, "^-[0-9]+")) { 86 # page-page range (no letter) 87 arr["chapter_end"] = int(substr(ref, 2)) 88 return "range" 89 } else if (match(ref, "^/")) { 90 arr["search"] = substr(ref, 2) 91 return "search" 92 } else if (ref == "") { 93 return "exact" 94 } else { 95 return "unknown" 96 } 97 98 # After letter, check for range 99 if (match(ref, "^-[0-9]+[a-e]$")) { 100 # page-letter to page-letter range 101 r = substr(ref, 2) 102 arr["chapter_end"] = int(substr(r, 1, length(r) - 1)) 103 arr["verse_end"] = letterval(substr(r, length(r), 1)) 104 return "range_ext" 105 } else if (match(ref, "^-[a-e]$")) { 106 # same-page letter range (e.g., 447a-c) 107 arr["chapter_end"] = arr["chapter"] 108 arr["verse_end"] = letterval(substr(ref, 2, 1)) 109 return "range" 110 } else if (match(ref, "^-[0-9]+$")) { 111 # letter to page range (e.g., 447a-449) 112 arr["chapter_end"] = int(substr(ref, 2)) 113 return "range" 114 } else if (ref == "") { 115 return "exact" 116 } else { 117 return "unknown" 118 } 119 } 120 121 function cleanbook(book) { 122 book = tolower(book) 123 gsub(" +", "", book) 124 return book 125 } 126 127 function bookmatches(book, bookabbr, query) { 128 book = cleanbook(book) 129 if (book == query) { 130 return book 131 } 132 133 bookabbr = cleanbook(bookabbr) 134 if (bookabbr == query) { 135 return book 136 } 137 138 if (substr(book, 1, length(query)) == query) { 139 return book 140 } 141 } 142 143 function printverse(verse, word_count, characters_printed) { 144 if (ENVIRON["GOR_NOLINEWRAP"] != "" && ENVIRON["GOR_NOLINEWRAP"] != "0") { 145 printf("%s\n", verse) 146 return 147 } 148 149 word_count = split(verse, words, " ") 150 for (i = 1; i <= word_count; i++) { 151 if (characters_printed + length(words[i]) + (characters_printed > 0 ? 1 : 0) > MAX_WIDTH - 8) { 152 printf("\n\t") 153 characters_printed = 0 154 } 155 if (characters_printed > 0) { 156 printf(" ") 157 characters_printed++ 158 } 159 printf("%s", words[i]) 160 characters_printed += length(words[i]) 161 } 162 printf("\n") 163 } 164 165 function processline() { 166 if (last_book_printed != $2) { 167 print $1 168 last_book_printed = $2 169 } 170 171 printf("%d%s\t", $4, letters[$5]) 172 printverse($6) 173 outputted_records++ 174 } 175 176 cmd == "ref" && mode == "exact" && bookmatches($1, $2, p["book"]) && (p["chapter"] == "" || $4 == p["chapter"]) && (p["verse"] == "" || $5 == p["verse"]) { 177 processline() 178 } 179 180 cmd == "ref" && mode == "range" && bookmatches($1, $2, p["book"]) && ((p["chapter_end"] == "" && $4 == p["chapter"]) || ($4 >= p["chapter"] && $4 <= p["chapter_end"])) && (p["verse"] == "" || $5 >= p["verse"]) && (p["verse_end"] == "" || $5 <= p["verse_end"]) { 181 processline() 182 } 183 184 cmd == "ref" && mode == "range_ext" && bookmatches($1, $2, p["book"]) && (($4 == p["chapter"] && $5 >= p["verse"] && p["chapter"] != p["chapter_end"]) || ($4 > p["chapter"] && $4 < p["chapter_end"]) || ($4 == p["chapter_end"] && $5 <= p["verse_end"] && p["chapter"] != p["chapter_end"]) || (p["chapter"] == p["chapter_end"] && $4 == p["chapter"] && $5 >= p["verse"] && $5 <= p["verse_end"])) { 185 processline() 186 } 187 188 cmd == "ref" && mode == "search" && (p["book"] == "" || bookmatches($1, $2, p["book"])) && (p["chapter"] == "" || $4 == p["chapter"]) && match(tolower($6), tolower(p["search"])) { 189 processline() 190 } 191 192 END { 193 if (cmd == "ref" && outputted_records == 0) { 194 print "Unknown reference: " ref 195 } 196 }