package geagle import ( "encoding/xml" "io" "strconv" "strings" ) type Boolean string func True() Boolean { return "yes" } func False() Boolean { return "no" } func (b Boolean) ToBool() bool { return b == "yes" || b == "on" } type Rotation string func (r Rotation) Angle() int { s := strings.TrimPrefix(string(r), "R") v, _ := strconv.Atoi(s) return v } // Layer definition type Layer struct { Number int `xml:"number,attr"` Name string `xml:"name,attr"` Color int `xml:"color,attr"` Fill int `xml:"fill,attr"` Visible Boolean `xml:"visible,attr"` Active Boolean `xml:"active,attr"` } // Grid definition type Grid struct { Distance float32 `xml:"distance,attr"` Unitdist string `xml:"unitdist,attr"` Unit string `xml:"unit,attr"` Style string `xml:"style,attr"` Multiple int `xml:"multiple,attr"` Display Boolean `xml:"display,attr"` // Alternative Grid Information AlternativeDistance float32 `xml:"altdistance,attr"` AlternativeDistanceUnit string `xml:"altunitdist,attr"` AlternativeUnit string `xml:"altunit,attr"` } type Point struct { X float32 `xml:"x,attr"` Y float32 `xml:"y,attr"` } type Hole struct { Point Drill string `xml:"drill,attr"` } type Line struct { X1 float32 `xml:"x1,attr"` X2 float32 `xml:"x2,attr"` Y1 float32 `xml:"y1,attr"` Y2 float32 `xml:"y2,attr"` } type Wire struct { Line Width float32 `xml:"width,attr"` Layer int `xml:"layer,attr"` Curve float64 `xml:"curve,attr,omitempty"` Cap string `xml:"cap,attr,omitempty"` } type Pad struct { Point Name string `xml:"name,attr"` Drill float32 `xml:"drill,attr"` Shape string `xml:"shape,attr"` Rotation Rotation `xml:"rot,attr,omitempty"` } type SmdPad struct { Point Name string `xml:"name,attr"` Width float32 `xml:"dx,attr"` Height float32 `xml:"dy,attr"` Layer int `xml:"layer,attr"` } type Text struct { Point Size float32 `xml:"size,attr"` Layer int `xml:"layer,attr"` Alignment string `xml:"align,attr,omitempty"` Ratio int `xml:"ratio,attr,omitempty"` Text string `xml:",innerxml"` } type Circle struct { Point Radius float32 `xml:"radius,attr"` Width float32 `xml:"width,attr"` Layer int `xml:"layer,attr"` } type Rectangle struct { Line Layer int `xml:"layer,attr"` } type Primitives struct { Wires []Wire `xml:"wire"` Circles []Circle `xml:"circle"` Texts []Text `xml:"text"` Rectangle []Rectangle `xml:"rectangle"` } type Package struct { Name string `xml:"name,attr"` Description string `xml:"description"` Urn string `xml:"urn,attr,omitempty"` Primitives Holes []Hole `xml:"hole"` Pads []Pad `xml:"pad"` SmdPads []SmdPad `xml:"smd"` } type Pin struct { Point Name string `xml:"name,attr"` Visible string `xml:"visible,attr,omitempty"` Length string `xml:"length,attr,omitempty"` Direction string `xml:"direction,attr,omitempty"` Rotation Rotation `xml:"rot,attr,omitempty"` Function string `xml:"function,attr,omitempty"` } type Symbol struct { Name string `xml:"name,attr"` Urn string `xml:"urn,attr,omitempty"` Primitives Pins []Pin `xml:"pin"` } type Gate struct { Point Name string `xml:"name,attr"` Symbol string `xml:"symbol,attr"` } type Technology struct { Name string `xml:"name,attr"` } type Connection struct { Gate string `xml:"gate,attr"` Pin string `xml:"pin,attr"` Pad string `xml:"pad,attr"` } type Package3d struct { Urn string `xml:"package3d_urn,attr"` } type Device struct { Name string `xml:"name,attr"` Package string `xml:"package,attr"` Package3d []Package3d `xml:package3dinstances>package3dinstance"` Technologies []Technology `xml:"technologies>technology"` Connections []Connection `xml:"connects>connect"` } type Deviceset struct { Name string `xml:"name,attr"` Prefix string `xml:"prefix,attr"` Description string `xml:"description,omitempty"` Urn string `xml:"urn,attr,omitempty"` Gates []Gate `xml:"gates>gate"` Devices []Device `xml:"devices>device"` } type Library struct { Packages []Package `xml:"packages>package"` Symbols []Symbol `xml:"symbols>symbol"` Devicesets []Deviceset `xml:"devicesets>deviceset"` } type Drawing struct { Grid Grid `xml:"grid"` Layers []Layer `xml:"layers>layer"` Library Library `xml:"library"` } type FileHeader struct { Version string `xml:"version,attr"` } func ParseLibrary(in io.Reader) (result Drawing, err error) { file := struct { Eagle FileHeader Drawing Drawing `xml:"drawing"` }{} decoder := xml.NewDecoder(in) err = decoder.Decode(&file) return file.Drawing, err } // defines an eagle file type eagle struct { FileHeader Drawing *Drawing `xml:"drawing"` } func (drw *Drawing) WriteTo(out io.Writer) error { // write DOCTYPE and xml header io.WriteString(out, "") io.WriteString(out, "") encoder := xml.NewEncoder(out) file := eagle{ FileHeader: FileHeader{"8.3.2"}, Drawing: drw, } return encoder.Encode(&file) }