summaryrefslogtreecommitdiff
path: root/internal/bible/validate.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/bible/validate.go')
-rw-r--r--internal/bible/validate.go38
1 files changed, 35 insertions, 3 deletions
diff --git a/internal/bible/validate.go b/internal/bible/validate.go
index 27ec519..9c99436 100644
--- a/internal/bible/validate.go
+++ b/internal/bible/validate.go
@@ -3,6 +3,8 @@ package bible
import (
"fmt"
"sort"
+ "strings"
+ "unicode/utf8"
)
// CorpusReport is the outcome of validating one corpus's sidecar + text (see
@@ -34,7 +36,10 @@ var validPsalmSystems = map[string]bool{"vulgate": true, "hebrew": true, "drb":
// chapter, or a repeated verse number within a chapter, is a warning only --
// real source texts legitimately do this (e.g. the LXX's lettered doublet
// verses in 3 Kingdoms, or a scanned translation's occasional merged verse),
-// and it must never turn a corpus that otherwise loads fine into a failure.
+// and it must never turn a corpus that otherwise loads fine into a failure. A
+// verse that IS present but whose text is a stub next to the aligned Vulgate
+// verse (a likely truncation or lost line -- the one defect the count-based
+// checks cannot see) is likewise a warning.
func CheckCorpus(code string) CorpusReport {
r := CorpusReport{Code: code}
@@ -62,6 +67,7 @@ func CheckCorpus(code string) CorpusReport {
ref := load("vul")
for book, chaps := range c.books {
+ refBook := ref.books[book] // nil if vul lacks the book (e.g. an EF-only name)
for ch, verses := range chaps {
seen := map[int]bool{}
maxV := 0
@@ -77,9 +83,35 @@ func CheckCorpus(code string) CorpusReport {
if maxV > len(seen) {
r.Warnings = append(r.Warnings, fmt.Sprintf("%s %d: verse gap (have %d verse(s), highest numbered %d)", book, ch, len(seen), maxV))
}
+
+ // Suspiciously-short verse: present, but a stub next to the SAME verse
+ // in the reference Vulgate -- a likely truncation or lost line (an
+ // opening dropped in a scrape, a merge artifact) that the
+ // presence-only checks cannot see, since the verse IS there. The
+ // comparison is cross-corpus, not within the chapter, precisely so a
+ // genuinely terse verse ("Non occides", "Jesus wept") is NOT flagged:
+ // the Vulgate's own copy is short too, so the guard below fails. It
+ // fires only when the corpus verse is a stub AND the aligned Vulgate
+ // verse is substantial. Skipped on the Psalms when the corpus
+ // renumbers them (psalm_system != vulgate), where the per-verse
+ // alignment with the Vulgate does not hold.
+ if refBook != nil && !(book == "Psalms" && m.PsalmSystem != "vulgate") {
+ if refCh, ok := refBook[ch]; ok {
+ refLen := make(map[int]int, len(refCh))
+ for _, rv := range refCh {
+ refLen[rv.Verse] = utf8.RuneCountInString(strings.TrimSpace(rv.Text))
+ }
+ for _, v := range verses {
+ n := utf8.RuneCountInString(strings.TrimSpace(v.Text))
+ if rl := refLen[v.Verse]; rl >= 40 && n < 12 && n*4 < rl {
+ r.Warnings = append(r.Warnings, fmt.Sprintf("%s %d:%d: text suspiciously short (%d chars vs vul %d)", book, ch, v.Verse, n, rl))
+ }
+ }
+ }
+ }
}
- if refChaps, ok := ref.books[book]; ok {
- for ch := range refChaps {
+ if refBook != nil {
+ for ch := range refBook {
if _, have := chaps[ch]; !have {
r.Warnings = append(r.Warnings, fmt.Sprintf("%s: missing chapter %d (present in vul)", book, ch))
}