use super::fragment::InlineFragment;
pub(super) fn join_touching_fragments(fragments: Vec<InlineFragment>) -> Vec<InlineFragment> {
let mut runs: Vec<Vec<InlineFragment>> = Vec::new();
for fragment in fragments {
match runs.last_mut() {
Some(run)
if run
.last()
.is_some_and(|previous| touches(previous, &fragment)) =>
{
run.push(fragment);
}
_ => runs.push(vec![fragment]),
}
}
runs.into_iter().map(merge_run).collect()
}
fn merge_run(run: Vec<InlineFragment>) -> InlineFragment {
match <[InlineFragment; 1]>::try_from(run) {
Ok([only]) => only,
Err(run) => {
InlineFragment::new(run.iter().map(|fragment| fragment.text.as_str()).collect())
}
}
}
fn touches(previous: &InlineFragment, next: &InlineFragment) -> bool {
let previous_ends_solid = previous
.text
.chars()
.next_back()
.is_some_and(|c| !c.is_whitespace());
let next_starts_solid = next.text.chars().next().is_some_and(|c| !c.is_whitespace());
previous_ends_solid && next_starts_solid
}