Add API.Bible translation support

This commit is contained in:
2026-06-13 07:12:14 -05:00
parent ffe3118ddf
commit 17f953882f
4 changed files with 177 additions and 20 deletions
+60 -20
View File
@@ -3,10 +3,13 @@
## Simple command-line tool for retrieving Biblical passages.
import std/[httpclient, json, logging, os, re, strutils, uri, wordwrap]
import std/[json, logging, os, re, strutils, wordwrap]
import cliutils, docopt, zero_functional
proc formatMarkdown(raw: string): string =
import ./api_bible
import ./esv
proc formatMarkdown(raw, translation: string): string =
var reference = ""
var inVerse = false
var verseLines = newSeq[string]()
@@ -30,9 +33,14 @@ proc formatMarkdown(raw: string): string =
map(wrapWords(it, maxLineWidth = 74, newLine = "\p"))).join("\p")
result = (wrapped.splitLines --> map("> " & it)).
join("\p") & "\p> -- *" & reference & " (ESV)*"
join("\p") & "\p> -- *" & reference & " (" &
translation.toUpperAscii & ")*"
proc formatPlain(
raw,
translation: string,
keepVerseNumbers = true): string =
proc formatPlain(raw: string, keepVerseNumbers = true): string =
var reference = ""
var inVerse = false
var verseLines = newSeq[string]()
@@ -60,7 +68,28 @@ proc formatPlain(raw: string, keepVerseNumbers = true): string =
map(wrapWords(it, maxLineWidth = 74, newLine = "\p"))).join("\p")
result = (wrapped.splitLines --> map(it)).
join("\p") & "\p " & reference & " (ESV)"
join("\p") & "\p " & reference & " (" & translation.toUpperAscii & ")"
proc fetchPassages(reference, translation: string, cfg: CombinedConfig): seq[string] =
case translation
of "esv":
esv.fetchPassages(
reference,
cfg.getVal("esv-api-token"),
cfg.getVal("esv-api-root", "https://api.esv.org"))
of "amp", "nkjv", "niv":
api_bible.fetchPassages(
reference,
translation,
cfg.getVal("api-bible-api-key"),
cfg.getVal("api-bible-root", api_bible.apiBibleRoot),
cfg.getVal(
"api-bible-" & translation & "-bible-id",
api_bible.defaultBibleId(translation)))
else:
raise newException(ValueError,
"unsupported translation '" & translation &
"'; supported translations: amp, esv, nkjv, niv")
when isMainModule:
const USAGE = """Usage:
@@ -76,10 +105,27 @@ Options:
-f, --output-format <format> Select a specific output format. Valid values
are 'raw', 'markdown', 'plain', 'reading'.
--translation <translation> Select a specific translation. Supported values
are 'amp', 'esv', 'nkjv', and 'niv'. Defaults
to 'esv'.
-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.
--api-bible-api-key <key> Provide the API.Bible API key for translations
backed by api.bible.
--api-bible-root <url> Override the API.Bible API root. Defaults to
https://rest.api.bible/v1.
--api-bible-amp-bible-id <id> Override the API.Bible Bible ID for AMP.
--api-bible-niv-bible-id <id> Override the API.Bible Bible ID for NIV.
--api-bible-nkjv-bible-id <id>
Override the API.Bible Bible ID for NKJV.
"""
let consoleLogger = newConsoleLogger(
@@ -103,30 +149,24 @@ Options:
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 translation = cfg.getVal("translation", "esv").strip.toLowerAscii
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 passages = fetchPassages(reference, translation, cfg)
let formattedPassages =
case $args["--output-format"]:
of "plain":
respJson["passages"].getElems --> map(formatPlain(it.getStr))
passages --> map(formatPlain(it, translation))
of "reading":
respJson["passages"].getElems -->
map(formatPlain(it.getStr, keepVerseNumbers = false))
passages -->
map(formatPlain(it, translation, keepVerseNumbers = false))
of "text":
respJson["passages"].getElems -->
map(it.getStr.multiReplace([(re"\[(\d+)\]", "$1")]))
of "raw": respJson["passages"].getElems --> map(it.getStr)
passages -->
map(it.multiReplace([(re"\[(\d+)\]", "$1")]))
of "raw": passages
else:
respJson["passages"].getElems --> map(formatMarkdown(it.getStr))
passages --> map(formatMarkdown(it, translation))
echo formattedPassages.join("\p\p")