Class: Html2rss::SST::Index

Inherits:
Object
  • Object
show all
Defined in:
lib/html2rss/sst/index.rb

Overview

Parent/depth indices for an SST tree. Built once by the Normalizer so Scoring/Segmenter never need Nokogiri ancestor walks.

Constant Summary collapse

NODE_BINDINGS =

Weak node→index bindings so Node#visible_text can memoize without call-site churn.

ObjectSpace::WeakMap.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root:, parents:, depths:, ignored_chrome:) ⇒ Index

Returns a new instance of Index.

Parameters:

  • root (Node)
  • parents (Hash{Node => Node, nil})
  • depths (Hash{Node => Integer})
  • ignored_chrome (Hash{Node => Boolean})


22
23
24
25
26
27
28
29
30
# File 'lib/html2rss/sst/index.rb', line 22

def initialize(root:, parents:, depths:, ignored_chrome:)
  @root = root
  @parents = parents
  @depths = depths
  @ignored_chrome = ignored_chrome
  @visible_text = {}.compare_by_identity
  @word_count = {}.compare_by_identity
  bind_tree(root)
end

Instance Attribute Details

#rootObject (readonly)

Returns the value of attribute root.



32
33
34
# File 'lib/html2rss/sst/index.rb', line 32

def root
  @root
end

Class Method Details

.for_node(node) ⇒ Index?

Parameters:

Returns:



15
# File 'lib/html2rss/sst/index.rb', line 15

def self.for_node(node) = NODE_BINDINGS[node]

Instance Method Details

#depth_of(node) ⇒ Integer

Parameters:

Returns:

  • (Integer)


42
# File 'lib/html2rss/sst/index.rb', line 42

def depth_of(node) = @depths.fetch(node, 0)

#descendant_of?(child, ancestor) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


73
74
75
76
77
78
79
80
81
# File 'lib/html2rss/sst/index.rb', line 73

def descendant_of?(child, ancestor)
  curr = parent_of(child)
  while curr
    return true if curr.equal?(ancestor)

    curr = parent_of(curr)
  end
  false
end

#each_node {|node| ... } ⇒ Enumerator

Yield Parameters:

Returns:

  • (Enumerator)


100
101
102
# File 'lib/html2rss/sst/index.rb', line 100

def each_node(&)
  root.each_node(&)
end

#ignored_chrome?(node) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


47
# File 'lib/html2rss/sst/index.rb', line 47

def ignored_chrome?(node) = @ignored_chrome.fetch(node, false)

#memo_visible_text(node) ⇒ String?

Memoized default visible text (separator space, no excludes).

Parameters:

Returns:

  • (String, nil)


54
55
56
57
58
# File 'lib/html2rss/sst/index.rb', line 54

def memo_visible_text(node)
  return @visible_text[node] if @visible_text.key?(node)

  @visible_text[node] = Text.extract(node)
end

#memo_word_count(node) ⇒ Integer

Parameters:

Returns:

  • (Integer)


63
64
65
66
67
# File 'lib/html2rss/sst/index.rb', line 63

def memo_word_count(node)
  return @word_count[node] if @word_count.key?(node)

  @word_count[node] = memo_visible_text(node).to_s.scan(/\p{Alnum}+/).size
end

#parent_of(node) ⇒ Node?

Parameters:

Returns:



37
# File 'lib/html2rss/sst/index.rb', line 37

def parent_of(node) = @parents[node]

#parent_until(node, condition) ⇒ Node?

Parameters:

  • node (Node)
  • condition (#call)

Returns:



87
88
89
90
91
92
93
94
95
# File 'lib/html2rss/sst/index.rb', line 87

def parent_until(node, condition)
  curr = node
  while curr && curr.name != :html
    return curr if condition.call(curr)

    curr = parent_of(curr)
  end
  nil
end