cataract 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.clang-tidy +30 -0
- data/.github/workflows/ci-macos.yml +12 -0
- data/.github/workflows/ci.yml +77 -0
- data/.github/workflows/test.yml +76 -0
- data/.gitignore +45 -0
- data/.overcommit.yml +38 -0
- data/.rubocop.yml +83 -0
- data/BENCHMARKS.md +201 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +27 -0
- data/LICENSE +21 -0
- data/RAGEL_MIGRATION.md +60 -0
- data/README.md +292 -0
- data/Rakefile +209 -0
- data/benchmarks/benchmark_harness.rb +193 -0
- data/benchmarks/benchmark_merging.rb +121 -0
- data/benchmarks/benchmark_optimization_comparison.rb +168 -0
- data/benchmarks/benchmark_parsing.rb +153 -0
- data/benchmarks/benchmark_ragel_removal.rb +56 -0
- data/benchmarks/benchmark_runner.rb +70 -0
- data/benchmarks/benchmark_serialization.rb +180 -0
- data/benchmarks/benchmark_shorthand.rb +109 -0
- data/benchmarks/benchmark_shorthand_expansion.rb +176 -0
- data/benchmarks/benchmark_specificity.rb +124 -0
- data/benchmarks/benchmark_string_allocation.rb +151 -0
- data/benchmarks/benchmark_stylesheet_to_s.rb +62 -0
- data/benchmarks/benchmark_to_s_cached.rb +55 -0
- data/benchmarks/benchmark_value_splitter.rb +54 -0
- data/benchmarks/benchmark_yjit.rb +158 -0
- data/benchmarks/benchmark_yjit_workers.rb +61 -0
- data/benchmarks/profile_to_s.rb +23 -0
- data/benchmarks/speedup_calculator.rb +83 -0
- data/benchmarks/system_metadata.rb +81 -0
- data/benchmarks/templates/benchmarks.md.erb +221 -0
- data/benchmarks/yjit_tests.rb +141 -0
- data/cataract.gemspec +34 -0
- data/cliff.toml +92 -0
- data/examples/color_conversion_visual_test/color_conversion_test.html +3603 -0
- data/examples/color_conversion_visual_test/generate.rb +202 -0
- data/examples/color_conversion_visual_test/template.html.erb +259 -0
- data/examples/css_analyzer/analyzer.rb +164 -0
- data/examples/css_analyzer/analyzers/base.rb +33 -0
- data/examples/css_analyzer/analyzers/colors.rb +133 -0
- data/examples/css_analyzer/analyzers/important.rb +88 -0
- data/examples/css_analyzer/analyzers/properties.rb +61 -0
- data/examples/css_analyzer/analyzers/specificity.rb +68 -0
- data/examples/css_analyzer/templates/report.html.erb +575 -0
- data/examples/css_analyzer.rb +69 -0
- data/examples/github_analysis.html +5343 -0
- data/ext/cataract/cataract.c +1086 -0
- data/ext/cataract/cataract.h +174 -0
- data/ext/cataract/css_parser.c +1435 -0
- data/ext/cataract/extconf.rb +48 -0
- data/ext/cataract/import_scanner.c +174 -0
- data/ext/cataract/merge.c +973 -0
- data/ext/cataract/shorthand_expander.c +902 -0
- data/ext/cataract/specificity.c +213 -0
- data/ext/cataract/value_splitter.c +116 -0
- data/ext/cataract_color/cataract_color.c +16 -0
- data/ext/cataract_color/color_conversion.c +1687 -0
- data/ext/cataract_color/color_conversion.h +136 -0
- data/ext/cataract_color/color_conversion_lab.c +571 -0
- data/ext/cataract_color/color_conversion_named.c +259 -0
- data/ext/cataract_color/color_conversion_oklab.c +547 -0
- data/ext/cataract_color/extconf.rb +23 -0
- data/ext/cataract_old/cataract.c +393 -0
- data/ext/cataract_old/cataract.h +250 -0
- data/ext/cataract_old/css_parser.c +933 -0
- data/ext/cataract_old/extconf.rb +67 -0
- data/ext/cataract_old/import_scanner.c +174 -0
- data/ext/cataract_old/merge.c +776 -0
- data/ext/cataract_old/shorthand_expander.c +902 -0
- data/ext/cataract_old/specificity.c +213 -0
- data/ext/cataract_old/stylesheet.c +290 -0
- data/ext/cataract_old/value_splitter.c +116 -0
- data/lib/cataract/at_rule.rb +97 -0
- data/lib/cataract/color_conversion.rb +18 -0
- data/lib/cataract/declarations.rb +332 -0
- data/lib/cataract/import_resolver.rb +210 -0
- data/lib/cataract/rule.rb +131 -0
- data/lib/cataract/stylesheet.rb +716 -0
- data/lib/cataract/stylesheet_scope.rb +257 -0
- data/lib/cataract/version.rb +5 -0
- data/lib/cataract.rb +107 -0
- data/lib/tasks/gem.rake +158 -0
- data/scripts/fuzzer/run.rb +828 -0
- data/scripts/fuzzer/worker.rb +99 -0
- data/scripts/generate_benchmarks_md.rb +155 -0
- metadata +135 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// color_conversion_named.c - CSS named color support
|
|
2
|
+
//
|
|
3
|
+
// Implements support for all 147 CSS named colors as defined in:
|
|
4
|
+
// https://www.w3.org/TR/css-color-4/#named-colors
|
|
5
|
+
//
|
|
6
|
+
// Named colors are case-insensitive and map directly to sRGB hex values.
|
|
7
|
+
// Examples: "red" -> #ff0000, "rebeccapurple" -> #663399
|
|
8
|
+
//
|
|
9
|
+
// This file uses a sorted array with binary search for O(log n) lookup.
|
|
10
|
+
|
|
11
|
+
#include "color_conversion.h"
|
|
12
|
+
#include <string.h>
|
|
13
|
+
#include <ctype.h>
|
|
14
|
+
|
|
15
|
+
// Named color entry: color name and its hex RGB value
|
|
16
|
+
struct named_color {
|
|
17
|
+
const char *name;
|
|
18
|
+
unsigned int hex; // RGB as 0xRRGGBB
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// All 147 CSS named colors, sorted alphabetically for binary search
|
|
22
|
+
// Source: https://www.w3.org/TR/css-color-4/#named-colors
|
|
23
|
+
static const struct named_color NAMED_COLORS[] = {
|
|
24
|
+
{"aliceblue", 0xf0f8ff},
|
|
25
|
+
{"antiquewhite", 0xfaebd7},
|
|
26
|
+
{"aqua", 0x00ffff},
|
|
27
|
+
{"aquamarine", 0x7fffd4},
|
|
28
|
+
{"azure", 0xf0ffff},
|
|
29
|
+
{"beige", 0xf5f5dc},
|
|
30
|
+
{"bisque", 0xffe4c4},
|
|
31
|
+
{"black", 0x000000},
|
|
32
|
+
{"blanchedalmond", 0xffebcd},
|
|
33
|
+
{"blue", 0x0000ff},
|
|
34
|
+
{"blueviolet", 0x8a2be2},
|
|
35
|
+
{"brown", 0xa52a2a},
|
|
36
|
+
{"burlywood", 0xdeb887},
|
|
37
|
+
{"cadetblue", 0x5f9ea0},
|
|
38
|
+
{"chartreuse", 0x7fff00},
|
|
39
|
+
{"chocolate", 0xd2691e},
|
|
40
|
+
{"coral", 0xff7f50},
|
|
41
|
+
{"cornflowerblue", 0x6495ed},
|
|
42
|
+
{"cornsilk", 0xfff8dc},
|
|
43
|
+
{"crimson", 0xdc143c},
|
|
44
|
+
{"cyan", 0x00ffff},
|
|
45
|
+
{"darkblue", 0x00008b},
|
|
46
|
+
{"darkcyan", 0x008b8b},
|
|
47
|
+
{"darkgoldenrod", 0xb8860b},
|
|
48
|
+
{"darkgray", 0xa9a9a9},
|
|
49
|
+
{"darkgreen", 0x006400},
|
|
50
|
+
{"darkgrey", 0xa9a9a9},
|
|
51
|
+
{"darkkhaki", 0xbdb76b},
|
|
52
|
+
{"darkmagenta", 0x8b008b},
|
|
53
|
+
{"darkolivegreen", 0x556b2f},
|
|
54
|
+
{"darkorange", 0xff8c00},
|
|
55
|
+
{"darkorchid", 0x9932cc},
|
|
56
|
+
{"darkred", 0x8b0000},
|
|
57
|
+
{"darksalmon", 0xe9967a},
|
|
58
|
+
{"darkseagreen", 0x8fbc8f},
|
|
59
|
+
{"darkslateblue", 0x483d8b},
|
|
60
|
+
{"darkslategray", 0x2f4f4f},
|
|
61
|
+
{"darkslategrey", 0x2f4f4f},
|
|
62
|
+
{"darkturquoise", 0x00ced1},
|
|
63
|
+
{"darkviolet", 0x9400d3},
|
|
64
|
+
{"deeppink", 0xff1493},
|
|
65
|
+
{"deepskyblue", 0x00bfff},
|
|
66
|
+
{"dimgray", 0x696969},
|
|
67
|
+
{"dimgrey", 0x696969},
|
|
68
|
+
{"dodgerblue", 0x1e90ff},
|
|
69
|
+
{"firebrick", 0xb22222},
|
|
70
|
+
{"floralwhite", 0xfffaf0},
|
|
71
|
+
{"forestgreen", 0x228b22},
|
|
72
|
+
{"fuchsia", 0xff00ff},
|
|
73
|
+
{"gainsboro", 0xdcdcdc},
|
|
74
|
+
{"ghostwhite", 0xf8f8ff},
|
|
75
|
+
{"gold", 0xffd700},
|
|
76
|
+
{"goldenrod", 0xdaa520},
|
|
77
|
+
{"gray", 0x808080},
|
|
78
|
+
{"green", 0x008000},
|
|
79
|
+
{"greenyellow", 0xadff2f},
|
|
80
|
+
{"grey", 0x808080},
|
|
81
|
+
{"honeydew", 0xf0fff0},
|
|
82
|
+
{"hotpink", 0xff69b4},
|
|
83
|
+
{"indianred", 0xcd5c5c},
|
|
84
|
+
{"indigo", 0x4b0082},
|
|
85
|
+
{"ivory", 0xfffff0},
|
|
86
|
+
{"khaki", 0xf0e68c},
|
|
87
|
+
{"lavender", 0xe6e6fa},
|
|
88
|
+
{"lavenderblush", 0xfff0f5},
|
|
89
|
+
{"lawngreen", 0x7cfc00},
|
|
90
|
+
{"lemonchiffon", 0xfffacd},
|
|
91
|
+
{"lightblue", 0xadd8e6},
|
|
92
|
+
{"lightcoral", 0xf08080},
|
|
93
|
+
{"lightcyan", 0xe0ffff},
|
|
94
|
+
{"lightgoldenrodyellow", 0xfafad2},
|
|
95
|
+
{"lightgray", 0xd3d3d3},
|
|
96
|
+
{"lightgreen", 0x90ee90},
|
|
97
|
+
{"lightgrey", 0xd3d3d3},
|
|
98
|
+
{"lightpink", 0xffb6c1},
|
|
99
|
+
{"lightsalmon", 0xffa07a},
|
|
100
|
+
{"lightseagreen", 0x20b2aa},
|
|
101
|
+
{"lightskyblue", 0x87cefa},
|
|
102
|
+
{"lightslategray", 0x778899},
|
|
103
|
+
{"lightslategrey", 0x778899},
|
|
104
|
+
{"lightsteelblue", 0xb0c4de},
|
|
105
|
+
{"lightyellow", 0xffffe0},
|
|
106
|
+
{"lime", 0x00ff00},
|
|
107
|
+
{"limegreen", 0x32cd32},
|
|
108
|
+
{"linen", 0xfaf0e6},
|
|
109
|
+
{"magenta", 0xff00ff},
|
|
110
|
+
{"maroon", 0x800000},
|
|
111
|
+
{"mediumaquamarine", 0x66cdaa},
|
|
112
|
+
{"mediumblue", 0x0000cd},
|
|
113
|
+
{"mediumorchid", 0xba55d3},
|
|
114
|
+
{"mediumpurple", 0x9370db},
|
|
115
|
+
{"mediumseagreen", 0x3cb371},
|
|
116
|
+
{"mediumslateblue", 0x7b68ee},
|
|
117
|
+
{"mediumspringgreen", 0x00fa9a},
|
|
118
|
+
{"mediumturquoise", 0x48d1cc},
|
|
119
|
+
{"mediumvioletred", 0xc71585},
|
|
120
|
+
{"midnightblue", 0x191970},
|
|
121
|
+
{"mintcream", 0xf5fffa},
|
|
122
|
+
{"mistyrose", 0xffe4e1},
|
|
123
|
+
{"moccasin", 0xffe4b5},
|
|
124
|
+
{"navajowhite", 0xffdead},
|
|
125
|
+
{"navy", 0x000080},
|
|
126
|
+
{"oldlace", 0xfdf5e6},
|
|
127
|
+
{"olive", 0x808000},
|
|
128
|
+
{"olivedrab", 0x6b8e23},
|
|
129
|
+
{"orange", 0xffa500},
|
|
130
|
+
{"orangered", 0xff4500},
|
|
131
|
+
{"orchid", 0xda70d6},
|
|
132
|
+
{"palegoldenrod", 0xeee8aa},
|
|
133
|
+
{"palegreen", 0x98fb98},
|
|
134
|
+
{"paleturquoise", 0xafeeee},
|
|
135
|
+
{"palevioletred", 0xdb7093},
|
|
136
|
+
{"papayawhip", 0xffefd5},
|
|
137
|
+
{"peachpuff", 0xffdab9},
|
|
138
|
+
{"peru", 0xcd853f},
|
|
139
|
+
{"pink", 0xffc0cb},
|
|
140
|
+
{"plum", 0xdda0dd},
|
|
141
|
+
{"powderblue", 0xb0e0e6},
|
|
142
|
+
{"purple", 0x800080},
|
|
143
|
+
{"rebeccapurple", 0x663399},
|
|
144
|
+
{"red", 0xff0000},
|
|
145
|
+
{"rosybrown", 0xbc8f8f},
|
|
146
|
+
{"royalblue", 0x4169e1},
|
|
147
|
+
{"saddlebrown", 0x8b4513},
|
|
148
|
+
{"salmon", 0xfa8072},
|
|
149
|
+
{"sandybrown", 0xf4a460},
|
|
150
|
+
{"seagreen", 0x2e8b57},
|
|
151
|
+
{"seashell", 0xfff5ee},
|
|
152
|
+
{"sienna", 0xa0522d},
|
|
153
|
+
{"silver", 0xc0c0c0},
|
|
154
|
+
{"skyblue", 0x87ceeb},
|
|
155
|
+
{"slateblue", 0x6a5acd},
|
|
156
|
+
{"slategray", 0x708090},
|
|
157
|
+
{"slategrey", 0x708090},
|
|
158
|
+
{"snow", 0xfffafa},
|
|
159
|
+
{"springgreen", 0x00ff7f},
|
|
160
|
+
{"steelblue", 0x4682b4},
|
|
161
|
+
{"tan", 0xd2b48c},
|
|
162
|
+
{"teal", 0x008080},
|
|
163
|
+
{"thistle", 0xd8bfd8},
|
|
164
|
+
{"tomato", 0xff6347},
|
|
165
|
+
{"turquoise", 0x40e0d0},
|
|
166
|
+
{"violet", 0xee82ee},
|
|
167
|
+
{"wheat", 0xf5deb3},
|
|
168
|
+
{"white", 0xffffff},
|
|
169
|
+
{"whitesmoke", 0xf5f5f5},
|
|
170
|
+
{"yellow", 0xffff00},
|
|
171
|
+
{"yellowgreen", 0x9acd32}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
#define NUM_NAMED_COLORS (sizeof(NAMED_COLORS) / sizeof(NAMED_COLORS[0]))
|
|
175
|
+
|
|
176
|
+
// Case-insensitive string comparison for binary search
|
|
177
|
+
static int strcasecmp_limited(const char *a, const char *b, size_t max_len) {
|
|
178
|
+
for (size_t i = 0; i < max_len; i++) {
|
|
179
|
+
if (a[i] == '\0' && b[i] == '\0') return 0;
|
|
180
|
+
if (a[i] == '\0') return -1;
|
|
181
|
+
if (b[i] == '\0') return 1;
|
|
182
|
+
|
|
183
|
+
int diff = tolower((unsigned char)a[i]) - tolower((unsigned char)b[i]);
|
|
184
|
+
if (diff != 0) return diff;
|
|
185
|
+
}
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Binary search for named color (case-insensitive)
|
|
190
|
+
// Returns hex value or -1 if not found
|
|
191
|
+
static int lookup_named_color(const char *name, size_t name_len) {
|
|
192
|
+
int left = 0;
|
|
193
|
+
int right = NUM_NAMED_COLORS - 1;
|
|
194
|
+
|
|
195
|
+
DEBUG_PRINTF("lookup: searching for '%.*s' (len=%zu)\n", (int)name_len, name, name_len);
|
|
196
|
+
|
|
197
|
+
while (left <= right) {
|
|
198
|
+
int mid = left + (right - left) / 2;
|
|
199
|
+
int cmp = strcasecmp_limited(name, NAMED_COLORS[mid].name, name_len);
|
|
200
|
+
|
|
201
|
+
DEBUG_PRINTF("lookup: mid=%d, name='%s', cmp=%d\n", mid, NAMED_COLORS[mid].name, cmp);
|
|
202
|
+
|
|
203
|
+
// Also need to check if the matched name is exactly the same length
|
|
204
|
+
if (cmp == 0) {
|
|
205
|
+
// Prefix matches, now check full length
|
|
206
|
+
if (NAMED_COLORS[mid].name[name_len] == '\0') {
|
|
207
|
+
// Exact match!
|
|
208
|
+
DEBUG_PRINTF("lookup: FOUND at mid=%d\n", mid);
|
|
209
|
+
return NAMED_COLORS[mid].hex;
|
|
210
|
+
} else {
|
|
211
|
+
// Prefix matches but array name is longer (e.g., "blue" vs "blueviolet")
|
|
212
|
+
// We want the shorter name, so search left
|
|
213
|
+
right = mid - 1;
|
|
214
|
+
}
|
|
215
|
+
} else if (cmp < 0) {
|
|
216
|
+
right = mid - 1;
|
|
217
|
+
} else {
|
|
218
|
+
left = mid + 1;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
DEBUG_PRINTF("lookup: NOT FOUND\n");
|
|
223
|
+
return -1; // Not found
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Parse named color to IR (sRGB 0-255)
|
|
227
|
+
// Syntax: just the color name (e.g., "red", "rebeccapurple")
|
|
228
|
+
struct color_ir parse_named(VALUE named_value) {
|
|
229
|
+
struct color_ir color;
|
|
230
|
+
INIT_COLOR_IR(color);
|
|
231
|
+
|
|
232
|
+
const char *name = StringValueCStr(named_value);
|
|
233
|
+
size_t name_len = strlen(name);
|
|
234
|
+
|
|
235
|
+
// Trim whitespace
|
|
236
|
+
while (name_len > 0 && isspace((unsigned char)name[name_len - 1])) {
|
|
237
|
+
name_len--;
|
|
238
|
+
}
|
|
239
|
+
while (name_len > 0 && isspace((unsigned char)*name)) {
|
|
240
|
+
name++;
|
|
241
|
+
name_len--;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Look up the color
|
|
245
|
+
int hex = lookup_named_color(name, name_len);
|
|
246
|
+
|
|
247
|
+
if (hex < 0) {
|
|
248
|
+
// Unknown color name - return invalid IR (red = -1 signals invalid)
|
|
249
|
+
color.red = -1;
|
|
250
|
+
return color;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Extract RGB from hex (0xRRGGBB)
|
|
254
|
+
color.red = (hex >> 16) & 0xFF;
|
|
255
|
+
color.green = (hex >> 8) & 0xFF;
|
|
256
|
+
color.blue = hex & 0xFF;
|
|
257
|
+
|
|
258
|
+
return color;
|
|
259
|
+
}
|