Browse Source

Try again, smaller and cleaner.

Beoran 2 years ago
parent
commit
cfe9548180
5 changed files with 806 additions and 622 deletions
  1. 35 0
      svg/length.go
  2. 646 0
      svg/old/svg.go
  3. 4 5
      svg/style.go
  4. 96 617
      svg/svg.go
  5. 25 0
      svg/svg_test.go

+ 35 - 0
svg/length.go

@@ -1,5 +1,10 @@
 package svg
 
+import "regexp"
+import "fmt"
+import "strconv"
+import "encoding/xml"
+
 type Unit string
 
 // Relative units are:
@@ -59,3 +64,33 @@ func (l Length) Pixels(parent ...float32) float32 {
 		return l.Magnitude
 	}
 }
+
+var ParseLengthRe = regexp.MustCompile(`([0-9]*\.?[0-9]*)(em|ex|px|in|cm|mm|pt|pc|%)?`)
+
+func ParseLength(s string) (Length, error) {
+	parts := ParseLengthRe.FindStringSubmatch(s)
+	res := Length{}
+	if len(parts) < 2 {
+		return res, fmt.Errorf("empty length")
+	}
+	magnitude, err := strconv.ParseFloat(parts[1], 32)
+	if err != nil {
+		return res, err
+	}
+	res.Magnitude = float32(magnitude)
+	if len(parts) > 2 {
+		res.Unit = Unit(parts[2])
+	}
+	return res, nil
+}
+
+func (l *Length) UnmarshalXMLAttr(attr xml.Attr) error {
+	length, err := ParseLength(attr.Value)
+	if err != nil {
+		return err
+	}
+	*l = length
+	return nil
+}
+
+var _ xml.UnmarshalerAttr = &Length{}

+ 646 - 0
svg/old/svg.go

