Class: Taggie
Constant Summary
collapse
- AttributeValue =
'("|\')(.*?)\2|(\S*)'
- OpenTag =
'<(\w+)[^>]*'
- CloseTag =
'\/>|>'
- SpecialTags =
'<!--.*?-->|<\?.*?\?>|[^>]'
- TagMatcher =
/(#{OpenTag}(?:#{CloseTag}((?:#{OpenTag}(?:#{CloseTag}.*<\/\4>)|#{SpecialTags})*)<\/\2>)|#{SpecialTags}*)/m
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods inherited from String
#to_taggie
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *a) ⇒ Object
17
|
# File 'lib/taggie.rb', line 17
def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super end
|
Instance Attribute Details
#parent ⇒ Object
Returns the value of attribute parent.
9
10
11
|
# File 'lib/taggie.rb', line 9
def parent
@parent
end
|
Instance Method Details
#[](a) ⇒ Object
10
|
# File 'lib/taggie.rb', line 10
def [] a; [Integer,Range].include?(a.class)?super: to_h[a.to_s] end
|
#[]=(a, v) ⇒ Object
11
|
# File 'lib/taggie.rb', line 11
def []= a,v;@attributes=@tag=nil;[Integer,Range].include?(a.class)?super: !%w(comment string).include?(type)? v ? (q=v.include?('"')? "'":'"';sub!(/^([^>]+#{a}=)(?:#{AttributeValue})/m,"\\1#{q}#{v}#{q}");sub!(/^([^>]+?)\s*(\/|\?)?>/m, "\\1 #{a}=#{q}#{v}#{q}\\2>") if tag !~/\s+#{a}=/m):sub!(/^([^>]+)\s+#{a}=(?:#{AttributeValue})/,'\1'):nil;rebuild!;v end
|
#attributes ⇒ Object
12
|
# File 'lib/taggie.rb', line 12
def attributes;@attributes||=%w(comment doctype string).include?(type)?[]:tag.scan(/([\S]+)=(?:#{AttributeValue})/m).map!{|m|[m[0],m[2]||m[3]]} end
|
#children ⇒ Object
13
|
# File 'lib/taggie.rb', line 13
def children;@children||=inner_html.siblings_and_self.map!{|c|c.parent=self;c} end
|
#inner_html ⇒ Object
14
|
# File 'lib/taggie.rb', line 14
def inner_html;r,c=inner_html_regex;m=match(r);m ?m.captures[c]:'' end
|
#inner_html=(v) ⇒ Object
15
|
# File 'lib/taggie.rb', line 15
def inner_html= v;@children=nil;sub! inner_html,v;rebuild!;v end
|
#inner_html_regex ⇒ Object
16
|
# File 'lib/taggie.rb', line 16
def inner_html_regex;r,c={'comment'=>/^<!--(.*?)-->/m,'doctype'=>//,'string'=>/^([^<]+)/m,'xml'=>/^<\?(.*?)\?>/m}[type],0;r,c=TagMatcher,2 if r.nil?;[r,c] end
|
#rebuild! ⇒ Object
18
|
# File 'lib/taggie.rb', line 18
def rebuild!;(parent.inner_html=parent.children.join;parent.parent.rebuild! if parent.parent) if parent end
|
#siblings ⇒ Object
19
|
# File 'lib/taggie.rb', line 19
def siblings;siblings_and_self[1..-1] end
|
#siblings_and_self ⇒ Object
20
|
# File 'lib/taggie.rb', line 20
def siblings_and_self;@siblings_and_self||=scan(inner_html_regex[0]).map!{|m|m[0]} end
|
#tag ⇒ Object
21
|
# File 'lib/taggie.rb', line 21
def tag;@tag||={'comment'=>self,'string'=>inner_html}[type]||match(/^([^>]+>)/m).captures[0] end
|
#to_h ⇒ Object
22
|
# File 'lib/taggie.rb', line 22
def to_h; Hash[*attributes.flatten].merge! :html=>self end
|
#to_s ⇒ Object
23
|
# File 'lib/taggie.rb', line 23
def to_s; String.new self end
|
#type ⇒ Object
24
|
# File 'lib/taggie.rb', line 24
def type;@type||(m={(/^<([\w\-_:]+)[^>]*>/m)=>'1',(/^<!--/m)=>'comment',(/^<!doctype[^>]*>/mi)=>'doctype',(/^<\?/m)=>'xml'}.detect{|r,v|r=~self};@type=m ?eval('$'+m[1])||m[1]:'string') end
|