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}