rewrite-html-blocks/src/lib.rs

60 lines
1.7 KiB
Rust

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::<Vec<_>>()
{
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#"<p>hello, world! <span class="replace-me">REPLACE ME</span> <span class="replace-me me-too">me too!</span></p>"#;
let rewritten_html = rewrite_tags(html, ".replace-me", |_| {
"<strong>it's a me!</strong>".to_string()
});
println!("{}", rewritten_html)
}
}