Changeset 137

Show
Ignore:
Timestamp:
04/14/2007 12:02:09 (20 months ago)
Author:
why
Message:
  • lib/hpricot/traverse.rb: new syntax for grabbing everything between two elements using a Range in the search method: (doc/("font".."font/br")) or in nodes_at like so: (doc/"font").nodes_at("*".."br"). Only works with either a pair of siblings or a set of a parent and a sibling.
  • lib/hpricot/elements.rb: Elements.expand(ele1, ele2) tries to build a list of all elements between two elements (used by the above.)
  • lib/hpricot/build.rb: the build method now used to construct new elements, kind of a token gesture, designed to be overridden.
Location:
trunk/lib/hpricot
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/lib/hpricot/builder.rb

    r128 r137  
    7676      childs = [] 
    7777      attrs = args.grep(Hash) 
    78       childs.concat((args - attrs).map { |x| Text.new(Hpricot.xs(x)) }) 
     78      childs.concat((args - attrs).map { |x| Text.new(Hpricot.xs(x)) if x }) 
    7979      attrs = attrs.inject({}) do |hsh, ath| 
    8080        ath.each do |k, v| 
     
    8989      # build children from the block 
    9090      if block 
    91         Hpricot.build(f, &block) 
     91        build(f, &block) 
    9292      end 
    9393 
    9494      @children << f 
    9595      f 
     96    end 
     97 
     98    def build(*a, &b) 
     99      Hpricot.build(*a, &b) 
    96100    end 
    97101 
  • trunk/lib/hpricot/elements.rb

    r132 r137  
    242242    end 
    243243 
     244    # Given two elements, attempt to gather an Elements array of everything between 
     245    # (and including) those two elements. 
     246    def self.expand(ele1, ele2) 
     247      ary = [] 
     248 
     249      if ele1 and ele2 
     250        # let's quickly take care of siblings 
     251        if ele1.parent == ele2.parent 
     252          ary = ele1.parent.children[ele1.node_position..ele2.node_position] 
     253        else 
     254          # find common parent 
     255          p, ele1_p = ele1, [ele1] 
     256          ele1_p.unshift p while p.respond_to?(:parent) and p = p.parent 
     257          p, ele2_p = ele2, [ele2] 
     258          ele2_p.unshift p while p.respond_to?(:parent) and p = p.parent 
     259          common_parent = ele1_p.zip(ele2_p).select { |p1, p2| p1 == p2 }.flatten.last 
     260 
     261          child = nil 
     262          if ele1 == common_parent 
     263            child = ele2 
     264          elsif ele2 == common_parent 
     265            child = ele1 
     266          end 
     267 
     268          if child 
     269            ary = common_parent.children[0..child.node_position] 
     270          end 
     271        end 
     272      end 
     273 
     274      return Elements[*ary] 
     275    end 
     276 
    244277    def filter(expr) 
    245278        nodes, = Elements.filter(self, expr) 
  • trunk/lib/hpricot/traverse.rb

    r131 r137  
    3535    end 
    3636 
     37    def index(name) 
     38      i = 0 
     39      return i if name == "*" 
     40      children.each do |x| 
     41        return i if (x.respond_to?(:name) and name == x.name) or 
     42          (x.text? and name == "text()") 
     43        i += 1 
     44      end 
     45      -1 
     46    end 
     47 
    3748    # Puts together an array of neighboring nodes based on their proximity 
    3849    # to this node.  So, for example, to get the next node, you could use 
     
    4758      sib = parent.children 
    4859      i, si = 0, sib.index(self) 
     60      pos.map! do |r| 
     61        if r.is_a?(Range) and r.begin.is_a?(String) 
     62          r = ((parent.index(r.begin)-si)..(parent.index(r.end)-si)) 
     63        end 
     64        r 
     65      end 
     66      p pos 
    4967      Elements[* 
    5068        sib.select do |x| 
    51           sel = case i - si when *pos 
    52                   true 
    53                 end 
     69          sel = 
     70            case i - si when *pos 
     71              true 
     72            end 
    5473          i += 1 
    5574          sel 
     
    217236    # is used to iterate through the matching set. 
    218237    def search(expr, &blk) 
     238      if Range === expr 
     239        return expand(at(expr.begin), at(expr.end)) 
     240      end 
    219241      last = nil 
    220242      nodes = [self]