Add translation-aware passage queries
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
esv_api
|
||||
bibleref
|
||||
tests/test_offline_kjv
|
||||
tests/test_passage_query
|
||||
data/private/
|
||||
*.sw?
|
||||
|
||||
+17
-12
@@ -10,6 +10,7 @@ import ./api_bible
|
||||
import ./esv
|
||||
import ./kjv
|
||||
import ./mev
|
||||
import ./passage_query
|
||||
|
||||
proc formatMarkdown(raw, translation: string): string =
|
||||
var reference = ""
|
||||
@@ -95,7 +96,7 @@ proc fetchPassages(reference, translation: string, cfg: CombinedConfig): seq[str
|
||||
else:
|
||||
raise newException(ValueError,
|
||||
"unsupported translation '" & translation &
|
||||
"'; supported translations: akjv, amp, esv, kjv, mev, nkjv, niv")
|
||||
"'; supported translations: " & supportedTranslationsList())
|
||||
|
||||
when isMainModule:
|
||||
const USAGE = """Usage:
|
||||
@@ -115,6 +116,9 @@ Options:
|
||||
Select a specific translation. Supported values
|
||||
are 'akjv', 'amp', 'esv', 'kjv', 'mev',
|
||||
'nkjv', and 'niv'. Defaults to 'esv'.
|
||||
Individual references may override this with a
|
||||
trailing marker, for example:
|
||||
'John 3:16 (KJV); John 3:16 (ESV)'.
|
||||
|
||||
--esv-api-token <token> Provide the API token on the command line. By
|
||||
default this will be read either from the
|
||||
@@ -156,24 +160,25 @@ Options:
|
||||
cfgFileJson = parseFile(cfgFilePath)
|
||||
|
||||
let cfg = CombinedConfig(docopt: args, json: cfgFileJson)
|
||||
let translation = cfg.getVal("translation", "esv").strip.toLowerAscii
|
||||
let defaultTranslation = cfg.getVal("translation", "esv")
|
||||
let reference = $args["<reference>"]
|
||||
let queries = parsePassageQueries(reference, defaultTranslation)
|
||||
|
||||
let passages = fetchPassages(reference, translation, cfg)
|
||||
|
||||
let formattedPassages =
|
||||
var formattedPassages: seq[string] = @[]
|
||||
for query in queries:
|
||||
for passage in fetchPassages(query.referenceText, query.translation, cfg):
|
||||
formattedPassages.add(
|
||||
case $args["--output-format"]:
|
||||
of "plain":
|
||||
passages --> map(formatPlain(it, translation))
|
||||
formatPlain(passage, query.translation)
|
||||
of "reading":
|
||||
passages -->
|
||||
map(formatPlain(it, translation, keepVerseNumbers = false))
|
||||
formatPlain(passage, query.translation, keepVerseNumbers = false)
|
||||
of "text":
|
||||
passages -->
|
||||
map(it.multiReplace([(re"\[(\d+)\]", "$1")]))
|
||||
of "raw": passages
|
||||
passage.multiReplace([(re"\[(\d+)\]", "$1")])
|
||||
of "raw":
|
||||
passage
|
||||
else:
|
||||
passages --> map(formatMarkdown(it, translation))
|
||||
formatMarkdown(passage, query.translation))
|
||||
|
||||
echo formattedPassages.join("\p\p")
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import std/strutils
|
||||
|
||||
import ./reference_parser
|
||||
|
||||
type PassageQuery* = object
|
||||
reference*: PassageReference
|
||||
translation*: string
|
||||
|
||||
const SupportedTranslations* = [
|
||||
"akjv", "amp", "esv", "kjv", "mev", "niv", "nkjv"
|
||||
]
|
||||
|
||||
proc supportedTranslationsList*(): string =
|
||||
SupportedTranslations.join(", ")
|
||||
|
||||
proc normalizeTranslation*(translation: string): string =
|
||||
result = translation.strip.toLowerAscii
|
||||
|
||||
for supported in SupportedTranslations:
|
||||
if result == supported:
|
||||
return
|
||||
|
||||
raise newException(ValueError,
|
||||
"unsupported translation '" & translation &
|
||||
"'; supported translations: " & supportedTranslationsList())
|
||||
|
||||
proc splitTrailingTranslationMarker(
|
||||
input: string): tuple[referenceText: string, translation: string] =
|
||||
|
||||
let text = input.strip
|
||||
if not text.endsWith(")"):
|
||||
return (text, "")
|
||||
|
||||
let openIdx = text.rfind("(")
|
||||
if openIdx < 0:
|
||||
return (text, "")
|
||||
|
||||
let referenceText = text[0 ..< openIdx].strip
|
||||
let translation = text[openIdx + 1 ..< text.len - 1].strip
|
||||
if referenceText.len == 0 or translation.len == 0:
|
||||
return (text, "")
|
||||
|
||||
(referenceText, translation)
|
||||
|
||||
proc parsePassageQuery*(input, defaultTranslation: string): PassageQuery =
|
||||
let parsed = splitTrailingTranslationMarker(input)
|
||||
result.reference = parseReference(parsed.referenceText)
|
||||
result.translation =
|
||||
if parsed.translation.len > 0:
|
||||
normalizeTranslation(parsed.translation)
|
||||
else:
|
||||
normalizeTranslation(defaultTranslation)
|
||||
|
||||
proc parsePassageQueries*(input, defaultTranslation: string): seq[PassageQuery] =
|
||||
for rawRef in input.split(';'):
|
||||
let refText = rawRef.strip
|
||||
if refText.len > 0:
|
||||
result.add(parsePassageQuery(refText, defaultTranslation))
|
||||
|
||||
if result.len == 0:
|
||||
raise newException(ValueError, "empty Bible reference")
|
||||
|
||||
proc referenceText*(query: PassageQuery): string =
|
||||
$query.reference
|
||||
@@ -0,0 +1,44 @@
|
||||
import std/unittest
|
||||
|
||||
import ../src/passage_query
|
||||
|
||||
suite "passage query parser":
|
||||
test "uses the default translation when no marker is present":
|
||||
let queries = parsePassageQueries("John 3:16", "kjv")
|
||||
|
||||
check queries.len == 1
|
||||
check queries[0].referenceText == "John 3:16"
|
||||
check queries[0].translation == "kjv"
|
||||
|
||||
test "uses a trailing translation marker":
|
||||
let queries = parsePassageQueries("2 John 5 (KJV)", "esv")
|
||||
|
||||
check queries.len == 1
|
||||
check queries[0].referenceText == "2 John 5"
|
||||
check queries[0].translation == "kjv"
|
||||
|
||||
test "parses mixed translation queries":
|
||||
let queries = parsePassageQueries("2 John 5 (KJV); 2 John 5 (ESV)", "mev")
|
||||
|
||||
check queries.len == 2
|
||||
check queries[0].referenceText == "2 John 5"
|
||||
check queries[0].translation == "kjv"
|
||||
check queries[1].referenceText == "2 John 5"
|
||||
check queries[1].translation == "esv"
|
||||
|
||||
test "uses the default translation per unmarked reference":
|
||||
let queries = parsePassageQueries("John 3:16; Psalm 23 (MEV)", "nkjv")
|
||||
|
||||
check queries.len == 2
|
||||
check queries[0].referenceText == "John 3:16"
|
||||
check queries[0].translation == "nkjv"
|
||||
check queries[1].referenceText == "Psalms 23"
|
||||
check queries[1].translation == "mev"
|
||||
|
||||
test "rejects unknown translation markers":
|
||||
expect ValueError:
|
||||
discard parsePassageQueries("John 3:16 (XYZ)", "esv")
|
||||
|
||||
test "rejects unknown default translations":
|
||||
expect ValueError:
|
||||
discard parsePassageQueries("John 3:16", "xyz")
|
||||
Reference in New Issue
Block a user