feat: referentiel projets dynamique + validation nommage by design

Durcit la convention de nommage des projets (dérive constatée : 'Sliding
Automation', 'code_versioning'... au lieu des formes canoniques).

- trilium_api.py : projets_canoniques() lit le référentiel = valeurs du label
  projet sur les notes de type=projet (source unique, pas de constante en dur).
  Note-projet CodeVersioning créée (manquait).
- mcp_server.py : _valider_projet() branché dans les 6 tools de création
  (add_decision/history/backlog, new_conversation, create_entite, add_skill).
  Refuse un projet non canonique (suggestion si faute) ou inconnu (renvoi au
  processus de création de projet). Ne verrouille pas si référentiel illisible.
- lint_audit.py : VAL-nommage aligné sur le référentiel (attrape casse, espace
  ET snake_case ; l'ancien 'contient un espace' ratait code_versioning).
- Données : 79 notes ré-étiquetées vers les 3 formes canoniques.

Quality by design : l'erreur de nommage devient impossible à l'écriture, le
Lint n'est plus que le filet de sécurité.
This commit is contained in:
2026-07-17 14:59:33 +02:00
parent d1e67431b6
commit 943acbc573
2425 changed files with 710525 additions and 6 deletions
@@ -0,0 +1,156 @@
#!/usr/bin/env python
#coding:utf-8
# Author: mozman --<mozman@gmx.at>
# Purpose: colornames
# Created: 06.10.2010
# Copyright (C) 2010, Manfred Moitzi
# License: MIT License
colornames = frozenset([
'aliceblue',
'antiquewhite',
'aqua',
'aquamarine',
'azure',
'beige',
'bisque',
'black',
'blanchedalmond',
'blue',
'blueviolet',
'brown',
'burlywood',
'cadetblue',
'chartreuse',
'chocolate',
'coral',
'cornflowerblue',
'cornsilk',
'crimson',
'cyan',
'darkblue',
'darkcyan',
'darkgoldenrod',
'darkgray',
'darkgreen',
'darkgrey',
'darkkhaki',
'darkmagenta',
'darkolivegreen',
'darkorange',
'darkorchid',
'darkred',
'darksalmon',
'darkseagreen',
'darkslateblue',
'darkslategray',
'darkslategrey',
'darkturquoise',
'darkviolet',
'deeppink',
'deepskyblue',
'dimgray',
'dimgrey',
'dodgerblue',
'firebrick',
'floralwhite',
'forestgreen',
'fuchsia',
'gainsboro',
'ghostwhite',
'gold',
'goldenrod',
'gray',
'green',
'greenyellow',
'grey',
'honeydew',
'hotpink',
'indianred',
'indigo',
'ivory',
'khaki',
'lavender',
'lavenderblush',
'lawngreen',
'lemonchiffon',
'lightblue',
'lightcoral',
'lightcyan',
'lightgoldenrodyellow',
'lightgray',
'lightgreen',
'lightgrey',
'lightpink',
'lightsalmon',
'lightseagreen',
'lightskyblue',
'lightslategray',
'lightslategrey',
'lightsteelblue',
'lightyellow',
'lime',
'limegreen',
'linen',
'magenta',
'maroon',
'mediumaquamarine',
'mediumblue',
'mediumorchid',
'mediumpurple',
'mediumseagreen',
'mediumslateblue',
'mediumspringgreen',
'mediumturquoise',
'mediumvioletred',
'midnightblue',
'mintcream',
'mistyrose',
'moccasin',
'navajowhite',
'navy',
'oldlace',
'olive',
'olivedrab',
'orange',
'orangered',
'orchid',
'palegoldenrod',
'palegreen',
'paleturquoise',
'palevioletred',
'papayawhip',
'peachpuff',
'peru',
'pink',
'plum',
'powderblue',
'purple',
'red',
'rosybrown',
'royalblue',
'saddlebrown',
'salmon',
'sandybrown',
'seagreen',
'seashell',
'sienna',
'silver',
'skyblue',
'slateblue',
'slategray',
'slategrey',
'snow',
'springgreen',
'steelblue',
'tan',
'teal',
'thistle',
'tomato',
'turquoise',
'violet',
'wheat',
'white',
'whitesmoke',
'yellow',
'yellowgreen',])
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,30 @@
#!/usr/bin/env python
#coding:utf-8
# Author: mozman --<mozman@gmx.at>
# Purpose: pattern module
# Created: 27.09.2010
# Copyright (C) 2010, Manfred Moitzi
# License: MIT License
import re
#coordinate ::= number ("em" | "ex" | "px" | "in" | "cm" | "mm" | "pt" | "pc" | "%")?
coordinate = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(cm|em|ex|in|mm|pc|pt|px|%)?$")
#length ::= number ("em" | "ex" | "px" | "in" | "cm" | "mm" | "pt" | "pc" | "%")?
length = coordinate
#angle ::= number (~"deg" | ~"grad" | ~"rad")?
angle = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(deg|rad|grad)?$")
# numbers without units
number = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)$")
# number as percentage value '###%'
percentage = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)%$")
#frequency ::= number (~"Hz" | ~"kHz")
frequency = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(Hz|kHz)?$")
#time ::= number (~"s" | ~"ms")
time = re.compile(r"(^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(s|ms)?$")
@@ -0,0 +1,132 @@
#!/usr/bin/env python
# coding:utf-8
# Authors: mozman <me@mozman.at>, Florian Festi
# Purpose: svgparser using re module
# Created: 16.10.2010
# Copyright (c) 2010, Manfred Moitzi & 2020, Florian Festi
# License: MIT License
__all__ = ["is_valid_transferlist", "is_valid_pathdata", "is_valid_animation_timing"]
import re
event_names = [
"focusin", "focusout", "activate", "click", "mousedown", "mouseup", "mouseover",
"mousemove", "mouseout", "DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
"DOMNodeRemovedFromDocument", "DOMNodeInsertedtoDocument", "DOMAttrModified",
"DOMCharacterDataModified", "SVGLoad", "SVGUnload", "SVGAbort", "SVGError",
"SVGResize", "SVGScroll", "SVGZoom", "beginEvent", "endEvent", "repeatEvent",
]
c = r"\s*[, ]\s*"
s = r"\s*[; ]\s*"
integer_constant = r"\d+"
exponent = r"([eE][+-]?\d+)"
nonnegative_number = fr"(\d+\.?\d*|\.\d+){exponent}?"
number = r"[+-]?" + nonnegative_number
flag = r"[01]"
comma_delimited_coordinates = fr"\s*{number}({c}{number})*\s*"
two_comma_delimited_numbers = fr"\s*{number}({c}{number}\s*)" "{1}"
four_comma_delimited_numbers = fr"\s*{number}\s*({c}{number}\s*)" "{3}"
six_comma_delimited_numbers = fr"\s*{number}\s*({c}{number}\s*)" "{5}"
comma_delimited_coordinate_pairs = fr"{two_comma_delimited_numbers}({c}{two_comma_delimited_numbers})*"
def is_valid(regex):
reg = re.compile(regex)
def f(term):
return bool(reg.fullmatch(term))
return f
def build_transferlist_parser():
matrix = fr"matrix\s*\(\s*{six_comma_delimited_numbers}\s*\)"
translate = fr"translate\s*\(\s*{number}({c}{number})?\s*\)"
scale = fr"scale\s*\(\s*{number}({c}{number})?\s*\)"
rotate = fr"rotate\s*\(\s*{number}({c}{number}{c}{number})?\s*\)"
skewX = fr"skewX\s*\(\s*{number}\s*\)"
skewY = fr"skewY\s*\(\s*{number}\s*\)"
tl_re = "|".join((fr"(\s*{cmd}\s*)" for cmd in (
matrix, translate, scale, rotate, skewX, skewY)))
return fr"({tl_re})({c}({tl_re}))*"
is_valid_transferlist = is_valid(build_transferlist_parser())
def build_pathdata_parser():
moveto = fr"[mM]\s*{comma_delimited_coordinate_pairs}"
lineto = fr"[lL]\s*{comma_delimited_coordinate_pairs}"
horizontal_lineto = fr"[hH]\s*{comma_delimited_coordinates}"
vertical_lineto = fr"[vV]\s*{comma_delimited_coordinates}"
curveto = fr"[cC]\s*({six_comma_delimited_numbers})({c}{six_comma_delimited_numbers})*"
smooth_curveto = fr"[sS]{four_comma_delimited_numbers}({c}{four_comma_delimited_numbers})*"
quadratic_bezier_curveto = fr"[qQ]{four_comma_delimited_numbers}({c}{four_comma_delimited_numbers})*"
smooth_quadratic_bezier_curveto = fr"[tT]\s*{comma_delimited_coordinate_pairs}"
elliptical_arc_argument = fr"{c}".join((
fr"{nonnegative_number}",
fr"{nonnegative_number}",
fr"{number}",
fr"{flag}",
fr"{flag}",
fr"{number}",
fr"{number}",))
elliptical_arc_argument = r"\s*" + elliptical_arc_argument + r"\s*"
elliptical_arc = fr"[aA]({elliptical_arc_argument})({c}{elliptical_arc_argument})*"
drawto_command = "|".join((fr"(\s*{cmd}\s*)" for cmd in (
moveto, lineto, horizontal_lineto, vertical_lineto, "[zZ]",
curveto, smooth_curveto, quadratic_bezier_curveto,
smooth_quadratic_bezier_curveto, elliptical_arc)))
return f"{moveto}({drawto_command})*"
is_valid_pathdata = is_valid(build_pathdata_parser())
digit2 = r"\d{2}"
digit4 = r"\d{4}"
seconds = fr"\d+(\.\d+)?"
seconds2 = fr"{digit2}(\.\d+)?"
metric = "(h|min|s|ms)"
def clock_val_re():
timecount_val = fr"{seconds}\s*({metric})?"
clock_val = fr"{digit2}:({digit2}:)?{seconds2}"
return fr"({timecount_val}|{clock_val})"
def wall_clock_val_re():
hhmmss = fr"{digit2}:{digit2}(:{seconds2})?"
walltime = fr"{hhmmss}(Z|[+-]?{digit2}:{digit2})?"
date = fr"{digit4}-{digit2}-{digit2}"
datetime = fr"{date}(T{walltime})?"
return "(" + "|".join((walltime, datetime)) + ")"
def build_animation_timing_parser():
clock_val = clock_val_re()
wallclock_val = wall_clock_val_re()
event_ref = "(" + "|".join(event_names) + ")"
id_value = "#?[-_a-zA-Z0-9]+"
wallclock_sync_value = fr"wallclock\(\s*{wallclock_val}\s*\)"
accesskey_value = fr"accessKey\(\s*[a-zA-Z]\s*\)\s*([+-]?{clock_val})?"
repeat_value = fr"({id_value}\.)?repeat\s*\(\s*\d+\s*\)\s*([+-?]{clock_val})?"
event_value = fr"({id_value}\.)?{event_ref}([+-]?{clock_val})?"
offset_value = fr"[-+]?{clock_val}"
syncbase_value = fr"{id_value}\.(begin|end)({offset_value})?"
begin_value = "(" + "|".join((f"({reg})" for reg in (
offset_value, syncbase_value, event_value, repeat_value,
accesskey_value, wallclock_sync_value, "indefinite"))) + ")"
return fr"{begin_value}({s}{begin_value})*"
is_valid_animation_timing = is_valid(build_animation_timing_parser())
@@ -0,0 +1,966 @@
#!/usr/bin/env python
#coding:utf-8
# Author: mozman --<mozman@gmx.at>
# Purpose: tiny12 data
# Created: 15.10.2010
# Copyright (C) 2010, Manfred Moitzi
# License: MIT License
from svgwrite.data.types import SVGAttribute, SVGMultiAttribute
from svgwrite.data.types import SVGElement
from svgwrite.data.typechecker import Tiny12TypeChecker as TypeChecker
empty_list = []
attributes = {
'about': SVGAttribute('about', anim=True,
types=frozenset(['string']),
const=empty_list),
'accent-height': SVGAttribute('accent-height', anim=False,
types=frozenset(['number']),
const=empty_list),
'accumulate': SVGAttribute('accumulate', anim=False,
types=empty_list,
const=frozenset(['none', 'sum'])),
'additive': SVGAttribute('additive', anim=False,
types=empty_list,
const=frozenset(['replace', 'sum'])),
'alphabetic': SVGAttribute('alphabetic', anim=False,
types=frozenset(['number']),
const=empty_list),
'arabic-form': SVGAttribute('arabic-form', anim=False,
types=empty_list,
const=frozenset(['terminal', 'initial', 'isolated', 'medial'])),
'ascent': SVGAttribute('ascent', anim=False,
types=frozenset(['number']),
const=empty_list),
'attributeName': SVGAttribute('attributeName', anim=False,
types=frozenset(['name']),
const=empty_list),
'attributeType': SVGAttribute('attributeType', anim=False,
types=empty_list,
const=frozenset(['XML', 'CSS', 'auto'])),
'audio-level': SVGAttribute('audio-level', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'bandwidth': SVGAttribute('bandwidth', anim=False,
types=frozenset(['number']),
const=frozenset(['auto'])),
'baseProfile': SVGAttribute('baseProfile', anim=False,
types=empty_list,
const=frozenset(['none', 'tiny', 'basic', 'full'])),
'bbox': SVGAttribute('bbox', anim=False,
types=frozenset(['string']),
const=empty_list),
'begin': SVGAttribute('begin', anim=False,
types=frozenset(['timing-value-list']),
const=frozenset(['indefinite'])),
'buffered-rendering': SVGAttribute('buffered-rendering', anim=True,
types=empty_list,
const=frozenset(['auto', 'dynamic', 'static', 'inherit'])),
'by': SVGAttribute('by', anim=False,
types=frozenset(['string']),
const=empty_list),
'calcMode': SVGAttribute('calcMode', anim=False,
types=empty_list,
const=frozenset(['discrete', 'linear', 'paced', 'spline'])),
'cap-height': SVGAttribute('cap-height', anim=False,
types=frozenset(['number']),
const=empty_list),
'class': SVGAttribute('class', anim=True,
types=frozenset(['list-of-name']),
const=empty_list),
'color': SVGAttribute('color', anim=True,
types=frozenset(['color']),
const=frozenset(['inherit'])),
'color-rendering': SVGAttribute('color-rendering', anim=True,
types=empty_list,
const=frozenset(['auto', 'optimizeSpeed', 'optimizeQuality', 'inherit'])),
'content': SVGAttribute('content', anim=True,
types=frozenset(['string']),
const=empty_list),
'contentScriptType': SVGAttribute('contentScriptType', anim=False,
types=frozenset(['content-type']),
const=empty_list),
'cx': SVGAttribute('cx', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'cy': SVGAttribute('cy', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'd': SVGAttribute('d', anim=True,
types=frozenset(['path-data']),
const=empty_list),
'datatype': SVGAttribute('datatype', anim=True,
types=frozenset(['string']),
const=empty_list),
'defaultAction': SVGAttribute('defaultAction', anim=False,
types=empty_list,
const=frozenset(['perform', 'cancel'])),
'descent': SVGAttribute('descent', anim=False,
types=frozenset(['number']),
const=empty_list),
'direction': SVGAttribute('direction', anim=False,
types=empty_list,
const=frozenset(['ltr', 'rtl', 'inherit'])),
'display': SVGAttribute('display', anim=True,
types=empty_list,
const=frozenset(['inline', 'block', 'list-item', 'run-in', 'compact',
'marker', 'table', 'inline-table', 'table-row-group',
'table-header-group', 'table-footer-group', 'table-row',
'table-column-group', 'table-column', 'table-cell',
'table-caption', 'none', 'inherit'])),
'display-align': SVGAttribute('display-align', anim=True,
types=empty_list,
const=frozenset(['auto', 'before', 'center', 'after', 'inherit'])),
'dur': SVGAttribute('dur', anim=False,
types=frozenset(['time']),
const=frozenset(['media', 'indefinite'])),
'editable': SVGAttribute('editable', anim=True,
types=empty_list,
const=frozenset(['none', 'simple'])),
'end': SVGAttribute('end', anim=False,
types=frozenset(['timing-value-list']),
const=frozenset(['indefinite'])),
'ev:event': SVGAttribute('ev:event', anim=False,
types=frozenset(['XML-Name']),
const=empty_list),
'event': SVGAttribute('event', anim=False,
types=frozenset(['XML-Name']),
const=empty_list),
'externalResourcesRequired': SVGAttribute('externalResourcesRequired', anim=False,
types=frozenset(['boolean']),
const=empty_list),
'fill': SVGMultiAttribute({
'*': SVGAttribute(
'fill', anim=True,
types=frozenset(['paint']),
const=frozenset(['inherit'])),
'set animateMotion animate animateColor animateTransform': SVGAttribute(
'fill', anim=False,
types=empty_list,
const=frozenset(['freeze', 'remove']))
}),
'fill-opacity': SVGAttribute('fill-opacity', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'fill-rule': SVGAttribute('fill-rule', anim=True,
types=empty_list,
const=frozenset(['nonzero', 'evenodd', 'inherit'])),
'focusHighlight': SVGAttribute('focusHighlight', anim=True,
types=empty_list,
const=frozenset(['auto', 'none'])),
'focusable': SVGAttribute('focusable', anim=True,
types=frozenset(['boolean']),
const=frozenset(['auto'])),
'font-family': SVGAttribute('font-family', anim=True,
types=frozenset(['string']),
const=frozenset(['inherit'])),
'font-size': SVGAttribute('font-size', anim=True,
types=frozenset(['length']),
const=frozenset(['inherit'])),
'font-stretch': SVGAttribute('font-stretch', anim=False,
types=empty_list,
const=frozenset(['condensed', 'normal', 'ultra-condensed', 'expanded',
'narrower', 'inherit', 'semi-condensed', 'extra-condensed',
'ultra-expanded', 'wider', 'semi-expanded', 'extra-expanded'])),
'font-style': SVGAttribute('font-style', anim=True,
types=empty_list,
const=frozenset(['normal', 'italic', 'oblique', 'inherit'])),
'font-variant': SVGAttribute('font-variant', anim=True,
types=empty_list,
const=frozenset(['normal', 'small-caps', 'inherit'])),
'font-weight': SVGAttribute('font-weight', anim=True,
types=empty_list,
const=frozenset(['normal', 'bold', 'bolder', 'lighter', '100', '200',
'300', '400', '500', '600', '700', '800', '900',
'inherit'])),
'from': SVGAttribute('from', anim=False,
types=frozenset(['string']),
const=empty_list),
'g1': SVGAttribute('g1', anim=False,
types=frozenset(['list-of-name']),
const=empty_list),
'g2': SVGAttribute('g2', anim=False,
types=frozenset(['list-of-name']),
const=empty_list),
'glyph-name': SVGAttribute('glyph-name', anim=False,
types=frozenset(['list-of-name']),
const=empty_list),
'gradientUnits': SVGAttribute('gradientUnits', anim=True,
types=empty_list,
const=frozenset(['userSpaceOnUse', 'objectBoundingBox'])),
'handler': SVGAttribute('handler', anim=False,
types=frozenset(['IRI']),
const=empty_list),
'hanging': SVGAttribute('hanging', anim=False,
types=frozenset(['number']),
const=empty_list),
'height': SVGMultiAttribute({
'*': SVGAttribute(
'height', anim=True,
types=frozenset(['length']),
const=empty_list),
'textArea': SVGAttribute(
'height', anim=True,
types=frozenset(['length']),
const=frozenset(['auto'])),
}),
'horiz-adv-x': SVGAttribute('horiz-adv-x', anim=False,
types=frozenset(['number']),
const=empty_list),
'horiz-origin-x': SVGAttribute('horiz-origin-x', anim=False,
types=frozenset(['number']),
const=empty_list),
'id': SVGAttribute('id', anim=False,
types=frozenset(['name']),
const=empty_list),
'ideographic': SVGAttribute('ideographic', anim=False,
types=frozenset(['number']),
const=empty_list),
'image-rendering': SVGAttribute('image-rendering', anim=True,
types=empty_list,
const=frozenset(['auto', 'optimizeSpeed', 'optimizeQuality', 'inherit'])),
'initialVisibility': SVGAttribute('initialVisibility', anim=False,
types=empty_list,
const=frozenset(['whenStarted', 'always'])),
'k': SVGAttribute('k', anim=False,
types=frozenset(['number']),
const=empty_list),
'keyPoints': SVGAttribute('keyPoints', anim=False,
types=frozenset(['semicolon-list']),
const=empty_list),
'keySplines': SVGAttribute('keySplines', anim=False,
types=frozenset(['semicolon-list']),
const=empty_list),
'keyTimes': SVGAttribute('keyTimes', anim=False,
types=frozenset(['semicolon-list']),
const=empty_list),
'lang': SVGAttribute('lang', anim=False,
types=frozenset(['list-of-name']),
const=empty_list),
'line-increment': SVGAttribute('line-increment', anim=True,
types=frozenset(['number']),
const=frozenset(['auto', 'inherit'])),
'mathematical': SVGAttribute('mathematical', anim=False,
types=frozenset(['number']),
const=empty_list),
'max': SVGAttribute('max', anim=False,
types=frozenset(['time']),
const=frozenset(['media'])),
'mediaCharacterEncoding': SVGAttribute('mediaCharacterEncoding', anim=False,
types=frozenset(['string']),
const=empty_list),
'mediaContentEncodings': SVGAttribute('mediaContentEncodings', anim=False,
types=frozenset(['string']),
const=empty_list),
'mediaSize': SVGAttribute('mediaSize', anim=False,
types=frozenset(['number']),
const=empty_list),
'mediaTime': SVGAttribute('mediaTime', anim=False,
types=frozenset(['time']),
const=empty_list),
'min': SVGAttribute('min', anim=False,
types=frozenset(['time']),
const=frozenset(['media'])),
'nav-down': SVGAttribute('nav-down', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-down-left': SVGAttribute('nav-down-left', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-down-right': SVGAttribute('nav-down-right', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-left': SVGAttribute('nav-left', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-next': SVGAttribute('nav-next', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-prev': SVGAttribute('nav-prev', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-right': SVGAttribute('nav-right', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-up': SVGAttribute('nav-up', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-up-left': SVGAttribute('nav-up-left', anim=True,
types=frozenset(['focus']),
const=empty_list),
'nav-up-right': SVGAttribute('nav-up-right', anim=True,
types=frozenset(['focus']),
const=empty_list),
'observer': SVGAttribute('observer', anim=False,
types=frozenset(['IDREF']),
const=empty_list),
'offset': SVGAttribute('offset', anim=True,
types=frozenset(['number']),
const=empty_list),
'opacity': SVGAttribute('opacity', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'origin': SVGAttribute('origin', anim=False,
types=empty_list,
const=frozenset(['default'])),
'overlay': SVGAttribute('overlay', anim=False,
types=empty_list,
const=frozenset(['none', 'top'])),
'overline-position': SVGAttribute('overline-position', anim=False,
types=frozenset(['number']),
const=empty_list),
'overline-thickness': SVGAttribute('overline-thickness', anim=False,
types=frozenset(['number']),
const=empty_list),
'panose-1': SVGAttribute('panose-1', anim=False,
types=frozenset(['list-of-integer']),
const=empty_list),
'path': SVGAttribute('path', anim=False,
types=frozenset(['path-data']),
const=empty_list),
'pathLength': SVGAttribute('pathLength', anim=True,
types=frozenset(['number']),
const=empty_list),
'phase': SVGAttribute('phase', anim=False,
types=empty_list,
const=frozenset(['default', 'capture'])),
'playbackOrder': SVGAttribute('playbackOrder', anim=False,
types=empty_list,
const=frozenset(['all', 'forwardOnly'])),
'pointer-events': SVGAttribute('pointer-events', anim=True,
types=empty_list,
const=frozenset(['visiblePainted', 'visibleFill', 'visibleStroke', 'visible',
'painted', 'fill', 'stroke', 'all', 'none', 'inherit'])),
'points': SVGAttribute('points', anim=True,
types=frozenset(['list-of-number']),
const=empty_list),
'preserveAspectRatio': SVGAttribute('preserveAspectRatio', anim=True,
types=frozenset(['string']),
const=empty_list),
'propagate': SVGAttribute('propagate', anim=False,
types=empty_list,
const=frozenset(['continue', 'stop'])),
'property': SVGAttribute('property', anim=True,
types=frozenset(['string']),
const=empty_list),
'r': SVGAttribute('r', anim=True,
types=frozenset(['length']),
const=empty_list),
'rel': SVGAttribute('rel', anim=True,
types=frozenset(['string']),
const=empty_list),
'repeatCount': SVGAttribute('repeatCount', anim=False,
types=frozenset(['number']),
const=frozenset(['indefinite'])),
'repeatDur': SVGAttribute('repeatDur', anim=False,
types=frozenset(['time']),
const=frozenset(['indefinite'])),
'requiredExtensions': SVGAttribute('requiredExtensions', anim=False,
types=frozenset(['list-of-IRI']),
const=empty_list),
'requiredFeatures': SVGAttribute('requiredFeatures', anim=False,
types=frozenset(['list-of-IRI']),
const=empty_list),
'requiredFonts': SVGAttribute('requiredFonts', anim=False,
types=frozenset(['string']),
const=empty_list),
'requiredFormats': SVGAttribute('requiredFormats', anim=False,
types=frozenset(['anything']),
const=empty_list),
'resource': SVGAttribute('resource', anim=True,
types=frozenset(['string']),
const=empty_list),
'restart': SVGAttribute('restart', anim=False,
types=empty_list,
const=frozenset(['always', 'never', 'whenNotActive'])),
'rev': SVGAttribute('rev', anim=True,
types=frozenset(['string']),
const=empty_list),
'role': SVGAttribute('role', anim=True,
types=frozenset(['string']),
const=empty_list),
'rotate': SVGAttribute('rotate', anim=True,
types=frozenset(['list-of-number']),
const=empty_list),
'rx': SVGAttribute('rx', anim=True,
types=frozenset(['length']),
const=empty_list),
'ry': SVGAttribute('ry', anim=True,
types=frozenset(['length']),
const=empty_list),
'shape-rendering': SVGAttribute('shape-rendering', anim=True,
types=empty_list,
const=frozenset(['auto', 'optimizeSpeed', 'crispEdges', 'geometricPrecision', 'inherit'])),
'slope': SVGAttribute('slope', anim=False,
types=frozenset(['number']),
const=empty_list),
'snapshotTime': SVGAttribute('snapshotTime', anim=False,
types=frozenset(['time']),
const=frozenset(['none'])),
'solid-color': SVGAttribute('solid-color', anim=True,
types=frozenset(['color']),
const=frozenset(['currentColor', 'inherit'])),
'solid-opacity': SVGAttribute('solid-opacity', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'stemh': SVGAttribute('stemh', anim=False,
types=frozenset(['number']),
const=empty_list),
'stemv': SVGAttribute('stemv', anim=False,
types=frozenset(['number']),
const=empty_list),
'stop-color': SVGAttribute('stop-color', anim=True,
types=frozenset(['color']),
const=frozenset(['inherit'])),
'stop-opacity': SVGAttribute('stop-opacity', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'strikethrough-position': SVGAttribute('strikethrough-position', anim=False,
types=frozenset(['number']),
const=empty_list),
'strikethrough-thickness': SVGAttribute('strikethrough-thickness', anim=False,
types=frozenset(['number']),
const=empty_list),
'stroke': SVGAttribute('stroke', anim=True,
types=frozenset(['paint']),
const=frozenset(['inherit'])),
'stroke-dasharray': SVGAttribute('stroke-dasharray', anim=True,
types=frozenset(['list-of-length']),
const=frozenset(['none', 'inherit'])),
'stroke-dashoffset': SVGAttribute('stroke-dashoffset', anim=True,
types=frozenset(['length']),
const=frozenset(['inherit'])),
'stroke-linecap': SVGAttribute('stroke-linecap', anim=True,
types=empty_list,
const=frozenset(['butt', 'round', 'square', 'inherit'])),
'stroke-linejoin': SVGAttribute('stroke-linejoin', anim=True,
types=empty_list,
const=frozenset(['miter', 'round', 'bevel', 'inherit'])),
'stroke-miterlimit': SVGAttribute('stroke-miterlimit', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'stroke-opacity': SVGAttribute('stroke-opacity', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'stroke-width': SVGAttribute('stroke-width', anim=True,
types=frozenset(['length']),
const=frozenset(['inherit'])),
'syncBehavior': SVGAttribute('syncBehavior', anim=False,
types=empty_list,
const=frozenset(['canSlip', 'locked', 'independent', 'default'])),
'syncBehaviorDefault': SVGAttribute('syncBehaviorDefault', anim=False,
types=empty_list,
const=frozenset(['canSlip', 'locked', 'independent', 'inherit'])),
'syncMaster': SVGAttribute('syncMaster', anim=False,
types=frozenset(['boolean']),
const=empty_list),
'syncTolerance': SVGAttribute('syncTolerance', anim=False,
types=frozenset(['time']),
const=frozenset(['default'])),
'syncToleranceDefault': SVGAttribute('syncToleranceDefault', anim=False,
types=frozenset(['time']),
const=frozenset(['inherit'])),
'systemLanguage': SVGAttribute('systemLanguage', anim=False,
types=frozenset(['string']),
const=empty_list),
'target': SVGMultiAttribute({
'* a': SVGAttribute(
'target', anim=True,
types=frozenset(['XML-Name']),
const=frozenset(['_replace', '_self', '_parent', '_top', '_blank'])),
'listener': SVGAttribute(
'target', anim=False,
types=frozenset(['XML-Name']),
const=empty_list),
}),
'text-align': SVGAttribute('text-align', anim=True,
types=empty_list,
const=frozenset(['start', 'center', 'end', 'inherit'])),
'text-anchor': SVGAttribute('text-anchor', anim=True,
types=empty_list,
const=frozenset(['start', 'middle', 'end', 'inherit'])),
'text-rendering': SVGAttribute('text-rendering', anim=True,
types=empty_list,
const=frozenset(['auto', 'optimizeSpeed', 'optimizeLegibility', 'geometricPrecision', 'inherit'])),
'timelineBegin': SVGAttribute('timelineBegin', anim=False,
types=empty_list,
const=frozenset(['onLoad', 'onStart'])),
'to': SVGAttribute('to', anim=False,
types=frozenset(['string']),
const=empty_list),
'transform': SVGAttribute('transform', anim=True,
types=frozenset(['transform-list']),
const=frozenset(['none'])),
'transformBehavior': SVGAttribute('transformBehavior', anim=False,
types=empty_list,
const=frozenset(['geometric', 'pinned', 'pinned90', 'pinned180', 'pinned270'])),
'type': SVGMultiAttribute({
'* audio image video': SVGAttribute(
'type', anim=True,
types=frozenset(['content-type']),
const=empty_list),
'handler script': SVGAttribute(
'type', anim=False,
types=frozenset(['content-type']),
const=empty_list),
'animateTransform': SVGAttribute(
'type', anim=False,
types=empty_list,
const=frozenset(['translate', 'scale', 'rotate', 'skewX', 'skewY'])),
}),
'typeof': SVGAttribute('typeof', anim=True,
types=frozenset(['string']),
const=empty_list),
'u1': SVGAttribute('u1', anim=False,
types=frozenset(['string']),
const=empty_list),
'u2': SVGAttribute('u2', anim=False,
types=frozenset(['string']),
const=empty_list),
'underline-position': SVGAttribute('underline-position', anim=False,
types=frozenset(['number']),
const=empty_list),
'underline-thickness': SVGAttribute('underline-thickness', anim=False,
types=frozenset(['number']),
const=empty_list),
'unicode': SVGAttribute('unicode', anim=False,
types=frozenset(['string']),
const=empty_list),
'unicode-bidi': SVGAttribute('unicode-bidi', anim=False,
types=empty_list,
const=frozenset(['normal', 'embed', 'bidi-override', 'inherit'])),
'unicode-range': SVGAttribute('unicode-range', anim=False,
types=frozenset(['string']),
const=empty_list),
'units-per-em': SVGAttribute('units-per-em', anim=False,
types=frozenset(['number']),
const=empty_list),
'values': SVGAttribute('values', anim=False,
types=frozenset(['list-of-number']),
const=empty_list),
'vector-effect': SVGAttribute('vector-effect', anim=True,
types=empty_list,
const=frozenset(['none', 'non-scaling-stroke', 'inherit'])),
'version': SVGAttribute('version', anim=False,
types=empty_list,
const=frozenset(['1.1', '1.2'])),
'viewBox': SVGAttribute('viewBox', anim=True,
types=frozenset(['four-numbers']),
const=empty_list),
'viewport-fill': SVGAttribute('viewport-fill', anim=True,
types=frozenset(['color']),
const=frozenset(['none', 'inherit'])),
'viewport-fill-opacity': SVGAttribute('viewport-fill-opacity', anim=True,
types=frozenset(['number']),
const=frozenset(['inherit'])),
'visibility': SVGAttribute('visibility', anim=True,
types=empty_list,
const=frozenset(['visible', 'hidden', 'inherit'])),
'width': SVGMultiAttribute({
'*': SVGAttribute(
'width', anim=True,
types=frozenset(['length']),
const=empty_list),
'textArea': SVGAttribute(
'width', anim=True,
types=frozenset(['length']),
const=frozenset(['auto'])),
}),
'widths': SVGAttribute('widths', anim=False,
types=frozenset(['string']),
const=empty_list),
'x': SVGMultiAttribute({
'*': SVGAttribute(
'x', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'text': SVGAttribute(
'x', anim=True,
types=frozenset(['list-of-coordinate']),
const=empty_list),
}),
'x-height': SVGAttribute('x-height', anim=False,
types=frozenset(['number']),
const=empty_list),
'x1': SVGAttribute('x1', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'x2': SVGAttribute('x2', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'xlink:actuate': SVGMultiAttribute({
'*': SVGAttribute(
'xlink:actuate', anim=False,
types=empty_list,
const=frozenset(['onLoad'])),
'a': SVGAttribute(
'xlink:actuate', anim=False,
types=empty_list,
const=frozenset(['onRequest'])),
}),
'xlink:arcrole': SVGAttribute('xlink:arcrole', anim=False,
types=frozenset(['IRI']),
const=empty_list),
'xlink:href': SVGAttribute('xlink:href', anim=True,
types=frozenset(['IRI']),
const=empty_list),
'xlink:role': SVGAttribute('xlink:role', anim=False,
types=frozenset(['IRI']),
const=empty_list),
'xlink:show': SVGMultiAttribute({
'*': SVGAttribute(
'xlink:show', anim=False,
types=empty_list,
const=frozenset(['other'])),
'animation audio foreignObject image use video': SVGAttribute(
'xlink:show', anim=False,
types=empty_list,
const=frozenset(['embed'])),
'a': SVGAttribute(
'xlink:show', anim=False,
types=empty_list,
const=frozenset(['new', 'replace'])),
}),
'xlink:title': SVGAttribute('xlink:title', anim=False,
types=frozenset(['string']),
const=empty_list),
'xlink:type': SVGAttribute('xlink:type', anim=True,
types=empty_list,
const=frozenset(['simple'])),
'xmlns': SVGAttribute('xmlns', anim=False,
types=frozenset(['IRI']),
const=empty_list),
'xmlns:xlink': SVGAttribute('xmlns:xlink', anim=False,
types=frozenset(['IRI']),
const=empty_list),
'xmlns:ev': SVGAttribute('xmlns:ev', anim=False,
types=frozenset(['IRI']),
const=empty_list),
'xml:base': SVGAttribute('xml:base', anim=False,
types=frozenset(['IRI']),
const=empty_list),
'xml:id': SVGAttribute('xml:id', anim=False,
types=frozenset(['name']),
const=empty_list),
'xml:lang': SVGAttribute('xml:lang', anim=False,
types=frozenset(['name']),
const=empty_list),
'xml:space': SVGMultiAttribute({
'*': SVGAttribute(
'xml:space', anim=False,
types=empty_list,
const=frozenset(['preserve', 'default'])),
'handler script': SVGAttribute(
'xml:space', anim=False,
types=empty_list,
const=frozenset(['preserve'])),
}),
'y': SVGMultiAttribute({
'*': SVGAttribute(
'y', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'text': SVGAttribute(
'y', anim=True,
types=frozenset(['list-of-coordinate']),
const=empty_list),
}),
'y1': SVGAttribute('y1', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'y2': SVGAttribute('y2', anim=True,
types=frozenset(['coordinate']),
const=empty_list),
'zoomAndPan': SVGAttribute('zoomAndPan', anim=False,
types=empty_list,
const=frozenset(['disable', 'magnify'])),
}
attribute_names = ['slope', 'keySplines', 'rx', 'accumulate', 'bandwidth',
'attributeType', 'unicode', 'nav-right', 'arabic-form',
'y2', 'horiz-origin-x', 'underline-position', 'zoomAndPan',
'cap-height', 'defaultAction', 'to', 'syncBehavior',
'alphabetic', 'g2', 'g1', 'panose-1', 'strikethrough-thickness',
'attributeName', 'bbox', 'nav-up-left', 'nav-left',
'restart', 'target', 'xlink:actuate', 'rotate', 'resource',
'd', 'syncToleranceDefault', 'initialVisibility',
'transformBehavior', 'nav-up-right', 'keyTimes',
'x', 'requiredFormats', 'nav-next', 'glyph-name',
'xml:lang', 'mathematical', 'observer', 'repeatDur',
'hanging', 'y1', 'xml:base', 'ascent', 'event',
'strikethrough-position', 'overlay', 'rev', 'ry',
'overline-thickness', 'content', 'version', 'rel',
'focusable', 'requiredFonts', 'nav-down-right', 'xml:id',
'offset', 'additive', 'underline-thickness', 'font-family',
'by', 'mediaTime', 'timelineBegin', 'about', 'horiz-adv-x',
'widths', 'k', 'requiredFeatures', 'preserveAspectRatio',
'contentScriptType', 'origin', 'xml:space', 'xlink:href',
'height', 'baseProfile', 'cy', 'cx', 'path', 'xlink:role',
'from', 'u1', 'transform', 'units-per-em', 'u2', 'width',
'handler', 'font-variant', 'x-height', 'dur', 'xlink:arcrole',
'type', 'focusHighlight', 'mediaCharacterEncoding',
'xlink:title', 'editable', 'stemv', 'systemLanguage',
'x2', 'x1', 'ideographic', 'xlink:show', 'overline-position',
'syncTolerance', 'gradientUnits', 'r', 'values', 'typeof',
'mediaContentEncodings', 'property', 'requiredExtensions',
'repeatCount', 'ev:event', 'nav-down', 'mediaSize', 'pathLength',
'syncMaster', 'font-style', 'fill', 'end', 'descent',
'calcMode', 'min', 'stemh', 'id', 'unicode-range',
'nav-up', 'font-stretch', 'role', 'font-weight', 'begin',
'xlink:type', 'syncBehaviorDefault', 'max', 'snapshotTime',
'playbackOrder', 'keyPoints', 'nav-prev', 'propagate',
'phase', 'externalResourcesRequired', 'nav-down-left',
'class', 'lang', 'datatype', 'viewBox', 'points',
'accent-height', 'y']
property_names = ['stroke-linejoin', 'font-size', 'text-rendering', 'color-rendering',
'fill-opacity', 'color', 'shape-rendering', 'solid-color', 'stroke',
'stroke-linecap', 'vector-effect', 'stroke-width', 'font-style',
'fill', 'solid-opacity', 'fill-rule', 'viewport-fill-opacity',
'display-align', 'buffered-rendering', 'stroke-miterlimit',
'font-variant', 'stop-opacity', 'font-weight', 'opacity', 'direction',
'audio-level', 'visibility', 'unicode-bidi', 'line-increment',
'image-rendering', 'font-family', 'viewport-fill', 'text-align',
'stroke-opacity', 'stroke-dashoffset', 'text-anchor', 'stop-color',
'pointer-events', 'stroke-dasharray', 'display']
media_group_names = ['audio-level', 'buffered-rendering', 'display', 'image-rendering',
'pointer-events', 'shape-rendering', 'text-rendering',
'viewport-fill', 'viewport-fill-opacity', 'visibility']
elements = {
'a': SVGElement('a',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'target', 'transform', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['likeparent', 'defs', 'text', 'g', 'textArea', 'svg']),
'animate': SVGElement('animate',
attributes=['about', 'accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'handler', 'metadata', 'switch', 'title']),
'animateColor': SVGElement('animateColor',
attributes=['about', 'accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'handler', 'metadata', 'switch', 'title']),
'animateMotion': SVGElement('animateMotion',
attributes=['about', 'accumulate', 'additive', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keyPoints', 'keySplines', 'keyTimes', 'max', 'min', 'origin', 'path', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'rotate', 'systemLanguage', 'to', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'handler', 'metadata', 'mpath', 'switch', 'title']),
'animateTransform': SVGElement('animateTransform',
attributes=['about', 'accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'type', 'typeof', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'handler', 'metadata', 'switch', 'title']),
'animation': SVGElement('animation',
attributes=['about', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'externalResourcesRequired', 'fill', 'focusHighlight', 'focusable', 'height', 'id', 'initialVisibility', 'max', 'min', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'preserveAspectRatio', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'syncBehavior', 'syncMaster', 'syncTolerance', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=media_group_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'audio': SVGElement('audio',
attributes=['about', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'externalResourcesRequired', 'fill', 'id', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'syncBehavior', 'syncMaster', 'syncTolerance', 'systemLanguage', 'type', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=media_group_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'circle': SVGElement('circle',
attributes=['about', 'class', 'content', 'cx', 'cy', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'r', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'defs': SVGElement('defs',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'animation', 'audio', 'circle', 'defs', 'desc', 'discard', 'ellipse', 'font', 'font-face', 'foreignObject', 'g', 'handler', 'image', 'line', 'linearGradient', 'listener', 'metadata', 'path', 'polygon', 'polyline', 'prefetch', 'radialGradient', 'rect', 'script', 'set', 'solidColor', 'switch', 'text', 'textArea', 'title', 'use', 'video']),
'desc': SVGElement('desc',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=media_group_names,
children=empty_list),
'discard': SVGElement('discard',
attributes=['about', 'begin', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'handler', 'metadata', 'switch', 'title']),
'ellipse': SVGElement('ellipse',
attributes=['about', 'class', 'content', 'cx', 'cy', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'rx', 'ry', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'font': SVGElement('font',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'horiz-adv-x', 'horiz-origin-x', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'font-face', 'glyph', 'hkern', 'metadata', 'missing-glyph', 'switch', 'title']),
'font-face': SVGElement('font-face',
attributes=['about', 'accent-height', 'alphabetic', 'ascent', 'bbox', 'cap-height', 'class', 'content', 'datatype', 'descent', 'externalResourcesRequired', 'font-family', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'hanging', 'id', 'ideographic', 'mathematical', 'overline-position', 'overline-thickness', 'panose-1', 'property', 'rel', 'resource', 'rev', 'role', 'slope', 'stemh', 'stemv', 'strikethrough-position', 'strikethrough-thickness', 'typeof', 'underline-position', 'underline-thickness', 'unicode-range', 'units-per-em', 'widths', 'x-height', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'font-face-src', 'metadata', 'switch', 'title']),
'font-face-src': SVGElement('font-face-src',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'font-face-uri', 'metadata', 'switch', 'title']),
'font-face-uri': SVGElement('font-face-uri',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'foreignObject': SVGElement('foreignObject',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=property_names,
children=['desc', 'metadata', 'svg', 'switch', 'title']),
'g': SVGElement('g',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'animation', 'audio', 'circle', 'defs', 'desc', 'discard', 'ellipse', 'font', 'font-face', 'foreignObject', 'g', 'handler', 'image', 'line', 'linearGradient', 'listener', 'metadata', 'path', 'polygon', 'polyline', 'prefetch', 'radialGradient', 'rect', 'script', 'set', 'solidColor', 'switch', 'text', 'textArea', 'title', 'use', 'video']),
'glyph': SVGElement('glyph',
attributes=['about', 'arabic-form', 'class', 'content', 'd', 'datatype', 'glyph-name', 'horiz-adv-x', 'id', 'lang', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'unicode', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'handler': SVGElement('handler',
attributes=['about', 'class', 'content', 'datatype', 'ev:event', 'externalResourcesRequired', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'type', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'hkern': SVGElement('hkern',
attributes=['about', 'class', 'content', 'datatype', 'g1', 'g2', 'id', 'k', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'u1', 'u2', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'image': SVGElement('image',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'opacity', 'preserveAspectRatio', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'type', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=media_group_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'line': SVGElement('line',
attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'x1', 'x2', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y1', 'y2'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'linearGradient': SVGElement('linearGradient',
attributes=['about', 'class', 'content', 'datatype', 'gradientUnits', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'x1', 'x2', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y1', 'y2'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'metadata', 'set', 'stop', 'switch', 'title']),
'listener': SVGElement('listener',
attributes=['about', 'class', 'content', 'datatype', 'defaultAction', 'event', 'handler', 'id', 'observer', 'phase', 'propagate', 'property', 'rel', 'resource', 'rev', 'role', 'target', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=empty_list),
'metadata': SVGElement('metadata',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=media_group_names,
children=empty_list),
'missing-glyph': SVGElement('missing-glyph',
attributes=['about', 'class', 'content', 'd', 'datatype', 'horiz-adv-x', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'mpath': SVGElement('mpath',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'path': SVGElement('path',
attributes=['about', 'class', 'content', 'd', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'pathLength', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'polygon': SVGElement('polygon',
attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'points', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'polyline': SVGElement('polyline',
attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'points', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'prefetch': SVGElement('prefetch',
attributes=['about', 'bandwidth', 'class', 'content', 'datatype', 'id', 'mediaCharacterEncoding', 'mediaContentEncodings', 'mediaSize', 'mediaTime', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'radialGradient': SVGElement('radialGradient',
attributes=['about', 'class', 'content', 'cx', 'cy', 'datatype', 'gradientUnits', 'id', 'property', 'r', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'metadata', 'set', 'stop', 'switch', 'title']),
'rect': SVGElement('rect',
attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'rx', 'ry', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'script': SVGElement('script',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'type', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'metadata', 'switch', 'title']),
'set': SVGElement('set',
attributes=['about', 'attributeName', 'attributeType', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'fill', 'id', 'max', 'min', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'systemLanguage', 'to', 'typeof', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=['desc', 'handler', 'metadata', 'switch', 'title']),
'solidColor': SVGElement('solidColor',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'stop': SVGElement('stop',
attributes=['about', 'class', 'content', 'datatype', 'id', 'offset', 'property', 'rel', 'resource', 'rev', 'role', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'metadata', 'set', 'switch', 'title']),
'svg': SVGElement('svg',
attributes=['about', 'baseProfile', 'class', 'content', 'contentScriptType', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'playbackOrder', 'preserveAspectRatio', 'property', 'rel', 'resource', 'rev', 'role', 'snapshotTime', 'syncBehaviorDefault', 'syncToleranceDefault', 'timelineBegin', 'transform', 'typeof', 'version', 'viewBox', 'width', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'xmlns', 'xmlns:xlink', 'xmlns:ev', 'zoomAndPan'],
properties=property_names,
children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'animation', 'audio', 'circle', 'defs', 'desc', 'discard', 'ellipse', 'font', 'font-face', 'foreignObject', 'g', 'handler', 'image', 'line', 'linearGradient', 'listener', 'metadata', 'path', 'polygon', 'polyline', 'prefetch', 'radialGradient', 'rect', 'script', 'set', 'solidColor', 'switch', 'text', 'textArea', 'title', 'use', 'video']),
'switch': SVGElement('switch',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['likeparent', 'set', 'textArea', 'text', 'image', 'missing-glyph', 'font-face', 'video', 'path', 'animate', 'font', 'ellipse', 'glyph', 'use', 'font-face-src', 'polygon', 'script', 'handler', 'circle', 'radialGradient', 'prefetch', 'defs', 'mpath', 'stop', 'animateMotion', 'animateColor', 'discard', 'solidColor', 'hkern', 'line', 'animation', 'rect', 'g', 'svg', 'animateTransform', 'linearGradient', 'font-face-uri', 'foreignObject', 'polyline', 'audio']),
'tbreak': SVGElement('tbreak',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=empty_list,
children=empty_list),
'text': SVGElement('text',
attributes=['about', 'class', 'content', 'datatype', 'editable', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'rotate', 'systemLanguage', 'transform', 'typeof', 'x', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=property_names,
children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title', 'tspan']),
'textArea': SVGElement('textArea',
attributes=['about', 'class', 'content', 'datatype', 'editable', 'focusHighlight', 'focusable', 'height', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'width', 'x', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=property_names,
children=['a', 'animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'tbreak', 'title', 'tspan']),
'title': SVGElement('title',
attributes=['about', 'class', 'content', 'datatype', 'id', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=media_group_names,
children=empty_list),
'tspan': SVGElement('tspan',
attributes=['about', 'class', 'content', 'datatype', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'typeof', 'xml:base', 'xml:id', 'xml:lang', 'xml:space'],
properties=property_names,
children=['likeparent', 'text', 'textArea']),
'use': SVGElement('use',
attributes=['about', 'class', 'content', 'datatype', 'externalResourcesRequired', 'focusHighlight', 'focusable', 'id', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'property', 'rel', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'rev', 'role', 'systemLanguage', 'transform', 'typeof', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=property_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
'video': SVGElement('video',
attributes=['about', 'begin', 'class', 'content', 'datatype', 'dur', 'end', 'externalResourcesRequired', 'fill', 'focusHighlight', 'focusable', 'height', 'id', 'initialVisibility', 'max', 'min', 'nav-down', 'nav-down-left', 'nav-down-right', 'nav-left', 'nav-next', 'nav-prev', 'nav-right', 'nav-up', 'nav-up-left', 'nav-up-right', 'overlay', 'preserveAspectRatio', 'property', 'rel', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'requiredFonts', 'requiredFormats', 'resource', 'restart', 'rev', 'role', 'syncBehavior', 'syncMaster', 'syncTolerance', 'systemLanguage', 'transform', 'transformBehavior', 'type', 'typeof', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:id', 'xml:lang', 'xml:space', 'y'],
properties=media_group_names,
children=['animate', 'animateColor', 'animateMotion', 'animateTransform', 'desc', 'discard', 'handler', 'metadata', 'set', 'switch', 'title']),
}
@@ -0,0 +1,342 @@
#!/usr/bin/env python
#coding:utf-8
# Author: mozman --<mozman@gmx.at>
# Purpose: typechecker
# Created: 15.10.2010
# Copyright (C) 2010, Manfred Moitzi
# License: MIT License
import re
from svgwrite.data import pattern
from svgwrite.data.colors import colornames
from svgwrite.data.svgparser import is_valid_transferlist, is_valid_pathdata, is_valid_animation_timing
from svgwrite.utils import is_string
def iterflatlist(values):
""" Flatten nested *values*, returns an *iterator*. """
for element in values:
if hasattr(element, "__iter__") and not is_string(element):
for item in iterflatlist(element):
yield item
else:
yield element
INVALID_NAME_CHARS = frozenset([' ', '\t', '\r', '\n', ',', '(', ')'])
WHITESPACE = frozenset([' ', '\t', '\r', '\n'])
SHAPE_PATTERN = re.compile(r"^rect\((.*),(.*),(.*),(.*)\)$")
FUNCIRI_PATTERN = re.compile(r"^url\((.*)\)$")
ICCCOLOR_PATTERN = re.compile(r"^icc-color\((.*)\)$")
COLOR_HEXDIGIT_PATTERN = re.compile(r"^#[a-fA-F0-9]{3}([a-fA-F0-9]{3})?$")
COLOR_RGB_INTEGER_PATTERN = re.compile(r"^rgb\( *\d+ *, *\d+ *, *\d+ *\)$")
COLOR_RGB_PERCENTAGE_PATTERN = re.compile(r"^rgb\( *\d+(\.\d*)?% *, *\d+(\.\d*)?% *, *\d+(\.\d*)?% *\)$")
NMTOKEN_PATTERN = re.compile(r"^[a-zA-Z_:][\w\-\.:]*$")
class Full11TypeChecker(object):
def get_version(self):
return '1.1', 'full'
def is_angle(self, value):
#angle ::= number (~"deg" | ~"grad" | ~"rad")?
if self.is_number(value):
return True
elif is_string(value):
return pattern.angle.match(value.strip()) is not None
return False
def is_anything(self, value):
#anything ::= Char*
return bool(str(value).strip())
is_string = is_anything
is_content_type = is_anything
def is_color(self, value):
#color ::= "#" hexdigit hexdigit hexdigit (hexdigit hexdigit hexdigit)?
# | "rgb(" wsp* integer comma integer comma integer wsp* ")"
# | "rgb(" wsp* number "%" comma number "%" comma number "%" wsp* ")"
# | color-keyword
#hexdigit ::= [0-9A-Fa-f]
#comma ::= wsp* "," wsp*
value = str(value).strip()
if value.startswith('#'):
if COLOR_HEXDIGIT_PATTERN.match(value):
return True
else:
return False
elif value.startswith('rgb('):
if COLOR_RGB_INTEGER_PATTERN.match(value):
return True
elif COLOR_RGB_PERCENTAGE_PATTERN.match(value):
return True
return False
return self.is_color_keyword(value)
def is_color_keyword(self, value):
return value.strip() in colornames
def is_frequency(self, value):
# frequency ::= number (~"Hz" | ~"kHz")
if self.is_number(value):
return True
elif is_string(value):
return pattern.frequency.match(value.strip()) is not None
return False
def is_FuncIRI(self, value):
# FuncIRI ::= "url(" <IRI> ")"
res = FUNCIRI_PATTERN.match(str(value).strip())
if res:
return self.is_IRI(res.group(1))
return False
def is_icccolor(self, value):
# icccolor ::= "icc-color(" name (comma-wsp number)+ ")"
res = ICCCOLOR_PATTERN.match(str(value).strip())
if res:
return self.is_list_of_T(res.group(1), 'name')
return False
def is_integer(self, value):
if isinstance(value, float):
return False
try:
number = int(value)
return True
except:
return False
def is_IRI(self, value):
# Internationalized Resource Identifiers
# a more generalized complement to Uniform Resource Identifiers (URIs)
# nearly everything can be a valid <IRI>
# only a none-empty string ist a valid input
if is_string(value):
return bool(value.strip())
else:
return False
def is_length(self, value):
# length ::= number ("em" | "ex" | "px" | "in" | "cm" | "mm" | "pt" | "pc" | "%")?
if value is None:
return False
if isinstance(value, (int, float)):
return self.is_number(value)
elif is_string(value):
result = pattern.length.match(value.strip())
if result:
number, tmp, unit = result.groups()
return self.is_number(number) # for tiny check!
return False
is_coordinate = is_length
def is_list_of_T(self, value, t='string'):
def split(value):
#TODO: improve split function!!!!
if isinstance(value, (int, float)):
return (value, )
if is_string(value):
return iterflatlist(v.split(',') for v in value.split(' '))
return value
#list-of-Ts ::= T
# | T comma-wsp list-of-Ts
#comma-wsp ::= (wsp+ ","? wsp*) | ("," wsp*)
#wsp ::= (#x20 | #x9 | #xD | #xA)
checker = self.get_func_by_name(t)
for v in split(value):
if not checker(v):
return False
return True
def is_four_numbers(self, value):
def split(value):
if is_string(value):
values = iterflatlist( (v.strip().split(' ') for v in value.split(',')) )
return (v for v in values if v)
else:
return iterflatlist(value)
values = list(split(value))
if len(values) != 4:
return False
checker = self.get_func_by_name('number')
for v in values:
if not checker(v):
return False
return True
def is_semicolon_list(self, value):
#a semicolon-separated list of values
# | value comma-wsp list-of-values
#comma-wsp ::= (wsp+ ";" wsp*) | ("," wsp*)
#wsp ::= (#x20 | #x9 | #xD | #xA)
return self.is_list_of_T(value.replace(';', ' '), 'string')
def is_name(self, value):
# name ::= [^,()#x20#x9#xD#xA] /* any char except ",", "(", ")" or wsp */
chars = frozenset(str(value).strip())
if not chars or INVALID_NAME_CHARS.intersection(chars):
return False
else:
return True
def is_number(self, value):
try:
number = float(value)
return True
except:
return False
def is_number_optional_number(self, value):
#number-optional-number ::= number
# | number comma-wsp number
if is_string(value):
values = re.split('[ ,]+', value.strip())
if 0 < len(values) < 3: # 1 or 2 numbers
for v in values:
if not self.is_number(v):
return False
return True
else:
try: # is it a 2-tuple
n1, n2 = value
if self.is_number(n1) and \
self.is_number(n2):
return True
except TypeError: # just one value
return self.is_number(value)
except ValueError: # more than 2 values
pass
return False
def is_paint(self, value):
#paint ::= "none" |
# "currentColor" |
# <color> [<icccolor>] |
# <funciri> [ "none" | "currentColor" | <color> [<icccolor>] |
# "inherit"
def split_values(value):
try:
funcIRI, value = value.split(")", 1)
values = [funcIRI+")"]
values.extend(split_values(value))
return values
except ValueError:
return value.split()
values = split_values(str(value).strip())
for value in [v.strip() for v in values]:
if value in ('none', 'currentColor', 'inherit'):
continue
elif self.is_color(value):
continue
elif self.is_icccolor(value):
continue
elif self.is_FuncIRI(value):
continue
return False
return True
def is_percentage(self, value):
#percentage ::= number "%"
if self.is_number(value):
return True
elif is_string(value):
return pattern.percentage.match(value.strip()) is not None
return False
def is_time(self, value):
#time ::= <number> (~"ms" | ~"s")?
if self.is_number(value):
return True
elif is_string(value):
return pattern.time.match(value.strip()) is not None
return False
def is_transform_list(self, value):
if is_string(value):
return is_valid_transferlist(value)
else:
return False
def is_path_data(self, value):
if is_string(value):
return is_valid_pathdata(value)
else:
return False
def is_XML_Name(self, value):
# http://www.w3.org/TR/2006/REC-xml-20060816/#NT-Name
# Nmtoken
return bool(NMTOKEN_PATTERN.match(str(value).strip()))
def is_shape(self, value):
# shape ::= (<top> <right> <bottom> <left>)
# where <top>, <bottom> <right>, and <left> specify offsets from the
# respective sides of the box.
# <top>, <right>, <bottom>, and <left> are <length> values
# i.e. 'rect(5px, 10px, 10px, 5px)'
res = SHAPE_PATTERN.match(value.strip())
if res:
for arg in res.groups():
if arg.strip() == 'auto':
continue
if not self.is_length(arg):
return False
else:
return False
return True
def is_timing_value_list(self, value):
if is_string(value):
return is_valid_animation_timing(value)
else:
return False
def is_list_of_text_decoration_style(self, value):
return self.is_list_of_T(value, t='text_decoration_style')
def is_text_decoration_style(self, value):
return value in ('overline', 'underline', 'line-through', 'blink')
def get_func_by_name(self, funcname):
return getattr(self,
'is_'+funcname.replace('-', '_'),
self.is_anything)
def check(self, typename, value):
if typename.startswith('list-of-'):
t = typename[8:]
return self.is_list_of_T(value, t)
return self.get_func_by_name(typename)(value)
FOCUS_CONST = frozenset(['nav-next', 'nav-prev', 'nav-up', 'nav-down', 'nav-left',
'nav-right', 'nav-up-left', 'nav-up-right', 'nav-down-left',
'nav-down-right'])
class Tiny12TypeChecker(Full11TypeChecker):
def get_version(self):
return '1.2', 'tiny'
def is_boolean(self, value):
if isinstance(value, bool):
return True
if is_string(value):
return value.strip().lower() in ('true', 'false')
return False
def is_number(self, value):
try:
number = float(value)
if -32767.9999 <= number <= 32767.9999:
return True
else:
return False
except:
return False
def is_focus(self, value):
return str(value).strip() in FOCUS_CONST
@@ -0,0 +1,81 @@
#!/usr/bin/env python
#coding:utf-8
# Author: mozman --<mozman@gmx.at>
# Purpose: svg types
# Created: 30.09.2010
# Copyright (C) 2010, Manfred Moitzi
# License: MIT License
class SVGAttribute(object):
def __init__(self, name, anim, types, const):
self.name = name
self._anim = anim
self._types = types
self._const = const
# 'elementname' is ignored, but necessary because of the signatures of
# the SVGMultiAttribute class methods get_...()
def get_anim(self, elementname='*'):
return self._anim
def get_types(self, elementname='*'):
return self._types
def get_const(self, elementname='*'):
return self._const
class SVGMultiAttribute(object):
# example: SVGMultiAttribute({'*':SVGAttribute(...), 'text tref':SVGAttribute(...)} )
# parametr is a dict-like object
# '*' is the default attribute definition
# 'text' and 'tref' share the same attribute definition
def __init__(self, attributes):
self.name = None
self._attributes = {}
for names, attribute in attributes.items():
for name in names.split():
name = name.strip()
self._attributes[name] = attribute
if not self.name:
self.name = attribute.name
elif self.name != attribute.name:
raise ValueError("Different attribute-names for SVGMultiAttribute "\
"(%s != %s)." % (self.name, attribute.name))
if '*' not in self._attributes and len(self._attributes):
# if no default attribute definition were given
# set the first attribute definition as the default attribute definition
firstkey = sorted(self._attributes.keys())[0]
self._attributes['*'] = self._attributes[firstkey]
def get_attribute(self, elementname):
if elementname in self._attributes:
return self._attributes[elementname]
else:
return self._attributes['*']
def get_anim(self, elementname='*'):
attribute = self.get_attribute(elementname)
return attribute.get_anim()
def get_types(self, elementname='*'):
attribute = self.get_attribute(elementname)
return attribute.get_types()
def get_const(self, elementname='*'):
attribute = self.get_attribute(elementname)
return attribute.get_const()
class SVGElement(object):
def __init__(self, name, attributes, properties, children):
self.name = name
s = set(attributes)
s.update(properties)
self.valid_attributes = frozenset(s)
self.valid_children = frozenset(children)