Is there a more reliable way of building a hash of the attributes associated with each SVG element?
#-----------------------------------------------------------------------
# Hash of SVG elements, attributes,animation from:
# http://www.w3.org/TR/2011/REC-SVG11-20110816/attindex.html
# Philip R Brenan at gmail dot com, 2013
#-----------------------------------------------------------------------
use v5.16;
use warnings FATAL => qw(all);
use strict;
use Carp;
use Data::Dump qw(dump);
#-----------------------------------------------------------------------
# Load elements and attributes by parsing the table supplied by W3C
#-----------------------------------------------------------------------
my $e; # Element, Attribute = animation
my $a; # Attributes
for(split(/\n/, &data))
{s/[‘’\t,]/ /g;
s/\A\s+//;
s/\s+\Z//;
my @w = split /\s+/;
my $E = shift @w;
$a->{$E}++; # element
my $A = do {if ($w[-1] eq "?") {pop @w; 1} else {0}};
for(@w)
{$e->{$_}{$E} = $A; # Attribute to element
$a->{$_}++; # attribute
}
}
#-----------------------------------------------------------------------
# Add presentation attributes
#-----------------------------------------------------------------------
for my $E(&presentationElements)
{for my $A(&presentationAttributes)
{$e->{$E}{$A} = 1; # They seem to be all animatable
}
}
$$a{$_}++ for &presentationAttributes;
#-----------------------------------------------------------------------
# Convert to camelCase
#-----------------------------------------------------------------------
sub cc($) {my ($a) = @_; $a =~ s/[:_-]([a-z])/\u1ドル/gr}
my $A = {map {cc($_)=>$_} keys %$a};
my $E;
for my $k(keys %$e)
{for(keys %{$e->{$k}})
{$E->{cc($k)}{cc($_)} = $e->{$k}{$_};
}
}
sub comment($)
{my ($t) = @_;
my $c = "#".("-"x71)."\n";
say "\n$c# $t\n$c";
}
comment("SVG attribute name from perl camel case name");
say "sub attributesFromCamelCase {+", dump($A), "}";
comment("Element, attribute, animation");
say "sub elementAttributesAnimation {+", dump($E), "}";
#-----------------------------------------------------------------------
# http://www.w3.org/TR/2011/REC-SVG11-20110816/attindex.html#PresentationAttributes
#-----------------------------------------------------------------------
sub data() {<<'END'};
‘accent-height’ ‘font-face’
‘accumulate’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘additive’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘alphabetic’ ‘font-face’
‘amplitude’ ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’ ?
‘arabic-form’ ‘glyph’
‘ascent’ ‘font-face’
‘attributeName’ ‘animate’, ‘animateColor’, ‘animateTransform’, ‘set’
‘attributeType’ ‘animate’, ‘animateColor’, ‘animateTransform’, ‘set’
‘azimuth’ ‘feDistantLight’ ?
‘baseFrequency’ ‘feTurbulence’ ?
‘baseProfile’ ‘svg’
‘bbox’ ‘font-face’
‘begin’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘bias’ ‘feConvolveMatrix’ ?
‘by’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘calcMode’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘cap-height’ ‘font-face’
‘class’ ‘a’, ‘altGlyph’, ‘circle’, ‘clipPath’, ‘defs’, ‘desc’, ‘ellipse’, ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feFlood’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’, ‘feTurbulence’, ‘filter’, ‘font’, ‘foreignObject’, ‘g’, ‘glyph’, ‘glyphRef’, ‘image’, ‘line’, ‘linearGradient’, ‘marker’, ‘mask’, ‘missing-glyph’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘radialGradient’, ‘rect’, ‘stop’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘title’, ‘tref’, ‘tspan’, ‘use’ ?
‘clipPathUnits’ ‘clipPath’ ?
‘contentScriptType’ ‘svg’
‘contentStyleType’ ‘svg’
‘cx’ ‘circle’ ?
‘cx’ ‘ellipse’ ?
‘cx’ ‘radialGradient’ ?
‘cy’ ‘circle’ ?
‘cy’ ‘ellipse’ ?
‘cy’ ‘radialGradient’ ?
‘d’ ‘path’ ?
‘d’ ‘glyph’, ‘missing-glyph’
‘descent’ ‘font-face’
‘diffuseConstant’ ‘feDiffuseLighting’ ?
‘divisor’ ‘feConvolveMatrix’ ?
‘dur’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘dx’ ‘altGlyph’ ?
‘dx’ ‘feOffset’ ?
‘dx’ ‘glyphRef’
‘dx’ ‘text’ ?
‘dx’ ‘tref’, ‘tspan’ ?
‘dy’ ‘altGlyph’ ?
‘dy’ ‘feOffset’ ?
‘dy’ ‘glyphRef’
‘dy’ ‘text’ ?
‘dy’ ‘tref’, ‘tspan’ ?
‘edgeMode’ ‘feConvolveMatrix’ ?
‘elevation’ ‘feDistantLight’ ?
‘end’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘exponent’ ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’ ?
‘externalResourcesRequired’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘cursor’, ‘defs’, ‘ellipse’, ‘feImage’, ‘filter’, ‘font’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘linearGradient’, ‘marker’, ‘mask’, ‘mpath’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘radialGradient’, ‘rect’, ‘script’, ‘set’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’, ‘view’
‘fill’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘filterRes’ ‘filter’ ?
‘filterUnits’ ‘filter’ ?
‘font-family’ ‘font-face’
‘font-size’ ‘font-face’
‘font-stretch’ ‘font-face’
‘font-style’ ‘font-face’
‘font-variant’ ‘font-face’
‘font-weight’ ‘font-face’
‘format’ ‘altGlyph’
‘format’ ‘glyphRef’
‘from’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘fx’ ‘radialGradient’ ?
‘fy’ ‘radialGradient’ ?
‘g1’ ‘hkern’, ‘vkern’
‘g2’ ‘hkern’, ‘vkern’
‘glyph-name’ ‘glyph’
‘glyphRef’ ‘altGlyph’
‘glyphRef’ ‘glyphRef’
‘gradientTransform’ ‘linearGradient’ ?
‘gradientTransform’ ‘radialGradient’ ?
‘gradientUnits’ ‘linearGradient’ ?
‘gradientUnits’ ‘radialGradient’ ?
‘hanging’ ‘font-face’
‘height’ ‘filter’ ?
‘height’ ‘foreignObject’ ?
‘height’ ‘image’ ?
‘height’ ‘pattern’ ?
‘height’ ‘rect’ ?
‘height’ ‘svg’ ?
‘height’ ‘use’ ?
‘height’ ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feFlood’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’, ‘feTurbulence’ ?
‘height’ ‘mask’ ?
‘horiz-adv-x’ ‘font’
‘horiz-adv-x’ ‘glyph’, ‘missing-glyph’
‘horiz-origin-x’ ‘font’
‘horiz-origin-y’ ‘font’
‘id’ ‘a’, ‘altGlyph’, ‘altGlyphDef’, ‘altGlyphItem’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘color-profile’, ‘cursor’, ‘defs’, ‘desc’, ‘ellipse’, ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feDistantLight’, ‘feFlood’, ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMergeNode’, ‘feMorphology’, ‘feOffset’, ‘fePointLight’, ‘feSpecularLighting’, ‘feSpotLight’, ‘feTile’, ‘feTurbulence’, ‘filter’, ‘font’, ‘font-face’, ‘font-face-format’, ‘font-face-name’, ‘font-face-src’, ‘font-face-uri’, ‘foreignObject’, ‘g’, ‘glyph’, ‘glyphRef’, ‘hkern’, ‘image’, ‘line’, ‘linearGradient’, ‘marker’, ‘mask’, ‘metadata’, ‘missing-glyph’, ‘mpath’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘radialGradient’, ‘rect’, ‘script’, ‘set’, ‘stop’, ‘style’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘title’, ‘tref’, ‘tspan’, ‘use’, ‘view’, ‘vkern’
‘ideographic’ ‘font-face’
‘in’ ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feGaussianBlur’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’ ?
‘in2’ ‘feBlend’ ?
‘in2’ ‘feComposite’ ?
‘in2’ ‘feDisplacementMap’ ?
‘intercept’ ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’ ?
‘k’ ‘hkern’, ‘vkern’
‘k1’ ‘feComposite’ ?
‘k2’ ‘feComposite’ ?
‘k3’ ‘feComposite’ ?
‘k4’ ‘feComposite’ ?
‘kernelMatrix’ ‘feConvolveMatrix’ ?
‘kernelUnitLength’ ‘feConvolveMatrix’ ?
‘kernelUnitLength’ ‘feDiffuseLighting’ ?
‘kernelUnitLength’ ‘feSpecularLighting’ ?
‘keyPoints’ ‘animateMotion’
‘keySplines’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘keyTimes’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘lang’ ‘glyph’
‘lengthAdjust’ ‘text’, ‘textPath’, ‘tref’, ‘tspan’ ?
‘limitingConeAngle’ ‘feSpotLight’ ?
‘local’ ‘color-profile’
‘markerHeight’ ‘marker’ ?
‘markerUnits’ ‘marker’ ?
‘markerWidth’ ‘marker’ ?
‘maskContentUnits’ ‘mask’ ?
‘maskUnits’ ‘mask’ ?
‘mathematical’ ‘font-face’
‘max’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘media’ ‘style’
‘method’ ‘textPath’ ?
‘min’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘mode’ ‘feBlend’ ?
‘name’ ‘color-profile’
‘name’ ‘font-face-name’
‘numOctaves’ ‘feTurbulence’ ?
‘offset’ ‘stop’ ?
‘offset’ ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’ ?
‘onabort’ ‘svg’
‘onactivate’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onbegin’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘onclick’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onend’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘onerror’ ‘svg’
‘onfocusin’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onfocusout’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onload’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onload’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘onmousedown’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onmousemove’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onmouseout’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onmouseover’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onmouseup’ ‘a’, ‘altGlyph’, ‘circle’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘onrepeat’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘onresize’ ‘svg’
‘onscroll’ ‘svg’
‘onunload’ ‘svg’
‘onzoom’ ‘svg’
‘operator’ ‘feComposite’ ?
‘operator’ ‘feMorphology’ ?
‘order’ ‘feConvolveMatrix’ ?
‘orient’ ‘marker’ ?
‘orientation’ ‘glyph’
‘origin’ ‘animateMotion’
‘overline-position’ ‘font-face’
‘overline-thickness’ ‘font-face’
‘panose-1’ ‘font-face’
‘path’ ‘animateMotion’
‘pathLength’ ‘path’ ?
‘patternContentUnits’ ‘pattern’ ?
‘patternTransform’ ‘pattern’ ?
‘patternUnits’ ‘pattern’ ?
‘points’ ‘polygon’ ?
‘points’ ‘polyline’ ?
‘pointsAtX’ ‘feSpotLight’ ?
‘pointsAtY’ ‘feSpotLight’ ?
‘pointsAtZ’ ‘feSpotLight’ ?
‘preserveAlpha’ ‘feConvolveMatrix’ ?
‘preserveAspectRatio’ ‘feImage’, ‘image’, ‘marker’, ‘pattern’, ‘svg’, ‘symbol’, ‘view’ ?
‘primitiveUnits’ ‘filter’ ?
‘r’ ‘circle’ ?
‘r’ ‘radialGradient’ ?
‘radius’ ‘feMorphology’ ?
‘refX’ ‘marker’ ?
‘refY’ ‘marker’ ?
‘rendering-intent’ ‘color-profile’
‘repeatCount’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘repeatDur’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘requiredExtensions’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘cursor’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘mask’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘rect’, ‘set’, ‘svg’, ‘switch’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘requiredFeatures’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘cursor’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘mask’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘rect’, ‘set’, ‘svg’, ‘switch’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘restart’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘result’ ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feFlood’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’, ‘feTurbulence’ ?
‘rotate’ ‘altGlyph’ ?
‘rotate’ ‘animateMotion’
‘rotate’ ‘text’ ?
‘rotate’ ‘tref’, ‘tspan’ ?
‘rx’ ‘ellipse’ ?
‘rx’ ‘rect’ ?
‘ry’ ‘ellipse’ ?
‘ry’ ‘rect’ ?
‘scale’ ‘feDisplacementMap’ ?
‘seed’ ‘feTurbulence’ ?
‘slope’ ‘font-face’
‘slope’ ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’ ?
‘spacing’ ‘textPath’ ?
‘specularConstant’ ‘feSpecularLighting’ ?
‘specularExponent’ ‘feSpecularLighting’ ?
‘specularExponent’ ‘feSpotLight’ ?
‘spreadMethod’ ‘linearGradient’ ?
‘spreadMethod’ ‘radialGradient’ ?
‘startOffset’ ‘textPath’ ?
‘stdDeviation’ ‘feGaussianBlur’ ?
‘stemh’ ‘font-face’
‘stemv’ ‘font-face’
‘stitchTiles’ ‘feTurbulence’ ?
‘strikethrough-position’ ‘font-face’
‘strikethrough-thickness’ ‘font-face’
‘string’ ‘font-face-format’
‘style’ ‘a’, ‘altGlyph’, ‘circle’, ‘clipPath’, ‘defs’, ‘desc’, ‘ellipse’, ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feFlood’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’, ‘feTurbulence’, ‘filter’, ‘font’, ‘foreignObject’, ‘g’, ‘glyph’, ‘glyphRef’, ‘image’, ‘line’, ‘linearGradient’, ‘marker’, ‘mask’, ‘missing-glyph’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘radialGradient’, ‘rect’, ‘stop’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘title’, ‘tref’, ‘tspan’, ‘use’
‘surfaceScale’ ‘feDiffuseLighting’ ?
‘surfaceScale’ ‘feSpecularLighting’ ?
‘systemLanguage’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘cursor’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘mask’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘rect’, ‘set’, ‘svg’, ‘switch’, ‘text’, ‘textPath’, ‘tref’, ‘tspan’, ‘use’
‘tableValues’ ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’ ?
‘target’ ‘a’ ?
‘targetX’ ‘feConvolveMatrix’ ?
‘targetY’ ‘feConvolveMatrix’ ?
‘textLength’ ‘text’ ?
‘textLength’ ‘textPath’, ‘tref’, ‘tspan’ ?
‘title’ ‘style’
‘to’ ‘set’
‘to’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘transform’ ‘a’, ‘circle’, ‘clipPath’, ‘defs’, ‘ellipse’, ‘foreignObject’, ‘g’, ‘image’, ‘line’, ‘path’, ‘polygon’, ‘polyline’, ‘rect’, ‘switch’, ‘text’, ‘use’ ?
‘type’ ‘animateTransform’
‘type’ ‘feColorMatrix’ ?
‘type’ ‘feTurbulence’ ?
‘type’ ‘script’
‘type’ ‘style’
‘type’ ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’ ?
‘u1’ ‘hkern’, ‘vkern’
‘u2’ ‘hkern’, ‘vkern’
‘underline-position’ ‘font-face’
‘underline-thickness’ ‘font-face’
‘unicode’ ‘glyph’
‘unicode-range’ ‘font-face’
‘units-per-em’ ‘font-face’
‘v-alphabetic’ ‘font-face’
‘v-hanging’ ‘font-face’
‘v-ideographic’ ‘font-face’
‘v-mathematical’ ‘font-face’
‘values’ ‘feColorMatrix’ ?
‘values’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’
‘version’ ‘svg’
‘vert-adv-y’ ‘font’
‘vert-adv-y’ ‘glyph’, ‘missing-glyph’
‘vert-origin-x’ ‘font’
‘vert-origin-x’ ‘glyph’, ‘missing-glyph’
‘vert-origin-y’ ‘font’
‘vert-origin-y’ ‘glyph’, ‘missing-glyph’
‘viewBox’ ‘marker’, ‘pattern’, ‘svg’, ‘symbol’, ‘view’ ?
‘viewTarget’ ‘view’
‘width’ ‘filter’ ?
‘width’ ‘foreignObject’ ?
‘width’ ‘image’ ?
‘width’ ‘pattern’ ?
‘width’ ‘rect’ ?
‘width’ ‘svg’ ?
‘width’ ‘use’ ?
‘width’ ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feFlood’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’, ‘feTurbulence’ ?
‘width’ ‘mask’ ?
‘widths’ ‘font-face’
‘x’ ‘altGlyph’ ?
‘x’ ‘cursor’ ?
‘x’ ‘fePointLight’ ?
‘x’ ‘feSpotLight’ ?
‘x’ ‘filter’ ?
‘x’ ‘foreignObject’ ?
‘x’ ‘glyphRef’
‘x’ ‘image’ ?
‘x’ ‘pattern’ ?
‘x’ ‘rect’ ?
‘x’ ‘svg’ ?
‘x’ ‘text’ ?
‘x’ ‘use’ ?
‘x’ ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feFlood’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’, ‘feTurbulence’ ?
‘x’ ‘mask’ ?
‘x’ ‘tref’, ‘tspan’ ?
‘x-height’ ‘font-face’
‘x1’ ‘line’ ?
‘x1’ ‘linearGradient’ ?
‘x2’ ‘line’ ?
‘x2’ ‘linearGradient’ ?
‘xChannelSelector’ ‘feDisplacementMap’ ?
‘xlink:actuate’ ‘a’
‘xlink:actuate’ ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘color-profile’, ‘cursor’, ‘feImage’, ‘filter’, ‘font-face-uri’, ‘glyphRef’, ‘image’, ‘mpath’, ‘pattern’, ‘script’, ‘set’, ‘use’
‘xlink:arcrole’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘color-profile’, ‘cursor’, ‘feImage’, ‘filter’, ‘font-face-uri’, ‘glyphRef’, ‘image’, ‘linearGradient’, ‘mpath’, ‘pattern’, ‘radialGradient’, ‘script’, ‘set’, ‘textPath’, ‘tref’, ‘use’
‘xlink:href’ ‘a’ ?
‘xlink:href’ ‘altGlyph’
‘xlink:href’ ‘color-profile’
‘xlink:href’ ‘cursor’ ?
‘xlink:href’ ‘feImage’ ?
‘xlink:href’ ‘filter’ ?
‘xlink:href’ ‘font-face-uri’
‘xlink:href’ ‘glyphRef’
‘xlink:href’ ‘image’ ?
‘xlink:href’ ‘linearGradient’ ?
‘xlink:href’ ‘mpath’
‘xlink:href’ ‘pattern’ ?
‘xlink:href’ ‘radialGradient’ ?
‘xlink:href’ ‘script’
‘xlink:href’ ‘textPath’ ?
‘xlink:href’ ‘use’ ?
‘xlink:href’ ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘set’
‘xlink:href’ ‘tref’ ?
‘xlink:role’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘color-profile’, ‘cursor’, ‘feImage’, ‘filter’, ‘font-face-uri’, ‘glyphRef’, ‘image’, ‘linearGradient’, ‘mpath’, ‘pattern’, ‘radialGradient’, ‘script’, ‘set’, ‘textPath’, ‘tref’, ‘use’
‘xlink:show’ ‘a’
‘xlink:show’ ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘color-profile’, ‘cursor’, ‘feImage’, ‘filter’, ‘font-face-uri’, ‘glyphRef’, ‘image’, ‘mpath’, ‘pattern’, ‘script’, ‘set’, ‘use’
‘xlink:title’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘color-profile’, ‘cursor’, ‘feImage’, ‘filter’, ‘font-face-uri’, ‘glyphRef’, ‘image’, ‘linearGradient’, ‘mpath’, ‘pattern’, ‘radialGradient’, ‘script’, ‘set’, ‘textPath’, ‘tref’, ‘use’
‘xlink:type’ ‘a’, ‘altGlyph’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘color-profile’, ‘cursor’, ‘feImage’, ‘filter’, ‘font-face-uri’, ‘glyphRef’, ‘image’, ‘linearGradient’, ‘mpath’, ‘pattern’, ‘radialGradient’, ‘script’, ‘set’, ‘textPath’, ‘tref’, ‘use’
‘xml:base’ ‘a’, ‘altGlyph’, ‘altGlyphDef’, ‘altGlyphItem’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘color-profile’, ‘cursor’, ‘defs’, ‘desc’, ‘ellipse’, ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feDistantLight’, ‘feFlood’, ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMergeNode’, ‘feMorphology’, ‘feOffset’, ‘fePointLight’, ‘feSpecularLighting’, ‘feSpotLight’, ‘feTile’, ‘feTurbulence’, ‘filter’, ‘font’, ‘font-face’, ‘font-face-format’, ‘font-face-name’, ‘font-face-src’, ‘font-face-uri’, ‘foreignObject’, ‘g’, ‘glyph’, ‘glyphRef’, ‘hkern’, ‘image’, ‘line’, ‘linearGradient’, ‘marker’, ‘mask’, ‘metadata’, ‘missing-glyph’, ‘mpath’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘radialGradient’, ‘rect’, ‘script’, ‘set’, ‘stop’, ‘style’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘title’, ‘tref’, ‘tspan’, ‘use’, ‘view’, ‘vkern’
‘xml:lang’ ‘a’, ‘altGlyph’, ‘altGlyphDef’, ‘altGlyphItem’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘color-profile’, ‘cursor’, ‘defs’, ‘desc’, ‘ellipse’, ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feDistantLight’, ‘feFlood’, ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMergeNode’, ‘feMorphology’, ‘feOffset’, ‘fePointLight’, ‘feSpecularLighting’, ‘feSpotLight’, ‘feTile’, ‘feTurbulence’, ‘filter’, ‘font’, ‘font-face’, ‘font-face-format’, ‘font-face-name’, ‘font-face-src’, ‘font-face-uri’, ‘foreignObject’, ‘g’, ‘glyph’, ‘glyphRef’, ‘hkern’, ‘image’, ‘line’, ‘linearGradient’, ‘marker’, ‘mask’, ‘metadata’, ‘missing-glyph’, ‘mpath’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘radialGradient’, ‘rect’, ‘script’, ‘set’, ‘stop’, ‘style’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘title’, ‘tref’, ‘tspan’, ‘use’, ‘view’, ‘vkern’
‘xml:space’ ‘a’, ‘altGlyph’, ‘altGlyphDef’, ‘altGlyphItem’, ‘animate’, ‘animateColor’, ‘animateMotion’, ‘animateTransform’, ‘circle’, ‘clipPath’, ‘color-profile’, ‘cursor’, ‘defs’, ‘desc’, ‘ellipse’, ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feDistantLight’, ‘feFlood’, ‘feFuncA’, ‘feFuncB’, ‘feFuncG’, ‘feFuncR’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMergeNode’, ‘feMorphology’, ‘feOffset’, ‘fePointLight’, ‘feSpecularLighting’, ‘feSpotLight’, ‘feTile’, ‘feTurbulence’, ‘filter’, ‘font’, ‘font-face’, ‘font-face-format’, ‘font-face-name’, ‘font-face-src’, ‘font-face-uri’, ‘foreignObject’, ‘g’, ‘glyph’, ‘glyphRef’, ‘hkern’, ‘image’, ‘line’, ‘linearGradient’, ‘marker’, ‘mask’, ‘metadata’, ‘missing-glyph’, ‘mpath’, ‘path’, ‘pattern’, ‘polygon’, ‘polyline’, ‘radialGradient’, ‘rect’, ‘script’, ‘set’, ‘stop’, ‘style’, ‘svg’, ‘switch’, ‘symbol’, ‘text’, ‘textPath’, ‘title’, ‘tref’, ‘tspan’, ‘use’, ‘view’, ‘vkern’
‘y’ ‘altGlyph’ ?
‘y’ ‘cursor’ ?
‘y’ ‘fePointLight’ ?
‘y’ ‘feSpotLight’ ?
‘y’ ‘filter’ ?
‘y’ ‘foreignObject’ ?
‘y’ ‘glyphRef’
‘y’ ‘image’ ?
‘y’ ‘pattern’ ?
‘y’ ‘rect’ ?
‘y’ ‘svg’ ?
‘y’ ‘text’ ?
‘y’ ‘use’ ?
‘y’ ‘feBlend’, ‘feColorMatrix’, ‘feComponentTransfer’, ‘feComposite’, ‘feConvolveMatrix’, ‘feDiffuseLighting’, ‘feDisplacementMap’, ‘feFlood’, ‘feGaussianBlur’, ‘feImage’, ‘feMerge’, ‘feMorphology’, ‘feOffset’, ‘feSpecularLighting’, ‘feTile’, ‘feTurbulence’ ?
‘y’ ‘mask’ ?
‘y’ ‘tref’, ‘tspan’ ?
‘y1’ ‘line’ ?
‘y1’ ‘linearGradient’ ?
‘y2’ ‘line’ ?
‘y2’ ‘linearGradient’ ?
‘yChannelSelector’ ‘feDisplacementMap’ ?
‘z’ ‘fePointLight’ ?
‘z’ ‘feSpotLight’ ?
‘zoomAndPan’ ‘svg’, ‘view’
END
#-----------------------------------------------------------------------
# Presentation attributes
#-----------------------------------------------------------------------
sub presentationAttributes()
{qw(alignment-baseline baseline-shift clip-path clip-rule clip color-interpolation-filters color-interpolation color-profile color-rendering color cursor direction display dominant-baseline enable-background fill-opacity fill-rule fill filter flood-color flood-opacity font-family font-size-adjust font-size font-stretch font-style font-variant font-weight glyph-orientation-horizontal glyph-orientation-vertical image-rendering kerning letter-spacing lighting-color marker-end marker-mid marker-start mask opacity overflow pointer-events shape-rendering stop-color stop-opacity stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width stroke text-anchor text-decoration text-rendering unicode-bidi visibility word-spacing writing-mode)
}
#-----------------------------------------------------------------------
# Elements which accept presentation attributes
#-----------------------------------------------------------------------
sub presentationElements()
{qw(a altGlyph animate animateColor circle clipPath defs ellipse feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feFlood feGaussianBlur feImage feMerge feMorphology feOffset feSpecularLighting feTile feTurbulence filter font foreignObject g glyph glyphRef image line linearGradient marker mask missing-glyph path pattern polygon polyline radialGradient rect stop svg switch symbol text textPath tref tspan use)
}
-
1\$\begingroup\$ Why do you want to parse SVG (XML) in Perl? Also: search.cpan.org/~msergeant/XML-Parser-2.36/Parser.pm \$\endgroup\$Dave Jarvis– Dave Jarvis2013年09月11日 20:03:41 +00:00Commented Sep 11, 2013 at 20:03
-
\$\begingroup\$ I am reopening this question, again, because it is not a duplciate of this question \$\endgroup\$rolfl– rolfl2015年07月11日 15:53:05 +00:00Commented Jul 11, 2015 at 15:53
1 Answer 1
Houston, we have a problem. I'm going to be blunt, not because I enjoy saying mean things to fellow programmers, but because there really isn't any way to sugar-coat it. This is unintentionally obfuscated Perl, the kind that gives the language a bad reputation.
Before continuing, I'd like to ask, What is the purpose of this code?
- If you want an SVG validator, consider using some standard XML DTD or schema validation tools. (XML validation is a solved problem; don't reinvent the wheel.)
- Do you want the resulting data structure to be used in, say, an SVG authoring tool? If that's the case, your question is about how to best represent a complex data structure as a Perl code literal.
- Are you doing this as an exercise in transforming the original W3C specification document into a more useful data structure? In that case, your question is mainly about screen scraping or text processing.
A key contributing factor to the unreadability of your code is naming. You have...
$a
,$e
$A
,$E
($E
is used twice in the global scope.$A
is used inside your firstfor
loop as a boolean meaning "animatable", then as an iteration dummy variable for presentation attributes, then as a hashref to a data structure for all attributes.)cc()
data()
It's not 1960, where every byte counts. Just saying camelCase()
instead of cc()
would help reduce mental workload. Short, cryptic variable names should only be used as iteration dummy variables in simple loops where it is absolutely obvious what it means. Your code doesn't qualify for that.
Let's assume your motivation is (3). Your for
loop desperately needs a comment — not a two-line comment, but an essay. Something like...
# Process the W3C SVG 1.1 Spec, Appendix M (Attribute Index)
# http://www.w3.org/TR/2011/REC-SVG11-20110816/attindex.html
# into two data structures, $a and $e.
#
# Each line of the input contains:
# Attribute-name (first word)
# Elements on which the attribute may be specified (subsequent words)
# '?' as the last word if the attribute is animatable
#
# The resulting data structure $a is a hashref whose keys are ...
# and whose values are ...
#
# The resulting data structure $e is a hashref whose keys are ...
# and whose values are ...
Instead of a here-doc string, try putting your data at the end of your code, after a __DATA__
marker, and reading from the <DATA>
filehandle.
If, on the other hand, your motivation is (2), then I would suggest a different approach altogether. I would encode the data structure as
$regular_attributes = {
non_anim('accent-height') => [qw(font-face)],
non_anim('accumulate') => [qw(animate animateColor animateMotion animateTransform)],
non_anim('additive') => [qw(animate animateColor animateMotion animateTransform)],
non_anim('alphabetic') => [qw(font-face)],
anim('amplitude') => [qw(feFuncA feFuncB feFuncG feFuncR)],
# etc...
};
Alternatively, you could write it as a YAML data structure inside your __DATA__
section, then load it using a YAML parser. One useful feature of YAML is that it supports multiple streams, so you can have several YAML documents in your __DATA__
section. Another nice feature is that it lets you mark and reference previously mentioned chunks of data:
__DATA__
accent-height:
anim: false
elements:
- font-face
accumulate:
anim: false
elements: &animElements
- animate
- animateColor
- animateMotion
- animateTransform
additive:
anim: false
elements: *animElements
# etc...