1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package main
19
20 import (
21 "bufio"
22 "encoding/xml"
23 "flag"
24 "fmt"
25 "image/color"
26 "os"
27 "reflect"
28 "strconv"
29 "strings"
30 )
31
32 var delim string
33
34 func init() {
35 flag.StringVar(&delim, "d", "\t", "indicate field delimiter of input")
36 flag.Parse()
37 }
38
39 type Colors struct {
40 Sequential []Scheme `xml:"sequential>scheme"`
41 Diverging []Scheme `xml:"diverging>scheme"`
42 Qualitative []Scheme `xml:"categorical>scheme"`
43 }
44
45 type Scheme struct {
46 ID string `xml:"id,attr"`
47 Name string `xml:"name"`
48 Class []Class `xml:"class"`
49 }
50
51 type Class struct {
52 Laptop *string `xml:"laptop"`
53 CRT *string `xml:"crt"`
54 ColorBlind *string `xml:"eye"`
55 Copy *string `xml:"copy"`
56 Projector *string `xml:"projector"`
57 Color []Color `xml:"color"`
58 }
59
60 type Color struct {
61 RGB string `xml:"rgb"`
62 Hex string `xml:"hex"`
63 CMYK string `xml:"cmyk"`
64 }
65
66 var (
67 usability = map[string]string{"x": "Bad", "q": "Unsure", "": "Good"}
68 class = map[string]string{"Diverging": "Diverging", "Qualitative": "NonDiverging", "Sequential": "NonDiverging"}
69 )
70
71 func mustAtoi(f string, base int) byte {
72 i, err := strconv.ParseUint(f, base, 8)
73 if err != nil {
74 panic(err)
75 }
76 return byte(i)
77 }
78
79 func getLetters(f string) map[string]map[color.RGBA]byte {
80 letters := make(map[string]map[color.RGBA]byte)
81
82 lf, err := os.Open(f)
83 if err != nil {
84 fmt.Printf("error: %v", err)
85 os.Exit(1)
86 }
87
88 label := make(map[string]int)
89 scanner := bufio.NewScanner(lf)
90 var (
91 lastType string
92
93 last = make(map[string]string)
94 )
95
96 for scanner.Scan() {
97 line := scanner.Text()
98 if len(strings.TrimSpace(line)) == 0 {
99 break
100 }
101 fields := strings.Split(line, delim)
102 if fields[0] == "ColorName" {
103 for i, f := range fields {
104 label[f] = i
105 }
106 continue
107 }
108 if name := fields[label["ColorName"]]; len(name) != 0 {
109 l, ok := letters[name]
110 if !ok {
111 l = make(map[color.RGBA]byte)
112 letters[name] = l
113 }
114 if len(fields) > label["SchemeType"] {
115 if typ := fields[label["SchemeType"]]; len(typ) != 0 {
116 lastType = typ
117 }
118 }
119 if name != last[lastType] {
120 last[lastType] = name
121 }
122 }
123 letters[last[lastType]][color.RGBA{
124 R: mustAtoi(fields[label["R"]], 10),
125 G: mustAtoi(fields[label["G"]], 10),
126 B: mustAtoi(fields[label["B"]], 10),
127 }] = fields[label["ColorLetter"]][0]
128 }
129 if err := scanner.Err(); err != nil {
130 fmt.Fprintln(os.Stderr, "reading standard input:", err)
131 os.Exit(1)
132 }
133
134 return letters
135 }
136
137 func main() {
138 var cols Colors
139 xf, err := os.Open(os.Args[1])
140 if err != nil {
141 fmt.Printf("error: %v", err)
142 os.Exit(1)
143 }
144 dec := xml.NewDecoder(xf)
145 err = dec.Decode(&cols)
146 if err != nil {
147 fmt.Printf("error: %v", err)
148 os.Exit(1)
149 }
150
151 letters := getLetters(os.Args[2])
152 fmt.Println(`// Apache-Style Software License for ColorBrewer software and ColorBrewer Color Schemes
153 //
154 // Copyright ©2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University.
155 //
156 // Licensed under the Apache License, Version 2.0 (the "License");
157 // you may not use this file except in compliance with the License.
158 // You may obtain a copy of the License at
159 //
160 // http://www.apache.org/licenses/LICENSE-2.0
161 //
162 // Unless required by applicable law or agreed to in writing, software distributed
163 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
164 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
165 // specific language governing permissions and limitations under the License.
166 // Go implementation Copyright ©2013 The bíogo Authors. All rights reserved.
167 // Use of this source code is governed by a BSD-style
168 // license that can be found in the LICENSE file.
169
170 // Go port Copyright ©2015 The gonum Authors. All rights reserved.
171 // Use of this source code is governed by a BSD-style
172 // license that can be found in the LICENSE file.
173
174 // Go port Copyright ©2013 The bíogo Authors. All rights reserved.
175 // Use of this source code is governed by a BSD-style
176 // license that can be found in the LICENSE file.
177
178 // Palette Copyright ©2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University.
179
180 package brewer
181
182 import (
183 "image/color"
184 )
185 `)
186 cv := reflect.ValueOf(cols)
187 ct := cv.Type()
188 for i := 0; i < cv.NumField(); i++ {
189 f := cv.Field(i)
190 n := ct.Field(i).Name
191 fmt.Println("var (")
192 for _, schm := range f.Interface().([]Scheme) {
193 fmt.Printf("\t%s = %s{\n", schm.ID, n, n)
194 for _, cls := range schm.Class {
195 fmt.Printf("\t\t%d: %sPalette{\n\t\t\tID: %q,\n\t\t\tName: %q,\n",
196 len(cls.Color), class[n],
197 schm.ID, schm.Name,
198 )
199 clv := reflect.ValueOf(cls)
200 clt := clv.Type()
201 for j := 0; j < clv.NumField()-1; j++ {
202 clvf := clv.Field(j)
203 if clvf.IsNil() {
204 continue
205 }
206 fmt.Printf("\t\t\t%s: %s,\n", clt.Field(j).Name, usability[*clvf.Interface().(*string)])
207 }
208 fmt.Println("\t\t\tColor: []color.Color{")
209 for _, col := range cls.Color {
210 r, g, b := mustAtoi(col.Hex[2:4], 16), mustAtoi(col.Hex[4:6], 16), mustAtoi(col.Hex[6:8], 16)
211 fmt.Printf("\t\t\t\tColor{%q, color.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff}},\n",
212 letters[schm.ID][color.RGBA{r, g, b, 0}], r, g, b,
213 )
214 }
215 fmt.Println("\t\t\t},\n\t\t},")
216 }
217 fmt.Println("\t}")
218 }
219 fmt.Println(")")
220 }
221 fmt.Println("var (")
222 for i := 0; i < cv.NumField(); i++ {
223 f := cv.Field(i)
224 n := ct.Field(i).Name
225 nl := strings.ToLower(n)
226 fmt.Printf("\t%s = map[string]%s{\n", nl, n)
227 for _, schm := range f.Interface().([]Scheme) {
228 fmt.Printf("\t\t%q: %s,\n", schm.ID, schm.ID)
229 }
230 fmt.Println("\t}")
231 }
232 fmt.Println("\tall = map[string]interface{}{")
233 for i := 0; i < cv.NumField(); i++ {
234 f := cv.Field(i)
235 for _, schm := range f.Interface().([]Scheme) {
236 fmt.Printf("\t\t%q: %s,\n", schm.ID, schm.ID)
237 }
238 }
239 fmt.Println("\t}")
240 fmt.Println(")")
241 }
242
View as plain text