Render embedded Bible paragraphs inline
This commit is contained in:
+55
-13
@@ -30,6 +30,17 @@ proc verseKey(code: string, chapter, verse: int): string =
|
|||||||
proc chapterKey(code: string, chapter: int): string =
|
proc chapterKey(code: string, chapter: int): string =
|
||||||
code & "\t" & $chapter
|
code & "\t" & $chapter
|
||||||
|
|
||||||
|
proc legacySegment(text: string): tuple[breakKind: SegmentBreak, text: string] =
|
||||||
|
const pilcrow = "\xC2\xB6"
|
||||||
|
let stripped = text.strip(leading = true, trailing = false)
|
||||||
|
|
||||||
|
if stripped.startsWith(pilcrow):
|
||||||
|
result.breakKind = sbParagraph
|
||||||
|
result.text = stripped[pilcrow.len .. ^1].strip(leading = true, trailing = false)
|
||||||
|
else:
|
||||||
|
result.breakKind = sbSame
|
||||||
|
result.text = text
|
||||||
|
|
||||||
proc parseSegmentBreak(s: string): SegmentBreak =
|
proc parseSegmentBreak(s: string): SegmentBreak =
|
||||||
case s
|
case s
|
||||||
of "same": sbSame
|
of "same": sbSame
|
||||||
@@ -64,14 +75,15 @@ proc loadBibleIndex(rows, translationName: string): BibleIndex =
|
|||||||
"invalid embedded " & translationName & " row: " & line)
|
"invalid embedded " & translationName & " row: " & line)
|
||||||
|
|
||||||
if parts.len == 4:
|
if parts.len == 4:
|
||||||
|
let legacy = legacySegment(parts[3])
|
||||||
result.addSegment(BibleSegment(
|
result.addSegment(BibleSegment(
|
||||||
code: parts[0],
|
code: parts[0],
|
||||||
chapter: parseInt(parts[1]),
|
chapter: parseInt(parts[1]),
|
||||||
verse: parseInt(parts[2]),
|
verse: parseInt(parts[2]),
|
||||||
segment: 0,
|
segment: 0,
|
||||||
breakKind: sbLine,
|
breakKind: legacy.breakKind,
|
||||||
indent: 0,
|
indent: 0,
|
||||||
text: parts[3]))
|
text: legacy.text))
|
||||||
else:
|
else:
|
||||||
result.addSegment(BibleSegment(
|
result.addSegment(BibleSegment(
|
||||||
code: parts[0],
|
code: parts[0],
|
||||||
@@ -151,9 +163,41 @@ proc addFormattedSegment(
|
|||||||
lines[^1].add(" ")
|
lines[^1].add(" ")
|
||||||
lines[^1].add(content)
|
lines[^1].add(content)
|
||||||
else:
|
else:
|
||||||
if segment.breakKind == sbParagraph and hasPassageLine:
|
let isMarkerlessParagraphContinuation =
|
||||||
lines.add("")
|
segment.breakKind == sbParagraph and marker.len == 0 and hasPassageLine
|
||||||
lines.add(prefix & content)
|
|
||||||
|
if isMarkerlessParagraphContinuation:
|
||||||
|
if lines[^1].len > 0 and not lines[^1][^1].isSpaceAscii:
|
||||||
|
lines[^1].add(" ")
|
||||||
|
lines[^1].add(content)
|
||||||
|
else:
|
||||||
|
if segment.breakKind == sbParagraph and hasPassageLine:
|
||||||
|
lines.add("")
|
||||||
|
lines.add(prefix & content)
|
||||||
|
|
||||||
|
proc normalizeFirstSelectedSegment(segment: BibleSegment): BibleSegment =
|
||||||
|
result = segment
|
||||||
|
if result.breakKind == sbSame:
|
||||||
|
result.breakKind = sbLine
|
||||||
|
elif result.breakKind == sbParagraph and result.segment == 0:
|
||||||
|
result.breakKind = sbLine
|
||||||
|
|
||||||
|
proc addAllSegments(lines: var seq[string], index: BibleIndex, code: string) =
|
||||||
|
var emittedVerses: Table[string, bool]
|
||||||
|
var firstSelected = true
|
||||||
|
|
||||||
|
discard index.requireLastChapter(code)
|
||||||
|
for segment in index.segments:
|
||||||
|
if segment.code == code:
|
||||||
|
var adjusted = segment
|
||||||
|
if firstSelected:
|
||||||
|
adjusted = normalizeFirstSelectedSegment(adjusted)
|
||||||
|
lines.addFormattedSegment(adjusted, emittedVerses)
|
||||||
|
firstSelected = false
|
||||||
|
|
||||||
|
proc addRangeSeparator(lines: var seq[string]) =
|
||||||
|
if lines.len > 1 and lines[^1].len > 0:
|
||||||
|
lines.add("")
|
||||||
|
|
||||||
proc addVerseLines(
|
proc addVerseLines(
|
||||||
lines: var seq[string],
|
lines: var seq[string],
|
||||||
@@ -170,8 +214,8 @@ proc addVerseLines(
|
|||||||
if segment.code == code and
|
if segment.code == code and
|
||||||
selected.hasKey(verseKey(segment.code, segment.chapter, segment.verse)):
|
selected.hasKey(verseKey(segment.code, segment.chapter, segment.verse)):
|
||||||
var adjusted = segment
|
var adjusted = segment
|
||||||
if firstSelected and adjusted.breakKind == sbSame:
|
if firstSelected:
|
||||||
adjusted.breakKind = sbLine
|
adjusted = normalizeFirstSelectedSegment(adjusted)
|
||||||
lines.addFormattedSegment(adjusted, emittedVerses)
|
lines.addFormattedSegment(adjusted, emittedVerses)
|
||||||
firstSelected = false
|
firstSelected = false
|
||||||
|
|
||||||
@@ -180,13 +224,11 @@ proc fetchReference(index: BibleIndex, reference: PassageReference): string =
|
|||||||
let code = reference.book.code
|
let code = reference.book.code
|
||||||
|
|
||||||
if reference.ranges.len == 0:
|
if reference.ranges.len == 0:
|
||||||
var emittedVerses: Table[string, bool]
|
lines.addAllSegments(index, code)
|
||||||
discard index.requireLastChapter(code)
|
|
||||||
for segment in index.segments:
|
|
||||||
if segment.code == code:
|
|
||||||
lines.addFormattedSegment(segment, emittedVerses)
|
|
||||||
else:
|
else:
|
||||||
for range in reference.ranges:
|
for idx, range in reference.ranges:
|
||||||
|
if idx > 0:
|
||||||
|
lines.addRangeSeparator()
|
||||||
lines.addVerseLines(index, reference, range)
|
lines.addVerseLines(index, reference, range)
|
||||||
|
|
||||||
lines.join("\n")
|
lines.join("\n")
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ JHN 8 31 0 paragraph 0 Then Jesus said,
|
|||||||
JHN 8 31 1 same 0 "If you remain in My word,
|
JHN 8 31 1 same 0 "If you remain in My word,
|
||||||
JHN 8 32 0 same 0 you shall know the truth."
|
JHN 8 32 0 same 0 you shall know the truth."
|
||||||
JHN 8 33 0 paragraph 0 They answered Him.
|
JHN 8 33 0 paragraph 0 They answered Him.
|
||||||
|
JHN 8 39 0 paragraph 0 They answered Him, "Abraham is our father."
|
||||||
|
JHN 8 39 1 paragraph 0 Jesus said to them, "If you were Abraham's children,
|
||||||
|
JHN 8 40 0 same 0 you would do the works of Abraham."
|
||||||
HEB 4 7 0 paragraph 0 again He establishes a certain day:
|
HEB 4 7 0 paragraph 0 again He establishes a certain day:
|
||||||
HEB 4 7 1 line 0 "Today, if you will hear His voice,
|
HEB 4 7 1 line 0 "Today, if you will hear His voice,
|
||||||
HEB 4 7 2 line 1 do not harden your hearts."
|
HEB 4 7 2 line 1 do not harden your hearts."
|
||||||
@@ -126,8 +129,28 @@ HEB 4 7 2 line 1 do not harden your hearts."
|
|||||||
"\n" &
|
"\n" &
|
||||||
" [33] They answered Him."
|
" [33] They answered Him."
|
||||||
|
|
||||||
|
test "joins markerless paragraph continuations":
|
||||||
|
let passages = embedded_bible.fetchPassages(layoutRows, "John 8:39-40", "TEST")
|
||||||
|
|
||||||
|
check passages[0] == "John 8:39-40\n" &
|
||||||
|
" [39] They answered Him, \"Abraham is our father.\" " &
|
||||||
|
"Jesus said to them, \"If you were Abraham's children, " &
|
||||||
|
"[40] you would do the works of Abraham.\""
|
||||||
|
|
||||||
test "supports legacy verse rows":
|
test "supports legacy verse rows":
|
||||||
const legacyRows = "JHN\t3\t16\tFor God so loved the world.\n"
|
const legacyRows = "JHN\t3\t16\tFor God so loved the world.\n"
|
||||||
let passages = embedded_bible.fetchPassages(legacyRows, "John 3:16", "TEST")
|
let passages = embedded_bible.fetchPassages(legacyRows, "John 3:16", "TEST")
|
||||||
|
|
||||||
check passages[0] == "John 3:16\n [16] For God so loved the world."
|
check passages[0] == "John 3:16\n [16] For God so loved the world."
|
||||||
|
|
||||||
|
test "groups legacy rows into paragraphs using pilcrows":
|
||||||
|
const legacyRows =
|
||||||
|
"JHN\t8\t31\tThen Jesus said.\n" &
|
||||||
|
"JHN\t8\t32\tYou shall know the truth.\n" &
|
||||||
|
"JHN\t8\t33\t\xC2\xB6 They answered Him.\n"
|
||||||
|
let passages = embedded_bible.fetchPassages(legacyRows, "John 8:31-33", "TEST")
|
||||||
|
|
||||||
|
check passages[0] == "John 8:31-33\n" &
|
||||||
|
" [31] Then Jesus said. [32] You shall know the truth.\n" &
|
||||||
|
"\n" &
|
||||||
|
" [33] They answered Him."
|
||||||
|
|||||||
Reference in New Issue
Block a user