use html5ever::QualName; use kuchiki::{traits::*, NodeRef}; pub fn rewrite_tags(html: &str, selector: &str, mapping: impl Fn(&NodeRef) -> String) -> String { let document = kuchiki::parse_html().one(html); for elem in document .select(selector) .expect("Failed to select document with given selector") .collect::>() { let node = elem.as_node(); let new_contents = kuchiki::parse_fragment( elem.name.clone(), elem.attributes .borrow() .map .clone() .into_iter() .map(|(name, value)| html5ever::Attribute { name: QualName::new(value.prefix, name.ns, name.local), value: value.value.into(), }) .collect(), ) .one(mapping(node)) .first_child() .expect("Root element somehow missing"); for child in node.children() { child.detach(); } for child in new_contents.children() { node.append(child); } } let mut out = Vec::new(); document .serialize(&mut out) .expect("Failed to serialize document"); String::from_utf8_lossy(&out).into_owned() } #[cfg(test)] mod tests { use crate::rewrite_tags; #[test] fn remap_block() { let html = r#"

hello, world! REPLACE ME me too!

"#; let rewritten_html = rewrite_tags(html, ".replace-me", |_| { "it's a me!".to_string() }); println!("{}", rewritten_html) } }