From 405910d2fd245e7a11e09eecb8c6fffb68d2169c Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 20 Aug 2026 14:40:12 +0200 Subject: feat(citation): canonical book ids and tradition mapping Seven books arrive in two spellings, inherited from lectio's ini and ultimately from Divinum Officium. Collapse them onto one id here rather than editing generated data. Naming and renumbering are kept apart: a tradition decides which book an id denotes, a language file decides what it is called. --- lib/citation/book.ml | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 lib/citation/book.ml (limited to 'lib/citation/book.ml') diff --git a/lib/citation/book.ml b/lib/citation/book.ml new file mode 100644 index 0000000..a2f9678 --- /dev/null +++ b/lib/citation/book.ml @@ -0,0 +1,74 @@ +(* SPDX-License-Identifier: AGPL-3.0-or-later *) + +type id = string + +let to_string t = t + +(* Every book the shipped EF lectionary cites, with every spelling it uses. + The dotted/undotted pairs are inherited from lectio -- see book.mli. *) +let table = + [ ("genesis", [ "Gen" ]); + ("exodus", [ "Ex" ]); + ("leviticus", [ "Lev" ]); + ("numbers", [ "Num" ]); + ("kings_3", [ "3 Kings"; "3 Kgs." ]); + ("kings_4", [ "4 Kings" ]); + ("esdras_2", [ "2 Esd." ]); + ("esther", [ "Esther" ]); + ("ecclesiasticus", [ "Ecclus" ]); + ("isaiah", [ "Isa"; "Isa." ]); + ("jeremiah", [ "Jer" ]); + ("ezekiel", [ "Ezech" ]); + ("daniel", [ "Dan" ]); + ("osee", [ "Osee" ]); + ("joel", [ "Joel" ]); + ("jonas", [ "Jonas" ]); + ("matthew", [ "Matt"; "Matt." ]); + ("mark", [ "Mark" ]); + ("luke", [ "Luke" ]); + ("john", [ "John" ]); + ("acts", [ "Acts" ]); + ("romans", [ "Rom" ]); + ("corinthians_1", [ "1 Cor"; "1 Cor." ]); + ("corinthians_2", [ "2 Cor." ]); + ("galatians", [ "Gal" ]); + ("ephesians", [ "Eph"; "Eph." ]); + ("philippians", [ "Phil" ]); + ("colossians", [ "Col" ]); + ("thessalonians_1", [ "1 Thess"; "1 Thess." ]); + ("thessalonians_2", [ "2 Thess" ]); + ("titus", [ "Titus" ]); + ("hebrews", [ "Heb" ]); + ("james", [ "Jas" ]); + ("peter_1", [ "1 Pet"; "1 Pet." ]); + ("john_1", [ "1 John" ]) ] + +(* Targets a tradition can map ONTO that the Vulgate data never cites + directly. Present so [tradition_of_fields] can validate both sides. *) +let tradition_targets = + [ "kings_1"; "kings_2"; "nehemiah"; "sirach"; "hosea"; "jonah" ] + +let all = List.map fst table @ tradition_targets + +let tokens = + List.concat_map (fun (id, sp) -> List.map (fun s -> (s, id)) sp) table + +let of_token s = + let s = String.trim s in + List.assoc_opt s tokens + +type tradition = (string * string) list + +let vulgate = [] + +let known id = List.mem id all + +let tradition_of_fields fields = + List.filter (fun (a, b) -> known a && known b) fields + +let unknown_fields fields = + List.filter_map + (fun (a, b) -> if known a && known b then None else Some a) + fields + +let map tr id = match List.assoc_opt id tr with Some x -> x | None -> id -- cgit v1.3