Class: Talius::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/talius.rb

Overview

Talius::Rule object represents one set of directives, e.g. tags, classes, etc.

Constant Summary collapse

@@NESTING_CHARS =

special characters

%w{> + ~ s}
@@NESTING_RX =
@@NESTING_CHARS.map{|el| '\\' + el}.join('')
@@SUBRULE_CHARS =
%w{. [ ] : #}
@@SUBRULE_RX =
@@SUBRULE_CHARS.map{|el| '\\' + el}.join('')
@@META_RX =
@@NESTING_RX + @@SUBRULE_RX

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(p_selector, raw) ⇒ Rule

Initializes a Talius::Rule object. The first param is the Talius object with which the rule will be associated. The second param is the raw string that describes the rule.

raw = 'section, div'
selector = Talius.new(raw)
selector.rules[0] # => {"tags"=>{"section"=>{"name"=>"section"}}}


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/talius.rb', line 199

def initialize(p_selector, raw)
	@selector = p_selector
	@classes = {}
	@tags = {}
	@ids = {}
	@pelements = {}
	@pclasses = {}
	@atts = {}
	
	# remove spaces before and after parens
	raw = raw.gsub(/\s*([\(\)])\s*/mu, '\1')
	
	# split into subrules
	pieces = raw.split(/(\[[^\[\]]*\])|(\:\:[^#{@@META_RX}]+)|([#{@@NESTING_RX}])|([#{@@META_RX}][^#{@@META_RX}]*)/mu)
	pieces = pieces.grep(/./mu)
	
	# build subrules
	pieces.each do |piece|
		# I haven't yet implemented nested rules, so at this point we should
		# not have any pieces that consist of just spaces
		if @@NESTING_CHARS.include?(piece)
			raise 'not-yet-implemented-nested-elements: ' + piece
		end
		
		# if piece consists of a single meta character, that's invalid
		if @@SUBRULE_CHARS.include?(piece)
			raise 'meta-character-without-value: ' + piece
		end
		
		# class
		if piece.match(/\A\..+/mu)
			@classes[piece.sub(/\A\./mu, '')] = true
		
		# pseudo element ::
		elsif piece.match(/\A\:\:/mu)
			pe = piece.sub(/\A\:\:/mu, '')
			pseudo @pelements, pe
			
		# pseudo class :
		elsif piece.match(/\A\:/mu)
			pc = piece.sub(/\A\:/mu, '')
			pseudo @pclasses, pc
			
		# attribute
		elsif piece.match(/\A\[.*\]\z/mu)
			full = piece
			full = full.sub(/\A\s*\[\s*/mu, '')
			full = full.sub(/\s*\]\s*\z/mu, '')
			nv = full.split(/\s*\=\s*/mu, 2)
			
			if nv[0]
				att = Talius::Node::Att.new(@selector.denormalize(nv[0]))
				@atts[att.full_name] = att
				
				if nv[1]
					att.value = @selector.denormalize(nv[1])
				end
			end
		
		# id
		elsif piece.match(/\A\#/mu)
			id = piece
			id = id.sub(/\A\#/mu, '')
			@ids[id] = true
		
		# else tag
		else
			tag = Talius::Node::Tag.new(@selector.denormalize(piece))
			@tags[tag.full_name] = tag
		end
	end
end

Instance Attribute Details

#attsObject (readonly)

Hash of attributes. The hash keys are the names of the attributes. The values are Talius::Node::Att objects.

raw = 'a[href][rel=parent]'
selector = Talius.new(raw)
selector.rules[0].atts # => {"href"=>{"name"=>"href"}, "rel"=>{"name"=>"rel", "value"=>"parent"}}


402
403
404
# File 'lib/talius.rb', line 402

def atts
  @atts
end

#classesObject (readonly)

A hash of the classes described in the selector. The hash keys are the names of the classes. The values are always true.

raw = 'section.ready.overview'
selector = Talius.new(raw)
selector.rules[0].classes # => {"ready"=>true, "overview"=>true}


298
299
300
# File 'lib/talius.rb', line 298

def classes
  @classes
end

#idsObject (readonly)

A hash of elements defined by ID. The hash keys are the id’s, the values are always true

raw = '#overview'
selector = Talius.new(raw)
rule = selector.rules[0]
rule.ids # => {"overview"=>true}


336
337
338
# File 'lib/talius.rb', line 336

def ids
  @ids
end

#pclassesObject (readonly)

A hash of pseudo-classes such as :visited. The hash keys are the names of the pseudo-elements. The values are either the value in the parens after the name of the pseudo-element, or, if there is no such value, nil.

raw = 'a:visited'
selector = Talius.new(raw)
selector.rules[0].pclasses # => {"visited"=>nil}

raw = 'ul:nth-child(9)'
selector = Talius.new(raw)
selector.rules[0].pclasses # => {"nth-child"=>"9"}


384
385
386
# File 'lib/talius.rb', line 384

def pclasses
  @pclasses
end

#pelementsObject (readonly)

A hash of pseudo-elements such as ::first-line. The hash keys are the names of the pseudo-elements. The values are either the value in the parens after the name of the pseudo-element, or, if there is no such value, nil.

raw = 'section::first-line'
selector = Talius.new(raw)
selector.rules[0].pelements # => {"first-line"=>nil}

raw = 'section::nth-line(9)'
selector = Talius.new(raw)
selector.rules[0].pelements # => {"nth-line"=>"9"}


360
361
362
# File 'lib/talius.rb', line 360

def pelements
  @pelements
end

#selectorObject (readonly)

The Talius object that this rule is associated with.



281
282
283
# File 'lib/talius.rb', line 281

def selector
  @selector
end

#tagsObject (readonly)

A hash of the tags described in the selector. The hash keys are the names if the tags. The values are Talius::Node::Tag objects. Currently, Talius can only parse a single tag from a selector rule, so for now this hash will always have a single element.

raw = 'section'
selector = Talius.new(raw)
selector.rules[0].tags # => {"section"=>{"name"=>"section"}}


317
318
319
# File 'lib/talius.rb', line 317

def tags
  @tags
end

Instance Method Details

#inspectObject

Returns a stringification of the results of to_h.



485
486
487
# File 'lib/talius.rb', line 485

def inspect
	return to_h.to_s
end

#to_hObject

Returns a hash representation of the rule.



414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/talius.rb', line 414

def to_h
	# $tm.hrm
	rv = {}
	
	# tags
	if @tags.any?
		rv['tags'] = {}.tap do |tags|
			@tags.each do |key, node|
				tags[node.full_name] = node.to_h
			end
		end
	end
	
	# ids
	if @ids.any?
		rv['ids'] = {}.tap do |ids|
			@ids.each do |key, val|
				ids[key] = val
			end
		end
	end
	
	# atts
	if @atts.any?
		rv['atts'] = {}.tap do |atts|
			@atts.each do |key, node|
				atts[node.full_name] = node.to_h
			end
		end
	end
	
	# classes
	if @classes.any?
		rv['classes'] = {}.tap do |classes|
			@classes.each do |key, val|
				classes[key] = val
			end
		end
	end
	
	# pclasses
	if @pclasses.any?
		rv['pclasses'] = {}.tap do |pclasses|
			@pclasses.each do |key, val|
				pclasses[key] = val
			end
		end
	end
	
	# pelements
	if @pelements.any?
		rv['pelements'] = {}.tap do |pelements|
			@pelements.each do |key, val|
				pelements[key] = val
			end
		end
	end
	
	# return
	return rv
end