use crate::Engine;
use crate::primitives_gen::assign_int as ip;
use retex_hyph::Language;
#[allow(missing_docs)]
pub mod codes {
pub const HYPHENATION: u32 = 0;
pub const PATTERNS: u32 = 1;
pub const PRE_HYPHEN_CHAR: u32 = 2;
pub const POST_HYPHEN_CHAR: u32 = 3;
pub const PRE_EX_HYPHEN_CHAR: u32 = 4;
pub const POST_EX_HYPHEN_CHAR: u32 = 5;
pub const HYPHENATION_MIN: u32 = 6;
pub const HJCODE: u32 = 7;
}
pub const MAX_LANGUAGE: i32 = 16383;
impl Engine {
pub fn cur_lang(&self) -> u32 {
let l = self.eqtb.int(ip::LANGUAGE);
if (0..=MAX_LANGUAGE).contains(&l) {
l as u32
} else {
0
}
}
pub fn language_mut(&mut self, n: u32) -> &mut Language {
let i = n as usize;
if self.languages.len() <= i {
self.languages.resize_with(i + 1, || None);
}
self.languages[i].get_or_insert_with(Language::new)
}
pub fn language(&self, n: u32) -> Option<&Language> {
self.languages.get(n as usize).and_then(Option::as_ref)
}
fn save_hyph_codes(&mut self, n: u32) {
if self.eqtb.int(ip::SAVINGHYPHCODES) <= 0 {
return;
}
if self.language(n).is_some_and(Language::has_hj_codes) {
return;
}
let codes: Vec<(u32, u32)> = self
.eqtb
.lc
.explicit()
.filter(|(_, v, _)| *v > 0)
.map(|(c, v, _)| (c, v as u32))
.collect();
self.language_mut(n).init_hj_codes(codes);
}
fn scan_hyph_text(&mut self) -> String {
let toks = self.scan_toks_expanded();
let s = self.print_to_string(|e| e.show_token_list(&toks, 0, toks.len(), i64::MAX));
String::from_utf8_lossy(&s).into_owned()
}
pub fn hyph_data(&mut self, _global: bool) {
let lang = self.cur_lang();
match self.cur_chr {
codes::PATTERNS => {
let text = self.scan_hyph_text();
self.save_hyph_codes(lang);
self.language_mut(lang).add_patterns(&text);
}
codes::HYPHENATION => {
let text = self.scan_hyph_text();
let r = if self.language(lang).is_some_and(Language::has_hj_codes) {
self.language_mut(lang).add_exceptions(&text)
} else {
let lc = self.eqtb.lc.clone();
self.language_mut(lang)
.add_exceptions_with(&text, &|c| lc.get(c).max(0) as u32)
};
if r.is_err() {
self.print_err("exception syntax error");
self.help(&[]);
self.error();
}
}
codes::HJCODE => {
self.scan_char_num();
let c = self.cur_val as u32;
self.scan_optional_equals();
self.scan_int();
let v = self.cur_val.max(0) as u32;
self.language_mut(lang).set_hj_code(c, v);
}
code => {
self.scan_optional_equals();
self.scan_int();
let v = self.cur_val;
let s = &mut self.language_mut(lang).settings;
match code {
codes::PRE_HYPHEN_CHAR => s.pre_hyphen_char = v,
codes::POST_HYPHEN_CHAR => s.post_hyphen_char = v,
codes::PRE_EX_HYPHEN_CHAR => s.pre_ex_hyphen_char = v,
codes::POST_EX_HYPHEN_CHAR => s.post_ex_hyphen_char = v,
_ => s.hyphenation_min = v,
}
}
}
}
}