Skip to main content

gnt_tools/
lib.rs

1//! Tools to help studying the greek new testament.
2//! The crate is provided AS-IS.
3//! # Examples
4//!
5//! ```
6//! use gnt_tools::core_char;
7//!
8//! let s = "16 Εἶπεν δὲ παραβολὴν πρὸς αὐτοὺς λέγων·
9//!          ἀνθρώπου τινὸς πλουσίου εὐφόρησεν ἡ χώρα. 17
10//!          καὶ διελογίζετο ἐν ἑαυτῷ λέγων· τί ποιήσω, ὅτι
11//!          οὐκ ἔχω ποῦ συνάξω τοὺς καρπούς μου; ";
12//!
13//! let s2 = "ειπενδεπαραβοληνπροϲαυτουϲλεγωνανθρωπουτ\
14//!           ινοϲπλουϲιουευφορηϲενηχωρακαιδιελογιζετοενεαυτω\
15//!           λεγωντιποιηϲωοτιουκεχωπουϲυναξωτουϲκαρπουϲμου";
16//!
17//! let core_text : String = s.chars()
18//!                           .filter_map(|c| core_char(&c))
19//!                           .collect();
20//!
21//! assert_eq!(core_text.as_str(), s2);
22//! ```
23
24use unicode_normalization::UnicodeNormalization;
25
26// TODO : doc de la fonction a re-ecrire.
27/// The function helps giving the core text of a greek new testament critical edition.  
28/// This might be useful for comparing greek new testament critical editions by gettig their "core" differences/concordances.
29///
30/// In concrete terms, core_char remove any character that is not in the greek alphabet, puts all greek letters in lowercase, and change all sigmas to lunar sigma.
31///
32/// So this function :
33/// - does not replace nomina sacras (e.g., κϲ) by their non-abreviated form (resp. κυριοϲ), nor words (e.g., κύριος) by their nomina sacras form (when a nomina sacra form exists) (resp. κϲ).
34/// - is made to delete any character used to encode nomina sacras (e.g., '|', or '(' and ')'), hence |κς| will give κϲ.
35/// - does delete all 'ˉ' characters (so παραβολὴˉ becomes παραβολη, not παραβολην)
36/// TODO : expliquer pourquoi on ne garde pas le point median.
37/// # Example :
38/// ```
39/// use gnt_tools::core_char;
40///
41/// let s = "16 Εἶπεν δὲ παραβολὴν πρὸς αὐτοὺς λέγων·
42///          ἀνθρώπου τινὸς πλουσίου εὐφόρησεν ἡ χώρα. 17
43///          καὶ διελογίζετο ἐν ἑαυτῷ λέγων· τί ποιήσω, ὅτι
44///          οὐκ ἔχω ποῦ συνάξω τοὺς καρπούς μου; ";
45///
46/// let s2 = "ειπενδεπαραβοληνπροϲαυτουϲλεγωνανθρωπουτ\
47///           ινοϲπλουϲιουευφορηϲενηχωρακαιδιελογιζετοενεαυτω\
48///           λεγωντιποιηϲωοτιουκεχωπουϲυναξωτουϲκαρπουϲμου";
49///
50/// let core_text : String = s.chars()
51///                           .filter_map(|c| core_char(&c))
52///                           .collect();
53///
54/// assert_eq!(core_text.as_str(), s2);
55/// ```
56// - gerer les invisibles nu? [ca demandera peut-etre un changement du type de retour]
57// - todo : faire une demande a l'unicode foundation pour ajouter les caracteres grecs onciales.
58// - expliquer pourquoi on ne garde pas le point milieu
59pub fn core_char(c: &char) -> Option<char> {
60   
61    c.nfd().fold(None, |core_c, i| 
62                
63            // TODO : on fait quoi avec les symboles numeriques?
64
65              /* It could be interesting to check if 
66               * `('α'..='ω').contains(&i)` is faster
67               * than 'α' <= i && i <= 'ω'. */
68              
69              if 'α' <= i && i <= 'ω' 
70              || 'Α' <= i && i <= 'Ω' 
71              {
72                  match i {
73                      'σ' | 'ς' | 'Σ' => Some('ϲ'),
74                      _ => i.to_lowercase().nth(0)
75                  }
76              }
77              else if i == ';'
78                   || 'Ͱ' > i || i > 'Ͽ'
79                   || i == '·'
80              {
81                  core_c
82              }
83              else {
84                  panic!("Greek unicode character '{i}' is \
85                  not handled. If you think it would be \
86                  relevant to handle this character, please \
87                  open an issue on our GitHub repository : \
88                  https://github.com/kylak/gnt-tools/issues.");
89              }
90            )
91}
92
93// fonction qui donne les caracteres supprimes par core_char
94// pub fn new_char(s1, s2)
95// ca permet de pouvoir etre sur des caracteres qu'on a supprime
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100
101    #[test]
102    fn test_core_text() {
103        let s = "16 Εἶπεν δὲ παραβολὴν πρὸς αὐτοὺς λέγων·
104            ἀνθρώπου τινὸς πλουσίου εὐφόρησεν ἡ χώρα. 17 
105            καὶ διελογίζετο ἐν ἑαυτῷ λέγων· τί ποιήσω, ὅτι 
106            οὐκ ἔχω ποῦ συνάξω τοὺς καρπούς μου; ";
107
108        let s2 = "ειπενδεπαραβοληνπροϲαυτουϲλεγωνανθρωπουτ\
109            ινοϲπλουϲιουευφορηϲενηχωρακαιδιελογιζετοενεαυτω\
110            λεγωντιποιηϲωοτιουκεχωπουϲυναξωτουϲκαρπουϲμου";
111
112        let core_text : String = s.chars()
113                                  .filter_map(|c| core_char(&c))
114                                  .collect();
115
116         assert_eq!(core_text.as_str(), s2);
117    }
118
119    /*
120       https://stackoverflow.com/questions/517923/what-is-the-best-way-to-remove-accents-normalize-in-a-python-unicode-string
121
122       https://crates.io/crates/hebrew_unicode_utils
123
124       Tester fonctionnalite :
125        - (1) qu'il n'y ait plus d'accentuations
126        - (2) qu'il n'y ait plus de majuscules
127        - (3) qu'il n'y ait plus de sigma autre que le lunaire
128        - (4) qu'il n'y ait pas d'autre caractere que les
129          caracteres alphabetique grec.
130       Tester une combinaison de deux :
131        - (1) et (2)
132        - (1) et (3)
133        - (1) et (4)
134        - (2) et (3)
135        - (2) et (4)
136        - (3) et (4)
137       Tester une combinaison de trois :
138        - (1) et (2) et (3)
139        - (1) et (2) et (4)
140        - (1) et (3) et (4)
141        - (2) et (3) et (4)
142      Tester toutes les fonctionnalite ensemble :
143        - (1) et (2) et (3) et (4)
144
145      Tester sur quelle donnee ?
146      (1) :
147          - (1.1) que sur des accents
148          - (1.2) que sur des caracteres accentues - un unicode
149          - (1.3) que sur des caractere accentues - deux unicodes
150          - (1.3) que sur des caracteres non accentues
151          - (1.4) que sur une chaine ayant des caracteres accentues et non accentues
152
153    */
154}