Adds elements immediately after this element, contained in the html string.
# File lib/hpricot/traverse.rb, line 121
121: def after(html = nil, &blk)
122: parent.insert_after(make(html, &blk), self)
123: end
Find the first matching node for the CSS or XPath expr string.
# File lib/hpricot/traverse.rb, line 341
341: def at(expr)
342: search(expr).first
343: end
Adds elements immediately before this element, contained in the html string.
# File lib/hpricot/traverse.rb, line 126
126: def before(html = nil, &blk)
127: parent.insert_before(make(html, &blk), self)
128: end
Is this object a stranded end tag?
# File lib/hpricot/traverse.rb, line 21
21: def bogusetag?() BogusETag::Trav === self end
Find children of a given tag_name.
ele.children_of_type('p')
#=> [...array of paragraphs...]
# File lib/hpricot/traverse.rb, line 390
390: def children_of_type(tag_name)
391: if respond_to? :children
392: children.find_all do |x|
393: x.respond_to?(:pathname) && x.pathname == tag_name
394: end
395: end
396: end
# File lib/hpricot/traverse.rb, line 203
203: def clean_path(path)
204: path.gsub(/^\s+|\s+$/, '')
205: end
Builds a unique CSS string for this node, from the root of the document containing it.
# File lib/hpricot/traverse.rb, line 226
226: def css_path
227: if elem? and has_attribute? 'id'
228: "##{get_attribute('id')}"
229: else
230: sim, i, id = 0, 0, 0
231: parent.children.each do |e|
232: id = sim if e == self
233: sim += 1 if e.pathname == self.pathname
234: end if parent.children
235: p = parent.css_path
236: p = p ? "#{p} > #{self.pathname}" : self.pathname
237: p += ":nth(#{id})" if sim >= 2
238: p
239: end
240: end
Is this object the enclosing HTML or XML document?
# File lib/hpricot/traverse.rb, line 7 7: def doc?() Doc::Trav === self end
Is this object a doctype tag?
# File lib/hpricot/traverse.rb, line 15
15: def doctype?() DocType::Trav === self end
Is this object an HTML or XML element?
# File lib/hpricot/traverse.rb, line 9 9: def elem?() Elem::Trav === self end
Find all nodes which follow the current one.
# File lib/hpricot/traverse.rb, line 114
114: def following
115: sibs = parent.children
116: si = sibs.index(self) + 1
117: return Elements[*sibs[si...sibs.length]]
118: end
# File lib/hpricot/traverse.rb, line 138
138: def get_subnode(*indexes)
139: n = self
140: indexes.each {|index|
141: n = n.get_subnode_internal(index)
142: }
143: n
144: end
Builds an HTML string from the contents of this node.
# File lib/hpricot/traverse.rb, line 168
168: def html(inner = nil, &blk)
169: if inner or blk
170: altered!
171: case inner
172: when Array
173: self.children = inner
174: else
175: self.children = make(inner, &blk)
176: end
177: reparent self.children
178: else
179: if respond_to?(:children) and children
180: children.map { |x| x.output("") }.join
181: else
182: ""
183: end
184: end
185: end
# File lib/hpricot/traverse.rb, line 47
47: def index(name)
48: i = 0
49: return i if name == "*"
50: children.each do |x|
51: return i if (x.respond_to?(:name) and name == x.name) or
52: (x.text? and name == "text()")
53: i += 1
54: end if children
55: 1
56: end
Inserts new contents into the current node, based on the HTML contained in string inner.
# File lib/hpricot/traverse.rb, line 191
191: def inner_html=(inner)
192: html(inner || [])
193: end
Builds a string from the text contained in this node. All HTML elements are removed.
# File lib/hpricot/traverse.rb, line 158
158: def inner_text
159: if respond_to?(:children) and children
160: children.map { |x| x.inner_text }.join
161: else
162: ""
163: end
164: end
Parses an HTML string, making an HTML fragment based on the options used to create the container document.
# File lib/hpricot/traverse.rb, line 25
25: def make(input = nil, &blk)
26: if parent and parent.respond_to? :make
27: parent.make(input, &blk)
28: else
29: Hpricot.make(input, &blk).children
30: end
31: end
Returns the node neighboring this node to the south: just below it. This method includes text nodes and comments and such.
# File lib/hpricot/traverse.rb, line 91
91: def next
92: sib = parent.children
93: sib[sib.index(self) + 1] if parent
94: end
# File lib/hpricot/traverse.rb, line 242
242: def node_position
243: parent.children.index(self)
244: end
Puts together an array of neighboring nodes based on their proximity to this node. So, for example, to get the next node, you could use nodes_at(1). Or, to get the previous node, use <tt>nodes_at(1).
This method also accepts ranges and sets of numbers.
ele.nodes_at(-3..-1, 1..3) # gets three nodes before and three after ele.nodes_at(1, 5, 7) # gets three nodes at offsets below the current node ele.nodes_at(0, 5..6) # the current node and two others
# File lib/hpricot/traverse.rb, line 67
67: def nodes_at(*pos)
68: sib = parent.children
69: i, si = 0, sib.index(self)
70: pos.map! do |r|
71: if r.is_a?(Range) and r.begin.is_a?(String)
72: r = Range.new(parent.index(r.begin)-si, parent.index(r.end)-si, r.exclude_end?)
73: end
74: r
75: end
76: p pos
77: Elements[*
78: sib.select do |x|
79: sel =
80: case i - si when *pos
81: true
82: end
83: i += 1
84: sel
85: end
86: ]
87: end
# File lib/hpricot/traverse.rb, line 246
246: def position
247: parent.children_of_type(self.pathname).index(self)
248: end
Find all preceding nodes.
# File lib/hpricot/traverse.rb, line 107
107: def preceding
108: sibs = parent.children
109: si = sibs.index(self)
110: return Elements[*sibs[0...si]]
111: end
Returns to node neighboring this node to the north: just above it. This method includes text nodes and comments and such.
# File lib/hpricot/traverse.rb, line 99
99: def previous
100: sib = parent.children
101: x = sib.index(self) - 1
102: sib[x] if sib and x >= 0
103: end
Is this object an XML processing instruction?
# File lib/hpricot/traverse.rb, line 17
17: def procins?() ProcIns::Trav === self end
Searches this node for all elements matching the CSS or XPath expr. Returns an Elements array containing the matching nodes. If blk is given, it is used to iterate through the matching set.
# File lib/hpricot/traverse.rb, line 254
254: def search(expr, &blk)
255: if Range === expr
256: return Elements.expand(at(expr.begin), at(expr.end), expr.exclude_end?)
257: end
258: last = nil
259: nodes = [self]
260: done = []
261: expr = expr.to_s
262: hist = []
263: until expr.empty?
264: expr = clean_path(expr)
265: expr.gsub!(%^//!, '')
266:
267: case expr
268: when %^/?\.\.!
269: last = expr = $'
270: nodes.map! { |node| node.parent }
271: when %^[>/]\s*!
272: last = expr = $'
273: nodes = Elements[*nodes.map { |node| node.children if node.respond_to? :children }.flatten.compact]
274: when %^\+!
275: last = expr = $'
276: nodes.map! do |node|
277: siblings = node.parent.children
278: siblings[siblings.index(node)+1]
279: end
280: nodes.compact!
281: when %^~!
282: last = expr = $'
283: nodes.map! do |node|
284: siblings = node.parent.children
285: siblings[(siblings.index(node)+1)..1]
286: end
287: nodes.flatten!
288: when %^[|,]!
289: last = expr = " #$'"
290: nodes.shift if nodes.first == self
291: done += nodes
292: nodes = [self]
293: else
294: m = expr.match(%^([#.]?)([a-z0-9\\*_-]*)!).to_a
295: after = $'
296: mt = after[%:[a-z0-9\\*_-]+!, 0]
297: oop = false
298: if mt and not (mt == ":not" or Traverse.method_defined? "filter[#{mt}]")
299: after = $'
300: m[2] += mt
301: expr = after
302: end
303: if m[1] == '#'
304: oid = get_element_by_id(m[2])
305: nodes = oid ? [oid] : []
306: expr = after
307: else
308: m[2] = "*" if after =~ /^\(\)/ || m[2] == "" || m[1] == "."
309: ret = []
310: nodes.each do |node|
311: case m[2]
312: when '*'
313: node.traverse_element { |n| ret << n }
314: else
315: if node.respond_to? :get_elements_by_tag_name
316: ret += [*node.get_elements_by_tag_name(m[2])] - [*(node unless last)]
317: end
318: end
319: end
320: nodes = ret
321: end
322: last = nil
323: end
324:
325: hist << expr
326: break if hist[1] == hist[2]
327: nodes, expr = Elements.filter(nodes, expr)
328: end
329: nodes = done + nodes.flatten.uniq
330: if blk
331: nodes.each(&blk)
332: self
333: else
334: Elements[*nodes]
335: end
336: end
Replace this element and its contents with the nodes contained in the html string.
# File lib/hpricot/traverse.rb, line 133
133: def swap(html = nil, &blk)
134: parent.altered!
135: parent.replace_child(self, make(html, &blk))
136: end
Is this object an HTML text node?
# File lib/hpricot/traverse.rb, line 11
11: def text?() Text::Trav === self end
Builds an HTML string from this node and its contents. If you need to write to a stream, try calling output(io) as a method on this object.
# File lib/hpricot/traverse.rb, line 36
36: def to_html
37: output("")
38: end
Attempts to preserve the original HTML of the document, only outputing new tags for elements which have changed.
# File lib/hpricot/traverse.rb, line 43
43: def to_original_html
44: output("", :preserve => true)
45: end
Builds a string from the text contained in this node. All HTML elements are removed.
# File lib/hpricot/traverse.rb, line 148
148: def to_plain_text
149: if respond_to?(:children) and children
150: children.map { |x| x.to_plain_text }.join.strip.gsub(/\n{2,}/, "\n\n")
151: else
152: ""
153: end
154: end
traverse_element traverses elements in the tree. It yields elements in depth first order.
If names are empty, it yields all elements. If non-empty names are given, it should be list of universal names.
A nested element is yielded in depth first order as follows.
t = Hpricot('<a id=0><b><a id=1 /></b><c id=2 /></a>')
t.traverse_element("a", "c") {|e| p e}
# =>
{elem <a id="0"> {elem <b> {emptyelem <a id="1">} </b>} {emptyelem <c id="2">} </a>}
{emptyelem <a id="1">}
{emptyelem <c id="2">}
Universal names are specified as follows.
t = Hpricot(<<'End')
<html>
<meta name="robots" content="index,nofollow">
<meta name="author" content="Who am I?">
</html>
End
t.traverse_element("{http://www.w3.org/1999/xhtml}meta") {|e| p e}
# =>
{emptyelem <{http://www.w3.org/1999/xhtml}meta name="robots" content="index,nofollow">}
{emptyelem <{http://www.w3.org/1999/xhtml}meta name="author" content="Who am I?">}
# File lib/hpricot/traverse.rb, line 374
374: def traverse_element(*names, &block) # :yields: element
375: if names.empty?
376: traverse_all_element(&block)
377: else
378: name_set = {}
379: names.each {|n| name_set[n] = true }
380: traverse_some_element(name_set, &block)
381: end
382: nil
383: end
traverse_text traverses texts in the tree
# File lib/hpricot/traverse.rb, line 680
680: def traverse_text(&block) # :yields: text
681: traverse_text_internal(&block)
682: nil
683: end
Is this object an XML declaration?
# File lib/hpricot/traverse.rb, line 13
13: def xmldecl?() XMLDecl::Trav === self end
Builds a unique XPath string for this node, from the root of the document containing it.
# File lib/hpricot/traverse.rb, line 209
209: def xpath
210: if elem? and has_attribute? 'id'
211: "//#{self.name}[@id='#{get_attribute('id')}']"
212: else
213: sim, id = 0, 0, 0
214: parent.children.each do |e|
215: id = sim if e == self
216: sim += 1 if e.pathname == self.pathname
217: end if parent.children
218: p = File.join(parent.xpath, self.pathname)
219: p += "[#{id+1}]" if sim >= 2
220: p
221: end
222: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.
Is this object a comment?
# File lib/hpricot/traverse.rb, line 19 19: def comment?() Comment::Trav === self end