Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
LukeSmithxyz committed Mar 6, 2019
0 parents commit 3b4bc84
Show file tree
Hide file tree
Showing 6 changed files with 34,298 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
vul
base/
25 changes: 25 additions & 0 deletions Makefile
@@ -0,0 +1,25 @@

PREFIX = /usr/local

vul: vul.sh vul.awk vul.tsv
cat vul.sh > $@
echo 'exit 0' >> $@
echo "#EOF" >> $@
tar cz vul.awk vul.tsv >> $@
chmod +x $@

test: vul.sh
shellcheck -s sh vul.sh

clean:
rm -f vul

install: vul
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f vul $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/vul

uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/vul

.PHONY: test clean install uninstall
53 changes: 53 additions & 0 deletions README.md
@@ -0,0 +1,53 @@
# vul -- Latin Vulgate Bible on the Command Line

A command line tool for search and reading the Clementine Vulgate.

Format and original implementation from [bontibon/kjv](https://github.com/bontibon/kjv). Meant to be a companion program.

## Usage

usage: ./vul [flags] [reference...]

-l list books
-W no line wrap
-h show help

Reference types:
<Book>
Individual book
<Book>:<Chapter>
Individual chapter of a book
<Book>:<Chapter>:<Verse>[,<Verse>]...
Individual verse(s) of a specific chapter of a book
<Book>:<Chapter>-<Chapter>
Range of chapters in a book
<Book>:<Chapter>:<Verse>-<Verse>
Range of verses in a book chapter
<Book>:<Chapter>:<Verse>-<Chapter>:<Verse>
Range of chapters and verses in a book

/<Search>
All verses that match a pattern
<Book>/<Search>
All verses in a book that match a pattern
<Book>:<Chapter>/<Search>
All verses in a chapter of a book that match a pattern

## Notes and Contents

- I/II Samuel and I/II Kings are named with their English titles despite the fact that in Latin they are respectively I-IV Kings. This is simply because the interface is in English and is supposed to be consistent with `kjv`.


## Install

Install `vul` by running:

```
git clone https://github.com/lukesmithxyz/vul.git
cd vul
sudo make install
```

## License

The script is in the public domain.
210 changes: 210 additions & 0 deletions vul.awk
@@ -0,0 +1,210 @@
BEGIN {
# $1 Book name
# $2 Book abbreviation
# $3 Book number
# $4 Chapter number
# $5 Verse number
# $6 Verse
FS = "\t"

MAX_WIDTH = 80
if (ENVIRON["KJV_MAX_WIDTH"] ~ /^[0-9]+$/) {
if (int(ENVIRON["KJV_MAX_WIDTH"]) < MAX_WIDTH) {
MAX_WIDTH = int(ENVIRON["KJV_MAX_WIDTH"])
}
}

if (cmd == "ref") {
mode = parseref(ref, p)
p["book"] = cleanbook(p["book"])
}
}

cmd == "list" {
if (!($2 in seen_books)) {
printf("%s (%s)\n", $1, $2)
seen_books[$2] = 1
}
}

function parseref(ref, arr) {
# 1. <book>
# 2. <book>:?<chapter>
# 3. <book>:?<chapter>:<verse>
# 3a. <book>:?<chapter>:<verse>[,<verse>]...
# 4. <book>:?<chapter>-<chapter>
# 5. <book>:?<chapter>:<verse>-<verse>
# 6. <book>:?<chapter>:<verse>-<chapter>:<verse>
# 7. /<search>
# 8. <book>/search
# 9. <book>:?<chapter>/search

if (match(ref, "^[1-9]?[a-zA-Z ]+")) {
# 1, 2, 3, 3a, 4, 5, 6, 8, 9
arr["book"] = substr(ref, 1, RLENGTH)
ref = substr(ref, RLENGTH + 1)
} else if (match(ref, "^/")) {
# 7
arr["search"] = substr(ref, 2)
return "search"
} else {
return "unknown"
}

if (match(ref, "^:?[1-9]+[0-9]*")) {
# 2, 3, 3a, 4, 5, 6, 9
if (sub("^:", "", ref)) {
arr["chapter"] = int(substr(ref, 1, RLENGTH - 1))
ref = substr(ref, RLENGTH)
} else {
arr["chapter"] = int(substr(ref, 1, RLENGTH))
ref = substr(ref, RLENGTH + 1)
}
} else if (match(ref, "^/")) {
# 8
arr["search"] = substr(ref, 2)
return "search"
} else if (ref == "") {
# 1
return "exact"
} else {
return "unknown"
}

if (match(ref, "^:[1-9]+[0-9]*")) {
# 3, 3a, 5, 6
arr["verse"] = int(substr(ref, 2, RLENGTH - 1))
ref = substr(ref, RLENGTH + 1)
} else if (match(ref, "^-[1-9]+[0-9]*$")) {
# 4
arr["chapter_end"] = int(substr(ref, 2))
return "range"
} else if (match(ref, "^/")) {
# 9
arr["search"] = substr(ref, 2)
return "search"
} else if (ref == "") {
# 2
return "exact"
} else {
return "unknown"
}

if (match(ref, "^-[1-9]+[0-9]*$")) {
# 5
arr["verse_end"] = int(substr(ref, 2))
return "range"
} else if (match(ref, "-[1-9]+[0-9]*")) {
# 6
arr["chapter_end"] = int(substr(ref, 2, RLENGTH - 1))
ref = substr(ref, RLENGTH + 1)
} else if (ref == "") {
# 3
return "exact"
} else if (match(ref, "^,[1-9]+[0-9]*")) {
# 3a
arr["verse", arr["verse"]] = 1
delete arr["verse"]
do {
arr["verse", substr(ref, 2, RLENGTH - 1)] = 1
ref = substr(ref, RLENGTH + 1)
} while (match(ref, "^,[1-9]+[0-9]*"))

if (ref != "") {
return "unknown"
}

return "exact_set"
} else {
return "unknown"
}

if (match(ref, "^:[1-9]+[0-9]*$")) {
# 6
arr["verse_end"] = int(substr(ref, 2))
return "range_ext"
} else {
return "unknown"
}
}

function cleanbook(book) {
book = tolower(book)
gsub(" +", "", book)
return book
}

function bookmatches(book, bookabbr, query) {
book = cleanbook(book)
if (book == query) {
return book
}

bookabbr = cleanbook(bookabbr)
if (bookabbr == query) {
return book
}

if (substr(book, 1, length(query)) == query) {
return book
}
}

function printverse(verse, word_count, characters_printed) {
if (ENVIRON["KJV_NOLINEWRAP"] != "" && ENVIRON["KJV_NOLINEWRAP"] != "0") {
printf("%s\n", verse)
return
}

word_count = split(verse, words, " ")
for (i = 1; i <= word_count; i++) {
if (characters_printed + length(words[i]) + (characters_printed > 0 ? 1 : 0) > MAX_WIDTH - 8) {
printf("\n\t")
characters_printed = 0
}
if (characters_printed > 0) {
printf(" ")
characters_printed++
}
printf("%s", words[i])
characters_printed += length(words[i])
}
printf("\n")
}

function processline() {
if (last_book_printed != $2) {
print $1
last_book_printed = $2
}

printf("%d:%d\t", $4, $5)
printverse($6)
outputted_records++
}

cmd == "ref" && mode == "exact" && bookmatches($1, $2, p["book"]) && (p["chapter"] == "" || $4 == p["chapter"]) && (p["verse"] == "" || $5 == p["verse"]) {
processline()
}

cmd == "ref" && mode == "exact_set" && bookmatches($1, $2, p["book"]) && (p["chapter"] == "" || $4 == p["chapter"]) && p["verse", $5] {
processline()
}

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"]) {
processline()
}

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"])) {
processline()
}

