(* 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"; "Liber Genesis"; "Genesis" ]); ("exodus", [ "Ex"; "Exod"; "Liber Exodi"; "Exodus" ]); ("leviticus", [ "Lev"; "Levit"; "Liber Levitici"; "Leviticus" ]); ("numbers", [ "Num"; "Liber Numeri"; "Numbers" ]); ("kings_3", [ "3 Kings"; "3 Kgs."; "3 Reg"; "Liber Regum III" ]); ("kings_4", [ "4 Kings"; "4 Reg"; "Liber Regum IV"; "4 Kgs." ]); ("esdras_2", [ "2 Esd."; "2 Esdr"; "Liber Esdrae"; "2 Esdras" ]); ("tobit", [ "Tob"; "Liber Tobiae"; "Tobias" ]); ("judith", [ "Judith"; "Iudith"; "Liber Iudith"; "Jth" ]); ("esther", [ "Esther"; "Esth"; "Liber Esther" ]); ("proverbs", [ "Prov"; "Proverbs" ]); ("song_of_songs", [ "Song"; "Cant."; "Canticle of Canticles" ]); ("wisdom", [ "Wis"; "Wis."; "Sap"; "Liber Sapientiae"; "Wisdom" ]); ("ecclesiasticus", [ "Ecclus"; "Sir"; "Eccli"; "Ecclesiasticus" ]); ("isaiah", [ "Isa"; "Isa."; "Isai"; "Isaias Propheta"; "Isaias" ]); ("jeremiah", [ "Jer"; "Ier"; "Ieremias Propheta"; "Jeremias" ]); ("ezekiel", [ "Ezech"; "Ezek"; "Ezechiel Propheta"; "Ezechiel" ]); ("daniel", [ "Dan"; "Daniel Propheta"; "Daniel" ]); ("osee", [ "Osee"; "Osee Propheta" ]); ("joel", [ "Joel"; "Ioel"; "Ioel Propheta" ]); ("jonas", [ "Jonas"; "Ionae"; "Ionas Propheta" ]); ("malachi", [ "Mal"; "Malach"; "Malachias Propheta"; "Malachias" ]); ("matthew", [ "Matt"; "Matt."; "Matth"; "Evangelium secundum Matthaeum"; "Matthew" ]); ("mark", [ "Mark"; "Marc"; "Evangelium secundum Marcum" ]); ("luke", [ "Luke"; "Luc"; "Evangelium secundum Lucam" ]); ("john", [ "John"; "Ioann"; "Evangelium secundum Ioannem" ]); ("acts", [ "Acts"; "Act"; "Actus Apostolorum"; "Acts of the Apostles" ]); ("romans", [ "Rom"; "Epistola ad Romanos"; "Romans" ]); ("corinthians_1", [ "1 Cor"; "1 Cor."; "Epistola I ad Corinthios"; "1 Corinthians" ]); ("corinthians_2", [ "2 Cor"; "2 Cor."; "Epistola II ad Corinthios"; "2 Corinthians" ]); ("galatians", [ "Gal"; "Epistola ad Galatas"; "Galatians" ]); ("ephesians", [ "Eph"; "Eph."; "Ephes"; "Epistola ad Ephesios"; "Ephesians" ]); ("philippians", [ "Phil"; "Epistola ad Philippenses"; "Philippians" ]); ("colossians", [ "Col"; "Col."; "Epistola ad Colossenses"; "Colossians" ]); ("thessalonians_1", [ "1 Thess"; "1 Thess."; "Epistola I ad Thessalonicenses"; "1 Thessalonians" ]); ("thessalonians_2", [ "2 Thess"; "Epistola II ad Thessalonicenses"; "2 Thessalonians" ]); ("timothy_1", [ "1 Tim."; "1 Tim"; "Epistola I ad Timotheum"; "1 Timothy" ]); ("timothy_2", [ "2 Tim"; "2 Tim."; "Epistola II ad Timotheum"; "2 Timothy" ]); ("titus", [ "Titus"; "Tit"; "Epistola ad Titum" ]); ("hebrews", [ "Heb"; "Hebr"; "Epistola ad Hebraeos"; "Hebrews" ]); ("james", [ "Jas"; "James"; "Iac"; "Epistola beati Iacobi Apostoli" ]); ("peter_1", [ "1 Pet"; "1 Pet."; "1 Petri"; "Epistola I beati Petri Apostoli"; "1 Peter" ]); ("peter_2", [ "2 Pet."; "2 Petri"; "Epistola II beati Petri Apostoli"; "2 Pet"; "2 Peter" ]); ("john_1", [ "1 John"; "1 Ioann"; "Epistola beati Ioannis Apostoli" ]); (* "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"; "Liber Apocalypsis"; "Apocalypse" ]) ] (* 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. *) (* The modern-numbering targets. They have table rows so that colitur's OWN rendered output re-parses: with --sigla-tradition modern the book prints as "1 Reg" or "1 Kings", and a user copying that back into an overlay must get it read correctly. The shipped data never cites them directly, which is why they are listed apart. *) let tradition_target_table = [ ("kings_1", [ "1 Reg"; "Liber Regum I"; "1 Kgs"; "1 Kings" ]); ("kings_2", [ "2 Reg"; "Liber Regum II"; "2 Kgs"; "2 Kings" ]); ("nehemiah", [ "Neh"; "Liber Nehemiae"; "Nehemiah" ]); ("sirach", [ "Liber Ecclesiastici"; "Sirach" ]); ("hosea", [ "Os"; "Hos"; "Hosea" ]); ("jonah", [ "Ion"; "Jon"; "Jonah" ]); ("revelation", [ "Apocalypsis"; "Revelation" ]); ] let tradition_targets = List.map fst tradition_target_table let all = List.map fst table @ tradition_targets let tokens = List.concat_map (fun (id, sp) -> List.map (fun s -> (s, id)) sp) (table @ tradition_target_table) let default_spelling id = match List.assoc_opt id (table @ tradition_target_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