class HTML::Selector

def nth_child(a, b, of_type, reverse)

* +reverse+ -- True to count in reverse order (last-).
* +of_type+ -- True to test only elements of this type (of-type).
* +b+ -- Value of b part.
* +a+ -- Value of a part.
pseudo class, given the following arguments:
Returns a lambda that can match an element against the nth-child
def nth_child(a, b, of_type, reverse)
  # a = 0 means select at index b, if b = 0 nothing selected
  return lambda { |element| false } if a == 0 && b == 0
  # a < 0 and b < 0 will never match against an index
  return lambda { |element| false } if a < 0 && b < 0
  b = a + b + 1 if b < 0   # b < 0 just picks last element from each group
  b -= 1 unless b == 0  # b == 0 is same as b == 1, otherwise zero based
  lambda do |element|
    # Element must be inside parent element.
    return false unless element.parent && element.parent.tag?
    index = 0
    # Get siblings, reverse if counting from last.
    siblings = element.parent.children
    siblings = siblings.reverse if reverse
    # Match element name if of-type, otherwise ignore name.
    name = of_type ? element.name : nil
    found = false
    for child in siblings
      # Skip text nodes/comments.
      if child.tag? && (name == nil || child.name == name)
        if a == 0
          # Shortcut when a == 0 no need to go past count
          if index == b
            found = child.equal?(element)
            break
          end
        elsif a < 0
          # Only look for first b elements
          break if index > b
          if child.equal?(element)
            found = (index % a) == 0
            break
          end
        else
          # Otherwise, break if child found and count ==  an+b
          if child.equal?(element)
            found = (index % a) == b
            break
          end
        end
        index += 1
      end
    end
    found
  end
end