syntax_tree-css 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,441 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SyntaxTree
4
+ module CSS
5
+ # A pretty-print visitor.
6
+ class PrettyPrint < BasicVisitor
7
+ attr_reader :q
8
+
9
+ def initialize(q)
10
+ @q = q
11
+ end
12
+
13
+ #-------------------------------------------------------------------------
14
+ # CSS3 nodes
15
+ #-------------------------------------------------------------------------
16
+
17
+ # Visit an AtKeywordToken node.
18
+ def visit_at_keyword_token(node)
19
+ token("at-keyword-token") do
20
+ q.breakable
21
+ q.pp(node.value)
22
+ end
23
+ end
24
+
25
+ # Visit an AtRule node.
26
+ def visit_at_rule(node)
27
+ token("at-rule") do
28
+ q.breakable
29
+ q.pp(node.name)
30
+
31
+ q.breakable
32
+ q.text("(prelude")
33
+ q.nest(2) do
34
+ q.breakable("")
35
+ q.seplist(node.prelude) { |token| q.pp(token) }
36
+ end
37
+
38
+ q.breakable("")
39
+ q.text(")")
40
+
41
+ q.breakable
42
+ q.pp(node.block)
43
+ end
44
+ end
45
+
46
+ # Visit a BadStringToken node.
47
+ def visit_bad_string_token(node)
48
+ token("bad-string-token") do
49
+ q.breakable
50
+ q.pp(node.value)
51
+ end
52
+ end
53
+
54
+ # Visit a BadURLToken node.
55
+ def visit_bad_url_token(node)
56
+ token("bad-url-token") do
57
+ q.breakable
58
+ q.pp(node.value)
59
+ end
60
+ end
61
+
62
+ # Visit a CDCToken node.
63
+ def visit_cdc_token(node)
64
+ token("cdc-token")
65
+ end
66
+
67
+ # Visit a CDOToken node.
68
+ def visit_cdo_token(node)
69
+ token("cdo-token")
70
+ end
71
+
72
+ # Visit a CloseCurlyToken node.
73
+ def visit_close_curly_token(node)
74
+ token("close-curly-token")
75
+ end
76
+
77
+ # Visit a CloseParenToken node.
78
+ def visit_close_paren_token(node)
79
+ token("close-paren-token")
80
+ end
81
+
82
+ # Visit a CloseSquareToken node.
83
+ def visit_close_square_token(node)
84
+ token("close-square-token")
85
+ end
86
+
87
+ # Visit a ColonToken node.
88
+ def visit_colon_token(node)
89
+ token("colon-token")
90
+ end
91
+
92
+ # Visit a CommentToken node.
93
+ def visit_comment_token(node)
94
+ token("comment-token") do
95
+ q.breakable
96
+ q.pp(node.value)
97
+ end
98
+ end
99
+
100
+ # Visit a CommaToken node.
101
+ def visit_comma_token(node)
102
+ token("comma-token")
103
+ end
104
+
105
+ # Visit a CSSStyleSheet node.
106
+ def visit_css_stylesheet(node)
107
+ token("css-stylesheet") do
108
+ if node.rules.any?
109
+ q.breakable
110
+ q.seplist(node.rules) { |rule| q.pp(rule) }
111
+ end
112
+ end
113
+ end
114
+
115
+ # Visit a Declaration node.
116
+ def visit_declaration(node)
117
+ token("declaration") do
118
+ q.breakable
119
+ q.text(node.name)
120
+
121
+ if node.important?
122
+ q.breakable
123
+ q.text("!important")
124
+ end
125
+
126
+ q.breakable
127
+ q.seplist(node.value) { |token| q.pp(token) }
128
+ end
129
+ end
130
+
131
+ # Visit a DelimToken node.
132
+ def visit_delim_token(node)
133
+ token("delim-token") do
134
+ q.breakable
135
+ q.pp(node.value)
136
+ end
137
+ end
138
+
139
+ # Visit a DimensionToken node.
140
+ def visit_dimension_token(node)
141
+ token("dimension-token") do
142
+ q.breakable
143
+ q.text(node.type)
144
+
145
+ q.breakable
146
+ q.pp(node.value)
147
+
148
+ q.breakable
149
+ q.text(node.unit)
150
+ end
151
+ end
152
+
153
+ # Visit an EOFToken node.
154
+ def visit_eof_token(node)
155
+ token("eof-token")
156
+ end
157
+
158
+ # Visit a Function node.
159
+ def visit_function(node)
160
+ token("function") do
161
+ q.breakable
162
+ q.text(node.name)
163
+
164
+ q.breakable
165
+ q.text("(value")
166
+ q.nest(2) do
167
+ q.breakable
168
+ q.seplist(node.value) { |token| q.pp(token) }
169
+ end
170
+
171
+ q.breakable("")
172
+ q.text(")")
173
+ end
174
+ end
175
+
176
+ # Visit a FunctionToken node.
177
+ def visit_function_token(node)
178
+ token("function-token") do
179
+ q.breakable
180
+ q.pp(node.value)
181
+ end
182
+ end
183
+
184
+ # Visit an IdentToken node.
185
+ def visit_ident_token(node)
186
+ token("ident-token") do
187
+ q.breakable
188
+ q.pp(node.value)
189
+ end
190
+ end
191
+
192
+ # Visit a HashToken node.
193
+ def visit_hash_token(node)
194
+ token("hash-token") do
195
+ q.breakable
196
+ q.pp(node.value)
197
+
198
+ q.breakable
199
+ q.text(node.type)
200
+ end
201
+ end
202
+
203
+ # Visit a NumberToken node.
204
+ def visit_number_token(node)
205
+ token("number-token") do
206
+ q.breakable
207
+ q.text(node.type)
208
+
209
+ q.breakable
210
+ q.pp(node.value)
211
+ end
212
+ end
213
+
214
+ # Visit an OpenCurlyToken node.
215
+ def visit_open_curly_token(node)
216
+ token("open-curly-token")
217
+ end
218
+
219
+ # Visit an OpenParenToken node.
220
+ def visit_open_paren_token(node)
221
+ token("open-paren-token")
222
+ end
223
+
224
+ # Visit an OpenSquareToken node.
225
+ def visit_open_square_token(node)
226
+ token("open-square-token")
227
+ end
228
+
229
+ # Visit a PercentageToken node.
230
+ def visit_percentage_token(node)
231
+ token("percentage-token") do
232
+ q.breakable
233
+ q.text(node.type)
234
+
235
+ q.breakable
236
+ q.pp(node.value)
237
+ end
238
+ end
239
+
240
+ # Visit a QualifiedRule node.
241
+ def visit_qualified_rule(node)
242
+ token("qualified-rule") do
243
+ q.breakable
244
+ q.text("(prelude")
245
+ q.nest(2) do
246
+ q.breakable("")
247
+ q.seplist(node.prelude) { |token| q.pp(token) }
248
+ end
249
+
250
+ q.breakable("")
251
+ q.text(")")
252
+
253
+ q.breakable
254
+ q.pp(node.block)
255
+ end
256
+ end
257
+
258
+ # Visit a SemicolonToken node.
259
+ def visit_semicolon_token(node)
260
+ token("semicolon-token")
261
+ end
262
+
263
+ # Visit a SimpleBlock node.
264
+ def visit_simple_block(node)
265
+ token("simple-block") do
266
+ q.breakable
267
+ q.pp(node.token)
268
+
269
+ if node.value.any?
270
+ q.breakable
271
+ q.seplist(node.value) { |val| q.pp(val) }
272
+ end
273
+ end
274
+ end
275
+
276
+ # Visit a StringToken node.
277
+ def visit_string_token(node)
278
+ token("string-token") do
279
+ q.breakable
280
+ q.pp(node.value)
281
+ end
282
+ end
283
+
284
+ # Visit a StyleRule node.
285
+ def visit_style_rule(node)
286
+ token("style-rule") do
287
+ q.breakable
288
+ q.text("(selectors")
289
+ q.nest(2) do
290
+ q.breakable
291
+ q.seplist(node.selectors) { |token| q.pp(token) }
292
+ end
293
+
294
+ q.breakable("")
295
+ q.text(")")
296
+
297
+ q.breakable
298
+ q.text("(declarations")
299
+
300
+ if node.declarations.any?
301
+ q.nest(2) do
302
+ q.breakable
303
+ q.seplist(node.declarations) { |token| q.pp(token) }
304
+ end
305
+
306
+ q.breakable("")
307
+ end
308
+
309
+ q.text(")")
310
+ end
311
+ end
312
+
313
+ # Visit a StyleSheet node.
314
+ def visit_stylesheet(node)
315
+ token("stylesheet") do
316
+ if node.rules.any?
317
+ q.breakable
318
+ q.seplist(node.rules) { |rule| q.pp(rule) }
319
+ end
320
+ end
321
+ end
322
+
323
+ # Visit a URange node.
324
+ def visit_urange(node)
325
+ token("urange") do
326
+ q.breakable
327
+ q.pp(node.start_value)
328
+ q.text("-")
329
+ q.pp(node.end_value)
330
+ end
331
+ end
332
+
333
+ # Visit a URLToken node.
334
+ def visit_url_token(node)
335
+ token("url-token") do
336
+ q.breakable
337
+ q.pp(node.value)
338
+ end
339
+ end
340
+
341
+ # Visit a WhitespaceToken node.
342
+ def visit_whitespace_token(node)
343
+ token("whitespace-token") do
344
+ q.breakable
345
+ q.pp(node.value)
346
+ end
347
+ end
348
+
349
+ #-------------------------------------------------------------------------
350
+ # Selector nodes
351
+ #-------------------------------------------------------------------------
352
+
353
+ # Visit a Selectors::ClassSelector node.
354
+ def visit_class_selector(node)
355
+ token("class-selector") do
356
+ q.breakable
357
+ q.pp(node.value)
358
+ end
359
+ end
360
+
361
+ # Visit a Selectors::IdSelector node.
362
+ def visit_id_selector(node)
363
+ token("id-selector") do
364
+ q.breakable
365
+ q.pp(node.value)
366
+ end
367
+ end
368
+
369
+ # Visit a Selectors::PseudoClassSelector node.
370
+ def visit_pseudo_class_selector(node)
371
+ token("pseudo-class-selector") do
372
+ q.breakable
373
+ q.pp(node.value)
374
+ end
375
+ end
376
+
377
+ # Visit a Selectors::PseudoClassFunction node.
378
+ def visit_pseudo_class_function(node)
379
+ token("pseudo-class-function") do
380
+ q.breakable
381
+ q.pp(node.name)
382
+
383
+ if node.arguments.any?
384
+ q.breakable
385
+ q.seplist(node.arguments) { |argument| q.pp(argument) }
386
+ end
387
+ end
388
+ end
389
+
390
+ # Visit a Selectors::PseudoElementSelector node.
391
+ def visit_pseudo_element_selector(node)
392
+ token("pseudo-element-selector") do
393
+ q.breakable
394
+ q.pp(node.value)
395
+ end
396
+ end
397
+
398
+ # Visit a Selectors::TypeSelector node.
399
+ def visit_type_selector(node)
400
+ token("type-selector") do
401
+ if node.prefix
402
+ q.breakable
403
+ q.pp(node.prefix)
404
+ end
405
+
406
+ q.breakable
407
+ q.pp(node.value)
408
+ end
409
+ end
410
+
411
+ # Visit a Selectors::WqName node.
412
+ def visit_wqname(node)
413
+ token("wqname") do
414
+ if node.prefix
415
+ q.breakable
416
+ q.pp(node.prefix)
417
+ end
418
+
419
+ q.breakable
420
+ q.pp(node.name)
421
+ end
422
+ end
423
+
424
+ private
425
+
426
+ def token(name)
427
+ q.group do
428
+ q.text("(")
429
+ q.text(name)
430
+
431
+ if block_given?
432
+ q.nest(2) { yield }
433
+ q.breakable("")
434
+ end
435
+
436
+ q.text(")")
437
+ end
438
+ end
439
+ end
440
+ end
441
+ end