aboutsummaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/image/colornames/gen.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/image/colornames/gen.go')
-rw-r--r--vendor/golang.org/x/image/colornames/gen.go197
1 files changed, 197 insertions, 0 deletions
diff --git a/vendor/golang.org/x/image/colornames/gen.go b/vendor/golang.org/x/image/colornames/gen.go
new file mode 100644
index 0000000..d46e968
--- /dev/null
+++ b/vendor/golang.org/x/image/colornames/gen.go
@@ -0,0 +1,197 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// This program generates table.go from
+// http://www.w3.org/TR/SVG/types.html#ColorKeywords
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "image/color"
+ "io"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+
+ "golang.org/x/net/html"
+ "golang.org/x/net/html/atom"
+)
+
+// matchFunc matches HTML nodes.
+type matchFunc func(*html.Node) bool
+
+// appendAll recursively traverses the parse tree rooted under the provided
+// node and appends all nodes matched by the matchFunc to dst.
+func appendAll(dst []*html.Node, n *html.Node, mf matchFunc) []*html.Node {
+ if mf(n) {
+ dst = append(dst, n)
+ }
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
+ dst = appendAll(dst, c, mf)
+ }
+ return dst
+}
+
+// matchAtom returns a matchFunc that matches a Node with the specified Atom.
+func matchAtom(a atom.Atom) matchFunc {
+ return func(n *html.Node) bool {
+ return n.DataAtom == a
+ }
+}
+
+// matchAtomAttr returns a matchFunc that matches a Node with the specified
+// Atom and a html.Attribute's namespace, key and value.
+func matchAtomAttr(a atom.Atom, namespace, key, value string) matchFunc {
+ return func(n *html.Node) bool {
+ return n.DataAtom == a && getAttr(n, namespace, key) == value
+ }
+}
+
+// getAttr fetches the value of a html.Attribute for a given namespace and key.
+func getAttr(n *html.Node, namespace, key string) string {
+ for _, attr := range n.Attr {
+ if attr.Namespace == namespace && attr.Key == key {
+ return attr.Val
+ }
+ }
+ return ""
+}
+
+// re extracts RGB values from strings like "rgb( 0, 223, 128)".
+var re = regexp.MustCompile(`rgb\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+)\)`)
+
+// parseRGB parses a color from a string like "rgb( 0, 233, 128)". It sets
+// the alpha value of the color to full opacity.
+func parseRGB(s string) (color.RGBA, error) {
+ m := re.FindStringSubmatch(s)
+ if m == nil {
+ return color.RGBA{}, fmt.Errorf("malformed color: %q", s)
+ }
+ var rgb [3]uint8
+ for i, t := range m[1:] {
+ num, err := strconv.ParseUint(t, 10, 8)
+ if err != nil {
+ return color.RGBA{}, fmt.Errorf("malformed value %q in %q: %s", t, s, err)
+ }
+ rgb[i] = uint8(num)
+ }
+ return color.RGBA{rgb[0], rgb[1], rgb[2], 0xFF}, nil
+}
+
+// extractSVGColors extracts named colors from the parse tree of the SVG 1.1
+// spec HTML document "Chapter 4: Basic data types and interfaces".
+func extractSVGColors(tree *html.Node) (map[string]color.RGBA, error) {
+ ret := make(map[string]color.RGBA)
+
+ // Find the tables which store the color keywords in the parse tree.
+ colorTables := appendAll(nil, tree, func(n *html.Node) bool {
+ return n.DataAtom == atom.Table && strings.Contains(getAttr(n, "", "summary"), "color keywords part")
+ })
+
+ for _, table := range colorTables {
+ // Color names and values are stored in TextNodes within spans in each row.
+ for _, tr := range appendAll(nil, table, matchAtom(atom.Tr)) {
+ nameSpan := appendAll(nil, tr, matchAtomAttr(atom.Span, "", "class", "prop-value"))
+ valueSpan := appendAll(nil, tr, matchAtomAttr(atom.Span, "", "class", "color-keyword-value"))
+
+ // Since SVG 1.1 defines an odd number of colors, the last row
+ // in the second table does not have contents. We skip it.
+ if len(nameSpan) != 1 || len(valueSpan) != 1 {
+ continue
+ }
+ n, v := nameSpan[0].FirstChild, valueSpan[0].FirstChild
+ // This sanity checks for the existence of TextNodes under spans.
+ if n == nil || n.Type != html.TextNode || v == nil || v.Type != html.TextNode {
+ return nil, fmt.Errorf("extractSVGColors: couldn't find name/value text nodes")
+ }
+ val, err := parseRGB(v.Data)
+ if err != nil {
+ return nil, fmt.Errorf("extractSVGColors: couldn't parse name/value %q/%q: %s", n.Data, v.Data, err)
+ }
+ ret[n.Data] = val
+ }
+ }
+ return ret, nil
+}
+
+const preamble = `// generated by go generate; DO NOT EDIT.
+
+package colornames
+
+import "image/color"
+
+`
+
+// WriteColorNames writes table.go.
+func writeColorNames(w io.Writer, m map[string]color.RGBA) {
+ keys := make([]string, 0, len(m))
+ for k := range m {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+
+ fmt.Fprintln(w, preamble)
+ fmt.Fprintln(w, "// Map contains named colors defined in the SVG 1.1 spec.")
+ fmt.Fprintln(w, "var Map = map[string]color.RGBA{")
+ for _, k := range keys {
+ c := m[k]
+ fmt.Fprintf(w, "%q:color.RGBA{%#02x, %#02x, %#02x, %#02x}, // rgb(%d, %d, %d)\n",
+ k, c.R, c.G, c.B, c.A, c.R, c.G, c.B)
+ }
+ fmt.Fprintln(w, "}\n")
+ fmt.Fprintln(w, "// Names contains the color names defined in the SVG 1.1 spec.")
+ fmt.Fprintln(w, "var Names = []string{")
+ for _, k := range keys {
+ fmt.Fprintf(w, "%q,\n", k)
+ }
+ fmt.Fprintln(w, "}\n")
+ fmt.Fprintln(w, "var (")
+ for _, k := range keys {
+ c := m[k]
+ // Make the upper case version of k: "Darkred" instead of "darkred".
+ k = string(k[0]-0x20) + k[1:]
+ fmt.Fprintf(w, "%s=color.RGBA{%#02x, %#02x, %#02x, %#02x} // rgb(%d, %d, %d)\n",
+ k, c.R, c.G, c.B, c.A, c.R, c.G, c.B)
+ }
+ fmt.Fprintln(w, ")")
+}
+
+const url = "http://www.w3.org/TR/SVG/types.html"
+
+func main() {
+ res, err := http.Get(url)
+ if err != nil {
+ log.Fatalf("Couldn't read from %s: %s\n", url, err)
+ }
+ defer res.Body.Close()
+
+ tree, err := html.Parse(res.Body)
+ if err != nil {
+ log.Fatalf("Couldn't parse %s: %s\n", url, err)
+ }
+
+ colors, err := extractSVGColors(tree)
+ if err != nil {
+ log.Fatalf("Couldn't extract colors: %s\n", err)
+ }
+
+ buf := &bytes.Buffer{}
+ writeColorNames(buf, colors)
+ fmted, err := format.Source(buf.Bytes())
+ if err != nil {
+ log.Fatalf("Error while formatting code: %s\n", err)
+ }
+
+ if err := ioutil.WriteFile("table.go", fmted, 0644); err != nil {
+ log.Fatalf("Error writing table.go: %s\n", err)
+ }
+}