-
Notifications
You must be signed in to change notification settings - Fork 9
/
brewtheme.ado
392 lines (278 loc) · 12.8 KB
/
brewtheme.ado
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
********************************************************************************
* Description of the Program - *
* This program is used to set theme values for things like backgrounds, point *
* sizes, font sizes, etc... The purpose is to allow the end user greater *
* flexibility in developing graph themes (e.g., create a ggplot2 theme with *
* a given set of palettes and also create a theme with a more Tufte inspired *
* set of background/size parameters). *
* *
* Data Requirements - *
* Allows users to build the property file interactively *
* *
* System Requirements - *
* none *
* *
* Program Output - *
* theme-[theme file name].theme - The theme file created by the user *
* theme-[theme file name]_achromatopsia.theme - Full Colorblind version *
* theme-[theme file name]_protanopia.theme - Full Colorblind version *
* theme-[theme file name]_deuteranopia.theme - Full Colorblind version *
* theme-[theme file name]_tritanopia.theme - Full Colorblind version *
* *
* Lines - *
* 391 *
* *
********************************************************************************
*! brewtheme
*! v 1.0.2
*! 09NOV2016
// Drop the program from memory if loaded
cap prog drop brewtheme
// Define program
prog def brewtheme
// Set version to interpret under
version 13.1
// Set syntax tree
syntax [anything(name=themefile id="Theme File Name")] [, ///
ABOvebelow(string asis) ANGLESTYle(string asis) ///
AREASTYle(string asis) ARROWSTYle(string asis) ///
AXISSTYle(string asis) BARLABELPos(string asis) ///
BARLABELSTYle(string asis) BARSTYle(string asis) ///
BYGRAPHSTYle(string asis) CLEGENDSTYle(string asis) ///
CLOCKdir(string asis) COLor(string asis) ///
COMPASS2dir(string asis) COMPASS3dir(string asis) ///
CONNECTSTYle(string asis) DOTTYPESTYle(string asis) ///
GRAPHSIze(string asis) GRAPHSTYle(string asis) ///
GRIDLINESTYle(string asis) GRIDRINGSTYle(string asis) ///
GRIDSTYle(string asis) GSIZE(string asis) ///
HORIZontal(string asis) LABELSTYle(string asis) ///
LEGENDSTYle(string asis) LINEPATtern(string asis) ///
LINESTYle(string asis) LINEWidth(string asis) ///
MARGin(string asis) MEDTYPESTYle(string asis) ///
NUMSTYle(string asis) NUMTICKS(string asis) ///
PIEGRAPHSTYle(string asis) PIELABELSTYle(string asis) ///
PLOTREGIONSTYle(string asis) RELATIVEPos(string asis) ///
RELSIze(string asis) SPECial(string asis) ///
STARSTYle(string asis) SYMBol(string asis) ///
SYMBOLSIze(string asis) SUNFLOWERSTYle(string asis) ///
TEXTBOXSTYle(string asis) TICKPosition(string asis) ///
TICKSTYle(string asis) TICKSETSTYle(string asis) ///
VERTICALText(string asis) YESNo(string asis) ///
ZYX2Rule(string asis) ZYX2STYle(string asis) ///
LOADThemedata brewscheme ]
// Check for brewscheme Mata library
qui: brewlibcheck
// Stores the root file path for theme files
loc themeroot `c(sysdir_personal)'b/theme/theme
// Preserve the current state of the data
preserve
// Only initialize this mata class if program not called by brewscheme
if `"`brewscheme'"' == "" {
// Create a brewcolors object
mata: brewc = brewcolors()
} // End IF Block to initialize brewcolors object
// Get the list of unique meta names
qui: mata: brewc.getNames(1, 1)
// Build dataset with classes, arguments, and parameter values
qui: themedata
// Store the name of the tempfile
loc tmptheme `r(themefile)'
// Load the tempfile
qui: use `tmptheme', clear
// Loop over the class names
foreach v in `"`r(classes)'"' {
// Store arguments in new locals
loc `v'args `"`r(``v'args')'"'
// If the user passed values
if `"``v''"' != "" {
// Loop over arguments
forv i = 1/`: word count ``v''' {
// Store argument
loc indi `: word `i' of ``v'''
loc arg `: word 1 of `indi''
loc val `: word 2 of `indi''
// Block used to handle cases with unbalanced quotation marks
// in the value of the key-value pair.
if substr(`"`val'"', 1, 1) != `"""' & ///
substr(`"`val'"', -1, 1) == `"""' {
// If the first character isn't a " but the last
// character is a " replace all instances of " with
// nothing in the value string
loc val `: subinstr loc val `"""' "", all'
} // End IF Block for unbalanced quotation mark handling
// Check if valid argument
if `"`: list arg in `v'args'"' != "" {
// Search for the RGB values
qui: mata: brewc.brewNameSearch("`val'")
foreach x in rgb achromatopsia protanopia deuteranopia tritanopia {
if `"``x''"' == "" loc `x' none
}
// Check for named color style
if `: list val in colornames' == 1 {
// Replace value with user specified value
qui: replace value = `"`val'"' if ///
classname == `"`v'"' & argname == `"`arg'"'
// Populate color blind variables
qui: replace achromatopsia = `"`val'_achromatopsia"' ///
if classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace protanopia = `"`val'_protanopia"' if ///
classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace deuteranopia = `"`val'_deuteranopia"' ///
if classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace tritanopia = `"`val'_tritanopia"' if ///
classname == `"`v'"' & argname == `"`arg'"'
} // End IF Block for color value
// Check to see if the value was a color
else if `"`val'"' != `"`rgb'"' & ///
`: list val in colornames' == 0 {
// Replace value with user specified value
qui: replace value = `""`rgb'""' if ///
classname == `"`v'"' & argname == `"`arg'"'
// Populate color blind variables
qui: replace achromatopsia = `""`achromatopsia'""' ///
if classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace protanopia = `""`protanopia'""' if ///
classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace deuteranopia = `""`deuteranopia'""' ///
if classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace tritanopia = `""`tritanopia'""' if ///
classname == `"`v'"' & argname == `"`arg'"'
} // End ELSEIF Block for color value
// For non color values
else {
// Replace value with user specified value
qui: replace value = `"`rgb'"' if ///
classname == `"`v'"' & argname == `"`arg'"'
// Populate color blind variables
qui: replace achromatopsia = `"`achromatopsia'"' ///
if classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace protanopia = `"`protanopia'"' if ///
classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace deuteranopia = `"`deuteranopia'"' if ///
classname == `"`v'"' & argname == `"`arg'"'
// Populate red colorblindness
qui: replace tritanopia = `"`tritanopia'"' if ///
classname == `"`v'"' & argname == `"`arg'"'
} // End ELSE Block for non color values
} // End IF Block for valid arguments
} // End Loop over arguments
} // End IF Block for user supplied values
} // End Loop over class names
// Save changes to the tempfile
qui: save `tmptheme', replace
// Check for name of themefile
if `"`themefile'"' != "" {
// Check for directory and if not build it
dirfile `c(sysdir_personal)'b, p(theme)
// Write the scheme file to a location on the path
qui: file open theme using `"`themeroot'-`themefile'.theme"', w replace
// Loop over colorblind variables
foreach cb in achromatopsia protanopia deuteranopia tritanopia {
// Open a theme file for each of the colorblind types
qui: file open `cb'theme using ///
`"`themeroot'-`themefile'_`cb'.theme"', w replace
} // End Loop to open color blindness theme files
// Call write subroutine
themewriter
} // End IF BLock for writing a theme file if user specified a theme file name
// If no name is passed write the default file
else {
// Check for directory and if not build it
dirfile `c(sysdir_personal)'b, p(theme)
// Write the scheme file to a location on the path
qui: file open theme using `"`themeroot'-default.theme"', w replace
// Loop over colorblind variables
foreach cb in achromatopsia protanopia deuteranopia tritanopia {
// Open a theme file for each of the colorblind types
qui: file open `cb'theme using ///
`"`themeroot'-default_`cb'.theme"', w replace
} // End Loop to open color blindness theme files
// Call write subroutine
themewriter
} // End else block for a default theme file
// Restore the data to the original state
restore
// Check loadthemedata option
if `"`loadthemedata'"' != "" {
// Load the tempfile
qui: use `tmptheme', clear
} // End IF Block for load theme data option
// End Program Definition
end
// Drop subroutine if already loaded in memory
cap prog drop themedata
// Subroutine to build look up dataset
prog def themedata, rclass
// Null syntax structure
syntax
// Drop data from memory
clear
// Check for file
cap confirm file `"`c(sysdir_plus)'b/brewthemedata.do"'
// If does not exist
if _rc != 0 {
// Download the file from GitHub
copy "http://wbuchanan.github.io/brewscheme/brewthemedata.do" ///
`"`c(sysdir_plus)'b/brewthemedata.do"'
} // End IF Block for non-existent file
// Run the do file
qui: do `"`c(sysdir_plus)'b/brewthemedata.do"'
// Reserve namespace for a temporary file
tempfile themedata
// Get the names of the classes that can have values altered
qui: levelsof classname if substr(classname, 1, 1) != "*", loc(classes)
// Return a local with the class names
ret loc classes `classes'
// Loop over the class names
foreach v of loc classes {
// Get the argument names for the classes
qui: levelsof argname if classname == `"`v'"', loc(args)
// Return the arguments for the given class
ret loc `v'args `args'
} // End Loop over the class names
// Save the data to a temporary file
qui: save `themedata'.dta, replace
// Clear those data from memory
clear
// Return the name of the tempfile
ret loc themefile `themedata'.dta
// End of the subroutine definition
end
// Drop subroutine if already loaded in memory
cap prog drop themewriter
// Subroutine for writing the data to a theme file
prog def themewriter
// Null syntax structure
syntax
// Loop over the observations
forv i = 1/`c(N)' {
// Combine the different variables into a single string
loc string `: di classnm[`i'] + argnm[`i'] + value[`i']'
// Write the string to the file and insert the number of new
// lines based on new line variable
file write theme `"`"`string'"' `: di newlines[`i']'"' _n
// Loop over the colorblindness types
foreach cb in achromatopsia protanopia deuteranopia tritanopia {
// Creates string with color bli
loc string `: di classnm[`i'] + argnm[`i'] + `cb'[`i']'
// Write to the colorblind simulated theme file
file write `cb'theme `"`"`string'"' `: di newlines[`i']'"' _n
} // End Loop over colorblind transformed theme files
} // End Loop over observations
// Close the open file connection
file close theme
// Loop over the colorblindness types
foreach cb in achromatopsia protanopia deuteranopia tritanopia {
// Close the theme file
file close `cb'theme
} // End loop over colorblindness type theme files
// End of sub routine
end