Rename CLI to bibleref

This commit is contained in:
2026-06-13 06:42:33 -05:00
parent 8f83c07693
commit 49594610dc
2 changed files with 8 additions and 8 deletions
+136
View File
@@ -0,0 +1,136 @@
# Nim CLI for retrieving Biblical passages
# © 2023 Jonathan Bernard
## Simple command-line tool for retrieving Biblical passages.
import std/[httpclient, json, logging, os, re, strutils, uri, wordwrap]
import cliutils, docopt, zero_functional
proc formatMarkdown(raw: string): string =
var reference = ""
var inVerse = false
var verseLines = newSeq[string]()
for line in raw.splitLines:
if reference.len == 0: reference = line.strip
if inVerse:
if line.startsWith("Footnotes"): inVerse = false
elif line.isEmptyOrWhitespace and verseLines[^1] != "":
verseLines.add("")
elif not line.match(re"^\s+[^\s]"): continue
elif line.match(re"$(.*)\(ESV\)$"): verseLines.add(line[0 ..< ^5])
else: verseLines.add(line)
elif line.match(re"^\s+\[\d+\]"):
inVerse = true
verseLines.add(line)
let wrapped = (verseLines -->
map(if it.len > 90: it.strip else: it & " ").
map(it.multiReplace([(re"\((\d+)\)", ""), (re"\[(\d+)\]", "**$1**")])).
map(wrapWords(it, maxLineWidth = 74, newLine = "\p"))).join("\p")
result = (wrapped.splitLines --> map("> " & it)).
join("\p") & "\p> -- *" & reference & " (ESV)*"
proc formatPlain(raw: string, keepVerseNumbers = true): string =
var reference = ""
var inVerse = false
var verseLines = newSeq[string]()
for line in raw.splitLines:
if reference.len == 0: reference = line.strip
if inVerse:
if line.startsWith("Footnotes"): inVerse = false
elif line.isEmptyOrWhitespace and verseLines[^1] != "":
verseLines.add("")
elif not line.match(re"^\s+[^\s]"): continue
elif line.match(re"$(.*)\(ESV\)$"): verseLines.add(line[0 ..< ^5])
else: verseLines.add(line)
elif line.match(re"^\s+\[\d+\]"):
inVerse = true
verseLines.add(line)
let wrapped = (verseLines -->
map(if it.len > 90: it.strip else: it & " ").
map(
if keepVerseNumbers:
it.multiReplace([(re"\((\d+)\)", ""), (re"\[(\d+)\]", "$1")])
else:
it.multiReplace([(re"\((\d+)\)", ""), (re"\[(\d+)\]", "")])).
map(wrapWords(it, maxLineWidth = 74, newLine = "\p"))).join("\p")
result = (wrapped.splitLines --> map(it)).
join("\p") & "\p " & reference & " (ESV)"
when isMainModule:
const USAGE = """Usage:
bibleref <reference> [options]
Options:
--debug Log debug information.
--echo-args Echo back the arguments that were passed on the
command line for debugging purposes.
-f, --output-format <format> Select a specific output format. Valid values
are 'raw', 'markdown', 'plain', 'reading'.
-t, --esv-api-token <token> Provide the API token on the command line. By
default this will be read either from the
.bibleref.cfg.json file or the ESV_API_TOKEN
envionment variable.
"""
let consoleLogger = newConsoleLogger(
levelThreshold=lvlInfo,
fmtStr="bibleref - $levelname: ")
logging.addHandler(consoleLogger)
try:
# Parse arguments
let args = docopt(USAGE, version = "0.3.0")
if args["--debug"]:
consoleLogger.levelThreshold = lvlDebug
if args["--echo-args"]: stderr.writeLine($args)
let cfgFilePath = getEnv("HOME") / ".bibleref.cfg.json"
var cfgFileJson = newJObject()
if fileExists(cfgFilePath):
debug "Loading config from " & cfgFilePath
cfgFileJson = parseFile(cfgFilePath)
let cfg = CombinedConfig(docopt: args, json: cfgFileJson)
let apiToken = cfg.getVal("esv-api-token")
let apiRoot = cfg.getVal("esv-api-root", "https://api.esv.org")
let reference = $args["<reference>"]
let http = newHttpClient()
http.headers = newHttpHeaders({"Authorization": "Token " & apiToken})
let urlPath = apiRoot & "/v3/passage/text/?q=" & encodeUrl(reference)
debug "requesting " & urlPath
let respJson = parseJson(http.getContent(urlPath))
let formattedPassages =
case $args["--output-format"]:
of "plain":
respJson["passages"].getElems --> map(formatPlain(it.getStr))
of "reading":
respJson["passages"].getElems -->
map(formatPlain(it.getStr, keepVerseNumbers = false))
of "text":
respJson["passages"].getElems -->
map(it.getStr.multiReplace([(re"\[(\d+)\]", "$1")]))
of "raw": respJson["passages"].getElems --> map(it.getStr)
else:
respJson["passages"].getElems --> map(formatMarkdown(it.getStr))
echo formattedPassages.join("\p\p")
except CatchableError:
fatal getCurrentExceptionMsg()
debug getCurrentException().getStackTrace()
quit(QuitFailure)