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,590 @@
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
+ // CSS Spec: http://www.w3.org/TR/css-syntax-3/
24
+
25
+ #ifndef __Katana__katana__
26
+ #define __Katana__katana__
27
+
28
+ #include <stdio.h>
29
+ #include <stdbool.h>
30
+ #include <stddef.h>
31
+
32
+ #ifdef __cplusplus
33
+ extern "C" {
34
+ #endif
35
+
36
+ #define KATANA_ERROR_MESSAGE_SIZE 100
37
+
38
+ typedef enum {
39
+ KatanaRuleUnkown,
40
+ KatanaRuleStyle,
41
+ KatanaRuleImport,
42
+ KatanaRuleMedia,
43
+ KatanaRulePage,
44
+ KatanaRuleFontFace,
45
+ KatanaRuleSupports,
46
+ KatanaRuleNamespace,
47
+ KatanaRuleKeyframes,
48
+ KatanaRuleCharset,
49
+ KatanaRuleHost,
50
+ } KatanaRuleType;
51
+
52
+ typedef enum {
53
+ KatanaMediaQueryRestrictorNone,
54
+ KatanaMediaQueryRestrictorOnly,
55
+ KatanaMediaQueryRestrictorNot,
56
+ } KatanaMediaQueryRestrictor;
57
+
58
+ typedef enum {
59
+ KatanaSupportsOperatorNone,
60
+ KatanaSupportsOperatorNot,
61
+ KatanaSupportsOperatorAnd,
62
+ KatanaSupportsOperatorOr,
63
+ } KatanaSupportsOperator;
64
+
65
+ typedef enum {
66
+ KatanaSelectorMatchUnknown = 0,
67
+ KatanaSelectorMatchTag, // Example: div
68
+ KatanaSelectorMatchId, // Example: #id
69
+ KatanaSelectorMatchClass, // example: .class
70
+ KatanaSelectorMatchPseudoClass, // Example: :nth-child(2)
71
+ KatanaSelectorMatchPseudoElement, // Example: ::first-line
72
+ KatanaSelectorMatchPagePseudoClass, // ??
73
+ KatanaSelectorMatchAttributeExact, // Example: E[foo="bar"]
74
+ KatanaSelectorMatchAttributeSet, // Example: E[foo]
75
+ KatanaSelectorMatchAttributeList, // Example: E[foo~="bar"]
76
+ KatanaSelectorMatchAttributeHyphen, // Example: E[foo|="bar"]
77
+ KatanaSelectorMatchAttributeContain, // css3: E[foo*="bar"]
78
+ KatanaSelectorMatchAttributeBegin, // css3: E[foo^="bar"]
79
+ KatanaSelectorMatchAttributeEnd, // css3: E[foo$="bar"]
80
+ KatanaSelectorMatchFirstAttribute = KatanaSelectorMatchAttributeExact,
81
+ } KatanaSelectorMatch;
82
+
83
+ typedef enum {
84
+ KatanaSelectorRelationSubSelector, // "No space" combinator
85
+ KatanaSelectorRelationDescendant, // "Space" combinator
86
+ KatanaSelectorRelationChild, // > combinator
87
+ KatanaSelectorRelationDirectAdjacent, // + combinator
88
+ KatanaSelectorRelationIndirectAdjacent, // ~ combinator
89
+ KatanaSelectorRelationShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
90
+ KatanaSelectorRelationShadowDeep // /shadow-deep/ combinator
91
+ } KatanaSelectorRelation;
92
+
93
+ typedef enum {
94
+ KatanaPseudoNotParsed,
95
+ KatanaPseudoUnknown,
96
+ KatanaPseudoEmpty,
97
+ KatanaPseudoFirstChild,
98
+ KatanaPseudoFirstOfType,
99
+ KatanaPseudoLastChild,
100
+ KatanaPseudoLastOfType,
101
+ KatanaPseudoOnlyChild,
102
+ KatanaPseudoOnlyOfType,
103
+ KatanaPseudoFirstLine,
104
+ KatanaPseudoFirstLetter,
105
+ KatanaPseudoNthChild,
106
+ KatanaPseudoNthOfType,
107
+ KatanaPseudoNthLastChild,
108
+ KatanaPseudoNthLastOfType,
109
+ KatanaPseudoLink,
110
+ KatanaPseudoVisited,
111
+ KatanaPseudoAny,
112
+ KatanaPseudoAnyLink,
113
+ KatanaPseudoAutofill,
114
+ KatanaPseudoHover,
115
+ KatanaPseudoDrag,
116
+ KatanaPseudoFocus,
117
+ KatanaPseudoActive,
118
+ KatanaPseudoChecked,
119
+ KatanaPseudoEnabled,
120
+ KatanaPseudoFullPageMedia,
121
+ KatanaPseudoDefault,
122
+ KatanaPseudoDisabled,
123
+ KatanaPseudoOptional,
124
+ KatanaPseudoRequired,
125
+ KatanaPseudoReadOnly,
126
+ KatanaPseudoReadWrite,
127
+ KatanaPseudoValid,
128
+ KatanaPseudoInvalid,
129
+ KatanaPseudoIndeterminate,
130
+ KatanaPseudoTarget,
131
+ KatanaPseudoBefore,
132
+ KatanaPseudoAfter,
133
+ KatanaPseudoBackdrop,
134
+ KatanaPseudoLang,
135
+ KatanaPseudoNot, // :not(selector), selector is Kind of KatanaSelector
136
+ KatanaPseudoResizer,
137
+ KatanaPseudoRoot,
138
+ KatanaPseudoScope,
139
+ KatanaPseudoScrollbar,
140
+ KatanaPseudoScrollbarButton,
141
+ KatanaPseudoScrollbarCorner,
142
+ KatanaPseudoScrollbarThumb,
143
+ KatanaPseudoScrollbarTrack,
144
+ KatanaPseudoScrollbarTrackPiece,
145
+ KatanaPseudoWindowInactive,
146
+ KatanaPseudoCornerPresent,
147
+ KatanaPseudoDecrement,
148
+ KatanaPseudoIncrement,
149
+ KatanaPseudoHorizontal,
150
+ KatanaPseudoVertical,
151
+ KatanaPseudoStart,
152
+ KatanaPseudoEnd,
153
+ KatanaPseudoDoubleButton,
154
+ KatanaPseudoSingleButton,
155
+ KatanaPseudoNoButton,
156
+ KatanaPseudoSelection,
157
+ KatanaPseudoLeftPage,
158
+ KatanaPseudoRightPage,
159
+ KatanaPseudoFirstPage,
160
+ KatanaPseudoFullScreen,
161
+ KatanaPseudoFullScreenDocument,
162
+ KatanaPseudoFullScreenAncestor,
163
+ KatanaPseudoInRange,
164
+ KatanaPseudoOutOfRange,
165
+ KatanaPseudoWebKitCustomElement,
166
+ KatanaPseudoCue,
167
+ KatanaPseudoFutureCue,
168
+ KatanaPseudoPastCue,
169
+ KatanaPseudoUnresolved,
170
+ KatanaPseudoContent,
171
+ KatanaPseudoHost,
172
+ KatanaPseudoHostContext,
173
+ KatanaPseudoShadow,
174
+ KatanaPseudoSpatialNavigationFocus,
175
+ KatanaPseudoListBox
176
+ } KatanaPseudoType;
177
+
178
+ typedef enum {
179
+ KatanaAttributeMatchTypeCaseSensitive,
180
+ KatanaAttributeMatchTypeCaseInsensitive,
181
+ } KatanaAttributeMatchType;
182
+
183
+ typedef enum {
184
+ KATANA_VALUE_UNKNOWN = 0,
185
+ KATANA_VALUE_NUMBER = 1,
186
+ KATANA_VALUE_PERCENTAGE = 2,
187
+ KATANA_VALUE_EMS = 3,
188
+ KATANA_VALUE_EXS = 4,
189
+
190
+ // double
191
+ KATANA_VALUE_PX = 5,
192
+ KATANA_VALUE_CM = 6,
193
+ KATANA_VALUE_MM = 7,
194
+ KATANA_VALUE_IN = 8,
195
+ KATANA_VALUE_PT = 9,
196
+ KATANA_VALUE_PC = 10,
197
+ KATANA_VALUE_DEG = 11,
198
+ KATANA_VALUE_RAD = 12,
199
+ KATANA_VALUE_GRAD = 13,
200
+ KATANA_VALUE_MS = 14,
201
+ KATANA_VALUE_S = 15,
202
+ KATANA_VALUE_HZ = 16,
203
+ KATANA_VALUE_KHZ = 17,
204
+ KATANA_VALUE_DIMENSION = 18,
205
+ KATANA_VALUE_STRING = 19,
206
+ KATANA_VALUE_URI = 20,
207
+ KATANA_VALUE_IDENT = 21,
208
+ KATANA_VALUE_ATTR = 22,
209
+ KATANA_VALUE_COUNTER = 23,
210
+ KATANA_VALUE_RECT = 24,
211
+ KATANA_VALUE_RGBCOLOR = 25,
212
+
213
+ KATANA_VALUE_VW = 26,
214
+ KATANA_VALUE_VH = 27,
215
+ KATANA_VALUE_VMIN = 28,
216
+ KATANA_VALUE_VMAX = 29,
217
+ KATANA_VALUE_DPPX = 30,
218
+ KATANA_VALUE_DPI = 31,
219
+ KATANA_VALUE_DPCM = 32,
220
+ KATANA_VALUE_FR = 33,
221
+ KATANA_VALUE_UNICODE_RANGE = 102,
222
+
223
+ KATANA_VALUE_PARSER_OPERATOR = 103,
224
+ KATANA_VALUE_PARSER_INTEGER = 104,
225
+ KATANA_VALUE_PARSER_HEXCOLOR = 105,
226
+ KATANA_VALUE_PARSER_FUNCTION = 0x100001,
227
+ KATANA_VALUE_PARSER_LIST = 0x100002,
228
+ KATANA_VALUE_PARSER_Q_EMS = 0x100003,
229
+
230
+ KATANA_VALUE_PARSER_IDENTIFIER = 106,
231
+
232
+ KATANA_VALUE_TURN = 107,
233
+ KATANA_VALUE_REMS = 108,
234
+ KATANA_VALUE_CHS = 109,
235
+
236
+ KATANA_VALUE_COUNTER_NAME = 110,
237
+
238
+ KATANA_VALUE_SHAPE = 111,
239
+
240
+ KATANA_VALUE_QUAD = 112,
241
+
242
+ KATANA_VALUE_CALC = 113,
243
+ KATANA_VALUE_CALC_PERCENTAGE_WITH_NUMBER = 114,
244
+ KATANA_VALUE_CALC_PERCENTAGE_WITH_LENGTH = 115,
245
+ KATANA_VALUE_VARIABLE_NAME = 116,
246
+
247
+ KATANA_VALUE_PROPERTY_ID = 117,
248
+ KATANA_VALUE_VALUE_ID = 118
249
+ } KatanaValueUnit;
250
+
251
+ //typedef enum {
252
+ // KATANA_VALUE_PARSER_OPERATOR = 0x100000,
253
+ // KATANA_VALUE_PARSER_FUNCTION = 0x100001,
254
+ // KATANA_VALUE_PARSER_LIST = 0x100002,
255
+ // KATANA_VALUE_PARSER_Q_EMS = 0x100003,
256
+ //} KatanaParserValueUnit;
257
+
258
+ typedef enum { KatanaParseError } KatanaErrorType;
259
+
260
+ /**
261
+ * Positon, for error debug
262
+ */
263
+ typedef struct {
264
+ unsigned int line;
265
+ unsigned int column;
266
+ } KatanaSourcePosition;
267
+
268
+ typedef struct {
269
+ const char* local; // tag local name
270
+ const char* prefix; // namesapce identifier
271
+ const char* uri; // namesapce uri
272
+ } KatanaQualifiedName;
273
+
274
+ typedef struct {
275
+ /** Data elements. This points to a dynamically-allocated array of capacity
276
+ * elements, each a void* to the element itself, remember free each element.
277
+ */
278
+ void** data;
279
+
280
+ /** Number of elements currently in the array. */
281
+ unsigned int length;
282
+
283
+ /** Current array capacity. */
284
+ unsigned int capacity;
285
+
286
+ } KatanaArray;
287
+
288
+ typedef struct {
289
+ const char* encoding;
290
+ KatanaArray /* KatanaRule */ rules;
291
+ KatanaArray /* KatanaImportRule */ imports;
292
+ } KatanaStylesheet;
293
+
294
+ typedef struct {
295
+ const char* name;
296
+ KatanaRuleType type;
297
+ } KatanaRule;
298
+
299
+ typedef struct {
300
+ KatanaRule base;
301
+ KatanaArray* /* KatanaSelector */ selectors;
302
+ KatanaArray* /* KatanaDeclaration */ declarations;
303
+ } KatanaStyleRule;
304
+
305
+ typedef struct {
306
+ const char* comment;
307
+ } KatanaComment; // unused for right
308
+
309
+ /**
310
+ * The `@font-face` at-rule.
311
+ */
312
+ typedef struct {
313
+ KatanaRule base;
314
+ KatanaArray* /* KatanaDeclaration */ declarations;
315
+ } KatanaFontFaceRule;
316
+
317
+ /**
318
+ * The `@host` at-rule.
319
+ */
320
+ typedef struct {
321
+ KatanaRule base;
322
+ KatanaArray* /* KatanaRule */ host;
323
+ } KatanaHostRule;
324
+
325
+ /**
326
+ * The `@import` at-rule.
327
+ */
328
+ typedef struct {
329
+ KatanaRule base;
330
+ /**
331
+ * The part following `@import `
332
+ */
333
+ const char* href;
334
+ /**
335
+ * The media list belonging to this import rule
336
+ */
337
+ KatanaArray* /* KatanaMediaQuery* */ medias;
338
+ } KatanaImportRule;
339
+
340
+ /**
341
+ * The `@keyframes` at-rule.
342
+ * Spec: http://www.w3.org/TR/css3-animations/#keyframes
343
+ */
344
+ typedef struct {
345
+ KatanaRule base;
346
+ /**
347
+ * The vendor prefix in `@keyframes`, or `undefined` if there is none.
348
+ */
349
+ const char* name;
350
+ KatanaArray* /* KatanaKeyframe */ keyframes;
351
+ } KatanaKeyframesRule;
352
+
353
+ typedef struct {
354
+ KatanaArray* /* KatanaValue: `percentage`, `from`, `to` */ selectors;
355
+ KatanaArray* /* KatanaDeclaration */ declarations;
356
+ } KatanaKeyframe;
357
+
358
+ /* @namespace */
359
+ typedef struct {
360
+ KatanaRule base;
361
+
362
+ const char* prefix;
363
+ const char* uri;
364
+ } KatanaNamespaceRule;
365
+
366
+ /**
367
+ * The `@media` at-rule.
368
+ */
369
+ typedef struct {
370
+ KatanaRule base;
371
+ /**
372
+ * The part following `@media `
373
+ */
374
+ KatanaArray* medias;
375
+ /**
376
+ * An `Array` of nodes with the types `rule`, `comment` and any of the
377
+ at-rule types.
378
+ */
379
+ KatanaArray* /* KatanaRule */ rules;
380
+ } KatanaMediaRule;
381
+
382
+ /**
383
+ * Media Query Exp List
384
+ * Spec: http://www.w3.org/TR/mediaqueries-4/
385
+ */
386
+
387
+ typedef struct {
388
+ KatanaMediaQueryRestrictor restrictor;
389
+ const char* type;
390
+ KatanaArray* expressions;
391
+ bool ignored;
392
+ } KatanaMediaQuery;
393
+
394
+ typedef struct {
395
+ const char* feature;
396
+ KatanaArray* values;
397
+ const char* raw;
398
+ } KatanaMediaQueryExp;
399
+
400
+ typedef struct {
401
+ KatanaRule base;
402
+ KatanaArray* /* KatanaDeclaration */ declarations;
403
+ } KatanaPageRule;
404
+
405
+ typedef struct {
406
+ const char* value;
407
+ union {
408
+ struct {
409
+ int a; // Used for :nth-*
410
+ int b; // Used for :nth-*
411
+ } nth;
412
+ KatanaAttributeMatchType attributeMatchType; // used for attribute selector (with value)
413
+ } bits;
414
+ KatanaQualifiedName* attribute;
415
+ const char* argument; // Used for :contains, :lang, :nth-*
416
+ KatanaArray* selectors; // Used for :any and :not
417
+ } KatanaSelectorRareData;
418
+
419
+ typedef struct KatanaSelector {
420
+ KatanaSourcePosition position;
421
+
422
+ size_t specificity;
423
+ KatanaSelectorMatch match;
424
+ KatanaPseudoType pseudo;
425
+ KatanaSelectorRelation relation;
426
+ KatanaQualifiedName* tag;
427
+ KatanaSelectorRareData* data;
428
+ struct KatanaSelector* tagHistory;
429
+ } KatanaSelector;
430
+
431
+ unsigned katana_calc_specificity_for_selector(KatanaSelector* selector);
432
+
433
+ typedef struct {
434
+ KatanaSourcePosition position;
435
+
436
+ // property name
437
+ const char* property;
438
+
439
+ // property value
440
+ KatanaArray* /* KatanaValue */ values;
441
+ const char* string;
442
+
443
+ // is this property marked important
444
+ bool important;
445
+
446
+ // origin css text of the property
447
+ const char* raw;
448
+ } KatanaDeclaration;
449
+
450
+ typedef struct {
451
+ const char* name;
452
+ KatanaArray* args;
453
+ } KatanaValueFunction;
454
+
455
+ typedef struct KatanaValue {
456
+ bool isInt;
457
+ union {
458
+ int iValue;
459
+ double fValue;
460
+ const char* string;
461
+ KatanaValueFunction* function;
462
+ KatanaArray* list;
463
+ };
464
+ KatanaValueUnit unit;
465
+ const char* raw;
466
+ } KatanaValue;
467
+
468
+ typedef struct {
469
+ KatanaSupportsOperator op;
470
+ KatanaArray* exps;
471
+ KatanaDeclaration* decl;
472
+ const char* raw;
473
+ } KatanaSupportsExp;
474
+
475
+ /**
476
+ * The `@supports` at-rule.
477
+ */
478
+ typedef struct {
479
+ KatanaRule base;
480
+ KatanaSupportsExp* exp;
481
+ KatanaArray* /* KatanaRule */ rules;
482
+ } KatanaSupportsRule;
483
+
484
+ /**
485
+ * The `@charset` at-rule.
486
+ */
487
+ typedef struct {
488
+ KatanaRule base;
489
+ /**
490
+ * The encoding information
491
+ */
492
+ const char* encoding;
493
+ } KatanaCharsetRule;
494
+
495
+ typedef struct {
496
+ KatanaErrorType type;
497
+ int first_line;
498
+ int first_column;
499
+ int last_line;
500
+ int last_column;
501
+ char message[KATANA_ERROR_MESSAGE_SIZE];
502
+ } KatanaError;
503
+
504
+ // TODO: @document
505
+ // TODO: @supports
506
+ // TODO: custom-at-rule
507
+
508
+ /**
509
+ * Parser mode
510
+ */
511
+ typedef enum KatanaParserMode {
512
+ // Normal CSS content used in External CSS files or Internal CSS, may include more than 1 css rules.
513
+ KatanaParserModeStylesheet,
514
+
515
+ // Single CSS rule like "@import", "selector{...}"
516
+ KatanaParserModeRule,
517
+
518
+ KatanaParserModeKeyframeRule,
519
+ KatanaParserModeKeyframeKeyList,
520
+ KatanaParserModeMediaList,
521
+
522
+ // CSS property value like "1px", "1em", "#eee"
523
+ KatanaParserModeValue,
524
+
525
+ // CSS selector like ".pages.active"
526
+ KatanaParserModeSelector,
527
+
528
+ // Inline stylesheet like "width: 20px; height: 20px;"
529
+ KatanaParserModeDeclarationList,
530
+ } KatanaParserMode;
531
+
532
+ typedef struct KatanaInternalOutput {
533
+ // Complete CSS string
534
+ KatanaStylesheet* stylesheet;
535
+ union {
536
+ // fragmental CSS string
537
+ KatanaRule* rule;
538
+ KatanaKeyframe* keyframe;
539
+ KatanaArray* keyframe_keys;
540
+ KatanaArray* values;
541
+ KatanaArray* medias;
542
+ KatanaArray* /* KatanaDeclaration */ declarations;
543
+ KatanaArray* selectors;
544
+ KatanaArray* supports;
545
+ };
546
+ KatanaParserMode mode;
547
+ KatanaArray /* KatanaError */ errors;
548
+ } KatanaOutput;
549
+
550
+ /**
551
+ * Parse a complete or fragmental CSS string
552
+ *
553
+ * @param str Input CSS string
554
+ * @param len Length of the input CSS string
555
+ * @param mode Parser mode, depends on the input
556
+ *
557
+ * @return The result of parsing
558
+ */
559
+ KatanaOutput* katana_parse(const char* str, size_t len, KatanaParserMode mode);
560
+
561
+ /**
562
+ * Parse a complete CSS file
563
+ *
564
+ * @param fp `FILE` point to the CSS file
565
+ *
566
+ * @return The result of parsing
567
+ */
568
+ KatanaOutput* katana_parse_in(FILE* fp);
569
+
570
+ /**
571
+ * Free the output
572
+ *
573
+ * @param output The result of parsing
574
+ */
575
+ void katana_destroy_output(KatanaOutput* output);
576
+
577
+ /**
578
+ * Print the formatted CSS string
579
+ *
580
+ * @param output The result of parsing
581
+ *
582
+ * @return The origin output
583
+ */
584
+ KatanaOutput* katana_dump_output(KatanaOutput* output);
585
+
586
+ #ifdef __cplusplus
587
+ }
588
+ #endif
589
+
590
+ #endif /* defined(__Katana__katana__) */