diff --git a/Cargo.toml b/Cargo.toml
index 8332bed..ec437a5 100644
@@ -1,6 +1,6 @@
[package]
name = "svgparser"
-version = "0.1.0"
+version = "0.2.0"
authors = ["Evgeniy Reizner <razrfalcon@gmail.com>"]
keywords = ["svg", "parser", "tokenizer"]
license = "MPL-2.0"
diff --git a/README.md b/README.md
index 02605f9..86775d2 100644
@@ -44,11 +44,11 @@ See the documentation for details.
- User agent colors, aka `fill="AppWorkspace"`, is not supported.
- There is no separate `opacity-value` type. It will be parsed as `<number>`,
but will be bound to 0..1 range.
- - An implicit path commands are not supported. All commands are parsed as explicit.
- - An implicit MoveTo commands automatically converted to an explicit LineTo.
+ - Implicit path commands are not supported. All commands are parsed as explicit.
+ - Implicit MoveTo commands will be automatically converted into explicit LineTo.
### Differences between *libsvgparser* and SVG spec
- - `<percentage>` type is part of `<length>` type.
+ - `<percentage>` type is part of the `<length>` type.
### Usage
diff --git a/codegen/spec/attributes.txt b/codegen/spec/attributes.txt
index eb552f3..87aaf3f 100644
@@ -1,14 +1,17 @@
accent-height
accumulate
+actuate
additive
alignment-baseline
alphabetic
amplitude
arabic-form
+arcrole
ascent
attributeName
attributeType
azimuth
+base
baseFrequency
baseline-shift
baseProfile
@@ -82,6 +85,7 @@ height
horiz-adv-x
horiz-origin-x
horiz-origin-y
+href
id
ideographic
image-rendering
@@ -178,13 +182,16 @@ requiredExtensions
requiredFeatures
restart
result
+role
rotate
rx
ry
scale
seed
shape-rendering
+show
slope
+space
spacing
specularConstant
specularExponent
@@ -251,18 +258,8 @@ x-height
x1
x2
xChannelSelector
-xlink:actuate
-xlink:arcrole
-xlink:href
-xlink:role
-xlink:show
-xlink:title
-xlink:type
-xml:base
-xml:lang
-xml:space
+xlink
xmlns
-xmlns:xlink
y
y1
y2
diff --git a/codegen/src/main.rs b/codegen/src/main.rs
index c809fb7..93bc793 100644
@@ -19,6 +19,9 @@ fn main() {
gen_file("spec/attributes.txt", "AttributeId", "ATTRIBUTES",
"List of all SVG attributes.",
"../src/attribute.rs");
+ gen_file("spec/attributes_ns.txt", "AttributeNSId", "ATTRIBUTES_NS",
+ "List of SVG namespaces.",
+ "../src/attribute_ns.rs");
gen_file("spec/values.txt", "ValueId", "VALUES",
"List of all values for presentation attributes.",
"../src/value_id.rs");
diff --git a/examples/extract_paths.rs b/examples/extract_paths.rs
index 9ef6989..b010948 100644
@@ -33,7 +33,7 @@ fn main() {
Ok(t) => {
// Filter 'Attribute' token.
match t {
- svg::Token::Attribute(name, value) => {
+ svg::Token::Attribute(_, name, value) => {
// Process only 'd' attributes.
if name == b"d" {
println!("New path:");
diff --git a/src/attribute.rs b/src/attribute.rs
index a0535cf..7952198 100644
@@ -12,15 +12,18 @@ use std::fmt;
pub enum AttributeId {
AccentHeight,
Accumulate,
+ Actuate,
Additive,
AlignmentBaseline,
Alphabetic,
Amplitude,
ArabicForm,
+ Arcrole,
Ascent,
AttributeName,
AttributeType,
Azimuth,
+ Base,
BaseFrequency,
BaselineShift,
BaseProfile,
@@ -94,6 +97,7 @@ pub enum AttributeId {
HorizAdvX,
HorizOriginX,
HorizOriginY,
+ Href,
Id,
Ideographic,
ImageRendering,
@@ -190,13 +194,16 @@ pub enum AttributeId {
RequiredFeatures,
Restart,
Result,
+ Role,
Rotate,
Rx,
Ry,
Scale,
Seed,
ShapeRendering,
+ Show,
Slope,
+ Space,
Spacing,
SpecularConstant,
SpecularExponent,
@@ -263,18 +270,8 @@ pub enum AttributeId {
X1,
X2,
XChannelSelector,
- XlinkActuate,
- XlinkArcrole,
- XlinkHref,
- XlinkRole,
- XlinkShow,
- XlinkTitle,
- XlinkType,
- XmlBase,
- XmlLang,
- XmlSpace,
+ Xlink,
Xmlns,
- XmlnsXlink,
Y,
Y1,
Y2,
@@ -286,334 +283,330 @@ pub enum AttributeId {
static ATTRIBUTES: ::phf::Map<&'static str, AttributeId> = ::phf::Map {
key: 1897749892740154578,
disps: ::phf::Slice::Static(&[
- (0, 52),
- (0, 9),
- (0, 121),
- (0, 149),
- (0, 71),
+ (0, 11),
+ (0, 44),
+ (0, 256),
+ (0, 8),
+ (0, 8),
(0, 0),
- (0, 187),
+ (0, 23),
(0, 14),
- (0, 2),
- (0, 12),
- (6, 197),
- (0, 30),
- (0, 5),
- (10, 57),
- (0, 12),
- (0, 209),
- (2, 0),
- (0, 30),
- (0, 6),
- (40, 213),
+ (0, 193),
(0, 6),
- (0, 42),
- (0, 12),
+ (1, 62),
+ (0, 99),
+ (0, 221),
+ (0, 235),
+ (0, 253),
+ (6, 89),
+ (0, 67),
+ (3, 121),
+ (20, 142),
+ (2, 57),
+ (0, 197),
+ (0, 91),
(0, 0),
- (0, 83),
- (0, 137),
- (0, 0),
- (0, 108),
- (0, 112),
- (12, 28),
- (6, 28),
- (1, 148),
- (0, 38),
- (0, 24),
- (10, 3),
- (25, 240),
- (0, 75),
- (0, 9),
- (0, 196),
+ (2, 138),
(0, 1),
- (18, 90),
- (1, 171),
+ (0, 167),
+ (0, 41),
(0, 1),
- (0, 42),
+ (1, 133),
(0, 4),
- (6, 200),
- (0, 3),
- (0, 170),
+ (0, 37),
+ (3, 12),
+ (0, 2),
+ (8, 246),
+ (8, 24),
+ (4, 167),
+ (1, 167),
(0, 0),
- (2, 78),
- (0, 40),
+ (1, 1),
+ (0, 14),
(0, 8),
- (1, 125),
+ (0, 5),
+ (0, 50),
+ (1, 75),
+ (0, 173),
+ (5, 70),
+ (14, 228),
+ (0, 71),
+ (26, 150),
(0, 37),
- (1, 251),
+ (0, 74),
+ (235, 180),
+ (0, 21),
+ (0, 265),
]),
entries: ::phf::Slice::Static(&[
- ("accumulate", AttributeId::Accumulate),
- ("target", AttributeId::Target),
- ("font-size", AttributeId::FontSize),
- ("hanging", AttributeId::Hanging),
- ("restart", AttributeId::Restart),
- ("patternTransform", AttributeId::PatternTransform),
- ("filter", AttributeId::Filter),
- ("onabort", AttributeId::Onabort),
- ("onmouseout", AttributeId::Onmouseout),
- ("xlink:arcrole", AttributeId::XlinkArcrole),
- ("k2", AttributeId::K2),
("v-hanging", AttributeId::VHanging),
+ ("font-stretch", AttributeId::FontStretch),
+ ("accumulate", AttributeId::Accumulate),
+ ("targetX", AttributeId::TargetX),
+ ("xlink", AttributeId::Xlink),
+ ("underline-thickness", AttributeId::UnderlineThickness),
+ ("stop-opacity", AttributeId::StopOpacity),
+ ("enable-background", AttributeId::EnableBackground),
+ ("pathLength", AttributeId::PathLength),
+ ("title", AttributeId::Title),
+ ("path", AttributeId::Path),
+ ("onunload", AttributeId::Onunload),
+ ("dominant-baseline", AttributeId::DominantBaseline),
+ ("limitingConeAngle", AttributeId::LimitingConeAngle),
+ ("flood-opacity", AttributeId::FloodOpacity),
+ ("text-anchor", AttributeId::TextAnchor),
+ ("v-mathematical", AttributeId::VMathematical),
("dur", AttributeId::Dur),
- ("xChannelSelector", AttributeId::XChannelSelector),
- ("repeatDur", AttributeId::RepeatDur),
- ("surfaceScale", AttributeId::SurfaceScale),
- ("in2", AttributeId::In2),
- ("id", AttributeId::Id),
- ("units-per-em", AttributeId::UnitsPerEm),
- ("by", AttributeId::By),
- ("transform", AttributeId::Transform),
- ("zoomAndPan", AttributeId::ZoomAndPan),
+ ("from", AttributeId::From),
+ ("baseProfile", AttributeId::BaseProfile),
+ ("kernelMatrix", AttributeId::KernelMatrix),
+ ("direction", AttributeId::Direction),
+ ("stroke-width", AttributeId::StrokeWidth),
+ ("patternContentUnits", AttributeId::PatternContentUnits),
+ ("filterUnits", AttributeId::FilterUnits),
+ ("k", AttributeId::K),
+ ("cx", AttributeId::Cx),
+ ("bias", AttributeId::Bias),
("style", AttributeId::Style),
- ("clip-path", AttributeId::ClipPath),
- ("ideographic", AttributeId::Ideographic),
- ("font", AttributeId::Font),
- ("color-interpolation-filters", AttributeId::ColorInterpolationFilters),
- ("overline-position", AttributeId::OverlinePosition),
- ("attributeName", AttributeId::AttributeName),
- ("onload", AttributeId::Onload),
("requiredFeatures", AttributeId::RequiredFeatures),
- ("pointsAtZ", AttributeId::PointsAtZ),
- ("horiz-adv-x", AttributeId::HorizAdvX),
- ("onmousedown", AttributeId::Onmousedown),
- ("primitiveUnits", AttributeId::PrimitiveUnits),
- ("scale", AttributeId::Scale),
- ("k3", AttributeId::K3),
+ ("x-height", AttributeId::XHeight),
+ ("onload", AttributeId::Onload),
+ ("unicode-bidi", AttributeId::UnicodeBidi),
+ ("v-alphabetic", AttributeId::VAlphabetic),
+ ("g2", AttributeId::G2),
+ ("fx", AttributeId::Fx),
+ ("keyTimes", AttributeId::KeyTimes),
+ ("font-size", AttributeId::FontSize),
+ ("orientation", AttributeId::Orientation),
+ ("lighting-color", AttributeId::LightingColor),
+ ("stop-color", AttributeId::StopColor),
+ ("k4", AttributeId::K4),
+ ("unicode", AttributeId::Unicode),
+ ("text-rendering", AttributeId::TextRendering),
+ ("maskContentUnits", AttributeId::MaskContentUnits),
+ ("begin", AttributeId::Begin),
+ ("cap-height", AttributeId::CapHeight),
+ ("panose-1", AttributeId::Panose1),
+ ("marker-mid", AttributeId::MarkerMid),
+ ("rendering-intent", AttributeId::RenderingIntent),
+ ("format", AttributeId::Format),
+ ("edgeMode", AttributeId::EdgeMode),
+ ("visibility", AttributeId::Visibility),
+ ("units-per-em", AttributeId::UnitsPerEm),
+ ("letter-spacing", AttributeId::LetterSpacing),
+ ("max", AttributeId::Max),
+ ("x", AttributeId::X),
+ ("font", AttributeId::Font),
+ ("u2", AttributeId::U2),
+ ("method", AttributeId::Method),
+ ("exponent", AttributeId::Exponent),
+ ("alphabetic", AttributeId::Alphabetic),
+ ("word-spacing", AttributeId::WordSpacing),
+ ("operator", AttributeId::Operator),
+ ("patternUnits", AttributeId::PatternUnits),
+ ("color-rendering", AttributeId::ColorRendering),
+ ("keySplines", AttributeId::KeySplines),
+ ("role", AttributeId::Role),
+ ("marker-end", AttributeId::MarkerEnd),
+ ("k1", AttributeId::K1),
+ ("version", AttributeId::Version),
+ ("overline-thickness", AttributeId::OverlineThickness),
("fy", AttributeId::Fy),
+ ("numOctaves", AttributeId::NumOctaves),
+ ("maskUnits", AttributeId::MaskUnits),
+ ("opacity", AttributeId::Opacity),
+ ("baseline-shift", AttributeId::BaselineShift),
+ ("flood-color", AttributeId::FloodColor),
+ ("to", AttributeId::To),
+ ("lang", AttributeId::Lang),
+ ("onabort", AttributeId::Onabort),
+ ("kerning", AttributeId::Kerning),
+ ("onmouseout", AttributeId::Onmouseout),
("widths", AttributeId::Widths),
- ("display", AttributeId::Display),
- ("divisor", AttributeId::Divisor),
- ("flood-opacity", AttributeId::FloodOpacity),
- ("xlink:show", AttributeId::XlinkShow),
- ("onscroll", AttributeId::Onscroll),
- ("x", AttributeId::X),
- ("spreadMethod", AttributeId::SpreadMethod),
- ("ascent", AttributeId::Ascent),
- ("pointer-events", AttributeId::PointerEvents),
- ("stroke-linecap", AttributeId::StrokeLinecap),
+ ("by", AttributeId::By),
+ ("specularExponent", AttributeId::SpecularExponent),
+ ("horiz-origin-y", AttributeId::HorizOriginY),
+ ("viewTarget", AttributeId::ViewTarget),
+ ("calcMode", AttributeId::CalcMode),
+ ("restart", AttributeId::Restart),
+ ("shape-rendering", AttributeId::ShapeRendering),
+ ("fill-opacity", AttributeId::FillOpacity),
+ ("type", AttributeId::Type),
+ ("actuate", AttributeId::Actuate),
+ ("z", AttributeId::Z),
+ ("overflow", AttributeId::Overflow),
+ ("preserveAlpha", AttributeId::PreserveAlpha),
+ ("stemv", AttributeId::Stemv),
+ ("onmouseup", AttributeId::Onmouseup),
("class", AttributeId::Class),
- ("u1", AttributeId::U1),
- ("specularConstant", AttributeId::SpecularConstant),
- ("v-mathematical", AttributeId::VMathematical),
- ("line-height", AttributeId::LineHeight),
- ("onzoom", AttributeId::Onzoom),
- ("mathematical", AttributeId::Mathematical),
- ("y1", AttributeId::Y1),
- ("fill-rule", AttributeId::FillRule),
- ("seed", AttributeId::Seed),
- ("gradientUnits", AttributeId::GradientUnits),
- ("startOffset", AttributeId::StartOffset),
- ("glyph-orientation-horizontal", AttributeId::GlyphOrientationHorizontal),
("offset", AttributeId::Offset),
- ("format", AttributeId::Format),
- ("enable-background", AttributeId::EnableBackground),
+ ("accent-height", AttributeId::AccentHeight),
+ ("in2", AttributeId::In2),
+ ("strikethrough-thickness", AttributeId::StrikethroughThickness),
+ ("arcrole", AttributeId::Arcrole),
+ ("vert-adv-y", AttributeId::VertAdvY),
+ ("show", AttributeId::Show),
+ ("bbox", AttributeId::Bbox),
+ ("clip-path", AttributeId::ClipPath),
+ ("r", AttributeId::R),
+ ("rotate", AttributeId::Rotate),
+ ("width", AttributeId::Width),
+ ("image-rendering", AttributeId::ImageRendering),
+ ("unicode-range", AttributeId::UnicodeRange),
+ ("markerUnits", AttributeId::MarkerUnits),
+ ("onend", AttributeId::Onend),
+ ("dy", AttributeId::Dy),
+ ("surfaceScale", AttributeId::SurfaceScale),
+ ("preserveAspectRatio", AttributeId::PreserveAspectRatio),
+ ("stemh", AttributeId::Stemh),
+ ("diffuseConstant", AttributeId::DiffuseConstant),
+ ("onmousedown", AttributeId::Onmousedown),
+ ("id", AttributeId::Id),
+ ("onclick", AttributeId::Onclick),
+ ("stroke-linecap", AttributeId::StrokeLinecap),
+ ("mode", AttributeId::Mode),
+ ("xmlns", AttributeId::Xmlns),
+ ("amplitude", AttributeId::Amplitude),
+ ("points", AttributeId::Points),
+ ("stroke-linejoin", AttributeId::StrokeLinejoin),
+ ("onfocusin", AttributeId::Onfocusin),
("min", AttributeId::Min),
- ("alphabetic", AttributeId::Alphabetic),
+ ("filter", AttributeId::Filter),
+ ("y2", AttributeId::Y2),
+ ("orient", AttributeId::Orient),
+ ("font-family", AttributeId::FontFamily),
+ ("contentScriptType", AttributeId::ContentScriptType),
("systemLanguage", AttributeId::SystemLanguage),
- ("amplitude", AttributeId::Amplitude),
- ("horiz-origin-x", AttributeId::HorizOriginX),
- ("fill", AttributeId::Fill),
- ("onerror", AttributeId::Onerror),
- ("u2", AttributeId::U2),
+ ("onactivate", AttributeId::Onactivate),
+ ("keyPoints", AttributeId::KeyPoints),
+ ("attributeName", AttributeId::AttributeName),
+ ("writing-mode", AttributeId::WritingMode),
+ ("onscroll", AttributeId::Onscroll),
+ ("display", AttributeId::Display),
("spacing", AttributeId::Spacing),
- ("rx", AttributeId::Rx),
- ("diffuseConstant", AttributeId::DiffuseConstant),
- ("stemh", AttributeId::Stemh),
- ("onmouseover", AttributeId::Onmouseover),
- ("tableValues", AttributeId::TableValues),
- ("color-interpolation", AttributeId::ColorInterpolation),
- ("word-spacing", AttributeId::WordSpacing),
- ("dy", AttributeId::Dy),
- ("stroke-opacity", AttributeId::StrokeOpacity),
- ("panose-1", AttributeId::Panose1),
- ("cap-height", AttributeId::CapHeight),
- ("requiredExtensions", AttributeId::RequiredExtensions),
- ("additive", AttributeId::Additive),
- ("textLength", AttributeId::TextLength),
- ("targetX", AttributeId::TargetX),
- ("dominant-baseline", AttributeId::DominantBaseline),
- ("method", AttributeId::Method),
- ("overflow", AttributeId::Overflow),
- ("rendering-intent", AttributeId::RenderingIntent),
- ("clip", AttributeId::Clip),
- ("x-height", AttributeId::XHeight),
- ("alignment-baseline", AttributeId::AlignmentBaseline),
+ ("ry", AttributeId::Ry),
+ ("onfocusout", AttributeId::Onfocusout),
+ ("descent", AttributeId::Descent),
+ ("divisor", AttributeId::Divisor),
+ ("patternTransform", AttributeId::PatternTransform),
+ ("radius", AttributeId::Radius),
("filterRes", AttributeId::FilterRes),
+ ("font-style", AttributeId::FontStyle),
+ ("viewBox", AttributeId::ViewBox),
+ ("textLength", AttributeId::TextLength),
+ ("font-weight", AttributeId::FontWeight),
("vert-origin-y", AttributeId::VertOriginY),
- ("k", AttributeId::K),
- ("z", AttributeId::Z),
- ("maskContentUnits", AttributeId::MaskContentUnits),
- ("mask", AttributeId::Mask),
- ("elevation", AttributeId::Elevation),
- ("x1", AttributeId::X1),
- ("kernelMatrix", AttributeId::KernelMatrix),
- ("color", AttributeId::Color),
- ("fill-opacity", AttributeId::FillOpacity),
- ("rotate", AttributeId::Rotate),
- ("in", AttributeId::In),
- ("operator", AttributeId::Operator),
- ("shape-rendering", AttributeId::ShapeRendering),
- ("onfocusout", AttributeId::Onfocusout),
- ("stroke-miterlimit", AttributeId::StrokeMiterlimit),
- ("fx", AttributeId::Fx),
- ("glyph-orientation-vertical", AttributeId::GlyphOrientationVertical),
+ ("x2", AttributeId::X2),
+ ("zoomAndPan", AttributeId::ZoomAndPan),
+ ("target", AttributeId::Target),
+ ("spreadMethod", AttributeId::SpreadMethod),
+ ("additive", AttributeId::Additive),
+ ("stroke-opacity", AttributeId::StrokeOpacity),
+ ("repeatDur", AttributeId::RepeatDur),
+ ("stroke-dashoffset", AttributeId::StrokeDashoffset),
("stroke", AttributeId::Stroke),
- ("kernelUnitLength", AttributeId::KernelUnitLength),
- ("clipPathUnits", AttributeId::ClipPathUnits),
- ("max", AttributeId::Max),
- ("contentStyleType", AttributeId::ContentStyleType),
- ("externalResourcesRequired", AttributeId::ExternalResourcesRequired),
- ("markerUnits", AttributeId::MarkerUnits),
+ ("g1", AttributeId::G1),
+ ("k2", AttributeId::K2),
("values", AttributeId::Values),
- ("gradientTransform", AttributeId::GradientTransform),
- ("baseFrequency", AttributeId::BaseFrequency),
- ("contentScriptType", AttributeId::ContentScriptType),
- ("y", AttributeId::Y),
- ("ry", AttributeId::Ry),
- ("keyPoints", AttributeId::KeyPoints),
- ("xlink:type", AttributeId::XlinkType),
- ("unicode-range", AttributeId::UnicodeRange),
- ("yChannelSelector", AttributeId::YChannelSelector),
- ("begin", AttributeId::Begin),
- ("orient", AttributeId::Orient),
- ("xml:space", AttributeId::XmlSpace),
- ("to", AttributeId::To),
- ("attributeType", AttributeId::AttributeType),
- ("result", AttributeId::Result),
- ("glyph-name", AttributeId::GlyphName),
- ("onresize", AttributeId::Onresize),
- ("numOctaves", AttributeId::NumOctaves),
- ("opacity", AttributeId::Opacity),
- ("strikethrough-thickness", AttributeId::StrikethroughThickness),
- ("xlink:href", AttributeId::XlinkHref),
- ("font-style", AttributeId::FontStyle),
- ("patternContentUnits", AttributeId::PatternContentUnits),
- ("path", AttributeId::Path),
- ("media", AttributeId::Media),
- ("underline-thickness", AttributeId::UnderlineThickness),
- ("color-profile", AttributeId::ColorProfile),
- ("repeatCount", AttributeId::RepeatCount),
- ("stroke-dashoffset", AttributeId::StrokeDashoffset),
- ("xml:lang", AttributeId::XmlLang),
- ("y2", AttributeId::Y2),
- ("descent", AttributeId::Descent),
- ("patternUnits", AttributeId::PatternUnits),
- ("horiz-origin-y", AttributeId::HorizOriginY),
+ ("in", AttributeId::In),
+ ("onmousemove", AttributeId::Onmousemove),
+ ("requiredExtensions", AttributeId::RequiredExtensions),
+ ("xChannelSelector", AttributeId::XChannelSelector),
+ ("ideographic", AttributeId::Ideographic),
("underline-position", AttributeId::UnderlinePosition),
- ("unicode", AttributeId::Unicode),
- ("viewBox", AttributeId::ViewBox),
- ("strikethrough-position", AttributeId::StrikethroughPosition),
- ("baseline-shift", AttributeId::BaselineShift),
- ("points", AttributeId::Points),
- ("end", AttributeId::End),
- ("k1", AttributeId::K1),
- ("writing-mode", AttributeId::WritingMode),
- ("stroke-width", AttributeId::StrokeWidth),
- ("stitchTiles", AttributeId::StitchTiles),
- ("keySplines", AttributeId::KeySplines),
- ("overline-thickness", AttributeId::OverlineThickness),
- ("stemv", AttributeId::Stemv),
- ("text-decoration", AttributeId::TextDecoration),
- ("from", AttributeId::From),
- ("onmouseup", AttributeId::Onmouseup),
- ("k4", AttributeId::K4),
- ("name", AttributeId::Name),
- ("vert-adv-y", AttributeId::VertAdvY),
- ("v-alphabetic", AttributeId::VAlphabetic),
- ("cy", AttributeId::Cy),
- ("v-ideographic", AttributeId::VIdeographic),
- ("flood-color", AttributeId::FloodColor),
("glyphRef", AttributeId::GlyphRef),
- ("orientation", AttributeId::Orientation),
- ("pathLength", AttributeId::PathLength),
- ("font-size-adjust", AttributeId::FontSizeAdjust),
- ("visibility", AttributeId::Visibility),
- ("letter-spacing", AttributeId::LetterSpacing),
- ("image-rendering", AttributeId::ImageRendering),
- ("unicode-bidi", AttributeId::UnicodeBidi),
- ("viewTarget", AttributeId::ViewTarget),
- ("onrepeat", AttributeId::Onrepeat),
- ("bbox", AttributeId::Bbox),
+ ("result", AttributeId::Result),
+ ("base", AttributeId::Base),
+ ("order", AttributeId::Order),
+ ("marker-start", AttributeId::MarkerStart),
+ ("origin", AttributeId::Origin),
+ ("clipPathUnits", AttributeId::ClipPathUnits),
+ ("onbegin", AttributeId::Onbegin),
+ ("refX", AttributeId::RefX),
+ ("onmouseover", AttributeId::Onmouseover),
+ ("intercept", AttributeId::Intercept),
+ ("stitchTiles", AttributeId::StitchTiles),
+ ("hanging", AttributeId::Hanging),
+ ("clip", AttributeId::Clip),
+ ("marker", AttributeId::Marker),
+ ("line-height", AttributeId::LineHeight),
("arabic-form", AttributeId::ArabicForm),
- ("limitingConeAngle", AttributeId::LimitingConeAngle),
+ ("u1", AttributeId::U1),
+ ("font-size-adjust", AttributeId::FontSizeAdjust),
+ ("v-ideographic", AttributeId::VIdeographic),
+ ("mask", AttributeId::Mask),
+ ("href", AttributeId::Href),
+ ("onzoom", AttributeId::Onzoom),
+ ("end", AttributeId::End),
+ ("color-interpolation-filters", AttributeId::ColorInterpolationFilters),
+ ("contentStyleType", AttributeId::ContentStyleType),
+ ("startOffset", AttributeId::StartOffset),
+ ("font-variant", AttributeId::FontVariant),
+ ("slope", AttributeId::Slope),
("stdDeviation", AttributeId::StdDeviation),
- ("pointsAtX", AttributeId::PointsAtX),
- ("pointsAtY", AttributeId::PointsAtY),
- ("radius", AttributeId::Radius),
- ("exponent", AttributeId::Exponent),
- ("font-family", AttributeId::FontFamily),
- ("lang", AttributeId::Lang),
+ ("seed", AttributeId::Seed),
+ ("alignment-baseline", AttributeId::AlignmentBaseline),
+ ("k3", AttributeId::K3),
+ ("yChannelSelector", AttributeId::YChannelSelector),
+ ("height", AttributeId::Height),
+ ("elevation", AttributeId::Elevation),
+ ("y1", AttributeId::Y1),
+ ("color-interpolation", AttributeId::ColorInterpolation),
+ ("rx", AttributeId::Rx),
("string", AttributeId::String),
- ("width", AttributeId::Width),
- ("marker", AttributeId::Marker),
- ("xml:base", AttributeId::XmlBase),
+ ("fill", AttributeId::Fill),
+ ("d", AttributeId::D),
+ ("kernelUnitLength", AttributeId::KernelUnitLength),
+ ("primitiveUnits", AttributeId::PrimitiveUnits),
+ ("x1", AttributeId::X1),
+ ("glyph-name", AttributeId::GlyphName),
+ ("gradientUnits", AttributeId::GradientUnits),
+ ("transform", AttributeId::Transform),
+ ("pointsAtX", AttributeId::PointsAtX),
+ ("refY", AttributeId::RefY),
+ ("pointsAtZ", AttributeId::PointsAtZ),
("stroke-dasharray", AttributeId::StrokeDasharray),
+ ("horiz-adv-x", AttributeId::HorizAdvX),
+ ("local", AttributeId::Local),
+ ("glyph-orientation-vertical", AttributeId::GlyphOrientationVertical),
+ ("stroke-miterlimit", AttributeId::StrokeMiterlimit),
+ ("cy", AttributeId::Cy),
+ ("lengthAdjust", AttributeId::LengthAdjust),
+ ("color-profile", AttributeId::ColorProfile),
+ ("horiz-origin-x", AttributeId::HorizOriginX),
+ ("onerror", AttributeId::Onerror),
+ ("attributeType", AttributeId::AttributeType),
+ ("space", AttributeId::Space),
+ ("y", AttributeId::Y),
+ ("targetY", AttributeId::TargetY),
+ ("pointer-events", AttributeId::PointerEvents),
+ ("scale", AttributeId::Scale),
+ ("vert-origin-x", AttributeId::VertOriginX),
+ ("text-decoration", AttributeId::TextDecoration),
+ ("onresize", AttributeId::Onresize),
+ ("onrepeat", AttributeId::Onrepeat),
+ ("baseFrequency", AttributeId::BaseFrequency),
+ ("tableValues", AttributeId::TableValues),
("markerWidth", AttributeId::MarkerWidth),
- ("bias", AttributeId::Bias),
- ("font-variant", AttributeId::FontVariant),
- ("stop-opacity", AttributeId::StopOpacity),
- ("cursor", AttributeId::Cursor),
- ("slope", AttributeId::Slope),
- ("onmousemove", AttributeId::Onmousemove),
- ("xmlns", AttributeId::Xmlns),
- ("xlink:role", AttributeId::XlinkRole),
- ("lighting-color", AttributeId::LightingColor),
+ ("repeatCount", AttributeId::RepeatCount),
+ ("pointsAtY", AttributeId::PointsAtY),
("markerHeight", AttributeId::MarkerHeight),
- ("preserveAspectRatio", AttributeId::PreserveAspectRatio),
- ("kerning", AttributeId::Kerning),
- ("g1", AttributeId::G1),
- ("local", AttributeId::Local),
- ("accent-height", AttributeId::AccentHeight),
- ("keyTimes", AttributeId::KeyTimes),
- ("stop-color", AttributeId::StopColor),
- ("intercept", AttributeId::Intercept),
- ("version", AttributeId::Version),
- ("preserveAlpha", AttributeId::PreserveAlpha),
- ("onfocusin", AttributeId::Onfocusin),
+ ("ascent", AttributeId::Ascent),
+ ("overline-position", AttributeId::OverlinePosition),
+ ("name", AttributeId::Name),
+ ("color", AttributeId::Color),
+ ("specularConstant", AttributeId::SpecularConstant),
+ ("clip-rule", AttributeId::ClipRule),
+ ("mathematical", AttributeId::Mathematical),
+ ("glyph-orientation-horizontal", AttributeId::GlyphOrientationHorizontal),
+ ("externalResourcesRequired", AttributeId::ExternalResourcesRequired),
+ ("strikethrough-position", AttributeId::StrikethroughPosition),
+ ("media", AttributeId::Media),
("dx", AttributeId::Dx),
- ("cx", AttributeId::Cx),
- ("vert-origin-x", AttributeId::VertOriginX),
- ("stroke-linejoin", AttributeId::StrokeLinejoin),
- ("onactivate", AttributeId::Onactivate),
- ("xmlns:xlink", AttributeId::XmlnsXlink),
+ ("cursor", AttributeId::Cursor),
("azimuth", AttributeId::Azimuth),
- ("marker-start", AttributeId::MarkerStart),
- ("d", AttributeId::D),
- ("filterUnits", AttributeId::FilterUnits),
- ("r", AttributeId::R),
- ("mode", AttributeId::Mode),
- ("x2", AttributeId::X2),
- ("xlink:title", AttributeId::XlinkTitle),
- ("font-weight", AttributeId::FontWeight),
- ("clip-rule", AttributeId::ClipRule),
- ("refY", AttributeId::RefY),
- ("type", AttributeId::Type),
- ("marker-end", AttributeId::MarkerEnd),
- ("origin", AttributeId::Origin),
- ("title", AttributeId::Title),
- ("baseProfile", AttributeId::BaseProfile),
- ("edgeMode", AttributeId::EdgeMode),
- ("onend", AttributeId::Onend),
- ("maskUnits", AttributeId::MaskUnits),
- ("xlink:actuate", AttributeId::XlinkActuate),
- ("refX", AttributeId::RefX),
- ("onunload", AttributeId::Onunload),
- ("specularExponent", AttributeId::SpecularExponent),
- ("height", AttributeId::Height),
- ("marker-mid", AttributeId::MarkerMid),
- ("onbegin", AttributeId::Onbegin),
- ("onclick", AttributeId::Onclick),
- ("order", AttributeId::Order),
- ("font-stretch", AttributeId::FontStretch),
- ("targetY", AttributeId::TargetY),
- ("color-rendering", AttributeId::ColorRendering),
- ("lengthAdjust", AttributeId::LengthAdjust),
- ("text-rendering", AttributeId::TextRendering),
- ("direction", AttributeId::Direction),
- ("text-anchor", AttributeId::TextAnchor),
- ("calcMode", AttributeId::CalcMode),
- ("g2", AttributeId::G2),
+ ("gradientTransform", AttributeId::GradientTransform),
+ ("fill-rule", AttributeId::FillRule),
]),
};
@@ -628,15 +621,18 @@ impl AttributeId {
match *self {
AttributeId::AccentHeight => "accent-height",
AttributeId::Accumulate => "accumulate",
+ AttributeId::Actuate => "actuate",
AttributeId::Additive => "additive",
AttributeId::AlignmentBaseline => "alignment-baseline",
AttributeId::Alphabetic => "alphabetic",
AttributeId::Amplitude => "amplitude",
AttributeId::ArabicForm => "arabic-form",
+ AttributeId::Arcrole => "arcrole",
AttributeId::Ascent => "ascent",
AttributeId::AttributeName => "attributeName",
AttributeId::AttributeType => "attributeType",
AttributeId::Azimuth => "azimuth",
+ AttributeId::Base => "base",
AttributeId::BaseFrequency => "baseFrequency",
AttributeId::BaselineShift => "baseline-shift",
AttributeId::BaseProfile => "baseProfile",
@@ -710,6 +706,7 @@ impl AttributeId {
AttributeId::HorizAdvX => "horiz-adv-x",
AttributeId::HorizOriginX => "horiz-origin-x",
AttributeId::HorizOriginY => "horiz-origin-y",
+ AttributeId::Href => "href",
AttributeId::Id => "id",
AttributeId::Ideographic => "ideographic",
AttributeId::ImageRendering => "image-rendering",
@@ -806,13 +803,16 @@ impl AttributeId {
AttributeId::RequiredFeatures => "requiredFeatures",
AttributeId::Restart => "restart",
AttributeId::Result => "result",
+ AttributeId::Role => "role",
AttributeId::Rotate => "rotate",
AttributeId::Rx => "rx",
AttributeId::Ry => "ry",
AttributeId::Scale => "scale",
AttributeId::Seed => "seed",
AttributeId::ShapeRendering => "shape-rendering",
+ AttributeId::Show => "show",
AttributeId::Slope => "slope",
+ AttributeId::Space => "space",
AttributeId::Spacing => "spacing",
AttributeId::SpecularConstant => "specularConstant",
AttributeId::SpecularExponent => "specularExponent",
@@ -879,18 +879,8 @@ impl AttributeId {
AttributeId::X1 => "x1",
AttributeId::X2 => "x2",
AttributeId::XChannelSelector => "xChannelSelector",
- AttributeId::XlinkActuate => "xlink:actuate",
- AttributeId::XlinkArcrole => "xlink:arcrole",
- AttributeId::XlinkHref => "xlink:href",
- AttributeId::XlinkRole => "xlink:role",
- AttributeId::XlinkShow => "xlink:show",
- AttributeId::XlinkTitle => "xlink:title",
- AttributeId::XlinkType => "xlink:type",
- AttributeId::XmlBase => "xml:base",
- AttributeId::XmlLang => "xml:lang",
- AttributeId::XmlSpace => "xml:space",
+ AttributeId::Xlink => "xlink",
AttributeId::Xmlns => "xmlns",
- AttributeId::XmlnsXlink => "xmlns:xlink",
AttributeId::Y => "y",
AttributeId::Y1 => "y1",
AttributeId::Y2 => "y2",
diff --git a/src/attribute_value.rs b/src/attribute_value.rs
index cfa520f..ee2fa96 100644
@@ -273,7 +273,7 @@ impl<'a> AttributeValue<'a> {
parse_or_err!(parse_func_iri(stream)))
}
- AId::XlinkHref => { parse_iri(stream) }
+ AId::Href => { parse_iri(stream) }
AId::Color => {
parse_or!(parse_predef!(ValueId::Inherit),
diff --git a/src/lib.rs b/src/lib.rs
index 6aa7ae1..c15ac53 100644
@@ -13,6 +13,7 @@
extern crate phf;
pub use attribute::AttributeId;
+pub use attribute_ns::AttributeNSId;
pub use attribute_value::{AttributeValue, PaintFallback};
pub use rgbcolor::RgbColor;
pub use element::ElementId;
@@ -31,6 +32,7 @@ pub mod svg;
pub mod transform;
mod attribute;
+mod attribute_ns;
mod attribute_value;
mod colors;
mod element;
diff --git a/src/macros.rs b/src/macros.rs
index 4d475ec..0940ba5 100644
@@ -26,3 +26,18 @@ macro_rules! impl_iter_for_tokenizer {
macro_rules! u8_to_str {
($text:expr) => (str::from_utf8($text).unwrap())
}
+
+#[macro_export]
+macro_rules! assert_eq_text {
+ ($left:expr, $right:expr) => ({
+ match ($left, $right) {
+ (left_val, right_val) => {
+ if !(*left_val == *right_val) {
+ panic!("assertion failed: `(left == right)` \
+ \nleft: `{}`\nright: `{}`",
+ u8_to_str!(left_val), u8_to_str!(right_val))
+ }
+ }
+ }
+ })
+}
diff --git a/src/svg.rs b/src/svg.rs
index 5bb6ee2..ed8e130 100644
@@ -14,8 +14,8 @@ use super::{Stream, Error};
pub enum ElementEnd<'a> {
/// Indicates `>`
Open,
- /// Indicates `</name>`
- Close(&'a [u8]),
+ /// Indicates `</ns:name>`
+ Close(Option<&'a [u8]>, &'a [u8]),
/// Indicates `/>`
Empty,
}
@@ -23,46 +23,57 @@ pub enum ElementEnd<'a> {
/// SVG token.
#[derive(PartialEq)]
pub enum Token<'a> {
- /// Tuple contains tag name of the element.
- ElementStart(&'a [u8]),
+ /// Tuple contains a namespace and a tag name of the element.
+ ElementStart(Option<&'a [u8]>, &'a [u8]),
/// Tuple contains the type of enclosing tag.
ElementEnd(ElementEnd<'a>),
- /// Tuple contains attribute name and value.
- Attribute(&'a [u8], Stream<'a>),
+ /// Tuple contains an attribute namespace, attribute name and value.
+ Attribute(Option<&'a [u8]>, &'a [u8], Stream<'a>),
/// Tuple contains a text object.
Text(Stream<'a>),
/// Tuple contains CDATA object without `<![CDATA[` and `]]>`.
Cdata(Stream<'a>),
/// Tuple contains whitespace object. It will contain only ` \n\t\r`.
Whitespace(&'a [u8]),
- /// Tuple contains comment object without `<!--` and `-->`.
+ /// Tuple contains a comment object without `<!--` and `-->`.
Comment(&'a [u8]),
/// Tuple contains a title of empty DOCTYPE.
DtdEmpty(&'a [u8]),
/// Tuple contains a title of DOCTYPE.
DtdStart(&'a [u8]),
- /// Tuple contains name and value of ENTITY.
+ /// Tuple contains a name and a value of ENTITY.
Entity(&'a [u8], Stream<'a>),
/// Tuple indicates DOCTYPE end.
DtdEnd,
- /// Tuple contains declaration object without `<?` and `?>`.
+ /// Tuple contains a declaration object without `<?` and `?>`.
Declaration(&'a [u8]),
}
+// TODO: rewrite
impl<'a> fmt::Debug for Token<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
- Token::ElementStart(s) => write!(f, "ElementStart({})", u8_to_str!(s)),
+ Token::ElementStart(ns, s) => {
+ match ns {
+ Some(ns_name) => write!(f, "ElementStart({}:{})", u8_to_str!(ns_name), u8_to_str!(s)),
+ None => write!(f, "ElementStart({})", u8_to_str!(s)),
+ }
+ }
Token::ElementEnd(ref e) => {
let c = match *e {
ElementEnd::Open => ">",
- ElementEnd::Close(_) => "</",
+ ElementEnd::Close(_, _) => "</",
ElementEnd::Empty => "/>",
};
write!(f, "ElementEnd({})", c)
}
- Token::Attribute(k, ref v) => {
- write!(f, "Attribute({}, {:?})", u8_to_str!(k), v)
+ Token::Attribute(ns, n, ref v) => {
+ match ns {
+ Some(ns_name) => {
+ write!(f, "Attribute({}:{}, {:?})", u8_to_str!(ns_name), u8_to_str!(n), v)
+ }
+ None => write!(f, "Attribute({}, {:?})", u8_to_str!(n), v),
+ }
}
Token::Text(ref s) => write!(f, "Text({:?})", s),
Token::Cdata(ref s) => write!(f, "CDATA({:?})", s),
@@ -133,7 +144,7 @@ impl<'a> Tokenizer<'a> {
self.parse_dtd()
} else if self.stream.starts_with(b"</") {
try!(self.stream.advance(2)); // </
- let text = try!(self.stream.read_to(b'>'));
+ let tag_name = try!(self.stream.read_to(b'>'));
try!(self.stream.advance(1)); // >
if self.depth == 0 {
@@ -144,7 +155,8 @@ impl<'a> Tokenizer<'a> {
self.depth -= 1;
- Ok(Token::ElementEnd(ElementEnd::Close(text)))
+ let (ns, name) = split_ns(tag_name);
+ Ok(Token::ElementEnd(ElementEnd::Close(ns, name)))
} else if self.stream.is_char_eq_raw(b'<') {
self.depth += 1;
self.parse_element()
@@ -352,7 +364,14 @@ impl<'a> Tokenizer<'a> {
self.stream.skip_spaces();
self.state = State::Attributes;
- Ok(Token::ElementStart(tag_name))
+ // if let Some(idx) = name.iter().position(|c| *c == b':') {
+ // Ok(Token::ElementStart(Some(&name[..idx]), &name[idx+1..], substream))
+ // } else {
+ // Ok(Token::ElementStart(None, name, substream))
+ // }
+
+ let (ns, name) = split_ns(tag_name);
+ Ok(Token::ElementStart(ns, name))
}
fn parse_attribute(&mut self) -> Result<Token<'a>, Error> {
@@ -370,7 +389,7 @@ impl<'a> Tokenizer<'a> {
return Ok(Token::ElementEnd(ElementEnd::Open));
}
- let key = try!(self.stream.read_to_trimmed(b'='));
+ let full_name = try!(self.stream.read_to_trimmed(b'='));
try!(self.stream.advance(1)); // =
self.stream.skip_spaces();
@@ -394,7 +413,16 @@ impl<'a> Tokenizer<'a> {
self.stream.skip_spaces();
- Ok(Token::Attribute(key, substream))
+ let (ns, name) = split_ns(full_name);
+ Ok(Token::Attribute(ns, name, substream))
+ }
+}
+
+fn split_ns(text: &[u8]) -> (Option<&[u8]>, &[u8]) {
+ if let Some(idx) = text.iter().position(|c| *c == b':') {
+ (Some(&text[..idx]), &text[idx+1..])
+ } else {
+ (None, text)
}
}
diff --git a/tests/svg.rs b/tests/svg.rs
index 11e30fa..8614ae6 100644
@@ -2,14 +2,13 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-extern crate svgparser;
+use std::str;
+
+#[macro_use] extern crate svgparser;
use svgparser::{Error, ErrorPos};
use svgparser::svg;
-// TODO: test randomly ended files
-// TODO: test parsing random parts of file
-
macro_rules! basic_assert_eq {
($tokenizer:expr, $token:expr) => (
assert_eq!($tokenizer.parse_next().unwrap(), $token)
@@ -19,18 +18,19 @@ macro_rules! basic_assert_eq {
macro_rules! cdata_assert_eq {
($tokenizer:expr, $text:expr) => (
match $tokenizer.parse_next().unwrap() {
- svg::Token::Cdata(stream) => assert_eq!(stream.slice(), $text.as_ref()),
+ svg::Token::Cdata(stream) => assert_eq_text!(stream.slice(), $text.as_ref()),
_ => unreachable!(),
}
)
}
macro_rules! attr_assert_eq {
- ($tokenizer:expr, $name:expr, $value:expr) => (
+ ($tokenizer:expr, $namespace:expr, $name:expr, $value:expr) => (
match $tokenizer.parse_next().unwrap() {
- svg::Token::Attribute(name, stream) => {
- assert_eq!(name, $name);
- assert_eq!(stream.slice(), $value.as_ref());
+ svg::Token::Attribute(ns, name, stream) => {
+ assert_eq!(ns, $namespace);
+ assert_eq_text!(name, $name);
+ assert_eq_text!(stream.slice(), $value.as_ref());
},
_ => unreachable!(),
}
@@ -40,7 +40,7 @@ macro_rules! attr_assert_eq {
macro_rules! text_assert_eq {
($tokenizer:expr, $text:expr) => (
match $tokenizer.parse_next().unwrap() {
- svg::Token::Text(stream) => assert_eq!(stream.slice(), $text.as_ref()),
+ svg::Token::Text(stream) => assert_eq_text!(stream.slice(), $text.as_ref()),
_ => unreachable!(),
}
)
@@ -50,8 +50,8 @@ macro_rules! entity_assert_eq {
($tokenizer:expr, $name:expr, $value:expr) => (
match $tokenizer.parse_next().unwrap() {
svg::Token::Entity(name, stream) => {
- assert_eq!(name, $name);
- assert_eq!(stream.slice(), $value.as_ref());
+ assert_eq_text!(name, $name);
+ assert_eq_text!(stream.slice(), $value.as_ref());
},
_ => unreachable!(),
}
@@ -129,7 +129,7 @@ fn parse_malformed_xml_inside_cdata() {
}
#[test]
-fn parse_multiply_cdata() {
+fn parse_multiply_cdata_1() {
let mut p = svg::Tokenizer::new(b"<![CDATA[1]]><![CDATA[2]]>");
cdata_assert_eq!(p, b"1");
cdata_assert_eq!(p, b"2");
@@ -137,24 +137,32 @@ fn parse_multiply_cdata() {
}
#[test]
+fn parse_multiply_cdata_2() {
+ let mut p = svg::Tokenizer::new(b"<![CDATA[]]]]><![CDATA[>]]>");
+ cdata_assert_eq!(p, b"]]");
+ cdata_assert_eq!(p, b">");
+ assert_eq!(p.next().is_none(), true);
+}
+
+#[test]
fn parse_cdata_inside_elem_1() {
let mut p = svg::Tokenizer::new(b"<style><![CDATA[data]]></style>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"style"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"style"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
cdata_assert_eq!(p, b"data");
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"style")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"style")));
assert_eq!(p.next().is_none(), true);
}
#[test]
fn parse_cdata_inside_elem_2() {
let mut p = svg::Tokenizer::new(b"<style> \t<![CDATA[data]]>\n</style>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"style"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"style"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
basic_assert_eq!(p, svg::Token::Whitespace(b" \t"));
cdata_assert_eq!(p, b"data");
basic_assert_eq!(p, svg::Token::Whitespace(b"\n"));
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"style")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"style")));
assert_eq!(p.next().is_none(), true);
}
@@ -211,7 +219,7 @@ fn parse_entity_4() {
#[test]
fn parse_elem_1() {
let mut p = svg::Tokenizer::new(b"<svg/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -219,28 +227,39 @@ fn parse_elem_1() {
#[test]
fn parse_elem_2() {
let mut p = svg::Tokenizer::new(b"<svg></svg>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"svg")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"svg")));
assert_eq!(p.next().is_none(), true);
}
#[test]
fn parse_elem_3() {
let mut p = svg::Tokenizer::new(b"<svg><rect/></svg>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"rect"));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"svg")));
+ assert_eq!(p.next().is_none(), true);
+}
+
+#[test]
+fn parse_elem_4() {
+ let mut p = svg::Tokenizer::new(b"<svg:svg><svg:rect/></svg:svg>");
+ basic_assert_eq!(p, svg::Token::ElementStart(Some(b"svg"), b"svg"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
- basic_assert_eq!(p, svg::Token::ElementStart(b"rect"));
+ basic_assert_eq!(p, svg::Token::ElementStart(Some(b"svg"), b"rect"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"svg")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(Some(b"svg"), b"svg")));
assert_eq!(p.next().is_none(), true);
}
#[test]
fn parse_attributes_1() {
let mut p = svg::Tokenizer::new(b"<svg version=\"1.0\"/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"version", b"1.0");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"version", b"1.0");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -248,8 +267,8 @@ fn parse_attributes_1() {
#[test]
fn parse_attributes_2() {
let mut p = svg::Tokenizer::new(b"<svg version='1.0'/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"version", b"1.0");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"version", b"1.0");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -257,8 +276,8 @@ fn parse_attributes_2() {
#[test]
fn parse_attributes_3() {
let mut p = svg::Tokenizer::new(b"<svg font=\"'Verdana'\"/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"font", b"'Verdana'");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"font", b"'Verdana'");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -266,9 +285,9 @@ fn parse_attributes_3() {
#[test]
fn parse_attributes_4() {
let mut p = svg::Tokenizer::new(b"<svg version=\"1.0\" color=\"red\"/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"version", b"1.0");
- attr_assert_eq!(p, b"color", b"red");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"version", b"1.0");
+ attr_assert_eq!(p, None, b"color", b"red");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -276,8 +295,8 @@ fn parse_attributes_4() {
#[test]
fn parse_attributes_5() {
let mut p = svg::Tokenizer::new(b"<svg xmlns=\"http://www.w3.org/2000/svg\"/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"xmlns", b"http://www.w3.org/2000/svg");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"xmlns", b"http://www.w3.org/2000/svg");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -285,9 +304,9 @@ fn parse_attributes_5() {
#[test]
fn parse_attributes_6() {
let mut p = svg::Tokenizer::new(b"<svg version=\"1.0\" color='red'/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"version", b"1.0");
- attr_assert_eq!(p, b"color", b"red");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"version", b"1.0");
+ attr_assert_eq!(p, None, b"color", b"red");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -296,8 +315,8 @@ fn parse_attributes_6() {
fn parse_attributes_7() {
// I don't know how much correct is this.
let mut p = svg::Tokenizer::new(b"<svg version=\"1.0' color='red\"/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"version", b"1.0' color='red");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"version", b"1.0' color='red");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -306,8 +325,18 @@ fn parse_attributes_7() {
fn parse_attributes_8() {
// '=' can be surrounded by spaces
let mut p = svg::Tokenizer::new(b"<svg version = '1.0'/>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
- attr_assert_eq!(p, b"version", b"1.0");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, None, b"version", b"1.0");
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
+ assert_eq!(p.next().is_none(), true);
+}
+
+#[test]
+fn parse_attributes_9() {
+ // namespace
+ let mut p = svg::Tokenizer::new(b"<svg xlink:href='#link'/>");
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
+ attr_assert_eq!(p, Some(&b"xlink"[..]), b"href", b"#link");
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -315,48 +344,48 @@ fn parse_attributes_8() {
#[test]
fn parse_text_1() {
let mut p = svg::Tokenizer::new(b"<p>text</p>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"p"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"p"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
text_assert_eq!(p, b"text");
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"p")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"p")));
assert_eq!(p.next().is_none(), true);
}
#[test]
fn parse_text_2() {
let mut p = svg::Tokenizer::new(b"<p> text </p>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"p"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"p"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
text_assert_eq!(p, b" text ");
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"p")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"p")));
assert_eq!(p.next().is_none(), true);
}
#[test]
fn parse_text_3() {
let mut p = svg::Tokenizer::new(b"<text><tspan>q1<tspan>q2</tspan>q3</tspan></text>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"text"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"text"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
- basic_assert_eq!(p, svg::Token::ElementStart(b"tspan"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"tspan"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
text_assert_eq!(p, b"q1");
- basic_assert_eq!(p, svg::Token::ElementStart(b"tspan"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"tspan"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
text_assert_eq!(p, b"q2");
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"tspan")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"tspan")));
text_assert_eq!(p, b"q3");
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"tspan")));
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"text")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"tspan")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"text")));
assert_eq!(p.next().is_none(), true);
}
#[test]
fn parse_whitespace_1() {
let mut p = svg::Tokenizer::new(b"<text> </text>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"text"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"text"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
basic_assert_eq!(p, svg::Token::Whitespace(b" "));
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"text")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"text")));
assert_eq!(p.next().is_none(), true);
}
@@ -364,7 +393,7 @@ fn parse_whitespace_1() {
#[test]
fn parse_whitespace_2() {
let mut p = svg::Tokenizer::new(b" <text/> ");
- basic_assert_eq!(p, svg::Token::ElementStart(b"text"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"text"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
assert_eq!(p.next().is_none(), true);
}
@@ -405,7 +434,7 @@ fn stream_end_on_element_4() {
#[test]
fn stream_end_on_element_5() {
let mut p = svg::Tokenizer::new(b"<svg><");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
assert_eq!(p.parse_next().err().unwrap(), Error::ElementWithoutTagName(ErrorPos::new(1, 7)));
}
@@ -419,49 +448,49 @@ fn stream_end_on_element_6() {
#[test]
fn stream_end_on_element_7() {
let mut p = svg::Tokenizer::new(b"<svg");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
assert_eq!(p.parse_next().err().unwrap(), Error::UnexpectedEndOfStream(ErrorPos::new(1, 5)));
}
#[test]
fn stream_end_on_attribute_1() {
let mut p = svg::Tokenizer::new(b"<svg x");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
assert_eq!(p.parse_next().err().unwrap(), Error::UnexpectedEndOfStream(ErrorPos::new(1, 6)));
}
#[test]
fn stream_end_on_attribute_2() {
let mut p = svg::Tokenizer::new(b"<svg x=");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
assert_eq!(p.parse_next().err().unwrap(), Error::UnexpectedEndOfStream(ErrorPos::new(1, 8)));
}
#[test]
fn stream_end_on_attribute_3() {
let mut p = svg::Tokenizer::new(b"<svg x=\"");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
assert_eq!(p.parse_next().err().unwrap(), Error::UnexpectedEndOfStream(ErrorPos::new(1, 9)));
}
#[test]
fn invalid_structure_1() {
let mut p = svg::Tokenizer::new(b"<svg><g/><rect/></g></svg>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
- basic_assert_eq!(p, svg::Token::ElementStart(b"g"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"g"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
- basic_assert_eq!(p, svg::Token::ElementStart(b"rect"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"rect"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Empty));
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"g")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"g")));
assert_eq!(p.parse_next().err().unwrap(), Error::UnexpectedClosingTag(ErrorPos::new(1, 27)));
}
#[test]
fn invalid_structure_2() {
let mut p = svg::Tokenizer::new(b"<svg></g></svg>");
- basic_assert_eq!(p, svg::Token::ElementStart(b"svg"));
+ basic_assert_eq!(p, svg::Token::ElementStart(None, b"svg"));
basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Open));
- basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(b"g")));
+ basic_assert_eq!(p, svg::Token::ElementEnd(svg::ElementEnd::Close(None, b"g")));
assert_eq!(p.parse_next().err().unwrap(), Error::UnexpectedClosingTag(ErrorPos::new(1, 16)));
}