Add svg and mathml support

This commit is contained in:
Joscha 2024-11-26 23:42:10 +01:00
parent cc3f85e6e1
commit 43b3236d3b
6 changed files with 150 additions and 8 deletions

View file

@ -14,10 +14,13 @@ pub fn is_ascii_alphanumeric(c: char) -> bool {
/// doesn't give an easy answer. Because of this, we're conservative in what we
/// allow. This way, the output we produce should parse correctly in a wide
/// range of circumstances while following the standard.
///
/// The `annotation-xml` MathML element requires us to allow dashes in tag
/// names.
pub fn is_valid_tag_name(name: &str) -> bool {
!name.is_empty()
&& name.chars().take(1).all(is_ascii_alpha)
&& name.chars().all(is_ascii_alphanumeric)
&& name.chars().all(|c| is_ascii_alphanumeric(c) || c == '-')
}
/// <https://html.spec.whatwg.org/multipage/syntax.html#syntax-attribute-name>

View file

@ -63,8 +63,13 @@ pub struct Element {
impl Element {
pub fn new(name: impl ToString, kind: ElementKind) -> Self {
let mut name = name.to_string();
if kind == ElementKind::Foreign {
name = name.to_ascii_lowercase()
}
Self {
name: name.to_string().to_ascii_lowercase(),
name,
kind,
attributes: BTreeMap::new(),
children: vec![],

View file

@ -112,9 +112,7 @@ element!(portal);
element!(source, ElementKind::Void);
// SVG and MathML
// TODO Proper SVG and MathML support
element!(svg, ElementKind::Foreign);
element!(math, ElementKind::Foreign);
// See corresponding modules
// Scripting
element!(canvas);

View file

@ -5,14 +5,16 @@
mod check;
mod element;
pub mod elements;
pub mod html;
pub mod mathml;
mod render;
pub mod svg;
pub use self::{element::*, elements::*, render::*};
pub use self::{element::*, render::*};
#[cfg(test)]
mod tests {
use crate::{elements::*, render::Render, Content, Element};
use crate::{html::*, Content, Element, Render};
#[test]
fn simple_website() {

50
src/mathml.rs Normal file
View file

@ -0,0 +1,50 @@
//! Definitions for all non-deprecated MathML elements.
//!
//! <https://developer.mozilla.org/en-US/docs/Web/MathML/Element>
use crate::{Element, ElementKind};
macro_rules! element {
( $name:ident ) => {
element!($name, stringify!($name));
};
( $name:ident, $tag:expr ) => {
pub fn $name() -> Element {
Element::new($tag, ElementKind::Foreign)
}
};
}
// MathML elements A to Z
// Deprecated and non-standard elements intentionally omitted.
element!(annotation);
element!(annotation_xml, "annotation-xml");
element!(math);
element!(merror);
element!(mfrac);
element!(mi);
element!(mmultiscripts);
element!(mn);
element!(mo);
element!(mover);
element!(mpadded);
element!(mphantom);
element!(mprescripts);
element!(mroot);
element!(mrow);
element!(ms);
element!(mspace);
element!(msqrt);
element!(mstyle);
element!(msub);
element!(msubsup);
element!(msup);
element!(mtable);
element!(mtd);
element!(mtext);
element!(mtr);
element!(munder);
element!(munderover);
element!(semantics);

84
src/svg.rs Normal file
View file

@ -0,0 +1,84 @@
//! Definitions for all non-deprecated SVG elements.
//!
//! <https://developer.mozilla.org/en-US/docs/Web/SVG/Element>
use crate::{Element, ElementKind};
macro_rules! element {
( $name:ident ) => {
element!($name, stringify!($name));
};
( $name:ident, $tag:expr ) => {
pub fn $name() -> Element {
Element::new($tag, ElementKind::Foreign)
}
};
}
// SVG elements A to Z
// Deprecated elements intentionally omitted.
element!(a);
element!(animate);
element!(animate_motion, "animateMotion");
element!(animate_transform, "animateTransform");
element!(circle);
element!(clip_path, "clipPath");
element!(defs);
element!(desc);
element!(ellipse);
element!(fe_blend, "feBlend");
element!(fe_color_matrix, "feColorMatrix");
element!(fe_component_transfer, "feComponentTransfer");
element!(fe_composite, "feComposite");
element!(fe_convolve_matrix, "feConvolveMatrix");
element!(fe_diffuse_lighting, "feDiffuseLighting");
element!(fe_displacement_map, "feDisplacementMap");
element!(fe_distant_light, "feDistantLight");
element!(fe_drop_shadow, "feDropShadow");
element!(fe_flood, "feFlood");
element!(fe_func_a, "feFuncA");
element!(fe_func_b, "feFuncB");
element!(fe_func_g, "feFuncG");
element!(fe_func_r, "feFuncR");
element!(fe_gaussian_blue, "feGaussianBlur");
element!(fe_image, "feImage");
element!(fe_merge, "feMerge");
element!(fe_merge_node, "feMergeNode");
element!(fe_morphology, "feMorphology");
element!(fe_offset, "feOffset");
element!(fe_point_light, "fePointLight");
element!(fe_specular_lighting, "feSpecularLighting");
element!(fe_spot_light, "feSpotLight");
element!(fe_tile, "feTile");
element!(fe_turbulence, "feTurbulence");
element!(filter);
element!(foreign_object, "foreignObject");
element!(g);
element!(image);
element!(line);
element!(linear_gradient, "linearGradient");
element!(marker);
element!(mask);
element!(metadata);
element!(mpath);
element!(path);
element!(pattern);
element!(polygon);
element!(polyline);
element!(radial_gradient, "radialGradient");
element!(rect);
element!(script);
element!(set);
element!(stop);
element!(style);
element!(svg);
element!(switch);
element!(symbol);
element!(text);
element!(text_path, "textPath");
element!(title);
element!(tspan);
element!(r#use);
element!(view);