habaki 0.5.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/Gemfile +3 -0
- data/ext/katana/extconf.rb +20 -0
- data/ext/katana/rb_katana.c +280 -0
- data/ext/katana/rb_katana.h +102 -0
- data/ext/katana/rb_katana_array.c +144 -0
- data/ext/katana/rb_katana_declaration.c +389 -0
- data/ext/katana/rb_katana_rule.c +461 -0
- data/ext/katana/rb_katana_selector.c +559 -0
- data/ext/katana/src/foundation.c +237 -0
- data/ext/katana/src/foundation.h +120 -0
- data/ext/katana/src/katana.h +590 -0
- data/ext/katana/src/katana.lex.c +4104 -0
- data/ext/katana/src/katana.lex.h +592 -0
- data/ext/katana/src/katana.tab.c +4422 -0
- data/ext/katana/src/katana.tab.h +262 -0
- data/ext/katana/src/parser.c +1563 -0
- data/ext/katana/src/parser.h +237 -0
- data/ext/katana/src/selector.c +659 -0
- data/ext/katana/src/selector.h +54 -0
- data/ext/katana/src/tokenizer.c +300 -0
- data/ext/katana/src/tokenizer.h +41 -0
- data/lib/habaki/charset_rule.rb +25 -0
- data/lib/habaki/declaration.rb +53 -0
- data/lib/habaki/declarations.rb +346 -0
- data/lib/habaki/error.rb +43 -0
- data/lib/habaki/font_face_rule.rb +24 -0
- data/lib/habaki/formal_syntax.rb +464 -0
- data/lib/habaki/formatter.rb +99 -0
- data/lib/habaki/import_rule.rb +34 -0
- data/lib/habaki/media_rule.rb +173 -0
- data/lib/habaki/namespace_rule.rb +31 -0
- data/lib/habaki/node.rb +52 -0
- data/lib/habaki/page_rule.rb +24 -0
- data/lib/habaki/qualified_name.rb +29 -0
- data/lib/habaki/rule.rb +48 -0
- data/lib/habaki/rules.rb +225 -0
- data/lib/habaki/selector.rb +98 -0
- data/lib/habaki/selectors.rb +49 -0
- data/lib/habaki/style_rule.rb +35 -0
- data/lib/habaki/stylesheet.rb +158 -0
- data/lib/habaki/sub_selector.rb +234 -0
- data/lib/habaki/sub_selectors.rb +42 -0
- data/lib/habaki/supports_rule.rb +65 -0
- data/lib/habaki/value.rb +321 -0
- data/lib/habaki/values.rb +86 -0
- data/lib/habaki/visitor/element.rb +50 -0
- data/lib/habaki/visitor/media.rb +22 -0
- data/lib/habaki/visitor/nokogiri_element.rb +56 -0
- data/lib/habaki.rb +39 -0
- metadata +190 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015 QFish <im@qfi.sh>
|
3
|
+
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9
|
+
* furnished to do so, subject to the following conditions:
|
10
|
+
*
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
12
|
+
* all copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
* THE SOFTWARE.
|
21
|
+
*/
|
22
|
+
|
23
|
+
#ifndef __Katana__selector__
|
24
|
+
#define __Katana__selector__
|
25
|
+
|
26
|
+
#include <stdio.h>
|
27
|
+
#include "katana.h"
|
28
|
+
#include "parser.h"
|
29
|
+
|
30
|
+
#ifdef __cplusplus
|
31
|
+
extern "C" {
|
32
|
+
#endif
|
33
|
+
|
34
|
+
KatanaParserString* katana_selector_to_string(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* next);
|
35
|
+
|
36
|
+
bool katana_selector_crosses_tree_scopes(const KatanaSelector* selector);
|
37
|
+
bool katana_selector_matches_pseudo_element(KatanaSelector* selector);
|
38
|
+
bool katana_selector_is_custom_pseudo_element(KatanaSelector* selector);
|
39
|
+
bool katana_selector_is_direct_adjacent(KatanaSelector* selector);
|
40
|
+
bool katana_selector_is_adjacent(KatanaSelector* selector);
|
41
|
+
bool katana_selector_is_shadow(KatanaSelector* selector);
|
42
|
+
bool katana_selector_is_sibling(KatanaSelector* selector);
|
43
|
+
bool katana_selector_is_attribute(const KatanaSelector* selector);
|
44
|
+
bool katana_selector_is_content_pseudo_element(KatanaSelector* selector);
|
45
|
+
bool katana_selector_is_shadow_pseudo_element(KatanaSelector* selector);
|
46
|
+
bool katana_selector_is_host_pseudo_class(KatanaSelector* selector);
|
47
|
+
bool katana_selector_is_tree_boundary_crossing(KatanaSelector* selector);
|
48
|
+
bool katana_selector_is_insertion_point_crossing(KatanaSelector* selector);
|
49
|
+
|
50
|
+
#ifdef __cplusplus
|
51
|
+
}
|
52
|
+
#endif
|
53
|
+
|
54
|
+
#endif /* defined(__Katana__selector__) */
|
@@ -0,0 +1,300 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015 QFish <im@qfi.sh>
|
3
|
+
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9
|
+
* furnished to do so, subject to the following conditions:
|
10
|
+
*
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
12
|
+
* all copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
* THE SOFTWARE.
|
21
|
+
*/
|
22
|
+
|
23
|
+
#include <assert.h>
|
24
|
+
|
25
|
+
#include "tokenizer.h"
|
26
|
+
#include "katana.tab.h"
|
27
|
+
#include "katana.lex.h"
|
28
|
+
#include "parser.h"
|
29
|
+
#include "foundation.h"
|
30
|
+
|
31
|
+
#undef assert
|
32
|
+
#define assert(x)
|
33
|
+
|
34
|
+
static inline double katana_characters_to_double(const char* data, size_t length, bool* ok);
|
35
|
+
static inline bool katana_is_html_space(char c);
|
36
|
+
static inline char* katana_normalize_text(yy_size_t* length, char *origin_text, yy_size_t origin_length, int tok);
|
37
|
+
|
38
|
+
#ifdef KATANA_FELX_DEBUG
|
39
|
+
#if KATANA_FELX_DEBUG
|
40
|
+
static char * katana_token_string(int tok);
|
41
|
+
#endif // #if KATANA_FELX_DEBUG
|
42
|
+
#endif // #ifdef KATANA_FELX_DEBUG
|
43
|
+
|
44
|
+
/**
|
45
|
+
* A hook function of flex, processing tokens which will be passed to bison
|
46
|
+
*
|
47
|
+
* @param yylval the medium for flex and bison
|
48
|
+
* @param yyscanner flex state
|
49
|
+
* @param tok the type of token
|
50
|
+
*
|
51
|
+
* @return the type of token
|
52
|
+
*/
|
53
|
+
int katana_tokenize(KATANASTYPE* lval , KATANALTYPE* loc, yyscan_t scanner, KatanaParser* parser, int tok)
|
54
|
+
{
|
55
|
+
char* origin_text = katanaget_text(scanner);
|
56
|
+
|
57
|
+
yy_size_t len = 0;
|
58
|
+
|
59
|
+
char* text = katana_normalize_text(&len, origin_text, katanaget_leng(scanner), tok);
|
60
|
+
|
61
|
+
#ifdef KATANA_FELX_DEBUG
|
62
|
+
#if KATANA_FELX_DEBUG
|
63
|
+
if ( tok == KATANA_CSS_WHITESPACE ) {
|
64
|
+
katana_parser_log(parser, "【%30s】=>【%30s】: %s", "", "", katana_token_string(tok));
|
65
|
+
} else {
|
66
|
+
katana_parser_log(parser, "【%30s】=>【%30s】: %s", origin_text, text, katana_token_string(tok));
|
67
|
+
}
|
68
|
+
#endif // #if KATANA_FELX_DEBUG
|
69
|
+
#endif // #ifdef KATANA_FELX_DEBUG
|
70
|
+
yy_size_t length = len;
|
71
|
+
switch ( tok ) {
|
72
|
+
case KATANA_CSS_INCLUDES:
|
73
|
+
case KATANA_CSS_DASHMATCH:
|
74
|
+
case KATANA_CSS_BEGINSWITH:
|
75
|
+
case KATANA_CSS_ENDSWITH:
|
76
|
+
case KATANA_CSS_CONTAINS:
|
77
|
+
break;
|
78
|
+
case KATANA_CSS_STRING:
|
79
|
+
case KATANA_CSS_IDENT:
|
80
|
+
case KATANA_CSS_NTH:
|
81
|
+
|
82
|
+
case KATANA_CSS_HEX:
|
83
|
+
case KATANA_CSS_IDSEL:
|
84
|
+
|
85
|
+
case KATANA_CSS_DIMEN:
|
86
|
+
case KATANA_CSS_INVALIDDIMEN:
|
87
|
+
case KATANA_CSS_URI:
|
88
|
+
case KATANA_CSS_FUNCTION:
|
89
|
+
case KATANA_CSS_ANYFUNCTION:
|
90
|
+
case KATANA_CSS_CUEFUNCTION:
|
91
|
+
case KATANA_CSS_NOTFUNCTION:
|
92
|
+
case KATANA_CSS_CALCFUNCTION:
|
93
|
+
case KATANA_CSS_MINFUNCTION:
|
94
|
+
case KATANA_CSS_MAXFUNCTION:
|
95
|
+
case KATANA_CSS_HOSTFUNCTION:
|
96
|
+
case KATANA_CSS_HOSTCONTEXTFUNCTION:
|
97
|
+
case KATANA_CSS_UNICODERANGE:
|
98
|
+
{
|
99
|
+
lval->string.data = text;
|
100
|
+
lval->string.length = length;
|
101
|
+
}
|
102
|
+
break;
|
103
|
+
case KATANA_CSS_IMPORT_SYM:
|
104
|
+
case KATANA_CSS_PAGE_SYM:
|
105
|
+
case KATANA_CSS_MEDIA_SYM:
|
106
|
+
case KATANA_CSS_SUPPORTS_SYM:
|
107
|
+
case KATANA_CSS_FONT_FACE_SYM:
|
108
|
+
case KATANA_CSS_CHARSET_SYM:
|
109
|
+
case KATANA_CSS_NAMESPACE_SYM:
|
110
|
+
// case KATANA_CSS_VIEWPORT_RULE_SYM:
|
111
|
+
case KATANA_INTERNAL_DECLS_SYM:
|
112
|
+
case KATANA_INTERNAL_MEDIALIST_SYM:
|
113
|
+
case KATANA_INTERNAL_RULE_SYM:
|
114
|
+
case KATANA_INTERNAL_SELECTOR_SYM:
|
115
|
+
case KATANA_INTERNAL_VALUE_SYM:
|
116
|
+
case KATANA_INTERNAL_KEYFRAME_RULE_SYM:
|
117
|
+
case KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM:
|
118
|
+
case KATANA_INTERNAL_SUPPORTS_CONDITION_SYM:
|
119
|
+
case KATANA_CSS_KEYFRAMES_SYM:
|
120
|
+
break;
|
121
|
+
case KATANA_CSS_QEMS:
|
122
|
+
length--;
|
123
|
+
case KATANA_CSS_GRADS:
|
124
|
+
case KATANA_CSS_TURNS:
|
125
|
+
length--;
|
126
|
+
case KATANA_CSS_DEGS:
|
127
|
+
case KATANA_CSS_RADS:
|
128
|
+
case KATANA_CSS_KHERTZ:
|
129
|
+
case KATANA_CSS_REMS:
|
130
|
+
length--;
|
131
|
+
case KATANA_CSS_MSECS:
|
132
|
+
case KATANA_CSS_HERTZ:
|
133
|
+
case KATANA_CSS_EMS:
|
134
|
+
case KATANA_CSS_CHS:
|
135
|
+
case KATANA_CSS_EXS:
|
136
|
+
case KATANA_CSS_PXS:
|
137
|
+
case KATANA_CSS_CMS:
|
138
|
+
case KATANA_CSS_MMS:
|
139
|
+
case KATANA_CSS_INS:
|
140
|
+
case KATANA_CSS_PTS:
|
141
|
+
case KATANA_CSS_PCS:
|
142
|
+
case KATANA_CSS_DPPX:
|
143
|
+
case KATANA_CSS_DPI:
|
144
|
+
case KATANA_CSS_DPCM:
|
145
|
+
case KATANA_CSS_VW:
|
146
|
+
case KATANA_CSS_VH:
|
147
|
+
case KATANA_CSS_VMIN:
|
148
|
+
case KATANA_CSS_VMAX:
|
149
|
+
length--;
|
150
|
+
case KATANA_CSS_SECS:
|
151
|
+
case KATANA_CSS_PERCENTAGE:
|
152
|
+
length--;
|
153
|
+
case KATANA_CSS_FLOATTOKEN:
|
154
|
+
lval->number.val = katana_characters_to_double(text, length, NULL);
|
155
|
+
lval->number.raw.data = text;
|
156
|
+
lval->number.raw.length = len;
|
157
|
+
break;
|
158
|
+
case KATANA_CSS_INTEGER:
|
159
|
+
lval->number.val = (int)katana_characters_to_double(text, length, NULL);
|
160
|
+
lval->number.raw.data = text;
|
161
|
+
lval->number.raw.length = len;
|
162
|
+
|
163
|
+
break;
|
164
|
+
default:
|
165
|
+
break;
|
166
|
+
}
|
167
|
+
|
168
|
+
return tok;
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* Format token
|
173
|
+
*
|
174
|
+
* @param length
|
175
|
+
* @param origin_text original text from the flex
|
176
|
+
* @param origin_length formatted length
|
177
|
+
* @param tok
|
178
|
+
*
|
179
|
+
* @return normalized text
|
180
|
+
*/
|
181
|
+
static inline char* katana_normalize_text(yy_size_t* length, char *origin_text, yy_size_t origin_length, int tok)
|
182
|
+
{
|
183
|
+
char * start = origin_text;
|
184
|
+
yy_size_t l = origin_length;
|
185
|
+
switch ( tok ) {
|
186
|
+
case KATANA_CSS_STRING:
|
187
|
+
l--;
|
188
|
+
/* nobreak */
|
189
|
+
case KATANA_CSS_HEX:
|
190
|
+
case KATANA_CSS_IDSEL:
|
191
|
+
start++;
|
192
|
+
l--;
|
193
|
+
break;
|
194
|
+
case KATANA_CSS_URI:
|
195
|
+
// "url("{w}{string}{w}")"
|
196
|
+
// "url("{w}{url}{w}")"
|
197
|
+
// strip "url(" and ")"
|
198
|
+
start += 4;
|
199
|
+
l -= 5;
|
200
|
+
// strip {w}
|
201
|
+
while (l && katana_is_html_space(*start)) {
|
202
|
+
++start;
|
203
|
+
--l;
|
204
|
+
}
|
205
|
+
while (l && katana_is_html_space(start[l - 1]))
|
206
|
+
--l;
|
207
|
+
if (l && (*start == '"' || *start == '\'')) {
|
208
|
+
assert(l >= 2 && start[l - 1] == *start);
|
209
|
+
++start;
|
210
|
+
l -= 2;
|
211
|
+
}
|
212
|
+
break;
|
213
|
+
default:
|
214
|
+
break;
|
215
|
+
}
|
216
|
+
|
217
|
+
*length = l;
|
218
|
+
return start;
|
219
|
+
}
|
220
|
+
|
221
|
+
double katana_characters_to_double(const char* data, size_t length, bool* ok)
|
222
|
+
{
|
223
|
+
if (!length) {
|
224
|
+
if (ok)
|
225
|
+
*ok = false;
|
226
|
+
return 0.0;
|
227
|
+
}
|
228
|
+
|
229
|
+
char* bytes = malloc(sizeof(char) * (length + 1));
|
230
|
+
for (unsigned i = 0; i < length; ++i)
|
231
|
+
bytes[i] = data[i] < 0x7F ? data[i] : '?';
|
232
|
+
bytes[length] = '\0';
|
233
|
+
char* end;
|
234
|
+
double val = strtod(bytes, &end);
|
235
|
+
if (ok)
|
236
|
+
*ok = (end == 0 || *end == '\0');
|
237
|
+
free(bytes);
|
238
|
+
return val;
|
239
|
+
}
|
240
|
+
|
241
|
+
#ifdef KATANA_FELX_DEBUG
|
242
|
+
#if KATANA_FELX_DEBUG
|
243
|
+
static char * katana_token_table[] = {
|
244
|
+
"TOKEN_EOF", "LOWEST_PREC", "UNIMPORTANT_TOK",
|
245
|
+
"KATANA_CSS_SGML_CD", "KATANA_CSS_WHITESPACE", "KATANA_CSS_INCLUDES",
|
246
|
+
"KATANA_CSS_DASHMATCH", "KATANA_CSS_BEGINSWITH", "KATANA_CSS_ENDSWITH",
|
247
|
+
"KATANA_CSS_CONTAINS", "KATANA_CSS_STRING", "KATANA_CSS_IDENT",
|
248
|
+
"KATANA_CSS_NTH", "KATANA_CSS_HEX", "KATANA_CSS_IDSEL", "KATANA_CSS_IMPORT_SYM", "KATANA_CSS_PAGE_SYM",
|
249
|
+
"KATANA_CSS_MEDIA_SYM", "KATANA_CSS_SUPPORTS_SYM",
|
250
|
+
"KATANA_CSS_FONT_FACE_SYM", "KATANA_CSS_CHARSET_SYM",
|
251
|
+
"KATANA_CSS_NAMESPACE_SYM", "KATANA_INTERNAL_DECLS_SYM",
|
252
|
+
"KATANA_INTERNAL_MEDIALIST_SYM", "KATANA_INTERNAL_RULE_SYM",
|
253
|
+
"KATANA_INTERNAL_SELECTOR_SYM", "KATANA_INTERNAL_VALUE_SYM",
|
254
|
+
"KATANA_INTERNAL_KEYFRAME_RULE_SYM",
|
255
|
+
"KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM",
|
256
|
+
"KATANA_INTERNAL_SUPPORTS_CONDITION_SYM", "KATANA_CSS_KEYFRAMES_SYM",
|
257
|
+
"KATANA_CSS_ATKEYWORD", "KATANA_CSS_IMPORTANT_SYM",
|
258
|
+
"KATANA_CSS_MEDIA_NOT", "KATANA_CSS_MEDIA_ONLY", "KATANA_CSS_MEDIA_AND",
|
259
|
+
"KATANA_CSS_MEDIA_OR", "KATANA_CSS_SUPPORTS_NOT",
|
260
|
+
"KATANA_CSS_SUPPORTS_AND", "KATANA_CSS_SUPPORTS_OR", "KATANA_CSS_REMS",
|
261
|
+
"KATANA_CSS_CHS", "KATANA_CSS_QEMS", "KATANA_CSS_EMS", "KATANA_CSS_EXS",
|
262
|
+
"KATANA_CSS_PXS", "KATANA_CSS_CMS", "KATANA_CSS_MMS", "KATANA_CSS_INS",
|
263
|
+
"KATANA_CSS_PTS", "KATANA_CSS_PCS", "KATANA_CSS_DEGS", "KATANA_CSS_RADS",
|
264
|
+
"KATANA_CSS_GRADS", "KATANA_CSS_TURNS", "KATANA_CSS_MSECS",
|
265
|
+
"KATANA_CSS_SECS", "KATANA_CSS_HERTZ", "KATANA_CSS_KHERTZ",
|
266
|
+
"KATANA_CSS_DIMEN", "KATANA_CSS_INVALIDDIMEN", "KATANA_CSS_PERCENTAGE",
|
267
|
+
"KATANA_CSS_FLOATTOKEN", "KATANA_CSS_INTEGER", "KATANA_CSS_VW",
|
268
|
+
"KATANA_CSS_VH", "KATANA_CSS_VMIN", "KATANA_CSS_VMAX", "KATANA_CSS_DPPX",
|
269
|
+
"KATANA_CSS_DPI", "KATANA_CSS_DPCM", "KATANA_CSS_FR", "KATANA_CSS_URI",
|
270
|
+
"KATANA_CSS_FUNCTION", "KATANA_CSS_ANYFUNCTION",
|
271
|
+
"KATANA_CSS_CUEFUNCTION", "KATANA_CSS_NOTFUNCTION",
|
272
|
+
"KATANA_CSS_CALCFUNCTION", "KATANA_CSS_MINFUNCTION",
|
273
|
+
"KATANA_CSS_MAXFUNCTION", "KATANA_CSS_HOSTFUNCTION",
|
274
|
+
"KATANA_CSS_HOSTCONTEXTFUNCTION", "KATANA_CSS_UNICODERANGE" };
|
275
|
+
|
276
|
+
static char * katana_token_string(int tok)
|
277
|
+
{
|
278
|
+
if (tok > 257)
|
279
|
+
{
|
280
|
+
return katana_token_table[tok-257];
|
281
|
+
}
|
282
|
+
else if ( 0 == tok )
|
283
|
+
{
|
284
|
+
return katana_token_table[0];
|
285
|
+
}
|
286
|
+
else
|
287
|
+
{
|
288
|
+
char* unicode = malloc(2);
|
289
|
+
unicode[0] = (char)tok;
|
290
|
+
unicode[1] = '\0';
|
291
|
+
return unicode;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
#endif // #if KATANA_FELX_DEBUG
|
295
|
+
#endif // #ifdef KATANA_FELX_DEBUG
|
296
|
+
|
297
|
+
inline bool katana_is_html_space(char c)
|
298
|
+
{
|
299
|
+
return c <= ' ' && (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f');
|
300
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright (c) 2015 QFish <im@qfi.sh>
|
3
|
+
*
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
9
|
+
* furnished to do so, subject to the following conditions:
|
10
|
+
*
|
11
|
+
* The above copyright notice and this permission notice shall be included in
|
12
|
+
* all copies or substantial portions of the Software.
|
13
|
+
*
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
* THE SOFTWARE.
|
21
|
+
*/
|
22
|
+
|
23
|
+
#ifndef __Katana__tokenizer__
|
24
|
+
#define __Katana__tokenizer__
|
25
|
+
|
26
|
+
#include <stdio.h>
|
27
|
+
#include "katana.lex.h"
|
28
|
+
#include "katana.tab.h"
|
29
|
+
#include "parser.h"
|
30
|
+
|
31
|
+
#ifdef __cplusplus
|
32
|
+
extern "C" {
|
33
|
+
#endif
|
34
|
+
|
35
|
+
int katana_tokenize(KATANASTYPE* lval , KATANALTYPE* loc, yyscan_t scanner, KatanaParser* parser, int tok);
|
36
|
+
|
37
|
+
#ifdef __cplusplus
|
38
|
+
}
|
39
|
+
#endif
|
40
|
+
|
41
|
+
#endif /* defined(__Katana__tokenizer__) */
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Habaki
|
2
|
+
# Rule for @charset
|
3
|
+
class CharsetRule < Rule
|
4
|
+
# @return [String]
|
5
|
+
attr_accessor :encoding
|
6
|
+
|
7
|
+
# @param [String] encoding
|
8
|
+
def initialize(encoding = nil)
|
9
|
+
@encoding
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [Formatter::Base] format
|
13
|
+
# @return [String]
|
14
|
+
def string(format = Formatter::Base.new)
|
15
|
+
"@charset #{format.quote}#{@encoding}#{format.quote};"
|
16
|
+
end
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
# @param [Katana::CharsetRule] rule
|
20
|
+
# @return [void]
|
21
|
+
def read_from_katana(rule)
|
22
|
+
@encoding = rule.encoding
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Habaki
|
2
|
+
class Declaration < Node
|
3
|
+
# @return [String]
|
4
|
+
attr_accessor :property
|
5
|
+
# @return [Values]
|
6
|
+
attr_accessor :values
|
7
|
+
# @return [Boolean]
|
8
|
+
attr_accessor :important
|
9
|
+
|
10
|
+
# @return [SourcePosition]
|
11
|
+
attr_accessor :position
|
12
|
+
|
13
|
+
def initialize(property = nil, important = false)
|
14
|
+
@property = property
|
15
|
+
@important = important
|
16
|
+
@values = Values.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# shortcut to first value
|
20
|
+
# @return [Value]
|
21
|
+
def value
|
22
|
+
@values.first
|
23
|
+
end
|
24
|
+
|
25
|
+
# check validity
|
26
|
+
# @return [Boolean]
|
27
|
+
def check
|
28
|
+
Habaki::FormalSyntax::Matcher.new(self).match?
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [Formatter::Base] format
|
32
|
+
# @return [String]
|
33
|
+
def string(format = Formatter::Base.new)
|
34
|
+
"#{format.declaration_prefix}#{@property}: #{@values.string(format)}#{important_string}"
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
# @param [Katana::Declaration] decl
|
39
|
+
# @return [void]
|
40
|
+
def read_from_katana(decl)
|
41
|
+
@property = decl.property.downcase if decl.property
|
42
|
+
@important = decl.important
|
43
|
+
@values = Values.read_from_katana(decl.values)
|
44
|
+
@position = SourcePosition.new(decl.position.line, decl.position.column)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def important_string
|
50
|
+
@important ? " !important" : ""
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|