ipa_translate/lib.rs
1use lazy_static::lazy_static;
2
3type TranslationPair = (&'static str, &'static str);
4
5macro_rules! load_translation_pairs {
6 ($($pair_var:ident = $pair_file:literal,)*) => {
7 lazy_static! {
8 $(static ref $pair_var: Vec<TranslationPair> = include!($pair_file);)*
9 }
10 };
11}
12
13load_translation_pairs! {
14 PAIRS_XSAMPA = "../translations/xsampa.rs",
15 PAIRS_PRAAT = "../translations/praat.rs",
16 PAIRS_BRANNER = "../translations/branner.rs",
17 PAIRS_SIL = "../translations/sil.rs",
18}
19
20fn translate_using_pairs(pairs: &Vec<TranslationPair>, text: &str) -> String {
21 let mut text = text.to_string();
22 for pair in pairs {
23 text = text.replace(pair.0, pair.1);
24 }
25 text
26}
27
28fn invert_using_pairs(pairs: &Vec<TranslationPair>, text: &str) -> String {
29 let mut text = text.to_string();
30 for pair in pairs {
31 text = text.replace(pair.1, pair.0);
32 }
33 text
34}
35
36/// Translates an X-SAMPA ASCII string to a unicode IPA string.
37/// Implemented according to [this Wikipedia article](https://en.wikipedia.org/wiki/X-SAMPA).
38///
39/// Usage example:
40/// ```
41/// let xsampa_text = "eks s{mp@";
42/// let ipa_text = "eks sæmpə";
43/// assert_eq!(ipa_translate::xsampa_to_ipa(xsampa_text), ipa_text);
44/// ```
45pub fn xsampa_to_ipa(text: &str) -> String {
46 translate_using_pairs(&PAIRS_XSAMPA, text)
47}
48
49/// Inverse counterpart to `xsampa_to_ipa()`.
50///
51/// Usage example:
52/// ```
53/// let xsampa_text = "eks s{mp@";
54/// let ipa_text = "eks sæmpə";
55/// assert_eq!(ipa_translate::ipa_to_xsampa(ipa_text), xsampa_text);
56/// ```
57pub fn ipa_to_xsampa(text: &str) -> String {
58 invert_using_pairs(&PAIRS_XSAMPA, text)
59}
60
61/// Translates a Praat ASCII string to a unicode IPA string.
62/// Implemented according to [this Praat manual entry](https://www.fon.hum.uva.nl/praat/manual/Phonetic_symbols.html).
63///
64/// Usage example:
65/// ```
66/// let praat_text = r"p\rta\:ft\^h";
67/// let ipa_text = "pɹaːtʰ";
68/// assert_eq!(ipa_translate::praat_to_ipa(praat_text), ipa_text);
69/// ```
70pub fn praat_to_ipa(text: &str) -> String {
71 translate_using_pairs(&PAIRS_PRAAT, text)
72}
73
74/// Inverse counterpart to `praat_to_ipa()`.
75///
76/// Usage example:
77/// ```
78/// let praat_text = r"p\rta\:ft\^h";
79/// let ipa_text = "pɹaːtʰ";
80/// assert_eq!(ipa_translate::ipa_to_praat(ipa_text), praat_text);
81/// ```
82pub fn ipa_to_praat(text: &str) -> String {
83 invert_using_pairs(&PAIRS_PRAAT, text)
84}
85
86/// Translates a "Branner" ASCII string to a unicode IPA string.
87/// Implemented according to [this Wikipedia article](https://en.wikipedia.org/wiki/Comparison_of_ASCII_encodings_of_the_International_Phonetic_Alphabet).
88///
89/// Usage example:
90/// ```
91/// let branner_text = "br&ae):nE&r^";
92/// let ipa_text = "bɹæːnɜ˞";
93/// assert_eq!(ipa_translate::branner_to_ipa(branner_text), ipa_text);
94/// ```
95pub fn branner_to_ipa(text: &str) -> String {
96 translate_using_pairs(&PAIRS_BRANNER, text)
97}
98
99/// Inverse counterpart to `branner_to_ipa()`.
100///
101/// Usage example:
102/// ```
103/// let branner_text = "br&ae):nE&r^";
104/// let ipa_text = "bɹæːnɜ˞";
105/// assert_eq!(ipa_translate::ipa_to_branner(ipa_text), branner_text);
106/// ```
107pub fn ipa_to_branner(text: &str) -> String {
108 invert_using_pairs(&PAIRS_BRANNER, text)
109}
110
111/// Translates a SIL ASCII string to a unicode IPA string.
112/// Implemented according to [this KeymanHelp page](https://help.keyman.com/keyboard/sil_ipa/1.8.6/sil_ipa).
113///
114/// Usage example:
115/// ```
116/// let sil_text = "si=l";
117/// let ipa_text = "sɪl";
118/// assert_eq!(ipa_translate::sil_to_ipa(sil_text), ipa_text);
119/// ```
120pub fn sil_to_ipa(text: &str) -> String {
121 translate_using_pairs(&PAIRS_SIL, text)
122}
123
124/// Inverse counterpart to `sil_to_ipa()`.
125///
126/// Usage example:
127/// ```
128/// let sil_text = "si=l";
129/// let ipa_text = "sɪl";
130/// assert_eq!(ipa_translate::ipa_to_sil(ipa_text), sil_text);
131/// ```
132pub fn ipa_to_sil(text: &str) -> String {
133 invert_using_pairs(&PAIRS_SIL, text)
134}