1use crate::Engine;
6use crate::primitives_gen::assign_int as ip;
7use retex_hyph::Language;
8
9#[allow(missing_docs)]
11pub mod codes {
12 pub const HYPHENATION: u32 = 0;
13 pub const PATTERNS: u32 = 1;
14 pub const PRE_HYPHEN_CHAR: u32 = 2;
15 pub const POST_HYPHEN_CHAR: u32 = 3;
16 pub const PRE_EX_HYPHEN_CHAR: u32 = 4;
17 pub const POST_EX_HYPHEN_CHAR: u32 = 5;
18 pub const HYPHENATION_MIN: u32 = 6;
19 pub const HJCODE: u32 = 7;
20}
21
22pub const MAX_LANGUAGE: i32 = 16383;
24
25impl Engine {
26 pub fn cur_lang(&self) -> u32 {
28 let l = self.eqtb.int(ip::LANGUAGE);
29 if (0..=MAX_LANGUAGE).contains(&l) {
30 l as u32
31 } else {
32 0
33 }
34 }
35
36 pub fn language_mut(&mut self, n: u32) -> &mut Language {
38 let i = n as usize;
39 if self.languages.len() <= i {
40 self.languages.resize_with(i + 1, || None);
41 }
42 self.languages[i].get_or_insert_with(Language::new)
43 }
44
45 pub fn language(&self, n: u32) -> Option<&Language> {
47 self.languages.get(n as usize).and_then(Option::as_ref)
48 }
49
50 fn save_hyph_codes(&mut self, n: u32) {
53 if self.eqtb.int(ip::SAVINGHYPHCODES) <= 0 {
54 return;
55 }
56 if self.language(n).is_some_and(Language::has_hj_codes) {
57 return;
58 }
59 let codes: Vec<(u32, u32)> = self
60 .eqtb
61 .lc
62 .explicit()
63 .filter(|(_, v, _)| *v > 0)
64 .map(|(c, v, _)| (c, v as u32))
65 .collect();
66 self.language_mut(n).init_hj_codes(codes);
67 }
68
69 fn scan_hyph_text(&mut self) -> String {
72 let toks = self.scan_toks_expanded();
73 let s = self.print_to_string(|e| e.show_token_list(&toks, 0, toks.len(), i64::MAX));
74 String::from_utf8_lossy(&s).into_owned()
75 }
76
77 pub fn hyph_data(&mut self, _global: bool) {
79 let lang = self.cur_lang();
80 match self.cur_chr {
81 codes::PATTERNS => {
82 let text = self.scan_hyph_text();
83 self.save_hyph_codes(lang);
84 self.language_mut(lang).add_patterns(&text);
85 }
86 codes::HYPHENATION => {
87 let text = self.scan_hyph_text();
88 let r = if self.language(lang).is_some_and(Language::has_hj_codes) {
89 self.language_mut(lang).add_exceptions(&text)
90 } else {
91 let lc = self.eqtb.lc.clone();
92 self.language_mut(lang)
93 .add_exceptions_with(&text, &|c| lc.get(c).max(0) as u32)
94 };
95 if r.is_err() {
96 self.print_err("exception syntax error");
97 self.help(&[]);
98 self.error();
99 }
100 }
101 codes::HJCODE => {
102 self.scan_char_num();
103 let c = self.cur_val as u32;
104 self.scan_optional_equals();
105 self.scan_int();
106 let v = self.cur_val.max(0) as u32;
107 self.language_mut(lang).set_hj_code(c, v);
108 }
109 code => {
110 self.scan_optional_equals();
111 self.scan_int();
112 let v = self.cur_val;
113 let s = &mut self.language_mut(lang).settings;
114 match code {
115 codes::PRE_HYPHEN_CHAR => s.pre_hyphen_char = v,
116 codes::POST_HYPHEN_CHAR => s.post_hyphen_char = v,
117 codes::PRE_EX_HYPHEN_CHAR => s.pre_ex_hyphen_char = v,
118 codes::POST_EX_HYPHEN_CHAR => s.post_ex_hyphen_char = v,
119 _ => s.hyphenation_min = v,
120 }
121 }
122 }
123 }
124}