Class: Banzai::Filter::TableOfContentsFilter

Inherits:
HTML::Pipeline::Filter
  • Object
show all
Defined in:
lib/banzai/filter/table_of_contents_filter.rb

Overview

HTML filter that adds an anchor child element to all Headers in a document, so that they can be linked to.

Generates the Table of Contents with links to each header. See Results.

Based on HTML::Pipeline::TableOfContentsFilter.

Context options:

:no_header_anchors - Skips all processing done by this filter.

Results:

:toc - String containing Table of Contents data as a `ul` element with
       `li` child elements.

Constant Summary collapse

PUNCTUATION_REGEXP =
/[^\p{Word}\- ]/u

Instance Method Summary collapse

Instance Method Details

#callObject


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
# File 'lib/banzai/filter/table_of_contents_filter.rb', line 19

def call
  return doc if context[:no_header_anchors]

  result[:toc] = ""

  headers = Hash.new(0)

  doc.css('h1, h2, h3, h4, h5, h6').each do |node|
    text = node.text

    id = text.downcase
    id.gsub!(PUNCTUATION_REGEXP, '') # remove punctuation
    id.tr!(' ', '-') # replace spaces with dash
    id.squeeze!('-') # replace multiple dashes with one

    uniq = (headers[id] > 0) ? "-#{headers[id]}" : ''
    headers[id] += 1

    if header_content = node.children.first
      href = "#{id}#{uniq}"
      push_toc(href, text)
      header_content.add_previous_sibling(anchor_tag(href))
    end
  end

  result[:toc] = %Q{<ul class="section-nav">\n#{result[:toc]}</ul>} unless result[:toc].empty?

  doc
end