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.
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
+ }