aboutsummaryrefslogtreecommitdiff
path: root/lib/citation/book.ml
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-08-20 14:40:12 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-08-20 14:40:12 +0200
commit405910d2fd245e7a11e09eecb8c6fffb68d2169c (patch)
tree7cb7e0011fee6c1c07ae81762640f0ab867e88b6 /lib/citation/book.ml
parent1aeca948c2a2a82bffaaec65077140aa05f7b3f4 (diff)
downloadcolitur-405910d2fd245e7a11e09eecb8c6fffb68d2169c.tar.gz
colitur-405910d2fd245e7a11e09eecb8c6fffb68d2169c.zip
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.
Diffstat (limited to 'lib/citation/book.ml')
-rw-r--r--lib/citation/book.ml74
1 files changed, 74 insertions, 0 deletions
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