#![warn(missing_docs)]
#![warn(unreachable_pub)]
mod builtin;
mod error;
mod grapheme;
mod pattern;
mod rasm;
mod resolve;
#[cfg(test)]
mod tests;
pub use builtin::{builtin_pattern_set, is_builtin_pattern_set};
pub use error::{CompileError, CompileErrorKind};
pub use pattern::{compile_pattern_text, PatternSet};
use grapheme::{is_bare_tatweel_at, joined_runs, split_graphemes, KASHIDA};
use resolve::resolve_run;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct KashidaPoint {
pub index: u32,
pub priority: u8,
}
pub fn find_kashida_points_patterns(word: &str, set: &PatternSet) -> Vec<KashidaPoint> {
let graphemes = split_graphemes(word);
let mut out = Vec::new();
for run in joined_runs(&graphemes) {
out.extend(resolve_run(&graphemes, &run, set));
}
out
}
fn strip_bare_tatweel(word: &str) -> String {
if !word.contains(KASHIDA) {
return word.to_string();
}
let chars: Vec<char> = word.chars().collect();
let mut out = String::with_capacity(word.len());
for k in 0..chars.len() {
if is_bare_tatweel_at(&chars, k) {
continue;
}
out.push(chars[k]);
}
out
}
pub fn find_kashida_points(
word: &str,
set: &PatternSet,
remove_existing_kashida: bool,
) -> (String, Vec<KashidaPoint>) {
let cleaned = if remove_existing_kashida {
strip_bare_tatweel(word)
} else {
word.to_string()
};
let points = find_kashida_points_patterns(&cleaned, set);
(cleaned, points)
}