talius 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +177 -0
  3. data/lib/talius.rb +736 -0
  4. metadata +59 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c923ee36c973d0f95514ccd29ed7d6b5181e55614c376817ff2c7cdbe4ac8291
4
+ data.tar.gz: 82037c3e6161cec2b6b7999542c0a112b1ac6de9f2329833de9dbdd3323da6d6
5
+ SHA512:
6
+ metadata.gz: ea1038d7afd52feff046aab805f225cc72cc05f1a17912b483986ce29c80fb2bab171953837783827ecc32efe890af9d723278100996b2f65f4185f809ceaac2
7
+ data.tar.gz: ec31c961daf6e5d2f80e456b903fadf2130749fd672e34cf41594fac16c3664b4f28749331d3c2e3917ca9ada5ad86877a8e6565e98831e48838946313398d1c
@@ -0,0 +1,177 @@
1
+ # Talius
2
+
3
+ Talius is a parser for CSS selectors. It does not parse CSS, just CSS
4
+ selectors.
5
+
6
+ `Talius.new` accepts a single string as the selector. The `Talius`
7
+ object provides an interface with which to access the properties of that
8
+ selector.
9
+
10
+ In this example, the selector consists of just `a`, meaning it selects
11
+ `<a>` tags:
12
+
13
+ <table>
14
+ <tr>
15
+ <td class='right'>
16
+ <pre>1
17
+ 2
18
+ 3
19
+ 4
20
+ </pre>
21
+ </td>
22
+ <td>
23
+ <pre>
24
+ raw = 'a'
25
+ selector = Talius.new(raw)
26
+ rule = selector.rules[0]
27
+ rule.tags # => {"a"=>{"name"=>"a"}}
28
+ </pre>
29
+ </td>
30
+ </tr>
31
+ </table>
32
+
33
+ Line 1 creates the raw CSS selector like you might find in a CSS file. Line 2
34
+ creates a `Talius` object.
35
+
36
+ Each Talius has one or more rules. In this example the object will have one
37
+ rule. Line 3 gets that rule. Each rule has a hash of tag names in the `tags`
38
+ property. Line 4 displays that hash. See below for more about the `tags` hash.
39
+
40
+ The following sections will describe how Talius provides information about
41
+ different elements of a selector. Talius is in its infancy, so there are
42
+ some important aspects of CSS selectors that it doesn't support. Those aspects
43
+ are detailed below.
44
+
45
+ ## Tags
46
+
47
+ If a selector contains a tag name, that information will be put into the
48
+ `tags` hash of the rule. Consider this example.
49
+
50
+ ```ruby
51
+ raw = 'a'
52
+ selector = Talius.new(raw)
53
+ rule = selector.rules[0]
54
+ rule.tags # => {"a"=>{"name"=>"a"}}
55
+ rule.tags['a'].class # => Talius::Node::Tag
56
+ rule.tags['a'].name # => "a"
57
+ rule.tags['a'].namespace # => nil
58
+ ```
59
+
60
+ That selector consists of just a single tag name, so the `selector` object has
61
+ just one rule. That rule has a property called `tags`, which is a hash of the
62
+ tags in the rule. The key for each hash element is the name of the tag. The
63
+ value of the element is a `Talius::Node::Tag` object. That object has two
64
+ properties, `name` and `namespace`.
65
+
66
+ To indicate the namespace for the tag, put the namespace, followed by `|`,
67
+ followed by the name of the tag. For example, the following code has a selector
68
+ for tags in the `mml` namespace with the name `a`. The keys in the `tags` hash
69
+ are formatted in the same way.
70
+
71
+ ```ruby
72
+ raw = 'mml|a'
73
+ selector = Talius.new(raw)
74
+ rule = selector.rules[0]
75
+ rule.tags # => {"mml|a"=>{"name"=>"a", "namespace"=>"mml"}}
76
+ rule.tags['mml|a'].class # => Talius::Node::Tag
77
+ rule.tags['mml|a'].name # => "a"
78
+ rule.tags['mml|a'].namespace # => "mml"
79
+ ```
80
+
81
+ ## Multiple rules
82
+
83
+ For multiple rules for a selector, separate the rules with a comma. For example,
84
+ the following code parses a selector with two rules, one for the `section` tag
85
+ and one for the `div` tag.
86
+
87
+ ```ruby
88
+ raw = 'section, div'
89
+ selector = Talius.new(raw)
90
+ selector.rules.length # => 2
91
+ selector.rules # => [{"tags"=>{"section"=>{"name"=>"section"}}}, {"tags"=>{"div"=>{"name"=>"div"}}}]
92
+ ```
93
+
94
+ ## IDs
95
+
96
+ If any ID descriptions are given, those IDs can be found in the rule's `ids`
97
+ hash. The keys are the names of the IDs, the values are always `true`.
98
+
99
+ ```ruby
100
+ raw = '#overview'
101
+ selector = Talius.new(raw)
102
+ rule = selector.rules[0]
103
+ rule.ids # => {"overview"=>true}
104
+ ```
105
+
106
+ ## Classes
107
+
108
+ Classes are available in the `classes` property of the rule. `classes` is a
109
+ simple hash in which the value of each class is true.
110
+
111
+ ```ruby
112
+ raw = 'section.overview.current'
113
+ selector = Talius.new(raw)
114
+ rule = selector.rules[0]
115
+ rule.classes # => {"overview"=>true, "current"=>true}
116
+ ```
117
+
118
+ ## Attributes
119
+
120
+ Attribute rules are provided in the rule's `atts` hash. The hash consists of the
121
+ key of each attribute and a `Talius::Node::Att` object.
122
+
123
+ In this simple example, the selector looks for tags with an `rel` attribute.
124
+
125
+ ```ruby
126
+ raw = '[rel]'
127
+ selector = Talius.new(raw)
128
+ rule = selector.rules[0]
129
+ att = rule.atts['rel']
130
+ att.class # => Talius::Node::Att
131
+ att.name # => rel
132
+ ```
133
+
134
+ If you assign a value to the attribute, that value will be in `value` property.
135
+
136
+ ```ruby
137
+ raw = '[rel=license]'
138
+ selector = Talius.new(raw)
139
+ rule = selector.rules[0]
140
+ att = rule.atts['rel']
141
+ att.name # => href
142
+ att.value # => license
143
+ ```
144
+
145
+ Attribute namespaces are indicated in the same way as with tags. You can access
146
+ the namespace with the `namespace` property.
147
+
148
+ ```ruby
149
+ raw = '[mml|rel]'
150
+ selector = Talius.new(raw)
151
+ rule = selector.rules[0]
152
+ att = rule.atts['mml|rel']
153
+ att.name # => rel
154
+ att.namespace # => mml
155
+ ```
156
+
157
+ ## Install
158
+
159
+ ``
160
+ gem install talius
161
+ ``
162
+
163
+ ## Author
164
+
165
+ Mike O'Sullivan
166
+ mike@idocs.com
167
+
168
+ ## Name
169
+
170
+ "Talius" doesn't mean anything in particular. It just sounded like a good name
171
+ and it was available on rubygems.rb.
172
+
173
+ ## History
174
+
175
+ | version | date | notes |
176
+ |---------|--------------|-------------------------------|
177
+ | 0.5 | May 29, 2020 | Initial upload. |
@@ -0,0 +1,736 @@
1
+ require 'lx'
2
+
3
+ #===============================================================================
4
+ # Talius
5
+ #
6
+
7
+ # A +Talius+ object represents a full CSS selector.
8
+ class Talius
9
+ # version '0.5'
10
+ VERSION = '0.5'
11
+
12
+
13
+ # An array of rule objects.
14
+ attr_reader :rules
15
+
16
+ #---------------------------------------------------------------------------
17
+ # initialize
18
+ #
19
+
20
+ # Initialize a new Talius object. Takes a raw CSS selector string as the
21
+ # single param.
22
+ #
23
+ # raw = 'a[href]'
24
+ # selector = Talius.new(raw)
25
+ def initialize(p_raw)
26
+ @raw = p_raw
27
+ @rules = []
28
+ @slashes = {}
29
+ @quotes = {}
30
+ @norm = nil
31
+
32
+ # normalize selector string
33
+ unslash()
34
+ unquote()
35
+ @norm.lx.collapse!
36
+
37
+ # split into rules
38
+ @norm.split(/\s*,\s*/mu).each do |rule_str|
39
+ @rules.push Talius::Rule.new(self, rule_str)
40
+ end
41
+ end
42
+ #
43
+ # initialize
44
+ #---------------------------------------------------------------------------
45
+
46
+
47
+ #---------------------------------------------------------------------------
48
+ # raw
49
+ #
50
+
51
+ # The original string used to the create the selector object.
52
+ #
53
+ # raw = 'a[href]'
54
+ # selector = Talius.new(raw)
55
+ # selector.raw # => "a[href]"
56
+ attr_reader :raw
57
+
58
+ #
59
+ # raw
60
+ #---------------------------------------------------------------------------
61
+
62
+
63
+ #---------------------------------------------------------------------------
64
+ # denormalize
65
+ #
66
+
67
+ # Used by Talius::Rule to rebuild a string that has placeholders in it. This
68
+ # method is not useful for any purpose beyond that.
69
+ def denormalize(raw)
70
+ return reslash(requote(raw))
71
+ end
72
+ #
73
+ # denormalize
74
+ #---------------------------------------------------------------------------
75
+
76
+
77
+ # private
78
+ private
79
+
80
+
81
+ #---------------------------------------------------------------------------
82
+ # requote
83
+ #
84
+ def requote(raw)
85
+ return @quotes[raw] || raw
86
+ end
87
+ #
88
+ # requote
89
+ #---------------------------------------------------------------------------
90
+
91
+
92
+ #---------------------------------------------------------------------------
93
+ # reslash
94
+ #
95
+ def reslash(rv)
96
+ # $tm.hrm
97
+
98
+ # loop through slashed strings
99
+ @slashes.each do |pattern, val|
100
+ rv = rv.sub(/#{pattern}/mu, val)
101
+ end
102
+
103
+ # return
104
+ return rv
105
+ end
106
+ #
107
+ # reslash
108
+ #---------------------------------------------------------------------------
109
+
110
+
111
+ #---------------------------------------------------------------------------
112
+ # unquote
113
+ #
114
+ def unquote()
115
+ rv = []
116
+
117
+ # split into slashed and unslashed strings
118
+ @norm.split(/("[^"]*")/mu).each do |token|
119
+ if token.match(/\A".*"\z/mu)
120
+ content = token
121
+ content = content.sub(/\A"/mu, '')
122
+ content = content.sub(/"\z/mu, '')
123
+ ph = LX.randstr()
124
+ @quotes[ph] = content
125
+ rv.push ph
126
+ else
127
+ rv.push token
128
+ end
129
+ end
130
+
131
+ # return new string
132
+ @norm = rv.join('')
133
+ end
134
+ #
135
+ # unquote
136
+ #---------------------------------------------------------------------------
137
+
138
+
139
+ #---------------------------------------------------------------------------
140
+ # unslash
141
+ #
142
+ def unslash()
143
+ rv = []
144
+
145
+ # split into slashed and unslashed strings
146
+ @raw.split(/(\\.)/mu).each do |token|
147
+ if token.match(/\A\\.\z/mu)
148
+ ph = LX.randstr()
149
+ @slashes[ph] = token[1]
150
+ rv.push ph
151
+ else
152
+ rv.push token
153
+ end
154
+ end
155
+
156
+ # return new string
157
+ @norm = rv.join('')
158
+ end
159
+ #
160
+ # unslash
161
+ #---------------------------------------------------------------------------
162
+ end
163
+ #
164
+ # Talius
165
+ #===============================================================================
166
+
167
+
168
+ #===============================================================================
169
+ # Talius::Rule
170
+ #
171
+
172
+ # Talius::Rule object represents one set of directives, e.g. tags, classes, etc.
173
+ class Talius::Rule
174
+ #---------------------------------------------------------------------------
175
+ # special characters
176
+ #
177
+ @@NESTING_CHARS = %w{> + ~ s}
178
+ @@NESTING_RX = @@NESTING_CHARS.map{|el| '\\' + el}.join('')
179
+ @@SUBRULE_CHARS = %w{. [ ] : #}
180
+ @@SUBRULE_RX = @@SUBRULE_CHARS.map{|el| '\\' + el}.join('')
181
+ @@META_RX = @@NESTING_RX + @@SUBRULE_RX
182
+ #
183
+ # special characters
184
+ #---------------------------------------------------------------------------
185
+
186
+
187
+ #---------------------------------------------------------------------------
188
+ # initialize
189
+ # Lexical parsing experts will probably recoil in horror at how I parse a
190
+ # selector rule. Whatever.
191
+ #
192
+
193
+ # Initializes a Talius::Rule object. The first param is the Talius object
194
+ # with which the rule will be associated. The second param is the raw string
195
+ # that describes the rule.
196
+ #
197
+ # raw = 'section, div'
198
+ # selector = Talius.new(raw)
199
+ # selector.rules[0] # => {"tags"=>{"section"=>{"name"=>"section"}}}
200
+ def initialize(p_selector, raw)
201
+ @selector = p_selector
202
+ @classes = {}
203
+ @tags = {}
204
+ @ids = {}
205
+ @pelements = {}
206
+ @pclasses = {}
207
+ @atts = {}
208
+
209
+ # remove spaces before and after parens
210
+ raw = raw.gsub(/\s*([\(\)])\s*/mu, '\1')
211
+
212
+ # split into subrules
213
+ pieces = raw.split(/(\[[^\[\]]*\])|(\:\:[^#{@@META_RX}]+)|([#{@@NESTING_RX}])|([#{@@META_RX}][^#{@@META_RX}]*)/mu)
214
+ pieces = pieces.grep(/./mu)
215
+
216
+ # build subrules
217
+ pieces.each do |piece|
218
+ # I haven't yet implemented nested rules, so at this point we should
219
+ # not have any pieces that consist of just spaces
220
+ if @@NESTING_CHARS.include?(piece)
221
+ raise 'not-yet-implemented-nested-elements: ' + piece
222
+ end
223
+
224
+ # if piece consists of a single meta character, that's invalid
225
+ if @@SUBRULE_CHARS.include?(piece)
226
+ raise 'meta-character-without-value: ' + piece
227
+ end
228
+
229
+ # class
230
+ if piece.match(/\A\..+/mu)
231
+ @classes[piece.sub(/\A\./mu, '')] = true
232
+
233
+ # pseudo element ::
234
+ elsif piece.match(/\A\:\:/mu)
235
+ pe = piece.sub(/\A\:\:/mu, '')
236
+ pseudo @pelements, pe
237
+
238
+ # pseudo class :
239
+ elsif piece.match(/\A\:/mu)
240
+ pc = piece.sub(/\A\:/mu, '')
241
+ pseudo @pclasses, pc
242
+
243
+ # attribute
244
+ elsif piece.match(/\A\[.*\]\z/mu)
245
+ full = piece
246
+ full = full.sub(/\A\s*\[\s*/mu, '')
247
+ full = full.sub(/\s*\]\s*\z/mu, '')
248
+ nv = full.split(/\s*\=\s*/mu, 2)
249
+
250
+ if nv[0]
251
+ att = Talius::Node::Att.new(@selector.denormalize(nv[0]))
252
+ @atts[att.full_name] = att
253
+
254
+ if nv[1]
255
+ att.value = @selector.denormalize(nv[1])
256
+ end
257
+ end
258
+
259
+ # id
260
+ elsif piece.match(/\A\#/mu)
261
+ id = piece
262
+ id = id.sub(/\A\#/mu, '')
263
+ @ids[id] = true
264
+
265
+ # else tag
266
+ else
267
+ tag = Talius::Node::Tag.new(@selector.denormalize(piece))
268
+ @tags[tag.full_name] = tag
269
+ end
270
+ end
271
+ end
272
+ #
273
+ # initialize
274
+ #---------------------------------------------------------------------------
275
+
276
+
277
+ #---------------------------------------------------------------------------
278
+ # selector
279
+ #
280
+
281
+ # The +Talius+ object that this rule is associated with.
282
+ attr_reader :selector
283
+
284
+ #
285
+ # selector
286
+ #---------------------------------------------------------------------------
287
+
288
+
289
+ #---------------------------------------------------------------------------
290
+ # classes
291
+ #
292
+
293
+ # A hash of the classes described in the selector. The hash keys are the
294
+ # names of the classes. The values are always true.
295
+ #
296
+ # raw = 'section.ready.overview'
297
+ # selector = Talius.new(raw)
298
+ # selector.rules[0].classes # => {"ready"=>true, "overview"=>true}
299
+ attr_reader :classes
300
+
301
+ #
302
+ # classes
303
+ #---------------------------------------------------------------------------
304
+
305
+
306
+ #---------------------------------------------------------------------------
307
+ # tags
308
+ #
309
+
310
+ # A hash of the tags described in the selector. The hash keys are the names
311
+ # if the tags. The values are Talius::Node::Tag objects. Currently, Talius
312
+ # can only parse a single tag from a selector rule, so for now this hash
313
+ # will always have a single element.
314
+ #
315
+ # raw = 'section'
316
+ # selector = Talius.new(raw)
317
+ # selector.rules[0].tags # => {"section"=>{"name"=>"section"}}
318
+ attr_reader :tags
319
+
320
+ #
321
+ # tags
322
+ #---------------------------------------------------------------------------
323
+
324
+
325
+ #---------------------------------------------------------------------------
326
+ # ids
327
+ #
328
+
329
+ # A hash of elements defined by ID. The hash keys are the id's, the
330
+ # values are always true
331
+ #
332
+ # raw = '#overview'
333
+ # selector = Talius.new(raw)
334
+ # rule = selector.rules[0]
335
+ # rule.ids # => {"overview"=>true}
336
+
337
+ attr_reader :ids
338
+
339
+ #
340
+ # ids
341
+ #---------------------------------------------------------------------------
342
+
343
+
344
+ #---------------------------------------------------------------------------
345
+ # pelements
346
+ #
347
+
348
+ # A hash of pseudo-elements such as +::first-line+. The hash keys are the
349
+ # names of the pseudo-elements. The values are either the value in the
350
+ # parens after the name of the pseudo-element, or, if there is no such
351
+ # value, +nil+.
352
+ #
353
+ # raw = 'section::first-line'
354
+ # selector = Talius.new(raw)
355
+ # selector.rules[0].pelements # => {"first-line"=>nil}
356
+ #
357
+ # raw = 'section::nth-line(9)'
358
+ # selector = Talius.new(raw)
359
+ # selector.rules[0].pelements # => {"nth-line"=>"9"}
360
+
361
+ attr_reader :pelements
362
+
363
+ #
364
+ # pelements
365
+ #---------------------------------------------------------------------------
366
+
367
+
368
+ #---------------------------------------------------------------------------
369
+ # pclasses
370
+ #
371
+
372
+ # A hash of pseudo-classes such as +:visited+. The hash keys are the
373
+ # names of the pseudo-elements. The values are either the value in the
374
+ # parens after the name of the pseudo-element, or, if there is no such
375
+ # value, +nil+.
376
+ #
377
+ # raw = 'a:visited'
378
+ # selector = Talius.new(raw)
379
+ # selector.rules[0].pclasses # => {"visited"=>nil}
380
+ #
381
+ # raw = 'ul:nth-child(9)'
382
+ # selector = Talius.new(raw)
383
+ # selector.rules[0].pclasses # => {"nth-child"=>"9"}
384
+
385
+ attr_reader :pclasses
386
+
387
+ #
388
+ # pclasses
389
+ #---------------------------------------------------------------------------
390
+
391
+
392
+ #---------------------------------------------------------------------------
393
+ # atts
394
+ #
395
+
396
+ # Hash of attributes. The hash keys are the names of the attributes. The
397
+ # values are Talius::Node::Att objects.
398
+ #
399
+ # raw = 'a[href][rel=parent]'
400
+ # selector = Talius.new(raw)
401
+ # selector.rules[0].atts # => {"href"=>{"name"=>"href"}, "rel"=>{"name"=>"rel", "value"=>"parent"}}
402
+
403
+ attr_reader :atts
404
+
405
+ #
406
+ # atts
407
+ #---------------------------------------------------------------------------
408
+
409
+
410
+ #---------------------------------------------------------------------------
411
+ # to_h
412
+ #
413
+
414
+ # Returns a hash representation of the rule.
415
+ def to_h
416
+ # $tm.hrm
417
+ rv = {}
418
+
419
+ # tags
420
+ if @tags.any?
421
+ rv['tags'] = {}.tap do |tags|
422
+ @tags.each do |key, node|
423
+ tags[node.full_name] = node.to_h
424
+ end
425
+ end
426
+ end
427
+
428
+ # ids
429
+ if @ids.any?
430
+ rv['ids'] = {}.tap do |ids|
431
+ @ids.each do |key, val|
432
+ ids[key] = val
433
+ end
434
+ end
435
+ end
436
+
437
+ # atts
438
+ if @atts.any?
439
+ rv['atts'] = {}.tap do |atts|
440
+ @atts.each do |key, node|
441
+ atts[node.full_name] = node.to_h
442
+ end
443
+ end
444
+ end
445
+
446
+ # classes
447
+ if @classes.any?
448
+ rv['classes'] = {}.tap do |classes|
449
+ @classes.each do |key, val|
450
+ classes[key] = val
451
+ end
452
+ end
453
+ end
454
+
455
+ # pclasses
456
+ if @pclasses.any?
457
+ rv['pclasses'] = {}.tap do |pclasses|
458
+ @pclasses.each do |key, val|
459
+ pclasses[key] = val
460
+ end
461
+ end
462
+ end
463
+
464
+ # pelements
465
+ if @pelements.any?
466
+ rv['pelements'] = {}.tap do |pelements|
467
+ @pelements.each do |key, val|
468
+ pelements[key] = val
469
+ end
470
+ end
471
+ end
472
+
473
+ # return
474
+ return rv
475
+ end
476
+ #
477
+ # to_h
478
+ #---------------------------------------------------------------------------
479
+
480
+
481
+ #---------------------------------------------------------------------------
482
+ # inspect
483
+ #
484
+
485
+ # Returns a stringification of the results of to_h.
486
+ def inspect
487
+ return to_h.to_s
488
+ end
489
+ #
490
+ # inspect
491
+ #---------------------------------------------------------------------------
492
+
493
+
494
+ # private
495
+ private
496
+
497
+
498
+ #---------------------------------------------------------------------------
499
+ # pseudo
500
+ #
501
+ def pseudo(hsh, raw)
502
+ # get value in parens
503
+ if raw.match(/\(/mu)
504
+ val = raw
505
+ raw = raw.sub(/\(.*/mu, '')
506
+ val = val.sub(/\A.*\(/mu, '')
507
+ val = val.sub(/\)\z/mu, '')
508
+ hsh[@selector.denormalize(raw).downcase] = @selector.denormalize(val)
509
+ else
510
+ hsh[@selector.denormalize(raw).downcase] = nil
511
+ end
512
+ end
513
+ #
514
+ # pseudo
515
+ #---------------------------------------------------------------------------
516
+ end
517
+ #
518
+ # Talius::Rule
519
+ #===============================================================================
520
+
521
+
522
+ #===============================================================================
523
+ # Talius::Node
524
+ #
525
+
526
+ # Base class for Talius::Node::Tag and Talius::Node::Att.
527
+ class Talius::Node
528
+ #---------------------------------------------------------------------------
529
+ # initialize
530
+ #
531
+
532
+ # Initializes a new node. Accepts the string from the selector. Generally,
533
+ # you won't have to instantiate a Talius::Node object yourself.
534
+ def initialize(raw)
535
+ tokens = raw.split('|', 2)
536
+
537
+ # if one element
538
+ if tokens.length == 1
539
+ @namespace = nil
540
+ @name = tokens[0]
541
+ elsif tokens.length == 2
542
+ @namespace = tokens[0]
543
+ @name = tokens[1]
544
+ else
545
+ raise 'node-syntax-error: ' + raw.to_s
546
+ end
547
+ end
548
+ #
549
+ # initialize
550
+ #---------------------------------------------------------------------------
551
+
552
+
553
+ #---------------------------------------------------------------------------
554
+ # The node's namespace. If a namespace is not explicitly given in the
555
+ # selector string then this property is nil.
556
+ #
557
+ # raw = 'section, mml|dev'
558
+ # selector = Talius.new(raw)
559
+ # selector.rules[0].tags['section'].namespace # => nil
560
+ # selector.rules[1].tags['mml|dev'].namespace # => "mml"
561
+ attr_reader :namespace
562
+ #
563
+ # namespace
564
+ #---------------------------------------------------------------------------
565
+
566
+
567
+ #---------------------------------------------------------------------------
568
+ # name
569
+ #
570
+
571
+ # The name of the tag or attribute. Does not include the namespace.
572
+ #
573
+ # raw = 'section, mml|dev'
574
+ # selector = Talius.new(raw)
575
+ # selector.rules[0].tags['section'].name # => "section"
576
+ # selector.rules[1].tags['mml|dev'].name # => "dev"
577
+ attr_reader :name
578
+ #
579
+ # name
580
+ #---------------------------------------------------------------------------
581
+
582
+
583
+ #---------------------------------------------------------------------------
584
+ # full_name
585
+ #
586
+
587
+ # Returns the namespace (if there is one) and the name of the node. If there
588
+ # is a namespace then the namespace is followed by |.
589
+ #
590
+ # raw = 'section, mml|dev'
591
+ # selector = Talius.new(raw)
592
+ # selector.rules[0].tags['section'].fullname # => "section"
593
+ # selector.rules[1].tags['mml|dev'].fullname # => "mml|dev"
594
+ def full_name
595
+ if @namespace
596
+ return @namespace + '|' + @name
597
+ else
598
+ return @name
599
+ end
600
+ end
601
+ #
602
+ # full_name
603
+ #---------------------------------------------------------------------------
604
+
605
+
606
+ #---------------------------------------------------------------------------
607
+ # to_s
608
+ #
609
+
610
+ # Returns the results of +full_name+.
611
+ def to_s
612
+ return full_name
613
+ end
614
+ #
615
+ # to_s
616
+ #---------------------------------------------------------------------------
617
+
618
+
619
+ #---------------------------------------------------------------------------
620
+ # to_h
621
+ #
622
+
623
+ # Returns a hash of the name and namespace (if there is a namespace).
624
+ #
625
+ # raw = 'section, mml|dev'
626
+ # selector = Talius.new(raw)
627
+ # selector.rules[0].tags['section'].to_h # => {"name"=>"section"}
628
+ # selector.rules[1].tags['mml|dev'].to_h # => {"name"=>"dev", "namespace"=>"mml"}
629
+ def to_h
630
+ rv = {}
631
+ rv['name'] = @name
632
+
633
+ # namespace
634
+ if @namespace
635
+ rv['namespace'] = @namespace
636
+ end
637
+
638
+ return rv
639
+ end
640
+ #
641
+ # to_h
642
+ #---------------------------------------------------------------------------
643
+
644
+
645
+ #---------------------------------------------------------------------------
646
+ # inspect
647
+ #
648
+
649
+ # Returns the stringification of the hash returned by +to_h+.
650
+ # raw = 'section, mml|dev'
651
+ # selector = Talius.new(raw)
652
+ # selector.rules[0].tags['section'].inspect # => {"name"=>"section"}
653
+ # selector.rules[1].tags['mml|dev'].inspect # => {"name"=>"dev", "namespace"=>"mml"}
654
+ def inspect
655
+ return to_h.inspect
656
+ end
657
+ #
658
+ # inspect
659
+ #---------------------------------------------------------------------------
660
+ end
661
+ #
662
+ # Talius::Node
663
+ #===============================================================================
664
+
665
+
666
+ #===============================================================================
667
+ # Talius::Node::Tag
668
+ #
669
+
670
+ # This class inherits from Talius::Node and adds nothing to it.
671
+ class Talius::Node::Tag < Talius::Node
672
+ end
673
+ #
674
+ # Talius::Node::Tag
675
+ #===============================================================================
676
+
677
+
678
+ #===============================================================================
679
+ # Talius::Node::Att
680
+ #
681
+
682
+ # This class inherits from Talius::Node and adds the value property.
683
+ class Talius::Node::Att < Talius::Node
684
+ #---------------------------------------------------------------------------
685
+ # initialize
686
+ #
687
+ def initialize(*opts)
688
+ super(*opts)
689
+ @value = nil
690
+ end
691
+ #
692
+ # initialize
693
+ #---------------------------------------------------------------------------
694
+
695
+
696
+ #---------------------------------------------------------------------------
697
+ # value
698
+ #
699
+
700
+ # The value of the attribute rule, if there is one.
701
+ #
702
+ # raw = 'a[href][rel=parent]'
703
+ # selector = Talius.new(raw)
704
+ # rule = selector.rules[0]
705
+ # rule.atts['href'].value # => nil
706
+ # rule.atts['rel'].value # => "parent"
707
+
708
+ attr_accessor :value
709
+
710
+ #
711
+ # value
712
+ #---------------------------------------------------------------------------
713
+
714
+
715
+ #---------------------------------------------------------------------------
716
+ # to_h
717
+ #
718
+
719
+ # Returns a hash representation of the obect.
720
+ def to_h
721
+ rv = super()
722
+
723
+ # value
724
+ if @value
725
+ rv['value'] = @value
726
+ end
727
+
728
+ return rv
729
+ end
730
+ #
731
+ # to_h
732
+ #---------------------------------------------------------------------------
733
+ end
734
+ #
735
+ # Talius::Node::Att
736
+ #===============================================================================
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: talius
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.5'
5
+ platform: ruby
6
+ authors:
7
+ - Mike O'Sullivan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: lx.rb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ description: CSS selector parser
28
+ email: mike@idocs.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - README.md
34
+ - lib/talius.rb
35
+ homepage: https://rubygems.org/gems/talius
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.7.6
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: CSS selector parser
59
+ test_files: []