aboutsummaryrefslogtreecommitdiff
path: root/lib/citation/book.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/citation/book.ml')
-rw-r--r--lib/citation/book.ml104
1 files changed, 104 insertions, 0 deletions
diff --git a/lib/citation/book.ml b/lib/citation/book.ml
new file mode 100644
index 0000000..2a2b9c0
--- /dev/null
+++ b/lib/citation/book.ml
@@ -0,0 +1,104 @@
+(* SPDX-License-Identifier: AGPL-3.0-or-later *)
+
+type id = string
+
+let to_string t = t
+
+(* Every book cited across the shipped EF data (lectionary, sanctoral
+ propers, and commons), with every spelling any of the three files uses.
+ The dotted/undotted and modern/Vulgate pairs are inherited from lectio --
+ see book.mli. Surveyed directly against the data, all three files, not
+ the lectionary alone -- sanctoral.sexp alone carries more citations than
+ the lectionary and was the source of every token missed in the first
+ pass. *)
+let table =
+ [ ("genesis", [ "Gen" ]);
+ ("exodus", [ "Ex"; "Exod" ]);
+ ("leviticus", [ "Lev" ]);
+ ("numbers", [ "Num" ]);
+ ("kings_3", [ "3 Kings"; "3 Kgs." ]);
+ ("kings_4", [ "4 Kings" ]);
+ ("esdras_2", [ "2 Esd." ]);
+ ("tobit", [ "Tob" ]);
+ ("judith", [ "Judith" ]);
+ ("esther", [ "Esther" ]);
+ ("proverbs", [ "Prov" ]);
+ ("song_of_songs", [ "Song" ]);
+ ("wisdom", [ "Wis"; "Wis." ]);
+ ("ecclesiasticus", [ "Ecclus"; "Sir"; "Eccli" ]);
+ ("isaiah", [ "Isa"; "Isa." ]);
+ ("jeremiah", [ "Jer" ]);
+ ("ezekiel", [ "Ezech"; "Ezek" ]);
+ ("daniel", [ "Dan" ]);
+ ("osee", [ "Osee" ]);
+ ("joel", [ "Joel" ]);
+ ("jonas", [ "Jonas" ]);
+ ("malachi", [ "Mal" ]);
+ ("matthew", [ "Matt"; "Matt." ]);
+ ("mark", [ "Mark" ]);
+ ("luke", [ "Luke" ]);
+ ("john", [ "John" ]);
+ ("acts", [ "Acts" ]);
+ ("romans", [ "Rom" ]);
+ ("corinthians_1", [ "1 Cor"; "1 Cor." ]);
+ ("corinthians_2", [ "2 Cor"; "2 Cor." ]);
+ ("galatians", [ "Gal" ]);
+ ("ephesians", [ "Eph"; "Eph." ]);
+ ("philippians", [ "Phil" ]);
+ ("colossians", [ "Col"; "Col." ]);
+ ("thessalonians_1", [ "1 Thess"; "1 Thess." ]);
+ ("thessalonians_2", [ "2 Thess" ]);
+ ("timothy_1", [ "1 Tim." ]);
+ ("timothy_2", [ "2 Tim"; "2 Tim." ]);
+ ("titus", [ "Titus" ]);
+ ("hebrews", [ "Heb" ]);
+ ("james", [ "Jas"; "James" ]);
+ ("peter_1", [ "1 Pet"; "1 Pet." ]);
+ ("peter_2", [ "2 Pet." ]);
+ ("john_1", [ "1 John" ]);
+ (* "Apoc" is the Vulgate spelling and "Rev" its modern equivalent, but
+ BOTH sit inside Vulgate-tradition data, so both resolve to the same
+ Vulgate id here -- see book.mli's note by [apocalypse] never being an
+ [of_token] result under that name. Do not add "revelation" as a
+ spelling: it exists only as a tradition target (below), and giving it
+ an [of_token] entry would let one book carry two different ids. *)
+ ("apocalypse", [ "Apoc"; "Rev" ]) ]
+
+(* Targets a tradition can map ONTO that the Vulgate data never cites
+ directly. Present so [tradition_of_fields] can validate both sides.
+ [sirach] and [revelation] exist ONLY here, never as an [of_token] result:
+ "Sir" and "Rev" already resolve to the Vulgate ids [ecclesiasticus] and
+ [apocalypse] above, so a modern-numbering tradition maps ONTO these
+ targets rather than data ever citing them directly. *)
+let tradition_targets =
+ [ "kings_1"; "kings_2"; "nehemiah"; "sirach"; "hosea"; "jonah"; "revelation" ]
+
+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 default_spelling id =
+ match List.assoc_opt id table with
+ | Some (first :: _) -> first
+ | Some [] | None -> id
+
+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