cmd == "ref" && mode == "search" && (p["book"] == "" || bookmatches($1, $2, p["book"])) && (p["chapter"] == "" || $4 == p["chapter"]) && match(tolower($6), tolower(p["search"])) {
processline()
}

END {
if (cmd == "ref" && outputted_records == 0) {
print "Unknown reference: " ref
}
}
95 changes: 95 additions & 0 deletions vul.sh
@@ -0,0 +1,95 @@
#!/bin/sh
# vul: Read the Word of God in Greek from your terminal
# License: Public domain

SELF="$0"

get_data() {
sed '1,/^#EOF$/d' < "$SELF" | tar xz -O "$1"
}

if [ -z "$PAGER" ]; then
if command -v less >/dev/null; then
PAGER="less"
else
PAGER="cat"
fi
fi

show_help() {
exec >&2
echo "usage: $(basename "$0") [flags] [reference...]"
echo
echo " -l list books"
echo " -W no line wrap"
echo " -h show help"
echo
echo " Reference types:"
echo " <Book>"
echo " Individual book"
echo " <Book>:<Chapter>"
echo " Individual chapter of a book"
echo " <Book>:<Chapter>:<Verse>[,<Verse>]..."
echo " Individual verse(s) of a specific chapter of a book"
echo " <Book>:<Chapter>-<Chapter>"
echo " Range of chapters in a book"
echo " <Book>:<Chapter>:<Verse>-<Verse>"
echo " Range of verses in a book chapter"
echo " <Book>:<Chapter>:<Verse>-<Chapter>:<Verse>"
echo " Range of chapters and verses in a book"
echo
echo " /<Search>"
echo " All verses that match a pattern"
echo " <Book>/<Search>"
echo " All verses in a book that match a pattern"
echo " <Book>:<Chapter>/<Search>"
echo " All verses in a chapter of a book that match a pattern"
exit 2
}

while [ $# -gt 0 ]; do
isFlag=0
firstChar="${1%"${1#?}"}"
if [ "$firstChar" = "-" ]; then
isFlag=1
fi

if [ "$1" = "--" ]; then
shift
break
elif [ "$1" = "-l" ]; then
# List all book names with their abbreviations
get_data vul.tsv | awk -v cmd=list "$(get_data vul.awk)"
exit
elif [ "$1" = "-W" ]; then
export KJV_NOLINEWRAP=1
shift
elif [ "$1" = "-h" ] || [ "$isFlag" -eq 1 ]; then
show_help
else
break
fi
done

cols=$(tput cols 2>/dev/null)
if [ $? -eq 0 ]; then
export KJV_MAX_WIDTH="$cols"
fi

if [ $# -eq 0 ]; then
if [ ! -t 0 ]; then
show_help
fi

# Interactive mode
while true; do
printf "vul> "
if ! read -r ref; then
break
fi
get_data vul.tsv | awk -v cmd=ref -v ref="$ref" "$(get_data vul.awk)" | ${PAGER}
done
exit 0
fi

get_data vul.tsv 2>/dev/null | awk -v cmd=ref -v ref="$*" "$(get_data vul.awk)" 2>/dev/null | ${PAGER}

0 comments on commit 3b4bc84

Please sign in to comment.