commit dc914b99772040f1be27c5a31b708553750fa0fc Author: videogame hacker Date: Thu Apr 28 19:39:41 2022 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..6280028 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rewrite-html-blocks" +version = "1.0.0" +edition = "2021" + +[dependencies] +html5ever = "0.25" +kuchiki = "0.8.1" diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..89fa7b1 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,58 @@ +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") + { + 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

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