commit a1db7dd9ba949bc1a738ca271fe4ed2c82ae1882 Author: Julian Daube Date: Tue Feb 5 00:30:06 2019 +0100 initial commit diff --git a/Library.go b/Library.go new file mode 100644 index 0000000..a9f1885 --- /dev/null +++ b/Library.go @@ -0,0 +1,238 @@ +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) +}