Class: HTree::Elem
- Inherits:
-
Object
- Object
- HTree::Elem
- Defined in:
- lib/htree/loc.rb,
lib/htree/loc.rb,
lib/htree/elem.rb,
lib/htree/rexml.rb,
lib/htree/output.rb,
lib/htree/inspect.rb,
lib/htree/modules.rb,
lib/htree/modules.rb,
lib/htree/modules.rb,
lib/htree/equality.rb,
lib/htree/raw_string.rb,
lib/htree/raw_string.rb
Defined Under Namespace
Constant Summary
Constants included from HTree
DefaultContext, ElementContent, ElementExclusions, ElementInclusions, EmptyBindingObject, HTMLContext, NamedCharacters, NamedCharactersPattern, OmittedAttrName
Class Method Summary collapse
-
.new(name, *args) ⇒ Object
The first argument name should be an instance of String or HTree::Name.
- .new! ⇒ Object
Instance Method Summary collapse
- #context ⇒ Object
-
#each_attribute(&block) ⇒ Object
:yields: attr_name, attr_text.
-
#element_name ⇒ Object
element_name
returns the name of the element name as a Name object. - #eliminate_raw_string ⇒ Object
- #empty_element? ⇒ Boolean
- #find_loc_step(index) ⇒ Object
-
#get_subnode_internal(index) ⇒ Object
:nodoc:.
-
#initialize(stag, children = nil, etag = nil) ⇒ Elem
constructor
:notnew:.
- #make_exact_equal_object ⇒ Object
- #make_usual_equal_object ⇒ Object
- #node_test_string ⇒ Object
- #output(out, context) ⇒ Object
- #pretty_print(q) ⇒ Object
- #raw_string_internal(result) ⇒ Object
-
#subst_subnode(pairs) ⇒ Object
call-seq: elem.subst_subnode(pairs) -> elem.
- #to_rexml_internal(parent, context) ⇒ Object
Methods included from Trav
#attributes, #each_attr, #fetch_attr, #fetch_attribute, #get_attr, #get_attribute, #name, #qualified_name, #traverse_all_element, #traverse_some_element
Methods included from Container::Trav
#each_child, #each_child_with_index, #each_hyperlink, #each_hyperlink_uri, #each_uri, #filter, #find_element, #traverse_element, #traverse_text_internal
Methods included from Traverse
#bogusetag?, #comment?, #doc?, #doctype?, #elem?, #get_subnode, #procins?, #text?, #traverse_text, #xmldecl?
Methods included from Container
Methods included from Node
#display_html, #display_xml, #extract_text, #generate_xml_output_code, #make_loc, #raw_string, #subst, #subst_internal, #to_node, #to_rexml
Methods included from HTree
#==, build_node, #check_equality, compile_template, #exact_equal?, #exact_equal_object, expand_template, fix_element, fix_structure_list, frozen_string, #hash, parse, parse_as, parse_pairs, parse_xml, scan, #usual_equal_object, with_frozen_string_hash
Constructor Details
#initialize(stag, children = nil, etag = nil) ⇒ Elem
:notnew:
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/htree/elem.rb', line 83 def initialize(stag, children=nil, etag=nil) # :notnew: unless stag.class == STag raise TypeError, "HTree::STag expected: #{stag.inspect}" end unless !children || children.all? {|c| c.kind_of?(HTree::Node) and !c.kind_of?(HTree::Doc) } unacceptable = children.reject {|c| c.kind_of?(HTree::Node) and !c.kind_of?(HTree::Doc) } unacceptable = unacceptable.map {|uc| uc.inspect }.join(', ') raise TypeError, "Unacceptable element child: #{unacceptable}" end unless !etag || etag.class == ETag raise TypeError, "HTree::ETag expected: #{etag.inspect}" end @stag = stag @children = (children ? children.dup : []).freeze @empty = children == nil && etag == nil @etag = etag end |
Class Method Details
.new(name, *args) ⇒ Object
The first argument name should be an instance of String or HTree::Name.
The rest of arguments should be a sequence of follows.
- Hash object
-
used as attributes.
- String object
-
specified string is converted to HTree::Text.
- HTree::Node object
-
used as a child.
- HTree::Doc object
-
used as children. It is expanded except HTree::XMLDecl and HTree::DocType objects.
- Array of String, HTree::Node, HTree::Doc
-
used as children.
- HTree::Context object
-
used as as context which represents XML namespaces. This should apper once at most.
HTree::Location object is accepted just as HTree::Node.
If the rest arguments consists only Hash and HTree::Context, empty element is created.
p HTree::Elem.new("e").empty_element? # => true
p HTree::Elem.new("e", []).empty_element? # => false
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/htree/elem.rb', line 35 def Elem.new(name, *args) attrs = [] children = [] context = nil args.each {|arg| arg = arg.to_node if HTree::Location === arg case arg when Context raise ArgumentError, "multiple context" if context context = arg when Hash arg.each {|k, v| attrs << [k, v] } when Array arg.each {|a| a = a.to_node if HTree::Location === a case a when HTree::Doc children.concat(a.children.reject {|c| HTree::XMLDecl === c || HTree::DocType === c }) when HTree::Node children << a when String children << Text.new(a) else raise TypeError, "unexpected argument: #{arg.inspect}" end } when HTree::Doc children.concat(arg.children.reject {|c| HTree::XMLDecl === c || HTree::DocType === c }) when HTree::Node children << arg when String children << Text.new(arg) else raise TypeError, "unexpected argument: #{arg.inspect}" end } context ||= DefaultContext if children.empty? && args.all? {|arg| Hash === arg || Context === arg } children = nil end new!(STag.new(name, attrs, context), children) end |
.new! ⇒ Object
10 |
# File 'lib/htree/elem.rb', line 10 alias new! new |
Instance Method Details
#context ⇒ Object
101 |
# File 'lib/htree/elem.rb', line 101 def context; @stag.context end |
#each_attribute(&block) ⇒ Object
:yields: attr_name, attr_text
110 111 112 |
# File 'lib/htree/elem.rb', line 110 def each_attribute(&block) # :yields: attr_name, attr_text @stag.each_attribute(&block) end |
#element_name ⇒ Object
element_name
returns the name of the element name as a Name object.
104 |
# File 'lib/htree/elem.rb', line 104 def element_name() @stag.element_name end |
#eliminate_raw_string ⇒ Object
77 78 79 80 81 82 |
# File 'lib/htree/raw_string.rb', line 77 def eliminate_raw_string Elem.new!( @stag.eliminate_raw_string, @empty ? nil : @children.map {|c| c.eliminate_raw_string }, @etag && @etag.eliminate_raw_string) end |
#empty_element? ⇒ Boolean
106 107 108 |
# File 'lib/htree/elem.rb', line 106 def empty_element? @empty end |
#find_loc_step(index) ⇒ Object
132 133 134 135 136 137 138 139 140 141 |
# File 'lib/htree/loc.rb', line 132 def find_loc_step(index) return super if Integer === index if String === index index = Name.parse_attribute_name(index, DefaultContext) end unless Name === index raise TypeError, "invalid index: #{index.inspect}" end "@#{index.qualified_name}" end |
#get_subnode_internal(index) ⇒ Object
:nodoc:
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/htree/elem.rb', line 114 def get_subnode_internal(index) # :nodoc: case index when String name = Name.parse_attribute_name(index, DefaultContext) update_attribute_hash[name.universal_name] when Name update_attribute_hash[index.universal_name] when Integer if index < 0 || @children.length <= index nil else @children[index] end else raise TypeError, "invalid index: #{index.inspect}" end end |
#make_exact_equal_object ⇒ Object
71 72 73 |
# File 'lib/htree/equality.rb', line 71 def make_exact_equal_object [@stag, @children, @empty, @etag] end |
#make_usual_equal_object ⇒ Object
75 76 77 |
# File 'lib/htree/equality.rb', line 75 def make_usual_equal_object [@stag, @children] end |
#node_test_string ⇒ Object
91 |
# File 'lib/htree/loc.rb', line 91 def node_test_string() @stag.element_name.qualified_name end |
#output(out, context) ⇒ Object
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/htree/output.rb', line 76 def output(out, context) if %r{\A\{http://www.w3.org/1999/xhtml\}(?:script|style)\z} =~ @stag.element_name.universal_name children_context = @stag.output_stag(out, context) out.output_cdata_content(@children, children_context) @stag.output_etag(out, context) elsif @empty @stag.output_emptytag(out, context) else children_context = @stag.output_stag(out, context) @children.each {|n| n.output(out, children_context) } @stag.output_etag(out, context) end end |
#pretty_print(q) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/htree/inspect.rb', line 19 def pretty_print(q) if @empty q.group(1, '{emptyelem', '}') { q.breakable; q.pp @stag } else q.group(1, "{elem", "}") { q.breakable; q.pp @stag @children.each {|elt| q.breakable; q.pp elt } if @etag q.breakable; q.pp @etag end } end end |
#raw_string_internal(result) ⇒ Object
26 27 28 29 30 |
# File 'lib/htree/raw_string.rb', line 26 def raw_string_internal(result) @stag.raw_string_internal(result) @children.each {|n| n.raw_string_internal(result) } @etag.raw_string_internal(result) if @etag end |
#subst_subnode(pairs) ⇒ Object
call-seq:
elem.subst_subnode(pairs) -> elem
The argument pairs should be a hash or an assocs.
The key of pairs should be one of following.
- HTree::Name or String object
-
attribute name.
- Integer object
-
child index.
The value of pairs should be one of follows.
- HTree::Node object
-
specified object is used as is.
- String object
-
specified string is converted to HTree::Text
- Array of above
-
specified HTree::Node and String is used in that order.
- nil
-
delete corresponding node.
e = HTree('<r><a/><b/><c/></r>').root
p e.subst_subnode({0=>HTree('<x/>'), 2=>HTree('<z/>')})
p e.subst_subnode([[0, HTree('<x/>')], [2,HTree('<z/>')]])
# =>
{elem <r> {emptyelem <x>} {emptyelem <b>} {emptyelem <z>}}
{elem <r> {emptyelem <x>} {emptyelem <b>} {emptyelem <z>}}
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 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 |
# File 'lib/htree/elem.rb', line 154 def subst_subnode(pairs) hash = {} pairs.each {|index, value| case index when Name, Integer when String index = Name.parse_attribute_name(index, DefaultContext) else raise TypeError, "invalid index: #{index.inspect}" end value = value.to_node if HTree::Location === value case value when Node value = [value] when String value = [value] when Array value = value.dup when nil value = [] else raise TypeError, "invalid value: #{value.inspect}" end value.map! {|v| v = v.to_node if HTree::Location === v case v when Node v when String Text.new(v) else raise TypeError, "invalid value: #{v.inspect}" end } if !hash.include?(index) hash[index] = [] end hash[index].concat value } attrs = [] @stag.attributes.each {|k, v| if hash.include? k v = hash[k] if !v.empty? attrs << {k=>Text.concat(*v)} end hash.delete k else attrs << {k=>v} end } hash.keys.each {|k| if Name === k v = hash[k] if !v.empty? attrs << {k=>Text.concat(*v)} end hash.delete k end } children_left = [] children = @children.dup children_right = [] hash.keys.sort.each {|index| value = hash[index] if index < 0 children_left << value elsif children.length <= index children_right << value else children[index] = value end } children = [children_left, children, children_right].flatten if children.empty? && @empty Elem.new( @stag.element_name, @stag.context, *attrs) else Elem.new( @stag.element_name, @stag.context, children, *attrs) end end |
#to_rexml_internal(parent, context) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/htree/rexml.rb', line 49 def to_rexml_internal(parent, context) ename = self.element_name ns_decl = {} if context.namespace_uri(ename.namespace_prefix) != ename.namespace_uri ns_decl[ename.namespace_prefix] = ename.namespace_uri end if ename.namespace_prefix result = REXML::Element.new("#{ename.namespace_prefix}:#{ename.local_name}", parent) else result = REXML::Element.new(ename.local_name, parent) end self.each_attribute {|aname, atext| if aname.namespace_prefix if context.namespace_uri(aname.namespace_prefix) != aname.namespace_uri ns_decl[aname.namespace_prefix] = aname.namespace_uri end result.add_attribute("#{aname.namespace_prefix}:#{aname.local_name}", atext.to_s) else result.add_attribute(aname.local_name, atext.to_s) end } ns_decl.each {|k, v| if k result.add_namespace(k, v) else result.add_namespace(v) end } context = context.subst_namespaces(ns_decl) self.children.each {|c| c.to_rexml_internal(result, context) } result end |