talius 0.5

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 (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: []