syntax_tree-css 0.1.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.
@@ -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