@@ -0,0 +1,646 @@
+package svg
+
+import "time"
+import "encoding/xml"
+
+type ID string
+
+type Chardata string
+type D string
+type Version string
+type Docbase string
+type Xmlns string
+type Cc string
+type Dc string
+type Inkscape string
+type Rdf string
+type Docname string
+type Sodipodi string
+type GString string
+type Space string
+type Box string
+type Xlink string
+type L string
+type Filename string
+type Xdpi string
+type Ydpi string
+type Background string
+type Bounds string
+type Origin string
+type Overflow string
+type A string
+type Graph string
+type I string
+type Rule string
+type Rendering string
+type Ratio string
+type Fill string
+type Linecap string
+type Linejoin string
+type Ns string
+type Ns0 string
+type Xap string
+type Img string
+type Pdf string
+type Pdfx string
+type Pdfy string
+type Author string
+type Text string
+type About string
+type Title string
+type Description string
+type Date time.Time
+type Resource string
+type Language string
+type Collect string
+type Transform string
+type Units string
+type Href string
+type Method string
+type Format string
+type Offset string
+type Stockid string
+type Nodetypes string
+type Type string
+type Orient string
+
+type Fx = float32
+type Fy = float32
+type Rx = float32
+type Ry = float32
+type R = float32
+type R1 = float32
+type R2 = float32
+type W = float32
+type H = float32
+type Cx = float32
+type Cy = float32
+
+type Stroke string
+type Variant string
+type Weight string
+type Name string
+type Family string
+type Unicode string
+type Layer string
+type Pageshadow string
+type Zoom string
+type Bbox string
+type Showgrid string
+type Showguides string
+type Guidetolerance string
+type Points string
+type Gridspacingx float32
+type Gridspacingy float32
+type Gridtolerance string
+type Gridcolor = Color
+type Gridopacity = Opacity
+type Gridoriginx = float32
+type Gridoriginy = float32
+type Gridhicolor = Color
+type Gridempcolor = Color
+type Gridempopacity = Opacity
+type Gridempspacing string
+
+type Guidecolor = Color
+type Guidehicolor = Color
+type Guidehiopacity = Opacity
+type Guideopacity = Opacity
+type Snaptogrid string
+type Showborder string
+type Snaptoguides string
+type Borderlayer string
+
+type Bordercolor = Color
+type Borderopacity = Opacity
+type Pagecolor = Color
+type Pageopacity = Opacity
+
+type Groupmode string
+type Label string
+type Insensitive string
+type Percent string
+type Knockout string
+type Trio string
+type Display string
+type Visible string
+type Visibility string
+type Cmyk string
+type PathString string
+type Flatsided string
+type Rounded string
+type Arg1 string
+type Arg2 string
+type Sides string
+type Randomized string
+type Size string // XXX
+type Anchor string
+type Linespacing = Spacing
+type Role string
+type S string
+type Extensions string
+type Align string
+type Valign string
+type Spacing string
+type Desc string
+type Class string
+type Original string
+type Radius = float32
+type Miterlimit string
+type End string
+type Open string
+type Start string
+type Argument string
+type Extension string
+type Revolution string
+type T0 = float32
+type Isolated string
+type Absref string
+type Of string
+type Expansion string
+type Extraneous string
+type Matrix string
+type Span string
+
+type Orientation string // XXX
+type Position string    // XXX
+
+type Color string   // XXX
+type Opacity string // XXX
+
+type G struct {
+	Text           Text        `xml:",chardata"`
+	ID             ID          `xml:"id,attr"`
+	Use            []Use       `xml:"use"`
+	Chardata       Chardata    `xml:",chardata"`
+	Transform      Transform   `xml:"transform,attr"`
+	Groupmode      Groupmode   `xml:"groupmode,attr"`
+	Label          Label       `xml:"label,attr"`
+	Insensitive    Insensitive `xml:"insensitive,attr"`
+	Style          Style       `xml:"style,attr"`
+	DimmedPercent  Percent     `xml:"dimmedPercent,attr"`
+	Knockout       Knockout    `xml:"knockout,attr"`
+	Layer          Layer       `xml:"layer,attr"`
+	RgbTrio        Trio        `xml:"rgbTrio,attr"`
+	Display        Display     `xml:"display,attr"`
+	Visible        Visible     `xml:"visible,attr"`
+	Visibility     Visibility  `xml:"visibility,attr"`
+	Fill           Fill        `xml:"fill,attr"`
+	Stroke         Stroke      `xml:"stroke,attr"`
+	StrokeWidth    float32     `xml:"stroke-width,attr"`
+	ExportFilename Filename    `xml:"export-filename,attr"`
+	ExportXdpi     Xdpi        `xml:"export-xdpi,attr"`
+	ExportYdpi     Ydpi        `xml:"export-ydpi,attr"`
+	StrokeLinecap  Linecap     `xml:"stroke-linecap,attr"`
+	Rect           []Rect      `xml:"rect"`
+	G              []G         `xml:"g"`
+	Defs           []Defs      `xml:"defs"`
+	ClipPath       `xml:"clipPath"`
+	Polygon        []Polygon `xml:"polygon"`
+	// removed A
+}
+
+type Stop struct {
+	Text   Text   `xml:",chardata"`
+	ID     D      `xml:"id,attr"`
+	Offset Offset `xml:"offset,attr"`
+	Style  Style  `xml:"style,attr"`
+}
+
+type LinearGradient struct {
+	Text              Text      `xml:",chardata"`
+	ID                ID        `xml:"id,attr"`
+	Collect           Collect   `xml:"collect,attr"`
+	GradientTransform Transform `xml:"gradientTransform,attr"`
+	GradientUnits     Units     `xml:"gradientUnits,attr"`
+	X1                float32   `xml:"x1,attr"`
+	X2                float32   `xml:"x2,attr"`
+	Href              Href      `xml:"href,attr"`
+	Y1                float32   `xml:"y1,attr"`
+	Y2                float32   `xml:"y2,attr"`
+	SpreadMethod      Method    `xml:"spreadMethod,attr"`
+	Stop              []Stop    `xml:"stop"`
+}
+
+type StyleSheet struct {
+	Text Text `xml:",chardata"` // .str0 {stroke:#1F1A17;str...
+	ID   ID   `xml:"id,attr"`
+	Type Type `xml:"type,attr"`
+}
+
+type Rect struct {
+	Text   Text    `xml:",chardata"`
+	Fill   Fill    `xml:"fill,attr"`
+	Height float32 `xml:"height,attr"`
+	ID     D       `xml:"id,attr"`
+	Stroke Stroke  `xml:"stroke,attr"`
+	Width  float32 `xml:"width,attr"`
+	X      float32 `xml:"x,attr"`
+	Y      float32 `xml:"y,attr"`
+}
+
+type Mask struct {
+	Text           Text           `xml:",chardata"`
+	ID             ID             `xml:"id,attr"`
+	LinearGradient LinearGradient `xml:"linearGradient"`
+	Rect           Rect           `xml:"rect"`
+}
+
+type Path struct {
+	Text             Text       `xml:",chardata"`
+	D                D          `xml:"d,attr"`
+	ID               ID         `xml:"id,attr"`
+	Nodetypes        Nodetypes  `xml:"nodetypes,attr"`
+	Style            Style      `xml:"style,attr"`
+	Fill             Fill       `xml:"fill,attr"`
+	Transform        Transform  `xml:"transform,attr"`
+	Class            Class      `xml:"class,attr"`
+	Cx               Cx         `xml:"cx,attr"`
+	Cy               Cy         `xml:"cy,attr"`
+	Rx               Rx         `xml:"rx,attr"`
+	Ry               Ry         `xml:"ry,attr"`
+	Type             Type       `xml:"type,attr"`
+	Knockout         Knockout   `xml:"knockout,attr"`
+	TileCx           Cx         `xml:"tile-cx,attr"`
+	TileCy           Cy         `xml:"tile-cy,attr"`
+	TileH            H          `xml:"tile-h,attr"`
+	TileW            W          `xml:"tile-w,attr"`
+	ClipRule         Rule       `xml:"clip-rule,attr"`
+	FillRule         Rule       `xml:"fill-rule,attr"`
+	Stroke           Stroke     `xml:"stroke,attr"`
+	StrokeWidth      float32    `xml:"stroke-width,attr"`
+	EnableBackground Background `xml:"enable-background,attr"`
+	Isolated         Isolated   `xml:"isolated,attr"`
+	Opacity          Opacity    `xml:"opacity,attr"`
+	ExportXdpi       Xdpi       `xml:"export-xdpi,attr"`
+	ExportYdpi       Ydpi       `xml:"export-ydpi,attr"`
+	End              End        `xml:"end,attr"`
+	Open             Open       `xml:"open,attr"`
+	Start            Start      `xml:"start,attr"`
+	StrokeMiterlimit Miterlimit `xml:"stroke-miterlimit,attr"`
+	Flatsided        Flatsided  `xml:"flatsided,attr"`
+	Label            Label      `xml:"label,attr"`
+	Randomized       Randomized `xml:"randomized,attr"`
+	Rounded          Rounded    `xml:"rounded,attr"`
+	Arg1             Arg1       `xml:"arg1,attr"`
+	Arg2             Arg2       `xml:"arg2,attr"`
+	R1               R1         `xml:"r1,attr"`
+	R2               R2         `xml:"r2,attr"`
+	Sides            Sides      `xml:"sides,attr"`
+	FillCmyk         Cmyk       `xml:"fill-cmyk,attr"`
+}
+
+type Marker struct {
+	Text         Text    `xml:",chardata"`
+	ID           ID      `xml:"id,attr"`
+	MarkerHeight float32 `xml:"markerHeight,attr"`
+	MarkerUnits  Units   `xml:"markerUnits,attr"`
+	MarkerWidth  float32 `xml:"markerWidth,attr"`
+	Orient       Orient  `xml:"orient,attr"`
+	RefX         float32 `xml:"refX,attr"`
+	RefY         float32 `xml:"refY,attr"`
+	ViewBox      Box     `xml:"viewBox,attr"`
+	Stockid      Stockid `xml:"stockid,attr"`
+	Style        Style   `xml:"style,attr"`
+	Path         Path    `xml:"path"`
+}
+
+type RadialGradient struct {
+	Text              Text      `xml:",chardata"`
+	ID                ID        `xml:"id,attr"`
+	Href              Href      `xml:"href,attr"`
+	Cx                Cx        `xml:"cx,attr"`
+	Cy                Cy        `xml:"cy,attr"`
+	Fx                Fx        `xml:"fx,attr"`
+	Fy                Fy        `xml:"fy,attr"`
+	R                 R         `xml:"r,attr"`
+	GradientTransform Transform `xml:"gradientTransform,attr"`
+	GradientUnits     Units     `xml:"gradientUnits,attr"`
+	Collect           Collect   `xml:"collect,attr"`
+	SpreadMethod      Method    `xml:"spreadMethod,attr"`
+	Stop              []Stop    `xml:"stop"`
+}
+
+type Use struct {
+	Text      Text      `xml:",chardata"`
+	ID        ID        `xml:"id,attr"`
+	Href      Href      `xml:"href,attr"`
+	X         float32   `xml:"x,attr"`
+	Y         float32   `xml:"y,attr"`
+	Height    float32   `xml:"height,attr"`
+	Width     float32   `xml:"width,attr"`
+	Transform Transform `xml:"transform,attr"`
+}
+
+type ClipPath struct {
+	Text Text `xml:",chardata"`
+	ID   ID   `xml:"id,attr"`
+	Path Path `xml:"path"`
+}
+
+type Named struct {
+	Text Text `xml:",chardata"`
+	ID   ID   `xml:"id,attr"`
+}
+
+type FontFace struct {
+	Text       Text   `xml:",chardata"`
+	FontFamily Family `xml:"font-family,attr"`
+	ID         ID     `xml:"id,attr"`
+}
+
+type MissingGlyph struct {
+	Text Text `xml:",chardata"`
+	ID   ID   `xml:"id,attr"`
+	Path Path `xml:"path"`
+}
+
+type Glyph struct {
+	Text      Text    `xml:",chardata"`
+	HorizAdvX float32 `xml:"horiz-adv-x,attr"`
+	ID        ID      `xml:"id,attr"`
+	Unicode   Unicode `xml:"unicode,attr"`
+	Path      Path    `xml:"path"`
+}
+
+type Font struct {
+	Text         Text         `xml:",chardata"`
+	FontVariant  Variant      `xml:"fontVariant,attr"`
+	FontWeight   Weight       `xml:"fontWeight,attr"`
+	FullFontName Name         `xml:"fullFontName,attr"`
+	ID           ID           `xml:"id,attr"`
+	FontFace     FontFace     `xml:"font-face"`
+	MissingGlyph MissingGlyph `xml:"missing-glyph"`
+	Glyph        []Glyph      `xml:"glyph"`
+}
+
+type ForeignObject struct {
+	Text               Text       `xml:",chardata"`
+	Height             float32    `xml:"height,attr"`
+	Overflow           Overflow   `xml:"overflow,attr"`
+	RequiredExtensions Extensions `xml:"requiredExtensions,attr"`
+	Width              float32    `xml:"width,attr"`
+	X                  float32    `xml:"x,attr"`
+	Y                  float32    `xml:"y,attr"`
+	FlowDef            struct {
+		Text   Text  `xml:",chardata"`
+		Xmlns  Xmlns `xml:"xmlns,attr"`
+		Region struct {
+			Text Text `xml:",chardata"`
+			Path struct {
+				Text Text `xml:",chardata"`
+				D    D    `xml:"d,attr"`
+			} `xml:"path"`
+		} `xml:"region"`
+		Flow struct {
+			Text       Text   `xml:",chardata"`
+			FontFamily Family `xml:"font-family,attr"`
+			FontSize   Size   `xml:"font-size,attr"`
+			Xmlns      Xmlns  `xml:"xmlns,attr"`
+			P          struct {
+				Text Text `xml:",chardata"`
+				Span Span `xml:"span"` // 9, 12, 6, 3, 9, 12, 6, 3
+			} `xml:"p"`
+		} `xml:"flow"`
+	} `xml:"flowDef"`
+	TargetRef struct {
+		Text Text `xml:",chardata"`
+		Href Href `xml:"href,attr"`
+	} `xml:"targetRef"`
+	PgfRef struct {
+		Text Text `xml:",chardata"`
+		Href Href `xml:"href,attr"`
+		ID   D    `xml:"id,attr"`
+	} `xml:"pgfRef"`
+}
+
+type Defs struct {
+	Text           Text             `xml:",chardata"`
+	ID             ID               `xml:"id,attr"`
+	LinearGradient []LinearGradient `xml:"linearGradient"`
+	Style          StyleSheet       `xml:"style"`
+	Mask           []Mask           `xml:"mask"`
+	Marker         []Marker         `xml:"marker"`
+	RadialGradient []RadialGradient `xml:"radialGradient"`
+	Rect           []Rect           `xml:"rect"`
+	G              []G              `xml:"g"`
+	ClipPath       []ClipPath       `xml:"clipPath"`
+	Defs           []Defs           `xml:"defs"`
+	Path           []Path           `xml:"path"`
+	Namedview      []NamedView      `xml:"namedview"`
+	Font           []Font           `xml:"font"`
+}
+
+type NamedView struct {
+	Text           Text           `xml:",chardata"`
+	Bordercolor    Bordercolor    `xml:"bordercolor,attr"`
+	Borderopacity  Borderopacity  `xml:"borderopacity,attr"`
+	ID             D              `xml:"id,attr"`
+	CurrentLayer   Layer          `xml:"current-layer,attr"`
+	Cx             Cx             `xml:"cx,attr"`
+	Cy             Cy             `xml:"cy,attr"`
+	Pageopacity    Pageopacity    `xml:"pageopacity,attr"`
+	Pageshadow     Pageshadow     `xml:"pageshadow,attr"`
+	WindowHeight   float32        `xml:"window-height,attr"`
+	WindowWidth    float32        `xml:"window-width,attr"`
+	WindowX        float32        `xml:"window-x,attr"`
+	WindowY        float32        `xml:"window-y,attr"`
+	Zoom           Zoom           `xml:"zoom,attr"`
+	Pagecolor      Pagecolor      `xml:"pagecolor,attr"`
+	DocumentUnits  Units          `xml:"document-units,attr"`
+	GridBbox       Bbox           `xml:"grid-bbox,attr"`
+	GuideBbox      Bbox           `xml:"guide-bbox,attr"`
+	Showgrid       Showgrid       `xml:"showgrid,attr"`
+	Showguides     Showguides     `xml:"showguides,attr"`
+	Guidetolerance Guidetolerance `xml:"guidetolerance,attr"`
+	GuidePoints    Points         `xml:"guide-points,attr"`
+	Gridspacingx   Gridspacingx   `xml:"gridspacingx,attr"`
+	Gridspacingy   Gridspacingy   `xml:"gridspacingy,attr"`
+	Gridtolerance  Gridtolerance  `xml:"gridtolerance,attr"`
+	GridPoints     Points         `xml:"grid-points,attr"`
+	Gridcolor      Gridcolor      `xml:"gridcolor,attr"`
+	Gridopacity    Gridopacity    `xml:"gridopacity,attr"`
+	Gridoriginx    Gridoriginx    `xml:"gridoriginx,attr"`
+	Gridoriginy    Gridoriginy    `xml:"gridoriginy,attr"`
+	Guidecolor     Guidecolor     `xml:"guidecolor,attr"`
+	Guidehicolor   Guidehicolor   `xml:"guidehicolor,attr"`
+	Guidehiopacity Guidehiopacity `xml:"guidehiopacity,attr"`
+	Guideopacity   Guideopacity   `xml:"guideopacity,attr"`
+	Snaptogrid     Snaptogrid     `xml:"snaptogrid,attr"`
+	Fill           Fill           `xml:"fill,attr"`
+	Gridhicolor    Gridhicolor    `xml:"gridhicolor,attr"`
+	Showborder     Showborder     `xml:"showborder,attr"`
+	Snaptoguides   Snaptoguides   `xml:"snaptoguides,attr"`
+	Borderlayer    Borderlayer    `xml:"borderlayer,attr"`
+	Gridempcolor   Gridempcolor   `xml:"gridempcolor,attr"`
+	Gridempopacity Gridempopacity `xml:"gridempopacity,attr"`
+	Gridempspacing Gridempspacing `xml:"gridempspacing,attr"`
+	Guide          []struct {
+		Text        Text        `xml:",chardata"`
+		ID          D           `xml:"id,attr"`
+		Orientation Orientation `xml:"orientation,attr"`
+		Position    Position    `xml:"position,attr"`
+	} `xml:"guide"`
+}
+
+type SVG struct {
+	XMLName             xml.Name    `xml:"Svg"`
+	Chardata            Chardata    `xml:",chardata"`
+	Height              float32     `xml:"height,attr"`
+	ID                  D           `xml:"id,attr"`
+	Version             Version     `xml:"version,attr"`
+	Docbase             Docbase     `xml:"docbase,attr"`
+	Docname             Docname     `xml:"docname,attr"`
+	Width               float32     `xml:"width,attr"`
+	Xmlns               Xmlns       `xml:"xmlns,attr"`
+	Cc                  Cc          `xml:"cc,attr"`
+	Dc                  Dc          `xml:"dc,attr"`
+	Inkscape            Inkscape    `xml:"inkscape,attr"`
+	Rdf                 Rdf         `xml:"rdf,attr"`
+	Sodipodi            Sodipodi    `xml:"sodipodi,attr"`
+	SVG                 G           `xml:"svg,attr"`
+	Space               Space       `xml:"space,attr"`
+	AttrStyle           Style       `xml:"style,attr"`
+	ViewBox             Box         `xml:"viewBox,attr"`
+	Xlink               Xlink       `xml:"xlink,attr"`
+	XML                 L           `xml:"xml,attr"`
+	X                   float32     `xml:"x,attr"`
+	Y                   float32     `xml:"y,attr"`
+	ExportFilename      Filename    `xml:"export-filename,attr"`
+	ExportXdpi          Xdpi        `xml:"export-xdpi,attr"`
+	ExportYdpi          Ydpi        `xml:"export-ydpi,attr"`
+	EnableBackground    Background  `xml:"enable-background,attr"`
+	PageBounds          Bounds      `xml:"pageBounds,attr"`
+	RulerOrigin         Origin      `xml:"rulerOrigin,attr"`
+	ViewOrigin          Origin      `xml:"viewOrigin,attr"`
+	Overflow            Overflow    `xml:"overflow,attr"`
+	A                   A           `xml:"a,attr"`
+	Graph               Graph       `xml:"graph,attr"`
+	I                   I           `xml:"i,attr"`
+	FillRule            Rule        `xml:"fill-rule,attr"`
+	ImageRendering      Rendering   `xml:"image-rendering,attr"`
+	ShapeRendering      Rendering   `xml:"shape-rendering,attr"`
+	TextRendering       Rendering   `xml:"text-rendering,attr"`
+	PreserveAspectRatio Ratio       `xml:"preserveAspectRatio,attr"`
+	Fill                Fill        `xml:"fill,attr"`
+	StrokeLinecap       Linecap     `xml:"stroke-linecap,attr"`
+	StrokeLinejoin      Linejoin    `xml:"stroke-linejoin,attr"`
+	StrokeWidth         float32     `xml:"stroke-width,attr"`
+	Ns                  Ns          `xml:"ns,attr"`
+	Ns0                 Ns0         `xml:"ns0,attr"`
+	Xap                 Xap         `xml:"xap,attr"`
+	XapGImg             Img         `xml:"xapGImg,attr"`
+	Pdf                 Pdf         `xml:"pdf,attr"`
+	Pdfx                Pdfx        `xml:"pdfx,attr"`
+	Author              Author      `xml:"author,attr"`
+	Metadata            interface{} `xml:"metadata"`
+	Defs                Defs        `xml:"defs"`
+	// Inkscape-specific
+	Namedview      NamedView        `xml:"namedview"`
+	G              G                `xml:"g"`
+	Path           []Path           `xml:"path"`
+	Circle         []Circle         `xml:"circle"`
+	Text           []Text           `xml:"text"`
+	Style          StyleSheet       `xml:"style"`
+	Switch         Switch           `xml:"switch"`
+	RadialGradient []RadialGradient `xml:"radialGradient"`
+	Use            []Use            `xml:"use"`
+	Image          []Image          `xml:"image"`
+	Polygon        []Polygon        `xml:"polygon"`
+	Ellipse        []Ellipse        `xml:"ellipse"`
+	RDF            interface{}      `xml:"RDF"`
+}
+
+type TextDrawing struct {
+	Text        Text        `xml:",chardata"` // PACE, Moscow, Stockholm, ...
+	ID          D           `xml:"id,attr"`
+	Style       Style       `xml:"style,attr"`
+	X           float32     `xml:"x,attr"`
+	Space       Space       `xml:"space,attr"`
+	Y           float32     `xml:"y,attr"`
+	Linespacing Linespacing `xml:"linespacing,attr"`
+	Transform   Transform   `xml:"transform,attr"`
+	Fill        Fill        `xml:"fill,attr"`
+	FontFamily  Family      `xml:"font-family,attr"`
+	FontSize    Size        `xml:"font-size,attr"`
+	FontWeight  Weight      `xml:"font-weight,attr"`
+	TextAnchor  Anchor      `xml:"text-anchor,attr"`
+	Class       Class       `xml:"class,attr"`
+	Tspan       []struct {
+		Text  Text    `xml:",chardata"` // FOR SALE, 858-361-2811, $...
+		ID    D       `xml:"id,attr"`
+		Role  Role    `xml:"role,attr"`
+		X     float32 `xml:"x,attr"`
+		Y     float32 `xml:"y,attr"`
+		Style Style   `xml:"style,attr"`
+	} `xml:"tspan"`
+}
+
+type Switch struct {
+	Text          Text          `xml:",chardata"`
+	ID            D             `xml:"id,attr"`
+	ForeignObject ForeignObject `xml:"foreignObject"`
+	G             G             `xml:"g"`
+}
+
+type Circle []struct {
+	Text  Text  `xml:",chardata"`
+	Cx    Cx    `xml:"cx,attr"`
+	Cy    Cy    `xml:"cy,attr"`
+	Fill  Fill  `xml:"fill,attr"`
+	ID    D     `xml:"id,attr"`
+	R     R     `xml:"r,attr"`
+	Class Class `xml:"class,attr"`
+	Rx    Rx    `xml:"rx,attr"`
+	Ry    Ry    `xml:"ry,attr"`
+	Style Style `xml:"style,attr"`
+}
+
+type Ellipse struct {
+	Text        Text      `xml:",chardata"`
+	ID          ID        `xml:"id,attr"`
+	Cx          Cx        `xml:"cx,attr"`
+	Cy          Cy        `xml:"cy,attr"`
+	Rx          Rx        `xml:"rx,attr"`
+	Ry          Ry        `xml:"ry,attr"`
+	Style       Style     `xml:"style,attr"`
+	Stroke      Stroke    `xml:"stroke,attr"`
+	StrokeWidth float32   `xml:"stroke-width,attr"`
+	Transform   Transform `xml:"transform,attr"`
+}
+
+type Polygon struct {
+	Text      Text      `xml:",chardata"`
+	ID        ID        `xml:"id,attr"`
+	Points    Points    `xml:"points,attr"`
+	Arg1      Arg1      `xml:"arg1,attr"`
+	Arg2      Arg2      `xml:"arg2,attr"`
+	Cx        Cx        `xml:"cx,attr"`
+	Cy        Cy        `xml:"cy,attr"`
+	R1        R1        `xml:"r1,attr"`
+	R2        R2        `xml:"r2,attr"`
+	Sides     Sides     `xml:"sides,attr"`
+	Type      Type      `xml:"type,attr"`
+	Style     Style     `xml:"style,attr"`
+	Transform Transform `xml:"transform,attr"`
+	Fill      Fill      `xml:"fill,attr"`
+	FillCmyk  Cmyk      `xml:"fill-cmyk,attr"`
+}
+
+type Image struct {
+	Text      Text      `xml:",chardata"`
+	ID        ID        `xml:"id,attr"`
+	Points    Points    `xml:"points,attr"`
+	Arg1      Arg1      `xml:"arg1,attr"`
+	Arg2      Arg2      `xml:"arg2,attr"`
+	Cx        Cx        `xml:"cx,attr"`
+	Cy        Cy        `xml:"cy,attr"`
+	R1        R1        `xml:"r1,attr"`
+	R2        R2        `xml:"r2,attr"`
+	Sides     Sides     `xml:"sides,attr"`
+	Type      Type      `xml:"type,attr"`
+	Style     Style     `xml:"style,attr"`
+	Transform Transform `xml:"transform,attr"`
+	Fill      Fill      `xml:"fill,attr"`
+	FillCmyk  Cmyk      `xml:"fill-cmyk,attr"`
+}

