class Infoboxer::Tree::Nodes

List of nodes, which tries to be useful both as array, and as proxy to its contents.

Many of Infoboxer's methods (especially {Navigation}'s) return `Nodes`, and in most cases you don't have to think about it. Same approach can be seen in jQuery or Nokogiri. You just do things like those:

“`ruby document.sections. # => Nodes returned,

select{|section|                  #    you can treat them as array, but also...
  section.text.length > 1000      #
}.                                #
lookup(:Wikilink, text: /Chile/). #    ...use Infoboxer's methods
follow.                           #    ...even to receive lists of other pages
infoboxes.                        #    ...and use methods on them
fetch('leader_name1').            #    ...including those which only some node types support
map(&:text)                       #    ...and still have full-functioning Array

“`

Constants

MAX_CHILDREN

@private For inspect shortening

Public Instance Methods

<<(node) click to toggle source

@private Internal, used by {Parser}

Calls superclass method
# File lib/infoboxer/tree/nodes.rb, line 193
def <<(node) # rubocop:disable Metrics/PerceivedComplexity
  if node.is_a?(Array)
    node.each { |n| self << n }
  elsif last&.can_merge?(node)
    last.merge!(node)
  else
    return if !node || node.empty?

    node = Text.new(node) if node.is_a?(String)
    super
  end
end
fetch_hashes(*args) click to toggle source

By list of variable names, fetches hashes of `{name => value}` from all templates inside.

See {Tree::Template#fetch_hash} for explanation.

@return [Array<Hash>]

# File lib/infoboxer/tree/nodes.rb, line 139
def fetch_hashes(*args)
  map { |t| t.fetch_hash(*args) }
end
first(n = nil) click to toggle source

Just like Array#first, but returns Nodes, if provided with `n` of elements.

Calls superclass method
# File lib/infoboxer/tree/nodes.rb, line 68
def first(n = nil)
  if n.nil?
    super()
  else
    Nodes[*super(n)]
  end
end
flat_map() click to toggle source

Just like Array#flat_map, but returns Nodes, if all map results are Node

Calls superclass method
# File lib/infoboxer/tree/nodes.rb, line 96
def flat_map
  res = super
  if res.all? { |n| n.is_a?(Node) || n.is_a?(Nodes) }
    Nodes[*res]
  else
    res
  end
end
flow_templates() click to toggle source

@private Internal, used by {Parser}

# File lib/infoboxer/tree/nodes.rb, line 217
def flow_templates
  # TODO: will it be better?..
  # make_nodes(map { |n| n.is_a?(Paragraph) ? n.to_templates? : n })
  self
end
follow() click to toggle source

Fetches pages by ALL wikilinks inside in ONE query to MediaWiki API.

NB: for now, if there's more then 50 wikilinks (limitation for one request to API), Infoboxer **will not** try to do next page. It will be fixed in next releases.

@return [Nodes<MediaWiki::Page>] It is still `Nodes`, so you

still can process them uniformely.
# File lib/infoboxer/tree/nodes.rb, line 179
def follow
  links = grep(Linkable)
  return Nodes[] if links.empty?

  page = first.lookup_parents(MediaWiki::Page).first or
    fail('Not in a page from real source')
  page.client or fail('MediaWiki client not set')
  pages = links.group_by(&:interwiki)
               .flat_map { |iw, ls| page.client.get(*ls.map(&:link), interwiki: iw) }
  pages.count == 1 ? pages.first : Nodes[*pages]
end
group_by() click to toggle source

Just like Array#group, but returns hash with `{<grouping variable> => Nodes}`

Calls superclass method
# File lib/infoboxer/tree/nodes.rb, line 106
def group_by
  super.transform_values { |group| Nodes[*group] }
end
inspect() click to toggle source
# File lib/infoboxer/tree/nodes.rb, line 148
def inspect
  '[' +
    case
    when count > MAX_CHILDREN
      self[0...MAX_CHILDREN].map(&:inspect).join(', ') +
      ", ...#{count - MAX_CHILDREN} more nodes"
    else
      map(&:inspect).join(', ')
    end + ']'
end
last(n = nil) click to toggle source

Just like Array#last, but returns Nodes, if provided with `n` of elements.

Calls superclass method
# File lib/infoboxer/tree/nodes.rb, line 77
def last(n = nil)
  if n.nil?
    super()
  else
    Nodes[*super(n)]
  end
end
map() click to toggle source

Just like Array#map, but returns Nodes, if all map results are Node

Calls superclass method
# File lib/infoboxer/tree/nodes.rb, line 86
def map
  res = super
  if res.all? { |n| n.is_a?(Node) || n.is_a?(Nodes) }
    Nodes[*res]
  else
    res
  end
end
strip() click to toggle source

@private Internal, used by {Parser}

# File lib/infoboxer/tree/nodes.rb, line 208
def strip
  res = dup
  res.pop while res.last.is_a?(Text) && res.last.raw_text =~ /^\s*$/
  res.last.raw_text.sub!(/\s+$/, '') if res.last.is_a?(Text)
  res
end
text() click to toggle source

Just join of all {Node#text Node#text}s inside.

# File lib/infoboxer/tree/nodes.rb, line 160
def text
  map(&:text).join
end
Also aliased as: to_s
to_s()
Alias for: text
to_tree() click to toggle source

Just join of all {Node#to_tree Node#to_tree} strings inside.

# File lib/infoboxer/tree/nodes.rb, line 144
def to_tree
  map(&:to_tree).join("\n")
end
unwrap() click to toggle source
# File lib/infoboxer/tree/nodes.rb, line 166
def unwrap
  map { |n| n.respond_to?(:unwrap) ? n.unwrap : n }
end

Private Instance Methods

make_nodes(arr) click to toggle source
# File lib/infoboxer/tree/nodes.rb, line 228
def make_nodes(arr)
  Nodes[*arr.flatten]
end