gor

Plato's Gorgias, at the command line.
git clone git://git.jtobin.io/gor.git
Log | Files | Refs

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 }