+ 4 - 5
svg/style.go

@@ -20,14 +20,13 @@ func ParseStyle(str string) (Style, error) {
 	return res, nil
 }
 
-func (s *Style) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
-	var value string
-	// Read tag content into value
-	d.DecodeElement(&value, &start)
-	style, err := ParseStyle(value)
+func (s *Style) UnmarshalXMLAttr(attr xml.Attr) error {
+	style, err := ParseStyle(attr.Value)
 	if err != nil {
 		return err
 	}
 	*s = style
 	return nil
 }
+
+var _ xml.UnmarshalerAttr = &Style{}

+ 96 - 617
svg/svg.go

@@ -1,646 +1,125 @@
 package svg
 
-import "time"
 import "encoding/xml"
+import "fmt"
 
-type ID string
-
-type Chardata string
-type D string
-type Version string
-type Docbase string
-type Xmlns string
-type Cc string
-type Dc string
-type Inkscape string
-type Rdf string
-type Docname string
-type Sodipodi string
-type GString string
-type Space string
-type Box string
-type Xlink string
-type L string
-type Filename string
-type Xdpi string
-type Ydpi string
-type Background string
-type Bounds string
-type Origin string
-type Overflow string
-type A string
-type Graph string
-type I string
-type Rule string
-type Rendering string
-type Ratio string
-type Fill string
-type Linecap string
-type Linejoin string
-type Ns string
-type Ns0 string
-type Xap string
-type Img string
-type Pdf string
-type Pdfx string
-type Pdfy string
-type Author string
-type Text string
-type About string
-type Title string
-type Description string
-type Date time.Time
-type Resource string
-type Language string
-type Collect string
-type Transform string
-type Units string
-type Href string
-type Method string
-type Format string
-type Offset string
-type Stockid string
-type Nodetypes string
-type Type string
-type Orient string
-
-type Fx = float32
-type Fy = float32
-type Rx = float32
-type Ry = float32
-type R = float32
-type R1 = float32
-type R2 = float32
-type W = float32
-type H = float32
-type Cx = float32
-type Cy = float32
-
-type Stroke string
-type Variant string
-type Weight string
-type Name string
-type Family string
-type Unicode string
-type Layer string
-type Pageshadow string
-type Zoom string
-type Bbox string
-type Showgrid string
-type Showguides string
-type Guidetolerance string
-type Points string
-type Gridspacingx float32
-type Gridspacingy float32
-type Gridtolerance string
-type Gridcolor = Color
-type Gridopacity = Opacity
-type Gridoriginx = float32
-type Gridoriginy = float32
-type Gridhicolor = Color
-type Gridempcolor = Color
-type Gridempopacity = Opacity
-type Gridempspacing string
-
-type Guidecolor = Color
-type Guidehicolor = Color
-type Guidehiopacity = Opacity
-type Guideopacity = Opacity
-type Snaptogrid string
-type Showborder string
-type Snaptoguides string
-type Borderlayer string
-
-type Bordercolor = Color
-type Borderopacity = Opacity
-type Pagecolor = Color
-type Pageopacity = Opacity
-
-type Groupmode string
-type Label string
-type Insensitive string
-type Percent string
-type Knockout string
-type Trio string
-type Display string
-type Visible string
-type Visibility string
-type Cmyk string
-type PathString string
-type Flatsided string
-type Rounded string
-type Arg1 string
-type Arg2 string
-type Sides string
-type Randomized string
-type Size string // XXX
-type Anchor string
-type Linespacing = Spacing
-type Role string
-type S string
-type Extensions string
-type Align string
-type Valign string
-type Spacing string
-type Desc string
-type Class string
-type Original string
-type Radius = float32
-type Miterlimit string
-type End string
-type Open string
-type Start string
-type Argument string
-type Extension string
-type Revolution string
-type T0 = float32
-type Isolated string
-type Absref string
-type Of string
-type Expansion string
-type Extraneous string
-type Matrix string
-type Span string
-
-type Orientation string // XXX
-type Position string    // XXX
-
-type Color string   // XXX
-type Opacity string // XXX
-
-type G struct {
-	Text           Text        `xml:",chardata"`
-	ID             ID          `xml:"id,attr"`
-	Use            []Use       `xml:"use"`
-	Chardata       Chardata    `xml:",chardata"`
-	Transform      Transform   `xml:"transform,attr"`
-	Groupmode      Groupmode   `xml:"groupmode,attr"`
-	Label          Label       `xml:"label,attr"`
-	Insensitive    Insensitive `xml:"insensitive,attr"`
-	Style          Style       `xml:"style,attr"`
-	DimmedPercent  Percent     `xml:"dimmedPercent,attr"`
-	Knockout       Knockout    `xml:"knockout,attr"`
-	Layer          Layer       `xml:"layer,attr"`
-	RgbTrio        Trio        `xml:"rgbTrio,attr"`
-	Display        Display     `xml:"display,attr"`
-	Visible        Visible     `xml:"visible,attr"`
-	Visibility     Visibility  `xml:"visibility,attr"`
-	Fill           Fill        `xml:"fill,attr"`
-	Stroke         Stroke      `xml:"stroke,attr"`
-	StrokeWidth    float32     `xml:"stroke-width,attr"`
-	ExportFilename Filename    `xml:"export-filename,attr"`
-	ExportXdpi     Xdpi        `xml:"export-xdpi,attr"`
-	ExportYdpi     Ydpi        `xml:"export-ydpi,attr"`
-	StrokeLinecap  Linecap     `xml:"stroke-linecap,attr"`
-	Rect           []Rect      `xml:"rect"`
-	G              []G         `xml:"g"`
-	Defs           []Defs      `xml:"defs"`
-	ClipPath       `xml:"clipPath"`
-	Polygon        []Polygon `xml:"polygon"`
-	// removed A
+type CoreAttributes struct {
+	Chardata string `xml:",chardata"`
+	ID       string `xml:"id,attr"`
 }
 
 type Stop struct {
-	Text   Text   `xml:",chardata"`
-	ID     D      `xml:"id,attr"`
-	Offset Offset `xml:"offset,attr"`
+	CoreAttributes
 	Style  Style  `xml:"style,attr"`
+	Offset string `xml:"offset,attr"`
 }
 
 type LinearGradient struct {
-	Text              Text      `xml:",chardata"`
-	ID                ID        `xml:"id,attr"`
-	Collect           Collect   `xml:"collect,attr"`
-	GradientTransform Transform `xml:"gradientTransform,attr"`
-	GradientUnits     Units     `xml:"gradientUnits,attr"`
-	X1                float32   `xml:"x1,attr"`
-	X2                float32   `xml:"x2,attr"`
-	Href              Href      `xml:"href,attr"`
-	Y1                float32   `xml:"y1,attr"`
-	Y2                float32   `xml:"y2,attr"`
-	SpreadMethod      Method    `xml:"spreadMethod,attr"`
-	Stop              []Stop    `xml:"stop"`
-}
-
-type StyleSheet struct {
-	Text Text `xml:",chardata"` // .str0 {stroke:#1F1A17;str...
-	ID   ID   `xml:"id,attr"`
-	Type Type `xml:"type,attr"`
-}
-
-type Rect struct {
-	Text   Text    `xml:",chardata"`
-	Fill   Fill    `xml:"fill,attr"`
-	Height float32 `xml:"height,attr"`
-	ID     D       `xml:"id,attr"`
-	Stroke Stroke  `xml:"stroke,attr"`
-	Width  float32 `xml:"width,attr"`
-	X      float32 `xml:"x,attr"`
-	Y      float32 `xml:"y,attr"`
-}
-
-type Mask struct {
-	Text           Text           `xml:",chardata"`
-	ID             ID             `xml:"id,attr"`
-	LinearGradient LinearGradient `xml:"linearGradient"`
-	Rect           Rect           `xml:"rect"`
-}
-
-type Path struct {
-	Text             Text       `xml:",chardata"`
-	D                D          `xml:"d,attr"`
-	ID               ID         `xml:"id,attr"`
-	Nodetypes        Nodetypes  `xml:"nodetypes,attr"`
-	Style            Style      `xml:"style,attr"`
-	Fill             Fill       `xml:"fill,attr"`
-	Transform        Transform  `xml:"transform,attr"`
-	Class            Class      `xml:"class,attr"`
-	Cx               Cx         `xml:"cx,attr"`
-	Cy               Cy         `xml:"cy,attr"`
-	Rx               Rx         `xml:"rx,attr"`
-	Ry               Ry         `xml:"ry,attr"`
-	Type             Type       `xml:"type,attr"`
-	Knockout         Knockout   `xml:"knockout,attr"`
-	TileCx           Cx         `xml:"tile-cx,attr"`
-	TileCy           Cy         `xml:"tile-cy,attr"`
-	TileH            H          `xml:"tile-h,attr"`
-	TileW            W          `xml:"tile-w,attr"`
-	ClipRule         Rule       `xml:"clip-rule,attr"`
-	FillRule         Rule       `xml:"fill-rule,attr"`
-	Stroke           Stroke     `xml:"stroke,attr"`
-	StrokeWidth      float32    `xml:"stroke-width,attr"`
-	EnableBackground Background `xml:"enable-background,attr"`
-	Isolated         Isolated   `xml:"isolated,attr"`
-	Opacity          Opacity    `xml:"opacity,attr"`
-	ExportXdpi       Xdpi       `xml:"export-xdpi,attr"`
-	ExportYdpi       Ydpi       `xml:"export-ydpi,attr"`
-	End              End        `xml:"end,attr"`
-	Open             Open       `xml:"open,attr"`
-	Start            Start      `xml:"start,attr"`
-	StrokeMiterlimit Miterlimit `xml:"stroke-miterlimit,attr"`
-	Flatsided        Flatsided  `xml:"flatsided,attr"`
-	Label            Label      `xml:"label,attr"`
-	Randomized       Randomized `xml:"randomized,attr"`
-	Rounded          Rounded    `xml:"rounded,attr"`
-	Arg1             Arg1       `xml:"arg1,attr"`
-	Arg2             Arg2       `xml:"arg2,attr"`
-	R1               R1         `xml:"r1,attr"`
-	R2               R2         `xml:"r2,attr"`
-	Sides            Sides      `xml:"sides,attr"`
-	FillCmyk         Cmyk       `xml:"fill-cmyk,attr"`
-}
-
-type Marker struct {
-	Text         Text    `xml:",chardata"`
-	ID           ID      `xml:"id,attr"`
-	MarkerHeight float32 `xml:"markerHeight,attr"`
-	MarkerUnits  Units   `xml:"markerUnits,attr"`
-	MarkerWidth  float32 `xml:"markerWidth,attr"`
-	Orient       Orient  `xml:"orient,attr"`
-	RefX         float32 `xml:"refX,attr"`
-	RefY         float32 `xml:"refY,attr"`
-	ViewBox      Box     `xml:"viewBox,attr"`
-	Stockid      Stockid `xml:"stockid,attr"`
-	Style        Style   `xml:"style,attr"`
-	Path         Path    `xml:"path"`
+	CoreAttributes
+	Href          string `xml:"href,attr"`
+	X1            string `xml:"x1,attr"`
+	Y1            string `xml:"y1,attr"`
+	X2            string `xml:"x2,attr"`
+	Y2            string `xml:"y2,attr"`
+	GradientUnits string `xml:"gradientUnits,attr"`
+	Stop          []Stop `xml:"stop"`
 }
 
 type RadialGradient struct {
-	Text              Text      `xml:",chardata"`
-	ID                ID        `xml:"id,attr"`
-	Href              Href      `xml:"href,attr"`
-	Cx                Cx        `xml:"cx,attr"`
-	Cy                Cy        `xml:"cy,attr"`
-	Fx                Fx        `xml:"fx,attr"`
-	Fy                Fy        `xml:"fy,attr"`
-	R                 R         `xml:"r,attr"`
-	GradientTransform Transform `xml:"gradientTransform,attr"`
-	GradientUnits     Units     `xml:"gradientUnits,attr"`
-	Collect           Collect   `xml:"collect,attr"`
-	SpreadMethod      Method    `xml:"spreadMethod,attr"`
-	Stop              []Stop    `xml:"stop"`
-}
-
-type Use struct {
-	Text      Text      `xml:",chardata"`
-	ID        ID        `xml:"id,attr"`
-	Href      Href      `xml:"href,attr"`
-	X         float32   `xml:"x,attr"`
-	Y         float32   `xml:"y,attr"`
-	Height    float32   `xml:"height,attr"`
-	Width     float32   `xml:"width,attr"`
-	Transform Transform `xml:"transform,attr"`
-}
-
-type ClipPath struct {
-	Text Text `xml:",chardata"`
-	ID   ID   `xml:"id,attr"`
-	Path Path `xml:"path"`
-}
-
-type Named struct {
-	Text Text `xml:",chardata"`
-	ID   ID   `xml:"id,attr"`
-}
-
-type FontFace struct {
-	Text       Text   `xml:",chardata"`
-	FontFamily Family `xml:"font-family,attr"`
-	ID         ID     `xml:"id,attr"`
-}
-
-type MissingGlyph struct {
-	Text Text `xml:",chardata"`
-	ID   ID   `xml:"id,attr"`
-	Path Path `xml:"path"`
-}
-
-type Glyph struct {
-	Text      Text    `xml:",chardata"`
-	HorizAdvX float32 `xml:"horiz-adv-x,attr"`
-	ID        ID      `xml:"id,attr"`
-	Unicode   Unicode `xml:"unicode,attr"`
-	Path      Path    `xml:"path"`
-}
-
-type Font struct {
-	Text         Text         `xml:",chardata"`
-	FontVariant  Variant      `xml:"fontVariant,attr"`
-	FontWeight   Weight       `xml:"fontWeight,attr"`
-	FullFontName Name         `xml:"fullFontName,attr"`
-	ID           ID           `xml:"id,attr"`
-	FontFace     FontFace     `xml:"font-face"`
-	MissingGlyph MissingGlyph `xml:"missing-glyph"`
-	Glyph        []Glyph      `xml:"glyph"`
-}
-
-type ForeignObject struct {
-	Text               Text       `xml:",chardata"`
-	Height             float32    `xml:"height,attr"`
-	Overflow           Overflow   `xml:"overflow,attr"`
-	RequiredExtensions Extensions `xml:"requiredExtensions,attr"`
-	Width              float32    `xml:"width,attr"`
-	X                  float32    `xml:"x,attr"`
-	Y                  float32    `xml:"y,attr"`
-	FlowDef            struct {
-		Text   Text  `xml:",chardata"`
-		Xmlns  Xmlns `xml:"xmlns,attr"`
-		Region struct {
-			Text Text `xml:",chardata"`
-			Path struct {
-				Text Text `xml:",chardata"`
-				D    D    `xml:"d,attr"`
-			} `xml:"path"`
-		} `xml:"region"`
-		Flow struct {
-			Text       Text   `xml:",chardata"`
-			FontFamily Family `xml:"font-family,attr"`
-			FontSize   Size   `xml:"font-size,attr"`
-			Xmlns      Xmlns  `xml:"xmlns,attr"`
-			P          struct {
-				Text Text `xml:",chardata"`
-				Span Span `xml:"span"` // 9, 12, 6, 3, 9, 12, 6, 3
-			} `xml:"p"`
-		} `xml:"flow"`
-	} `xml:"flowDef"`
-	TargetRef struct {
-		Text Text `xml:",chardata"`
-		Href Href `xml:"href,attr"`
-	} `xml:"targetRef"`
-	PgfRef struct {
-		Text Text `xml:",chardata"`
-		Href Href `xml:"href,attr"`
-		ID   D    `xml:"id,attr"`
-	} `xml:"pgfRef"`
+	CoreAttributes
+	Href              string `xml:"href,attr"`
+	Cx                string `xml:"cx,attr"`
+	Cy                string `xml:"cy,attr"`
+	Fx                string `xml:"fx,attr"`
+	Fy                string `xml:"fy,attr"`
+	R                 string `xml:"r,attr"`
+	GradientTransform string `xml:"gradientTransform,attr"`
+	GradientUnits     string `xml:"gradientUnits,attr"`
+	Stop              []Stop `xml:"stop"`
 }
 
 type Defs struct {
-	Text           Text             `xml:",chardata"`
-	ID             ID               `xml:"id,attr"`
+	CoreAttributes
 	LinearGradient []LinearGradient `xml:"linearGradient"`
-	Style          StyleSheet       `xml:"style"`
-	Mask           []Mask           `xml:"mask"`
-	Marker         []Marker         `xml:"marker"`
-	RadialGradient []RadialGradient `xml:"radialGradient"`
-	Rect           []Rect           `xml:"rect"`
-	G              []G              `xml:"g"`
-	ClipPath       []ClipPath       `xml:"clipPath"`
-	Defs           []Defs           `xml:"defs"`
-	Path           []Path           `xml:"path"`
-	Namedview      []NamedView      `xml:"namedview"`
-	Font           []Font           `xml:"font"`
-}
-
-type NamedView struct {
-	Text           Text           `xml:",chardata"`
-	Bordercolor    Bordercolor    `xml:"bordercolor,attr"`
-	Borderopacity  Borderopacity  `xml:"borderopacity,attr"`
-	ID             D              `xml:"id,attr"`
-	CurrentLayer   Layer          `xml:"current-layer,attr"`
-	Cx             Cx             `xml:"cx,attr"`
-	Cy             Cy             `xml:"cy,attr"`
-	Pageopacity    Pageopacity    `xml:"pageopacity,attr"`
-	Pageshadow     Pageshadow     `xml:"pageshadow,attr"`
-	WindowHeight   float32        `xml:"window-height,attr"`
-	WindowWidth    float32        `xml:"window-width,attr"`
-	WindowX        float32        `xml:"window-x,attr"`
-	WindowY        float32        `xml:"window-y,attr"`
-	Zoom           Zoom           `xml:"zoom,attr"`
-	Pagecolor      Pagecolor      `xml:"pagecolor,attr"`
-	DocumentUnits  Units          `xml:"document-units,attr"`
-	GridBbox       Bbox           `xml:"grid-bbox,attr"`
-	GuideBbox      Bbox           `xml:"guide-bbox,attr"`
-	Showgrid       Showgrid       `xml:"showgrid,attr"`
-	Showguides     Showguides     `xml:"showguides,attr"`
-	Guidetolerance Guidetolerance `xml:"guidetolerance,attr"`
-	GuidePoints    Points         `xml:"guide-points,attr"`
-	Gridspacingx   Gridspacingx   `xml:"gridspacingx,attr"`
-	Gridspacingy   Gridspacingy   `xml:"gridspacingy,attr"`
-	Gridtolerance  Gridtolerance  `xml:"gridtolerance,attr"`
-	GridPoints     Points         `xml:"grid-points,attr"`
-	Gridcolor      Gridcolor      `xml:"gridcolor,attr"`
-	Gridopacity    Gridopacity    `xml:"gridopacity,attr"`
-	Gridoriginx    Gridoriginx    `xml:"gridoriginx,attr"`
-	Gridoriginy    Gridoriginy    `xml:"gridoriginy,attr"`
-	Guidecolor     Guidecolor     `xml:"guidecolor,attr"`
-	Guidehicolor   Guidehicolor   `xml:"guidehicolor,attr"`
-	Guidehiopacity Guidehiopacity `xml:"guidehiopacity,attr"`
-	Guideopacity   Guideopacity   `xml:"guideopacity,attr"`
-	Snaptogrid     Snaptogrid     `xml:"snaptogrid,attr"`
-	Fill           Fill           `xml:"fill,attr"`
-	Gridhicolor    Gridhicolor    `xml:"gridhicolor,attr"`
-	Showborder     Showborder     `xml:"showborder,attr"`
-	Snaptoguides   Snaptoguides   `xml:"snaptoguides,attr"`
-	Borderlayer    Borderlayer    `xml:"borderlayer,attr"`
-	Gridempcolor   Gridempcolor   `xml:"gridempcolor,attr"`
-	Gridempopacity Gridempopacity `xml:"gridempopacity,attr"`
-	Gridempspacing Gridempspacing `xml:"gridempspacing,attr"`
-	Guide          []struct {
-		Text        Text        `xml:",chardata"`
-		ID          D           `xml:"id,attr"`
-		Orientation Orientation `xml:"orientation,attr"`
-		Position    Position    `xml:"position,attr"`
-	} `xml:"guide"`
-}
-
-type SVG struct {
-	XMLName             xml.Name    `xml:"Svg"`
-	Chardata            Chardata    `xml:",chardata"`
-	Height              float32     `xml:"height,attr"`
-	ID                  D           `xml:"id,attr"`
-	Version             Version     `xml:"version,attr"`
-	Docbase             Docbase     `xml:"docbase,attr"`
-	Docname             Docname     `xml:"docname,attr"`
-	Width               float32     `xml:"width,attr"`
-	Xmlns               Xmlns       `xml:"xmlns,attr"`
-	Cc                  Cc          `xml:"cc,attr"`
-	Dc                  Dc          `xml:"dc,attr"`
-	Inkscape            Inkscape    `xml:"inkscape,attr"`
-	Rdf                 Rdf         `xml:"rdf,attr"`
-	Sodipodi            Sodipodi    `xml:"sodipodi,attr"`
-	SVG                 G           `xml:"svg,attr"`
-	Space               Space       `xml:"space,attr"`
-	AttrStyle           Style       `xml:"style,attr"`
-	ViewBox             Box         `xml:"viewBox,attr"`
-	Xlink               Xlink       `xml:"xlink,attr"`
-	XML                 L           `xml:"xml,attr"`
-	X                   float32     `xml:"x,attr"`
-	Y                   float32     `xml:"y,attr"`
-	ExportFilename      Filename    `xml:"export-filename,attr"`
-	ExportXdpi          Xdpi        `xml:"export-xdpi,attr"`
-	ExportYdpi          Ydpi        `xml:"export-ydpi,attr"`
-	EnableBackground    Background  `xml:"enable-background,attr"`
-	PageBounds          Bounds      `xml:"pageBounds,attr"`
-	RulerOrigin         Origin      `xml:"rulerOrigin,attr"`
-	ViewOrigin          Origin      `xml:"viewOrigin,attr"`
-	Overflow            Overflow    `xml:"overflow,attr"`
-	A                   A           `xml:"a,attr"`
-	Graph               Graph       `xml:"graph,attr"`
-	I                   I           `xml:"i,attr"`
-	FillRule            Rule        `xml:"fill-rule,attr"`
-	ImageRendering      Rendering   `xml:"image-rendering,attr"`
-	ShapeRendering      Rendering   `xml:"shape-rendering,attr"`
-	TextRendering       Rendering   `xml:"text-rendering,attr"`
-	PreserveAspectRatio Ratio       `xml:"preserveAspectRatio,attr"`
-	Fill                Fill        `xml:"fill,attr"`
-	StrokeLinecap       Linecap     `xml:"stroke-linecap,attr"`
-	StrokeLinejoin      Linejoin    `xml:"stroke-linejoin,attr"`
-	StrokeWidth         float32     `xml:"stroke-width,attr"`
-	Ns                  Ns          `xml:"ns,attr"`
-	Ns0                 Ns0         `xml:"ns0,attr"`
-	Xap                 Xap         `xml:"xap,attr"`
-	XapGImg             Img         `xml:"xapGImg,attr"`
-	Pdf                 Pdf         `xml:"pdf,attr"`
-	Pdfx                Pdfx        `xml:"pdfx,attr"`
-	Author              Author      `xml:"author,attr"`
-	Metadata            interface{} `xml:"metadata"`
-	Defs                Defs        `xml:"defs"`
-	// Inkscape-specific
-	Namedview      NamedView        `xml:"namedview"`
-	G              G                `xml:"g"`
-	Path           []Path           `xml:"path"`
-	Circle         []Circle         `xml:"circle"`
-	Text           []Text           `xml:"text"`
-	Style          StyleSheet       `xml:"style"`
-	Switch         Switch           `xml:"switch"`
 	RadialGradient []RadialGradient `xml:"radialGradient"`
-	Use            []Use            `xml:"use"`
-	Image          []Image          `xml:"image"`
-	Polygon        []Polygon        `xml:"polygon"`
-	Ellipse        []Ellipse        `xml:"ellipse"`
-	RDF            interface{}      `xml:"RDF"`
+	Drawable       []Drawable
 }
 
-type TextDrawing struct {
-	Text        Text        `xml:",chardata"` // PACE, Moscow, Stockholm, ...
-	ID          D           `xml:"id,attr"`
-	Style       Style       `xml:"style,attr"`
-	X           float32     `xml:"x,attr"`
-	Space       Space       `xml:"space,attr"`
-	Y           float32     `xml:"y,attr"`
-	Linespacing Linespacing `xml:"linespacing,attr"`
-	Transform   Transform   `xml:"transform,attr"`
-	Fill        Fill        `xml:"fill,attr"`
-	FontFamily  Family      `xml:"font-family,attr"`
-	FontSize    Size        `xml:"font-size,attr"`
-	FontWeight  Weight      `xml:"font-weight,attr"`
-	TextAnchor  Anchor      `xml:"text-anchor,attr"`
-	Class       Class       `xml:"class,attr"`
-	Tspan       []struct {
-		Text  Text    `xml:",chardata"` // FOR SALE, 858-361-2811, $...
-		ID    D       `xml:"id,attr"`
-		Role  Role    `xml:"role,attr"`
-		X     float32 `xml:"x,attr"`
-		Y     float32 `xml:"y,attr"`
-		Style Style   `xml:"style,attr"`
+type Ellipse struct {
+	CoreAttributes
+	Style string `xml:"style,attr"`
+	Cx    string `xml:"cx,attr"`
+	Cy    string `xml:"cy,attr"`
+	Rx    string `xml:"rx,attr"`
+	Ry    string `xml:"ry,attr"`
+}
+
+type Text struct {
+	CoreAttributes
+	Space string `xml:"space,attr"`
+	Style string `xml:"style,attr"`
+	X     string `xml:"x,attr"`
+	Y     string `xml:"y,attr"`
+	Tspan struct {
+		CoreAttributes
+		Style string `xml:"style,attr"`
+		X     string `xml:"x,attr"`
+		Y     string `xml:"y,attr"`
 	} `xml:"tspan"`
 }
 
-type Switch struct {
-	Text          Text          `xml:",chardata"`
-	ID            D             `xml:"id,attr"`
-	ForeignObject ForeignObject `xml:"foreignObject"`
-	G             G             `xml:"g"`
-}
-
-type Circle []struct {
-	Text  Text  `xml:",chardata"`
-	Cx    Cx    `xml:"cx,attr"`
-	Cy    Cy    `xml:"cy,attr"`
-	Fill  Fill  `xml:"fill,attr"`
-	ID    D     `xml:"id,attr"`
-	R     R     `xml:"r,attr"`
-	Class Class `xml:"class,attr"`
-	Rx    Rx    `xml:"rx,attr"`
-	Ry    Ry    `xml:"ry,attr"`
-	Style Style `xml:"style,attr"`
-}
-
-type Ellipse struct {
-	Text        Text      `xml:",chardata"`
-	ID          ID        `xml:"id,attr"`
-	Cx          Cx        `xml:"cx,attr"`
-	Cy          Cy        `xml:"cy,attr"`
-	Rx          Rx        `xml:"rx,attr"`
-	Ry          Ry        `xml:"ry,attr"`
-	Style       Style     `xml:"style,attr"`
-	Stroke      Stroke    `xml:"stroke,attr"`
-	StrokeWidth float32   `xml:"stroke-width,attr"`
-	Transform   Transform `xml:"transform,attr"`
+type Rect struct {
+	Text   string `xml:",chardata"`
+	Style  string `xml:"style,attr"`
+	ID     string `xml:"id,attr"`
+	Width  string `xml:"width,attr"`
+	Height string `xml:"height,attr"`
+	X      string `xml:"x,attr"`
+	Y      string `xml:"y,attr"`
+}
+
+type Drawable struct {
+	*Rect
+	*Ellipse
+	*Text
+}
+
+func (d *Drawable) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {
+	var err error
+	switch start.Name.Local {
+	case "rect":
+		r := Rect{}
+		err = dec.DecodeElement(&r, &start)
+		d.Rect = &r
+	case "ellipse":
+		r := Ellipse{}
+		err = dec.DecodeElement(&r, &start)
+		d.Ellipse = &r
+	case "text":
+		r := Text{}
+		err = dec.DecodeElement(&r, &start)
+		d.Text = &r
+	default:
+		return fmt.Errorf("drawable not supported: %s", start)
+	}
+	return err
 }
 
-type Polygon struct {
-	Text      Text      `xml:",chardata"`
-	ID        ID        `xml:"id,attr"`
-	Points    Points    `xml:"points,attr"`
-	Arg1      Arg1      `xml:"arg1,attr"`
-	Arg2      Arg2      `xml:"arg2,attr"`
-	Cx        Cx        `xml:"cx,attr"`
-	Cy        Cy        `xml:"cy,attr"`
-	R1        R1        `xml:"r1,attr"`
-	R2        R2        `xml:"r2,attr"`
-	Sides     Sides     `xml:"sides,attr"`
-	Type      Type      `xml:"type,attr"`
-	Style     Style     `xml:"style,attr"`
-	Transform Transform `xml:"transform,attr"`
-	Fill      Fill      `xml:"fill,attr"`
-	FillCmyk  Cmyk      `xml:"fill-cmyk,attr"`
+type G struct {
+	CoreAttributes
+	Drawable []Drawable `xml:",any"`
 }
 
-type Image struct {
-	Text      Text      `xml:",chardata"`
-	ID        ID        `xml:"id,attr"`
-	Points    Points    `xml:"points,attr"`
-	Arg1      Arg1      `xml:"arg1,attr"`
-	Arg2      Arg2      `xml:"arg2,attr"`
-	Cx        Cx        `xml:"cx,attr"`
-	Cy        Cy        `xml:"cy,attr"`
-	R1        R1        `xml:"r1,attr"`
-	R2        R2        `xml:"r2,attr"`
-	Sides     Sides     `xml:"sides,attr"`
-	Type      Type      `xml:"type,attr"`
-	Style     Style     `xml:"style,attr"`
-	Transform Transform `xml:"transform,attr"`
-	Fill      Fill      `xml:"fill,attr"`
-	FillCmyk  Cmyk      `xml:"fill-cmyk,attr"`
+type SVG struct {
+	CoreAttributes
+	XMLName xml.Name `xml:"svg"`
+	Width   Length   `xml:"width,attr"`
+	Height  Length   `xml:"height,attr"`
+	ViewBox string   `xml:"viewBox,attr"`
+	Version string   `xml:"version,attr"`
+	Xlink   string   `xml:"xlink,attr"`
+	Xmlns   string   `xml:"xmlns,attr"`
+	SVG     string   `xml:"svg,attr"`
+	Defs    []Defs   `xml:"defs"`
+	G       G        `xml:"g"`
 }

+ 25 - 0
svg/svg_test.go

@@ -0,0 +1,25 @@
+package svg
+
+import "testing"
+import "encoding/xml"
+import "io"
+import "os"
+
+func TestLoadSimple(t *testing.T) {
+	f, err := os.Open("../testdata/yellow_circle.svg")
+	if err != nil {
+		t.Fatalf("%s", err)
+	}
+	defer f.Close()
+	buf, err := io.ReadAll(f)
+	if err != nil {
+		t.Fatalf("%s", err)
+	}
+	svg := SVG{}
+	err = xml.Unmarshal(buf, &svg)
+	if err != nil {
+		t.Fatalf("%s", err)
+	}
+
+	t.Logf("svg: %v+", svg)
+}