Class: Banzai::Filter::TableOfContentsFilter

Inherits:
HTML::Pipeline::Filter
  • Object
show all
Includes:
Gitlab::Utils::Markdown
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.

Defined Under Namespace

Classes: HeaderNode

Constant Summary collapse

CSS =
'h1, h2, h3, h4, h5, h6'
XPATH =
Gitlab::Utils::Nokogiri.css_to_xpath(CSS).freeze

Constants included from Gitlab::Utils::Markdown

Gitlab::Utils::Markdown::PRODUCT_SUFFIX, Gitlab::Utils::Markdown::PUNCTUATION_REGEXP

Instance Method Summary collapse

Methods included from Gitlab::Utils::Markdown

#string_to_anchor

Instance Method Details

#callObject



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

def call
  return doc if context[:no_header_anchors]

  result[:toc] = +""

  headers = Hash.new(0)
  header_root = current_header = HeaderNode.new

  doc.xpath(XPATH).each do |node|
    next unless header_content = node.children.first

    id = string_to_anchor(node.text[0...255])

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

    current_header = HeaderNode.new(node: node, href: href, previous_header: current_header)

    header_content.add_previous_sibling(anchor_tag(href))
  end

  push_toc(header_root.children, root: true)

  doc
end