Class: Mato::Renderers::HtmlTocRenderer

Inherits:
Object
  • Object
show all
Defined in:
lib/mato/renderers/html_toc_renderer.rb

Constant Summary collapse

H_SELECTOR =
%w(h1 h2 h3 h4 h5 h6).join(',')
ANCHOR_SELECTOR =
"a.#{AnchorBuilder::CSS_CLASS_NAME}"

Instance Method Summary collapse

Instance Method Details

#call(doc) ⇒ String

Parameters:

  • doc (Nokogiri::HTML::DocumentFragment)

Returns:

  • (String)


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/mato/renderers/html_toc_renderer.rb', line 14

def call(doc)
  s = +''

  stack = [0]

  doc.css(H_SELECTOR).each do |hx|
    h_level = level(hx)

    if h_level > stack.last
      stack.push(h_level)
      s << %{<ul>\n}
    elsif h_level < stack.last
      while h_level < stack.last
        # keep the user-level stack top element (i.e. [0, #]) here
        if stack.size <= 2
          s << %{</li>\n}
          stack.pop
          stack.push(h_level)
          break
        else
          s << %{</li></ul>\n}
          stack.pop
        end
      end
    else
      s << %{</li>\n}
    end

    node = hx.dup

    anchor = node.css(ANCHOR_SELECTOR).first

    s << %{<li>}
    if anchor
      s << %{<a href="##{anchor['id']}">}
      anchor.unlink
    end

    node.css('a').each do |a|
      a.replace(a.children)
    end
    s << node.children.to_html(save_with: 0)

    if anchor
      s << %{</a>}
    end
  end

  # roll up all the stack elements
  while stack.last != 0
    stack.pop
    s << %{</li></ul>\n}
  end

  s
end