Any way to add custom jobs? #160
-
|
I'm pretty new to Rust and wanted to write a custom OXVG What would be the best way to run my Here is my custom use std::cell::RefCell;
use oxvg_ast::{
element::Element as ElementTrait,
visitor::{Context, ContextFlags, Info, PrepareOutcome, Visitor}
};
use serde::{Deserialize, Serialize};
use tsify::Tsify;
#[derive(Tsify, Deserialize, Serialize, Debug, Clone)]
#[serde(transparent)]
/// Extracts the SVG's width and height from the `width`/`height` or `viewBox` attribute on `<svg>`.
/// Based on
/// https://github.com/noahbald/oxvg/blob/d8fc238617d043969dc2af4395c8a53298e65c42/crates/oxvg_optimiser/src/jobs/remove_view_box.rs,
/// https://github.com/noahbald/oxvg/blob/d8fc238617d043969dc2af4395c8a53298e65c42/crates/oxvg_optimiser/src/jobs/remove_dimensions.rs
pub struct ExtractDimensions(pub RefCell<Option<(f64, f64)>>);
impl<'arena, E: ElementTrait<'arena>> Visitor<'arena, E> for ExtractDimensions {
type Error = String;
fn element(
&self,
element: &mut E,
_context: &mut Context<'arena, '_, '_, E>,
) -> Result<(), Self::Error> {
// TODO: Traverse the tree and find the root <svg> element, then extract the width and height from the attributes.
// See: https://github.com/noahbald/oxvg/blob/d8fc238617d043969dc2af4395c8a53298e65c42/crates/oxvg_optimiser/src/jobs/remove_view_box.rs
// See: https://github.com/noahbald/oxvg/blob/d8fc238617d043969dc2af4395c8a53298e65c42/crates/oxvg_optimiser/src/jobs/remove_dimensions.rs
// TODO: Check if root
if element.prefix().is_some() || element.local_name().as_ref() != "svg" {
return Ok(());
}
// Already extracted
if self.0.borrow().is_some() {
return Ok(());
}
if let (Some(width_attr), Some(height_attr)) = (
element.get_attribute_local(&"width".into()),
element.get_attribute_local(&"height".into()),
) {
if let (Ok(width), Ok(height)) = (
width_attr.as_ref().parse::<f64>(),
height_attr.as_ref().parse::<f64>(),
) {
*self.0.borrow_mut() = Some((width, height));
return Ok(());
}
}
if let Some(view_box_attr) = element.get_attribute_local(&"viewBox".into()) {
let mut nums = Vec::with_capacity(4);
nums.extend(SEPARATOR.split(view_box_attr.as_ref()));
if nums.len() == 4 {
if let (Ok(width), Ok(height)) = (
nums[2].parse::<f64>(),
nums[3].parse::<f64>(),
) {
*self.0.borrow_mut() = Some((width, height));
return Ok(());
}
}
};
Ok(())
}
}
lazy_static! {
pub static ref SEPARATOR: regex::Regex = regex::Regex::new(r"[ ,]+").unwrap();
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Hey Jonas, there's currently no way to include your own jobs as parts of the set of You should be able to do something like the following (note I haven't checked if this compiles) let mut jobs = Jobs::default();
let arena = typed_arena::Arena::new();
let dom = parse(
r#"<svg xmlns="http://www.w3.org/2000/svg">
test
</svg>"#,
&arena,
)
.unwrap();
let info = Info::<Element>::new(&arena);
// You can run your own jobs before/after `Jobs`.
let extract_dimensions = ExtractDimentions::new();
extract_dimensions.start(&mut Element::from_parent(dom.clone()), &info, None); // `start` as a method of the `Visitor` trait
// Run jobs as usual
jobs.run(&dom, &info).unwrap();
// Serialize once done
dom.serialize_with_options(Options::default()).unwrap();It looks like your visitor is just extracting information, so you could run the visitor by itself if that makes more sense for you. Oxvg is still pretty new as a project, so feel free to make some suggestions on how we can improve the api for you |
Beta Was this translation helpful? Give feedback.
Hey Jonas, there's currently no way to include your own jobs as parts of the set of
Jobs, however you can still run your visitor alongside it.You should be able to do something like the following (note I haven't checked if this compiles)