Render embedded markdown footnotes
This commit is contained in:
+20
-1
@@ -113,6 +113,20 @@ proc fetchPlainPassages(
|
||||
for passage in fetchPassages(reference, translation, cfg):
|
||||
result.add(formatPlain(passage, translation, keepVerseNumbers))
|
||||
|
||||
proc fetchMarkdownPassages(
|
||||
reference,
|
||||
translation: string,
|
||||
cfg: CombinedConfig): seq[string] =
|
||||
|
||||
case translation
|
||||
of "akjv", "kjv":
|
||||
result = kjv.fetchMarkdownPassages(reference)
|
||||
of "mev":
|
||||
result = mev.fetchMarkdownPassages(reference)
|
||||
else:
|
||||
for passage in fetchPassages(reference, translation, cfg):
|
||||
result.add(formatMarkdown(passage, translation))
|
||||
|
||||
when isMainModule:
|
||||
const USAGE = """Usage:
|
||||
bibleref <reference> [options]
|
||||
@@ -189,7 +203,7 @@ Options:
|
||||
query.translation,
|
||||
keepVerseNumbers = true,
|
||||
cfg))
|
||||
else:
|
||||
of "reading", "text", "raw":
|
||||
for passage in fetchPassages(query.referenceText, query.translation, cfg):
|
||||
formattedPassages.add(
|
||||
case $args["--output-format"]:
|
||||
@@ -201,6 +215,11 @@ Options:
|
||||
passage
|
||||
else:
|
||||
formatMarkdown(passage, query.translation))
|
||||
else:
|
||||
formattedPassages.add(fetchMarkdownPassages(
|
||||
query.referenceText,
|
||||
query.translation,
|
||||
cfg))
|
||||
|
||||
echo formattedPassages.join("\p\p")
|
||||
|
||||
|
||||
+100
-26
@@ -23,6 +23,10 @@ type
|
||||
offset: int
|
||||
targetText: string
|
||||
|
||||
EmbeddedOutputFormat = enum
|
||||
eofPlain
|
||||
eofMarkdown
|
||||
|
||||
BibleIndex = object
|
||||
segments: seq[BibleSegment]
|
||||
verses: Table[string, bool]
|
||||
@@ -292,7 +296,8 @@ proc addSegmentWithFootnotes(
|
||||
line: var string,
|
||||
segment: BibleSegment,
|
||||
keepVerseNumbers: bool,
|
||||
notes: var seq[string]) =
|
||||
notes: var seq[string],
|
||||
outputFormat: EmbeddedOutputFormat) =
|
||||
|
||||
var text = segment.text
|
||||
var annotations = segment.annotations
|
||||
@@ -304,13 +309,20 @@ proc addSegmentWithFootnotes(
|
||||
notes.add(annotation.targetText)
|
||||
|
||||
let insertAt = max(0, min(text.len, annotation.offset + inserted))
|
||||
let marker = "[" & label & "]"
|
||||
let marker =
|
||||
case outputFormat
|
||||
of eofPlain: "[" & label & "]"
|
||||
of eofMarkdown: "[^" & label & "]"
|
||||
text.insert(marker, insertAt)
|
||||
inserted += marker.len
|
||||
|
||||
let marker =
|
||||
if keepVerseNumbers: $segment.verse & " "
|
||||
else: ""
|
||||
if keepVerseNumbers:
|
||||
case outputFormat
|
||||
of eofPlain: $segment.verse & " "
|
||||
of eofMarkdown: "**" & $segment.verse & "** "
|
||||
else:
|
||||
""
|
||||
|
||||
let content = marker & text
|
||||
if line.len == 0:
|
||||
@@ -320,13 +332,20 @@ proc addSegmentWithFootnotes(
|
||||
else:
|
||||
line.add("\n" & repeat(" ", segment.indent) & content)
|
||||
|
||||
proc addFootnotes(lines: var seq[string], notes: seq[string]) =
|
||||
proc addFootnotes(
|
||||
lines: var seq[string],
|
||||
notes: seq[string],
|
||||
outputFormat: EmbeddedOutputFormat) =
|
||||
if notes.len == 0:
|
||||
return
|
||||
|
||||
lines.add("")
|
||||
for idx, note in notes:
|
||||
lines.add(footnoteLabel(idx) & ". " & note)
|
||||
let label = footnoteLabel(idx)
|
||||
lines.add(
|
||||
case outputFormat
|
||||
of eofPlain: label & ". " & note
|
||||
of eofMarkdown: "[^" & label & "]: " & note)
|
||||
|
||||
proc selectedChapters(index: BibleIndex, reference: PassageReference):
|
||||
seq[tuple[chapter: int, verses: Table[string, bool]]] =
|
||||
@@ -353,11 +372,12 @@ proc selectedChapters(index: BibleIndex, reference: PassageReference):
|
||||
result.add((chapter, verses))
|
||||
result[chapterPositions[chapter]].verses[key] = true
|
||||
|
||||
proc plainChapter(
|
||||
proc formattedChapter(
|
||||
index: BibleIndex,
|
||||
code: string,
|
||||
selected: Table[string, bool],
|
||||
keepVerseNumbers: bool): string =
|
||||
keepVerseNumbers: bool,
|
||||
outputFormat: EmbeddedOutputFormat): string =
|
||||
|
||||
var lines: seq[string]
|
||||
var currentLine = ""
|
||||
@@ -404,17 +424,21 @@ proc plainChapter(
|
||||
renderSegment.verse = 0
|
||||
|
||||
if marker:
|
||||
currentLine.addSegmentWithFootnotes(renderSegment, keepVerseNumbers, notes)
|
||||
currentLine.addSegmentWithFootnotes(
|
||||
renderSegment,
|
||||
keepVerseNumbers,
|
||||
notes,
|
||||
outputFormat)
|
||||
else:
|
||||
var noVerseSegment = renderSegment
|
||||
noVerseSegment.text = renderSegment.text
|
||||
noVerseSegment.breakKind = sbSame
|
||||
currentLine.addSegmentWithFootnotes(noVerseSegment, false, notes)
|
||||
currentLine.addSegmentWithFootnotes(noVerseSegment, false, notes, outputFormat)
|
||||
|
||||
firstSelected = false
|
||||
|
||||
flushLine()
|
||||
lines.addFootnotes(notes)
|
||||
lines.addFootnotes(notes, outputFormat)
|
||||
|
||||
var wrapped: seq[string]
|
||||
for line in lines:
|
||||
@@ -428,25 +452,75 @@ proc plainChapter(
|
||||
wrapped.add(wrapWords(prepared, maxLineWidth = 74, newLine = "\p"))
|
||||
wrapped.join("\p")
|
||||
|
||||
proc fetchFormattedPassages(
|
||||
rows,
|
||||
reference,
|
||||
translationName: string,
|
||||
keepVerseNumbers: bool,
|
||||
outputFormat: EmbeddedOutputFormat): seq[string] =
|
||||
|
||||
let index = loadBibleIndex(rows, translationName)
|
||||
for parsedReference in parseReferences(reference):
|
||||
var parts: seq[string]
|
||||
for chapter in index.selectedChapters(parsedReference):
|
||||
parts.add(index.formattedChapter(
|
||||
parsedReference.book.code,
|
||||
chapter.verses,
|
||||
keepVerseNumbers,
|
||||
outputFormat))
|
||||
|
||||
let body = parts.join("\p\p")
|
||||
let referenceSeparator =
|
||||
case outputFormat
|
||||
of eofPlain:
|
||||
if body.contains("\pa. "): "\p\p"
|
||||
else: "\p"
|
||||
of eofMarkdown:
|
||||
if body.contains("\p[^a]: "): "\p\p"
|
||||
else: "\p"
|
||||
|
||||
let referenceLine =
|
||||
case outputFormat
|
||||
of eofPlain:
|
||||
"– " & $parsedReference & " (" & translationName.toUpperAscii & ")"
|
||||
of eofMarkdown:
|
||||
"> -- *" & $parsedReference & " (" &
|
||||
translationName.toUpperAscii & ")*"
|
||||
|
||||
let formattedBody =
|
||||
case outputFormat
|
||||
of eofPlain:
|
||||
body
|
||||
of eofMarkdown:
|
||||
var markdownLines: seq[string]
|
||||
for line in body.splitLines:
|
||||
if line.len == 0:
|
||||
markdownLines.add("")
|
||||
elif line.startsWith("[^"):
|
||||
markdownLines.add(line)
|
||||
else:
|
||||
markdownLines.add("> " & line)
|
||||
markdownLines.join("\p")
|
||||
|
||||
result.add(formattedBody & referenceSeparator & referenceLine)
|
||||
|
||||
proc fetchPlainPassages*(
|
||||
rows,
|
||||
reference,
|
||||
translationName: string,
|
||||
keepVerseNumbers = true): seq[string] =
|
||||
|
||||
let index = loadBibleIndex(rows, translationName)
|
||||
for parsedReference in parseReferences(reference):
|
||||
var parts: seq[string]
|
||||
for chapter in index.selectedChapters(parsedReference):
|
||||
parts.add(index.plainChapter(
|
||||
parsedReference.book.code,
|
||||
chapter.verses,
|
||||
keepVerseNumbers))
|
||||
fetchFormattedPassages(
|
||||
rows,
|
||||
reference,
|
||||
translationName,
|
||||
keepVerseNumbers,
|
||||
eofPlain)
|
||||
|
||||
let body = parts.join("\p\p")
|
||||
let referenceSeparator =
|
||||
if body.contains("\pa. "): "\p\p"
|
||||
else: "\p"
|
||||
|
||||
result.add(body & referenceSeparator & "– " & $parsedReference & " (" &
|
||||
translationName.toUpperAscii & ")")
|
||||
proc fetchMarkdownPassages*(rows, reference, translationName: string): seq[string] =
|
||||
fetchFormattedPassages(
|
||||
rows,
|
||||
reference,
|
||||
translationName,
|
||||
keepVerseNumbers = true,
|
||||
eofMarkdown)
|
||||
|
||||
@@ -8,3 +8,6 @@ proc fetchPassages*(reference: string): seq[string] =
|
||||
|
||||
proc fetchPlainPassages*(reference: string, keepVerseNumbers = true): seq[string] =
|
||||
embedded_bible.fetchPlainPassages(kjvRows, reference, "KJV", keepVerseNumbers)
|
||||
|
||||
proc fetchMarkdownPassages*(reference: string): seq[string] =
|
||||
embedded_bible.fetchMarkdownPassages(kjvRows, reference, "KJV")
|
||||
|
||||
@@ -18,3 +18,10 @@ proc fetchPlainPassages*(reference: string, keepVerseNumbers = true): seq[string
|
||||
else:
|
||||
raise newException(ValueError,
|
||||
"MEV data is not embedded; generate data/private/mev.tsv and rebuild")
|
||||
|
||||
proc fetchMarkdownPassages*(reference: string): seq[string] =
|
||||
when hasEmbeddedTranslationData("mev"):
|
||||
embedded_bible.fetchMarkdownPassages(mevRows, reference, "MEV")
|
||||
else:
|
||||
raise newException(ValueError,
|
||||
"MEV data is not embedded; generate data/private/mev.tsv and rebuild")
|
||||
|
||||
@@ -204,3 +204,37 @@ HEB 4 7 2 line 1 do not harden your hearts."
|
||||
"a. Jn 8:12\n" &
|
||||
"\n" &
|
||||
"– John 8:59-9:1 (TEST)"
|
||||
|
||||
test "markdown output renders native footnotes":
|
||||
const rows =
|
||||
"JHN\t8\t1\t0\tparagraph\t0\tBut Jesus went to the Mount of Olives.\t" &
|
||||
"""{"annotations":[{"kind":"crossReference","marker":"a","offset":40,"targetText":"Mt 21:1"}]}""" & "\n" &
|
||||
"JHN\t8\t2\t0\tsame\t0\tEarly in the morning He returned to the temple.\t" &
|
||||
"""{"annotations":[{"kind":"crossReference","marker":"a","offset":49,"targetText":"Mt 26:55; Lk 4:20"}]}""" & "\n"
|
||||
let passages = embedded_bible.fetchMarkdownPassages(rows, "John 8:1-2", "TEST")
|
||||
|
||||
check passages[0] == "> **1** But Jesus went to the Mount of Olives.[^a] **2** Early in the\n" &
|
||||
"> morning He returned to the temple.[^b]\n" &
|
||||
"\n" &
|
||||
"[^a]: Mt 21:1\n" &
|
||||
"[^b]: Mt 26:55; Lk 4:20\n" &
|
||||
"\n" &
|
||||
"> -- *John 8:1-2 (TEST)*"
|
||||
|
||||
test "markdown output resets native footnotes per chapter":
|
||||
const rows =
|
||||
"JHN\t8\t59\t0\tparagraph\t0\tThey took up stones.\t" &
|
||||
"""{"annotations":[{"kind":"crossReference","marker":"a","offset":21,"targetText":"Lev 24:16"}]}""" & "\n" &
|
||||
"JHN\t9\t1\t0\tparagraph\t0\tAs Jesus passed by.\t" &
|
||||
"""{"annotations":[{"kind":"crossReference","marker":"a","offset":20,"targetText":"Jn 8:12"}]}""" & "\n"
|
||||
let passages = embedded_bible.fetchMarkdownPassages(rows, "John 8:59-9:1", "TEST")
|
||||
|
||||
check passages[0] == "> **59** They took up stones.[^a]\n" &
|
||||
"\n" &
|
||||
"[^a]: Lev 24:16\n" &
|
||||
"\n" &
|
||||
"> **1** As Jesus passed by.[^a]\n" &
|
||||
"\n" &
|
||||
"[^a]: Jn 8:12\n" &
|
||||
"\n" &
|
||||
"> -- *John 8:59-9:1 (TEST)*"
|
||||
|
||||
Reference in New Issue
Block a user