habaki 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/ext/katana/extconf.rb +20 -0
  4. data/ext/katana/rb_katana.c +280 -0
  5. data/ext/katana/rb_katana.h +102 -0
  6. data/ext/katana/rb_katana_array.c +144 -0
  7. data/ext/katana/rb_katana_declaration.c +389 -0
  8. data/ext/katana/rb_katana_rule.c +461 -0
  9. data/ext/katana/rb_katana_selector.c +559 -0
  10. data/ext/katana/src/foundation.c +237 -0
  11. data/ext/katana/src/foundation.h +120 -0
  12. data/ext/katana/src/katana.h +590 -0
  13. data/ext/katana/src/katana.lex.c +4104 -0
  14. data/ext/katana/src/katana.lex.h +592 -0
  15. data/ext/katana/src/katana.tab.c +4422 -0
  16. data/ext/katana/src/katana.tab.h +262 -0
  17. data/ext/katana/src/parser.c +1563 -0
  18. data/ext/katana/src/parser.h +237 -0
  19. data/ext/katana/src/selector.c +659 -0
  20. data/ext/katana/src/selector.h +54 -0
  21. data/ext/katana/src/tokenizer.c +300 -0
  22. data/ext/katana/src/tokenizer.h +41 -0
  23. data/lib/habaki/charset_rule.rb +25 -0
  24. data/lib/habaki/declaration.rb +53 -0
  25. data/lib/habaki/declarations.rb +346 -0
  26. data/lib/habaki/error.rb +43 -0
  27. data/lib/habaki/font_face_rule.rb +24 -0
  28. data/lib/habaki/formal_syntax.rb +464 -0
  29. data/lib/habaki/formatter.rb +99 -0
  30. data/lib/habaki/import_rule.rb +34 -0
  31. data/lib/habaki/media_rule.rb +173 -0
  32. data/lib/habaki/namespace_rule.rb +31 -0
  33. data/lib/habaki/node.rb +52 -0
  34. data/lib/habaki/page_rule.rb +24 -0
  35. data/lib/habaki/qualified_name.rb +29 -0
  36. data/lib/habaki/rule.rb +48 -0
  37. data/lib/habaki/rules.rb +225 -0
  38. data/lib/habaki/selector.rb +98 -0
  39. data/lib/habaki/selectors.rb +49 -0
  40. data/lib/habaki/style_rule.rb +35 -0
  41. data/lib/habaki/stylesheet.rb +158 -0
  42. data/lib/habaki/sub_selector.rb +234 -0
  43. data/lib/habaki/sub_selectors.rb +42 -0
  44. data/lib/habaki/supports_rule.rb +65 -0
  45. data/lib/habaki/value.rb +321 -0
  46. data/lib/habaki/values.rb +86 -0
  47. data/lib/habaki/visitor/element.rb +50 -0
  48. data/lib/habaki/visitor/media.rb +22 -0
  49. data/lib/habaki/visitor/nokogiri_element.rb +56 -0
  50. data/lib/habaki.rb +39 -0
  51. metadata +190 -0
