diff --git a/crates/core/__fixture__/plugins/convertEllipseToCircle.01.svg b/crates/core/__fixture__/plugins/convertEllipseToCircle.01.svg new file mode 100644 index 0000000..6e3ce03 --- /dev/null +++ b/crates/core/__fixture__/plugins/convertEllipseToCircle.01.svg @@ -0,0 +1,15 @@ + + + + + + + +@@@ + + + + + + + diff --git a/crates/core/src/plugins/convert_ellipse_to_circle.rs b/crates/core/src/plugins/convert_ellipse_to_circle.rs new file mode 100644 index 0000000..4840922 --- /dev/null +++ b/crates/core/src/plugins/convert_ellipse_to_circle.rs @@ -0,0 +1,84 @@ +// Converts non-eccentric s to s. + +use swc_core::common::DUMMY_SP; +use swc_xml_ast::*; +use swc_xml_visit::{VisitMut, VisitMutWith}; +use serde::Deserialize; + +struct Visitor {} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Params {} + +impl Default for Params { + fn default() -> Self { + Self {} + } +} + +impl Visitor { + fn new() -> Self { + Self {} + } +} + +impl VisitMut for Visitor { + fn visit_mut_element(&mut self, n: &mut Element) { + if n.tag_name.to_string() == "ellipse" { + let mut rx = "0".to_string(); + let mut ry = "0".to_string(); + let mut new_attributes = vec![]; + for attr in n.attributes.clone() { + if attr.name.to_string() == "rx" { + if let Some(value) = attr.value.clone() { + rx = value.to_string(); + } + } else if attr.name.to_string() == "ry" { + if let Some(value) = attr.value.clone() { + ry = value.to_string(); + } + } else { + new_attributes.push(attr); + } + } + + if rx == ry || + rx == "auto" || + ry == "auto" // SVG2 + { + n.tag_name = "circle".to_string().into(); + let radius = if rx == "auto" { ry } else { rx }; + new_attributes.push(Attribute { + span: DUMMY_SP, + namespace: None, + prefix: None, + name: "r".to_string().into(), + raw_name: None, + value: Some(radius.into()), + raw_value: None, + }); + n.attributes = new_attributes; + } + } + n.visit_mut_children_with(self); + } +} + +pub fn apply(doc: &mut Document, _: &Params) { + let mut v = Visitor::new(); + doc.visit_mut_with(&mut v); +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use crate::testing::test_plugin; + use super::*; + + #[testing::fixture("__fixture__/plugins/convertEllipseToCircle.*.svg")] + fn pass(input: PathBuf) { + test_plugin(apply, input); + } +} diff --git a/crates/core/src/plugins/mod.rs b/crates/core/src/plugins/mod.rs index 83a61dc..b28b44e 100644 --- a/crates/core/src/plugins/mod.rs +++ b/crates/core/src/plugins/mod.rs @@ -4,3 +4,4 @@ pub mod cleanup_ids; pub mod cleanup_numeric_values; pub mod collapse_groups; pub mod convert_colors; +pub mod convert_ellipse_to_circle;