Module: Infoboxer::Navigation::Lookup::Node

Included in:
Tree::Node
Defined in:
lib/infoboxer/navigation/lookup.rb

Overview

Lookup::Node module provides methods for navigating through page tree in XPath-like manner.

What you need to know about it:

Selectors

Each lookup_* method (and others similar) receive list of selectors. Examples of acceptable selectors:

# 1. Node class:
document.lookup(Bold) # all Bolds

# 2. Class symbol
document.lookup(:Bold)
# same as above, useful if you don't want to include Infoboxer::Tree
# in all of your code or write things like lookup(Infoboxer::Tree::Bold)

# 3. Getter/pattern:
document.lookup(text: /something/)
# finds all nodes where result of getter matches pattern

# Checks against patterns are performed with `===`, so you can
# use regexps to find by text, or ranges to find by number, like
document.lookup(:Heading, level: (3..4))

# Nodes where method is not defined are ignored, so you can
# rewrite above example as just
document.lookup(level: 3..4)
# ...and receive meaningful result without any NoMethodError

# 4. Check symbol
document.lookup(:bold?)
# finds all nodes for which `:bold?` is defined and returns
# truthy value;

# 5. Code block
document.lookup{|node| node.params.has_key?(:class)}

You also can use any of those method without any selector, thus receiving ALL parents, ALL children, ALL siblings and so on.

Chainable navigation

Each lookup_* method returns an instance of Tree::Nodes class, which behaves like an Array, but also defines similar set of lookup_* methods, so, you can brainlessly do the things like

document.
  lookup(:Paragraph){|p| p.text.length > 100}.
  lookup(:Wikilink, text: /^List of/).
  select(&:bold?)

Underscored methods

For all methods of this module you can notice "underscored" version (lookup_children vs _lookup_children and so on). Basically, underscored versions accept instance of Selector, which is already preprocessed version of all selectors. It is kinda internal thing, though can be useful if you store selectors in variables -- it is easier to have and use just one instance of Selector, than list of arguments and blocks.

Instance Method Summary collapse

Instance Method Details

#_lookup(selector) ⇒ Object

Underscored version of #lookup



106
107
108
109
# File 'lib/infoboxer/navigation/lookup.rb', line 106

def _lookup(selector)
  Tree::Nodes[_matches?(selector) ? self : nil, *children._lookup(selector)].
    flatten.compact
end

#_lookup_children(selector) ⇒ Object

Underscored version of #lookup_children



112
113
114
# File 'lib/infoboxer/navigation/lookup.rb', line 112

def _lookup_children(selector)
  @children._find(selector)
end

#_lookup_next_siblings(selector) ⇒ Object

Underscored version of #lookup_next_siblings



139
140
141
# File 'lib/infoboxer/navigation/lookup.rb', line 139

def _lookup_next_siblings(selector)
  next_siblings._find(selector)
end

#_lookup_parents(selector) ⇒ Object

Underscored version of #lookup_parents



117
118
119
120
121
122
123
124
125
126
# File 'lib/infoboxer/navigation/lookup.rb', line 117

def _lookup_parents(selector)
  case
  when !parent
    Tree::Nodes[]
  when parent._matches?(selector)
    Tree::Nodes[parent, *parent._lookup_parents(selector)]
  else
    parent._lookup_parents(selector)
  end
end

#_lookup_prev_siblings(selector) ⇒ Object

Underscored version of #lookup_prev_siblings



134
135
136
# File 'lib/infoboxer/navigation/lookup.rb', line 134

def _lookup_prev_siblings(selector)
  prev_siblings._find(selector)
end

#_lookup_siblings(selector) ⇒ Object

Underscored version of #lookup_siblings



129
130
131
# File 'lib/infoboxer/navigation/lookup.rb', line 129

def _lookup_siblings(selector)
  siblings._find(selector)
end

#_matches?(selector) ⇒ Boolean

Underscored version of #matches?

Returns:

  • (Boolean)


101
102
103
# File 'lib/infoboxer/navigation/lookup.rb', line 101

def _matches?(selector)
  selector.matches?(self)
end

#has_parent?(*selectors, &block) ⇒ Boolean

Checks if node has any parent matching selectors.

Returns:

  • (Boolean)


155
156
157
# File 'lib/infoboxer/navigation/lookup.rb', line 155

def has_parent?(*selectors, &block)
  !lookup_parents(*selectors, &block).empty?
end

#lookup(*selectors, &block) ⇒ Object

Selects matching nodes from entire subtree inside current node.



# File 'lib/infoboxer/navigation/lookup.rb', line 79

#lookup_children(*selectors, &block) ⇒ Object

Selects nodes only from this node's direct children.



# File 'lib/infoboxer/navigation/lookup.rb', line 82

#lookup_next_siblings(*selectors, &block) ⇒ Object

Selects matching nodes from current node's siblings, which are below current node in parents children list.



# File 'lib/infoboxer/navigation/lookup.rb', line 92

#lookup_parents(*selectors, &block) ⇒ Object

Selects matching nodes of this node's parents chain, up to entire Document.



# File 'lib/infoboxer/navigation/lookup.rb', line 85

#lookup_prev_siblings(*selectors, &block) ⇒ Object

Selects matching nodes from current node's siblings, which are above current node in parents children list.



# File 'lib/infoboxer/navigation/lookup.rb', line 96

#lookup_siblings(*selectors, &block) ⇒ Object

Selects matching nodes from current node's siblings.



# File 'lib/infoboxer/navigation/lookup.rb', line 89

#matches?(*selectors, &block) ⇒ Object

Checks if current node matches selectors.



# File 'lib/infoboxer/navigation/lookup.rb', line 76