@@ -0,0 +1,559 @@
1
+ /*
2
+ * Selectors
3
+ */
4
+ #include "rb_katana.h"
5
+
6
+ // QualifiedName
7
+
8
+ /*
9
+ * @return [String, nil]
10
+ */
11
+ VALUE rb_name_local(VALUE self)
12
+ {
13
+ KatanaQualifiedName *c_name;
14
+ Data_Get_Struct(self, KatanaQualifiedName, c_name);
15
+ if (c_name->local)
16
+ return rb_str_new2(c_name->local);
17
+ else
18
+ return Qnil;
19
+ }
20
+
21
+ /*
22
+ * @return [String, nil]
23
+ */
24
+ VALUE rb_name_prefix(VALUE self)
25
+ {
26
+ KatanaQualifiedName *c_name;
27
+ Data_Get_Struct(self, KatanaQualifiedName, c_name);
28
+ if (c_name->prefix)
29
+ return rb_str_new2(c_name->prefix);
30
+ else
31
+ return Qnil;
32
+ }
33
+
34
+ /*
35
+ * @return [String, nil]
36
+ */
37
+ VALUE rb_name_uri(VALUE self)
38
+ {
39
+ KatanaQualifiedName *c_name;
40
+ Data_Get_Struct(self, KatanaQualifiedName, c_name);
41
+ if (c_name->uri)
42
+ return rb_str_new2(c_name->uri);
43
+ else
44
+ return Qnil;
45
+ }
46
+
47
+ // Selector
48
+
49
+ /*
50
+ * @return [Symbol]
51
+ */
52
+ VALUE rb_selector_specificity(VALUE self)
53
+ {
54
+ KatanaSelector *c_sel;
55
+ Data_Get_Struct(self, KatanaSelector, c_sel);
56
+ return INT2NUM(c_sel->specificity);
57
+ }
58
+
59
+ /*
60
+ * @return [Symbol]
61
+ */
62
+ VALUE rb_selector_match(VALUE self)
63
+ {
64
+ ID id;
65
+ KatanaSelector *c_sel;
66
+ Data_Get_Struct(self, KatanaSelector, c_sel);
67
+ switch (c_sel->match)
68
+ {
69
+ case KatanaSelectorMatchUnknown:
70
+ id = rb_intern("unknown");
71
+ break;
72
+ case KatanaSelectorMatchTag:
73
+ id = rb_intern("tag");
74
+ break;
75
+ case KatanaSelectorMatchId:
76
+ id = rb_intern("id");
77
+ break;
78
+ case KatanaSelectorMatchClass:
79
+ id = rb_intern("class");
80
+ break;
81
+ case KatanaSelectorMatchPseudoClass:
82
+ id = rb_intern("pseudo_class");
83
+ break;
84
+ case KatanaSelectorMatchPseudoElement:
85
+ id = rb_intern("pseudo_element");
86
+ break;
87
+ case KatanaSelectorMatchPagePseudoClass:
88
+ id = rb_intern("page_pseudo_class");
89
+ break;
90
+ case KatanaSelectorMatchAttributeExact:
91
+ id = rb_intern("attribute_exact");
92
+ break;
93
+ case KatanaSelectorMatchAttributeSet:
94
+ id = rb_intern("attribute_set");
95
+ break;
96
+ case KatanaSelectorMatchAttributeList:
97
+ id = rb_intern("attribute_list");
98
+ break;
99
+ case KatanaSelectorMatchAttributeHyphen:
100
+ id = rb_intern("attribute_hyphen");
101
+ break;
102
+ case KatanaSelectorMatchAttributeContain:
103
+ id = rb_intern("attribute_contain");
104
+ break;
105
+ case KatanaSelectorMatchAttributeBegin:
106
+ id = rb_intern("attribute_begin");
107
+ break;
108
+ case KatanaSelectorMatchAttributeEnd:
109
+ id = rb_intern("attribute_end");
110
+ break;
111
+ default:
112
+ id = rb_intern("undefined");
113
+ break;
114
+ }
115
+ return ID2SYM(id);
116
+ }
117
+
118
+ /*
119
+ * @return [Symbol]
120
+ */
121
+ VALUE rb_selector_relation(VALUE self)
122
+ {
123
+ ID id;
124
+ KatanaSelector *c_sel;
125
+ Data_Get_Struct(self, KatanaSelector, c_sel);
126
+ switch (c_sel->relation)
127
+ {
128
+ case KatanaSelectorRelationSubSelector:
129
+ id = rb_intern("sub_selector");
130
+ break;
131
+ case KatanaSelectorRelationDescendant:
132
+ id = rb_intern("descendant");
133
+ break;
134
+ case KatanaSelectorRelationChild:
135
+ id = rb_intern("child");
136
+ break;
137
+ case KatanaSelectorRelationDirectAdjacent:
138
+ id = rb_intern("direct_adjacent");
139
+ break;
140
+ case KatanaSelectorRelationIndirectAdjacent:
141
+ id = rb_intern("indirect_adjacent");
142
+ break;
143
+ case KatanaSelectorRelationShadowPseudo:
144
+ id = rb_intern("shadow_pseudo");
145
+ break;
146
+ case KatanaSelectorRelationShadowDeep:
147
+ id = rb_intern("shadow_deep");
148
+ break;
149
+ default:
150
+ id = rb_intern("unknown");
151
+ break;
152
+ }
153
+ return ID2SYM(id);
154
+ }
155
+
156
+ /*
157
+ * @return [Symbol]
158
+ */
159
+ VALUE rb_selector_pseudo(VALUE self)
160
+ {
161
+ ID id;
162
+ KatanaSelector *c_sel;
163
+ Data_Get_Struct(self, KatanaSelector, c_sel);
164
+ switch (c_sel->pseudo)
165
+ {
166
+ case KatanaPseudoNotParsed:
167
+ id = rb_intern("not_parsed");
168
+ break;
169
+ case KatanaPseudoUnknown:
170
+ id = rb_intern("unknown");
171
+ break;
172
+ case KatanaPseudoEmpty:
173
+ id = rb_intern("empty");
174
+ break;
175
+ case KatanaPseudoFirstChild:
176
+ id = rb_intern("first_child");
177
+ break;
178
+ case KatanaPseudoFirstOfType:
179
+ id = rb_intern("first_of_type");
180
+ break;
181
+ case KatanaPseudoLastChild:
182
+ id = rb_intern("last_child");
183
+ break;
184
+ case KatanaPseudoLastOfType:
185
+ id = rb_intern("last_of_type");
186
+ break;
187
+ case KatanaPseudoOnlyChild:
188
+ id = rb_intern("only_child");
189
+ break;
190
+ case KatanaPseudoOnlyOfType:
191
+ id = rb_intern("only_of_type");
192
+ break;
193
+ case KatanaPseudoFirstLine:
194
+ id = rb_intern("first_line");
195
+ break;
196
+ case KatanaPseudoFirstLetter:
197
+ id = rb_intern("first_letter");
198
+ break;
199
+ case KatanaPseudoNthChild:
200
+ id = rb_intern("nth_child");
201
+ break;
202
+ case KatanaPseudoNthOfType:
203
+ id = rb_intern("nth_of_type");
204
+ break;
205
+ case KatanaPseudoNthLastChild:
206
+ id = rb_intern("nth_last_child");
207
+ break;
208
+ case KatanaPseudoNthLastOfType:
209
+ id = rb_intern("nth_last_of_type");
210
+ break;
211
+ case KatanaPseudoLink:
212
+ id = rb_intern("link");
213
+ break;
214
+ case KatanaPseudoVisited:
215
+ id = rb_intern("visited");
216
+ break;
217
+ case KatanaPseudoAny:
218
+ id = rb_intern("any");
219
+ break;
220
+ case KatanaPseudoAnyLink:
221
+ id = rb_intern("any_link");
222
+ break;
223
+ case KatanaPseudoAutofill:
224
+ id = rb_intern("autofill");
225
+ break;
226
+ case KatanaPseudoHover:
227
+ id = rb_intern("hover");
228
+ break;
229
+ case KatanaPseudoDrag:
230
+ id = rb_intern("drag");
231
+ break;
232
+ case KatanaPseudoFocus:
233
+ id = rb_intern("focus");
234
+ break;
235
+ case KatanaPseudoActive:
236
+ id = rb_intern("active");
237
+ break;
238
+ case KatanaPseudoChecked:
239
+ id = rb_intern("checked");
240
+ break;
241
+ case KatanaPseudoEnabled:
242
+ id = rb_intern("enabled");
243
+ break;
244
+ case KatanaPseudoFullPageMedia:
245
+ id = rb_intern("full_page_media");
246
+ break;
247
+ case KatanaPseudoDefault:
248
+ id = rb_intern("default");
249
+ break;
250
+ case KatanaPseudoDisabled:
251
+ id = rb_intern("disabled");
252
+ break;
253
+ case KatanaPseudoOptional:
254
+ id = rb_intern("optional");
255
+ break;
256
+ case KatanaPseudoRequired:
257
+ id = rb_intern("required");
258
+ break;
259
+ case KatanaPseudoReadOnly:
260
+ id = rb_intern("read_only");
261
+ break;
262
+ case KatanaPseudoReadWrite:
263
+ id = rb_intern("read_write");
264
+ break;
265
+ case KatanaPseudoValid:
266
+ id = rb_intern("valid");
267
+ break;
268
+ case KatanaPseudoInvalid:
269
+ id = rb_intern("invalid");
270
+ break;
271
+ case KatanaPseudoIndeterminate:
272
+ id = rb_intern("indeterminate");
273
+ break;
274
+ case KatanaPseudoTarget:
275
+ id = rb_intern("target");
276
+ break;
277
+ case KatanaPseudoBefore:
278
+ id = rb_intern("before");
279
+ break;
280
+ case KatanaPseudoAfter:
281
+ id = rb_intern("after");
282
+ break;
283
+ case KatanaPseudoBackdrop:
284
+ id = rb_intern("backdrop");
285
+ break;
286
+ case KatanaPseudoLang:
287
+ id = rb_intern("lang");
288
+ break;
289
+ case KatanaPseudoNot:
290
+ id = rb_intern("not");
291
+ break;
292
+ case KatanaPseudoResizer:
293
+ id = rb_intern("resizer");
294
+ break;
295
+ case KatanaPseudoRoot:
296
+ id = rb_intern("root");
297
+ break;
298
+ case KatanaPseudoScope:
299
+ id = rb_intern("scope");
300
+ break;
301
+ case KatanaPseudoScrollbar:
302
+ id = rb_intern("scrollbar");
303
+ break;
304
+ case KatanaPseudoScrollbarButton:
305
+ id = rb_intern("scrollbar_button");
306
+ break;
307
+ case KatanaPseudoScrollbarCorner:
308
+ id = rb_intern("scrollbar_corner");
309
+ break;
310
+ case KatanaPseudoScrollbarThumb:
311
+ id = rb_intern("scrollbar_thumb");
312
+ break;
313
+ case KatanaPseudoScrollbarTrack:
314
+ id = rb_intern("scrollbar_track");
315
+ break;
316
+ case KatanaPseudoScrollbarTrackPiece:
317
+ id = rb_intern("scrollbar_track_piece");
318
+ break;
319
+ case KatanaPseudoWindowInactive:
320
+ id = rb_intern("window_inactive");
321
+ break;
322
+ case KatanaPseudoCornerPresent:
323
+ id = rb_intern("corner_present");
324
+ break;
325
+ case KatanaPseudoDecrement:
326
+ id = rb_intern("decrement");
327
+ break;
328
+ case KatanaPseudoIncrement:
329
+ id = rb_intern("increment");
330
+ break;
331
+ case KatanaPseudoHorizontal:
332
+ id = rb_intern("horizontal");
333
+ break;
334
+ case KatanaPseudoVertical:
335
+ id = rb_intern("vertical");
336
+ break;
337
+ case KatanaPseudoStart:
338
+ id = rb_intern("start");
339
+ break;
340
+ case KatanaPseudoEnd:
341
+ id = rb_intern("end");
342
+ break;
343
+ case KatanaPseudoDoubleButton:
344
+ id = rb_intern("double_button");
345
+ break;
346
+ case KatanaPseudoSingleButton:
347
+ id = rb_intern("single_button");
348
+ break;
349
+ case KatanaPseudoNoButton:
350
+ id = rb_intern("no_button");
351
+ break;
352
+ case KatanaPseudoSelection:
353
+ id = rb_intern("selection");
354
+ break;
355
+ case KatanaPseudoLeftPage:
356
+ id = rb_intern("left_page");
357
+ break;
358
+ case KatanaPseudoRightPage:
359
+ id = rb_intern("right_page");
360
+ break;
361
+ case KatanaPseudoFirstPage:
362
+ id = rb_intern("first_page");
363
+ break;
364
+ case KatanaPseudoFullScreen:
365
+ id = rb_intern("full_screen");
366
+ break;
367
+ case KatanaPseudoFullScreenDocument:
368
+ id = rb_intern("full_screen_document");
369
+ break;
370
+ case KatanaPseudoFullScreenAncestor:
371
+ id = rb_intern("full_screen_ancestor");
372
+ break;
373
+ case KatanaPseudoInRange:
374
+ id = rb_intern("in_range");
375
+ break;
376
+ case KatanaPseudoOutOfRange:
377
+ id = rb_intern("out_of_range");
378
+ break;
379
+ case KatanaPseudoWebKitCustomElement:
380
+ id = rb_intern("web_kit_custom_element");
381
+ break;
382
+ case KatanaPseudoCue:
383
+ id = rb_intern("cue");
384
+ break;
385
+ case KatanaPseudoFutureCue:
386
+ id = rb_intern("future_cue");
387
+ break;
388
+ case KatanaPseudoPastCue:
389
+ id = rb_intern("past_cue");
390
+ break;
391
+ case KatanaPseudoUnresolved:
392
+ id = rb_intern("unresolved");
393
+ break;
394
+ case KatanaPseudoContent:
395
+ id = rb_intern("content");
396
+ break;
397
+ case KatanaPseudoHost:
398
+ id = rb_intern("host");
399
+ break;
400
+ case KatanaPseudoHostContext:
401
+ id = rb_intern("host_context");
402
+ break;
403
+ case KatanaPseudoShadow:
404
+ id = rb_intern("shadow");
405
+ break;
406
+ case KatanaPseudoSpatialNavigationFocus:
407
+ id = rb_intern("spatial_navigation_focus");
408
+ break;
409
+ case KatanaPseudoListBox:
410
+ id = rb_intern("list_box");
411
+ break;
412
+ default:
413
+ id = rb_intern("unknown");
414
+ break;
415
+ }
416
+ return ID2SYM(id);
417
+ }
418
+
419
+ /*
420
+ * @return [Katana::QualifiedName, nil]
421
+ */
422
+ VALUE rb_selector_tag(VALUE self)
423
+ {
424
+ KatanaSelector *c_sel;
425
+ Data_Get_Struct(self, KatanaSelector, c_sel);
426
+ if (c_sel->tag)
427
+ return Data_Wrap_Struct(rb_QualifiedName, NULL, NULL, c_sel->tag);
428
+ else
429
+ return Qnil;
430
+ }
431
+
432
+ /*
433
+ * @return [Katana::SelectorData, nil]
434
+ */
435
+ VALUE rb_selector_data(VALUE self)
436
+ {
437
+ KatanaSelector *c_sel;
438
+ Data_Get_Struct(self, KatanaSelector, c_sel);
439
+ if (c_sel->data)
440
+ return Data_Wrap_Struct(rb_SelectorData, NULL, NULL, c_sel->data);
441
+ else
442
+ return Qnil;
443
+ }
444
+
445
+ /*
446
+ * @return [Katana::Selector, nil]
447
+ */
448
+ VALUE rb_selector_tag_history(VALUE self)
449
+ {
450
+ KatanaSelector *c_sel;
451
+ Data_Get_Struct(self, KatanaSelector, c_sel);
452
+ if (c_sel->tagHistory)
453
+ return Data_Wrap_Struct(rb_Selector, NULL, NULL, c_sel->tagHistory);
454
+ else
455
+ return Qnil;
456
+ }
457
+
458
+ /*
459
+ * @return [SourcePosition]
460
+ */
461
+ VALUE rb_selector_position(VALUE self)
462
+ {
463
+ KatanaSelector *c_sel;
464
+ Data_Get_Struct(self, KatanaSelector, c_sel);
465
+ return Data_Wrap_Struct(rb_KPosition, NULL, NULL, &c_sel->position);
466
+ }
467
+
468
+ // SelectorData
469
+
470
+ /*
471
+ * @return [String, nil]
472
+ */
473
+ VALUE rb_selector_data_value(VALUE self)
474
+ {
475
+ KatanaSelectorRareData *c_sel;
476
+ Data_Get_Struct(self, KatanaSelectorRareData, c_sel);
477
+ if (c_sel->value)
478
+ {
479
+ // force UTF-8
480
+ return rb_enc_associate_index(rb_str_new2(c_sel->value), rb_enc_find_index("UTF-8"));
481
+ }
482
+ else
483
+ return Qnil;
484
+ }
485
+
486
+ /*
487
+ * @return [Katana::QualifiedName, nil]
488
+ */
489
+ VALUE rb_selector_data_attr(VALUE self)
490
+ {
491
+ KatanaSelectorRareData *c_sel;
492
+ Data_Get_Struct(self, KatanaSelectorRareData, c_sel);
493
+ if (c_sel->attribute)
494
+ return Data_Wrap_Struct(rb_QualifiedName, NULL, NULL, c_sel->attribute);
495
+ else
496
+ return Qnil;
497
+ }
498
+
499
+ /*
500
+ * @return [String, nil]
501
+ */
502
+ VALUE rb_selector_data_argument(VALUE self)
503
+ {
504
+ KatanaSelectorRareData *c_sel;
505
+ Data_Get_Struct(self, KatanaSelectorRareData, c_sel);
506
+ if (c_sel->argument)
507
+ return rb_str_new2(c_sel->argument);
508
+ else
509
+ return Qnil;
510
+ }
511
+
512
+ /*
513
+ * @return [Katana::Array, nil]
514
+ */
515
+ VALUE rb_selector_data_selectors(VALUE self)
516
+ {
517
+ KatanaSelectorRareData *c_sel;
518
+ Data_Get_Struct(self, KatanaSelectorRareData, c_sel);
519
+
520
+ if (c_sel->selectors)
521
+ {
522
+ VALUE array = Data_Wrap_Struct(rb_KArray, NULL, NULL, c_sel->selectors);
523
+
524
+ VALUE sing = rb_singleton_class(array);
525
+ rb_define_method(sing, "each", rb_selector_each, 0);
526
+
527
+ return array;
528
+ }
529
+ else
530
+ return Qnil;
531
+ }
532
+
533
+ void init_katana_selector()
534
+ {
535
+ // QualifiedName
536
+ rb_QualifiedName = rb_define_class_under(rb_Katana, "QualifiedName", rb_cObject);
537
+ rb_define_method(rb_QualifiedName, "local", rb_name_local, 0);
538
+ rb_define_method(rb_QualifiedName, "prefix", rb_name_prefix, 0);
539
+ rb_define_method(rb_QualifiedName, "uri", rb_name_uri, 0);
540
+
541
+ // SelectorData
542
+ rb_SelectorData = rb_define_class_under(rb_Katana, "SelectorData", rb_cObject);
543
+ // TODO: bits
544
+ rb_define_method(rb_SelectorData, "value", rb_selector_data_value, 0);
545
+ rb_define_method(rb_SelectorData, "attribute", rb_selector_data_attr, 0);
546
+ rb_define_method(rb_SelectorData, "argument", rb_selector_data_argument, 0);
547
+ rb_define_method(rb_SelectorData, "selectors", rb_selector_data_selectors, 0);
548
+
549
+ // Selector
550
+ rb_Selector = rb_define_class_under(rb_Katana, "Selector", rb_cObject);
551
+ rb_define_method(rb_Selector, "specificity", rb_selector_specificity, 0);
552
+ rb_define_method(rb_Selector, "match", rb_selector_match, 0);
553
+ rb_define_method(rb_Selector, "tag", rb_selector_tag, 0);
554
+ rb_define_method(rb_Selector, "relation", rb_selector_relation, 0);
555
+ rb_define_method(rb_Selector, "pseudo", rb_selector_pseudo, 0);
556
+ rb_define_method(rb_Selector, "data", rb_selector_data, 0);
557
+ rb_define_method(rb_Selector, "tag_history", rb_selector_tag_history, 0);
558
+ rb_define_method(rb_Selector, "position", rb_selector_position, 0);
559
+ }