-
Notifications
You must be signed in to change notification settings - Fork 9
/
brewterpolate.ado
208 lines (148 loc) · 6.92 KB
/
brewterpolate.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
********************************************************************************
* Description of the Program - *
* This program is used to generate a series of colors interpolated between two *
* known colors. There are also options available to return an arbitrarily *
* brighter and/or darker color (for RGB), the inverse of the color, and *
* provides options to return color strings in several color spaces. *
* *
* Data Requirements - *
* none *
* *
* System Requirements - *
* JRE >= 1.8 *
* *
* Program Output - *
* r(start) - The value of the color used as the starting point *
* r(end) - The value of the color used as the end point *
* r(colorstring) - A string of colors from start to end in a single macro *
* r(terpcolor#) - The ith interpolated color between start and end *
* *
* Lines - *
* 207 *
* *
********************************************************************************
*! brewterpolate
*! v 1.0.1
*! 03APR2016
// Drop the program from memory if loaded
cap prog drop brewterpolate
// Define the program with rclass property
prog def brewterpolate, rclass
// Set the version to interpret the code under
version 13.1
// Set the syntax for the program
syntax, SColor(string) EColor(string) Colors(integer) ///
[ CMod(string) ICSpace(string) RCSpace(string) INVerse Grayscale ]
// If user specified grayscale set the boolean for that macro
if `"`grayscale'"' != "" loc grayscale "true"
// If not set to false to prevent the returned colors coming back in
// grayscale
else loc grayscale "false"
// Check arguments passed to color modification parameter
if !inlist(`"`cmod'"', "brighter", "darker", "saturated", ///
"desaturated", "") {
// Print error message to screen
di as err `"Argument `cmod' not allowed for the color "' ///
"modification parameter. Ignoring this argument."
// Reset color modification to a nullstring
loc cmod ""
} // End IF Block for color modification parameter
if mi("`cmod'") loc cmod `""'
// Check input color space
if !inlist(`"`icspace'"', "rgb", "rgba", "srgb", "srgba", "hsb") & ///
!inlist(`"`icspace'"', "hsba", "web", "weba", "hex", "hexa", "") {
// Print error message to screen
di as err `"Illegal input color space `icspace'."' _n ///
"The only allowable values are: rgb, srgb, hsb, hsba, and " ///
"web." _n "Program defaults to RGB if no value passed."
// Return error code
err 198
} // End IF Block for invalid input color space
// Check for web-based color values
else if inlist(`"`icspace'"', "weba", "hexa") {
// Check for a sufficient number of characters in the string
if (length(`"`scolor'"') < 8) {
// Print error message
di as err "Hexademical values with alpha transparency must have be >= 8 characters in length"
// Set error message
err 119
} // End IF Block for too few characters
// Check for valid specification using a decimal valued alpha parameter
// requires a space delimiter between the hexstring and decimal values
// which may or may not include a leading zero/one
else if !regexm(`"`scolor'"', "^([a-zA-Z0-9].*) ([0-1]\.[0-9.*])|(\.[0-9])$") {
// Print error message
di as err "Must use a single space between the hex string and decimal valued alpha parameter"
// Set error message
err 119
} // End ELSE Block for malformed alpha param
} // End ELSEIF Block for web-based colors
// Check for web-based color values
else if `"`icspace'"' == "" loc icspace "rgb"
// Check returned color space
if !inlist(`"`rcspace'"', "rgb", "rgba", "srgb", "srgba", "hsb") & ///
!inlist(`"`rcspace'"', "hsba", "hex", "hexa", "web", "weba", "") {
// Print error message to screen
di as err `"Illegal input color space `icspace'."' _n ///
"The only allowable values are: rgb(a), srgb(a), and hsb(a)." ///
_n "Program defaults to RGB if no value passed."
// Return error code
err 198
} // End IF Block for invalid input color space
// Check for null return spaces
else if `"`rcspace'"' == "" loc rcspace "rgb"
// Remove ',' characters and replace with spaces
loc ecolor : subinstr loc ecolor "," " ", all
// Remove double spaces and replace with single space
loc ecolor : subinstr loc ecolor " " " ", all
// Remove ',' characters and replace with spaces
loc scolor : subinstr loc scolor "," " ", all
// Remove double spaces and replace with single space
loc scolor : subinstr loc scolor " " " ", all
// Set boolean value for no inverted colors
if "`inverse'" == "" loc inverse "false"
// If user wants inverted colors
else loc inverse "true"
// Incremented by 1 in the Java plugin
loc icolors = `colors'
// Call the java program to interpolate the colors
javacall org.paces.stata.ColorTerp interpcolors, ///
args(`icspace' `rcspace' "`scolor'" "`ecolor'" `colors' "`cmod'" ///
`inverse' `grayscale')
// Clear existing return valies
return clear
// Return colors
loc retcolors `= `colors' + 2'
// Loop over the returned results
forv i = 1/`retcolors' {
// Set the return macros
ret loc terpcolor`i' "`color`i''"
// On first iteration
if `i' == 1 {
// Add each of the colors to the same macro
loc scolorstring `""`color`i''""'
// Store the starting color
loc startingcolor "`color`i''"
} // End IF Block for first iteration
// ELSE Block for cases after the first iteration
else {
// Add each of the colors to the same macro
loc scolorstring `"`scolorstring' "`color`i''""'
// Check for last iteration and store ending color
if `i' == `retcolors' loc endingcolor "`color`i''"
} // End ELSE Block for iterations after the first
} // End Loop
// Return starting color
ret loc start "`startingcolor'"
// Return ending color
ret loc end "`endingcolor'"
// Return the total number of colors
ret loc totalcolors `retcolors'
// Return range for interpolated colors
ret loc interpstart 2
ret loc interpend `= `retcolors' - 1'
// Return all the colors in a single macro
ret loc colorstring `scolorstring'
ret loc colorsdelim `: subinstr loc scolorstring `"" ""' `"", ""', all'
// End Program definition
end