Class: HyperNavigator::PatternMatcher

Inherits:
Object
  • Object
show all
Defined in:
lib/hyper_navigator/node.rb

Instance Method Summary collapse

Constructor Details

#initialize(headers, opts = {}) ⇒ PatternMatcher

Returns a new instance of PatternMatcher.



30
31
32
33
# File 'lib/hyper_navigator/node.rb', line 30

def initialize(headers,opts={})
  @opts = opts
  @headers = headers
end

Instance Method Details

#make_node(link, depth = nil) ⇒ Object



81
82
83
84
85
# File 'lib/hyper_navigator/node.rb', line 81

def make_node(link, depth=nil)
  padding = '  ' * depth
  puts "#{padding}#{link}" if @opts[:verbose]
  Node.new(link["rel"], link["href"], @headers, depth)
end

#match(href, exp) ⇒ Object



35
36
37
# File 'lib/hyper_navigator/node.rb', line 35

def match(href, exp)
  match_here(exp, Node.new(:root, href, @headers, 0))
end

#match_here(exp, node) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/hyper_navigator/node.rb', line 39

def match_here(exp, node)
  if exp == nil
    return nil
  elsif exp[1] == :star
    match_star(exp[0], exp.drop(2), node)
    return node
  elsif exp[0] == :any
    node.descendants = match_here_descendants(exp.drop(1), node)
    return node
  elsif exp[0] == node.rel
    node.descendants = match_here_descendants(exp.drop(1), node)
    return node
  end
  return nil
end

#match_here_descendants(exp, node) ⇒ Object



55
56
57
58
59
60
# File 'lib/hyper_navigator/node.rb', line 55

def match_here_descendants(exp, node)
  return [] if exp == nil
  nodes = node.links.map {|link| make_node(link, node.depth + 1)}
  matched_nodes = nodes.map {|n| match_here(exp, n) }
  return matched_nodes.compact
end

#match_star(exp_star, exp, node) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/hyper_navigator/node.rb', line 62

def match_star(exp_star, exp, node)
  # exp can match here, ending the descent
  exp_node_here = match_here(exp, node)
  if exp_node_here
    # finish the star match
  else
    nodes = match_here_descendants([exp_star], node)

    # continue the star matching for each descendant
    nodes.each {|n| match_star(exp_star, exp, n) }
    if exp.empty?
      node.descendants = nodes
    else
      # removing nodes that are not in the path to the next exp
      node.descendants = nodes.reject {|n| n.descendants.empty? && n.rel != exp[0] }
    end
  end
end