module XPath::DSL

def anywhere(*expressions)

def anywhere(*expressions)
  Expression.new(:anywhere, expressions)
end

def attr(expression)

def attr(expression)
  Expression.new(:attribute, current, expression)
end

def axis(name, *element_names)

def axis(name, *element_names)
  Expression.new(:axis, current, name, element_names)
end

def binary_operator(name, rhs)

def binary_operator(name, rhs)
  Expression.new(:binary_operator, name, current, rhs)
end

def child(*expressions)

def child(*expressions)
  Expression.new(:child, current, expressions)
end

def contains_word(word)

def contains_word(word)
  function(:concat, ' ', current.normalize_space, ' ').contains(" #{word} ")
end

def css(selector)

def css(selector)
  Expression.new(:css, current, Literal.new(selector))
end

def current

def current
  Expression.new(:this_node)
end

def descendant(*expressions)

def descendant(*expressions)
  Expression.new(:descendant, current, expressions)
end

def ends_with(suffix)

def ends_with(suffix)
  function(:substring, current, function(:'string-length', current).minus(function(:'string-length', suffix)).plus(1)) == suffix
end

def function(name, *arguments)

def function(name, *arguments)
  Expression.new(:function, name, *arguments)
end

def is(expression)

def is(expression)
  Expression.new(:is, current, expression)
end

def last

def last
  function(:last)
end

def lowercase

def lowercase
  method(:translate, UPPERCASE_LETTERS, LOWERCASE_LETTERS)
end

def method(name, *arguments)

def method(name, *arguments)
  Expression.new(:function, name, current, *arguments)
end

def next_sibling(*expressions)

def next_sibling(*expressions)
  axis(:"following-sibling")[1].axis(:self, *expressions)
end

def one_of(*expressions)

def one_of(*expressions)
  expressions.map { |e| current.equals(e) }.reduce(:or)
end

def position

def position
  function(:position)
end

def previous_sibling(*expressions)

def previous_sibling(*expressions)
  axis(:"preceding-sibling")[1].axis(:self, *expressions)
end

def qname

def qname
  method(:name)
end

def text

def text
  Expression.new(:text, current)
end

def union(*expressions)

def union(*expressions)
  Union.new(*[self, expressions].flatten)
end

def uppercase

def uppercase
  method(:translate, LOWERCASE_LETTERS, UPPERCASE_LETTERS)
end

def where(expression)

def where(expression)
  if expression
    Expression.new(:where, current, expression)
  else
    current
  end
end