rf-web/vendor/bundle/gems/kramdown-2.1.0/lib/kramdown/converter/toc.rb
2019-10-21 10:18:17 +02:00

70 lines
1.8 KiB
Ruby

# -*- coding: utf-8; frozen_string_literal: true -*-
#
#--
# Copyright (C) 2009-2019 Thomas Leitner <t_leitner@gmx.at>
#
# This file is part of kramdown which is licensed under the MIT.
#++
#
require 'kramdown/converter'
module Kramdown
module Converter
# Converts a Kramdown::Document to an element tree that represents the table of contents.
#
# The returned tree consists of Element objects of type :toc where the root element is just used
# as container object. Each :toc element contains as value the wrapped :header element and under
# the attribute key :id the header ID that should be used (note that this ID may not exist in
# the wrapped element).
#
# Since the TOC tree consists of special :toc elements, one cannot directly feed this tree to
# other converters!
class Toc < Base
def initialize(root, options)
super
@toc = Element.new(:toc)
@stack = []
@options[:template] = ''
end
def convert(el)
if el.type == :header && in_toc?(el)
attr = el.attr.dup
attr['id'] = generate_id(el.options[:raw_text]) if @options[:auto_ids] && !attr['id']
add_to_toc(el, attr['id']) if attr['id']
else
el.children.each {|child| convert(child) }
end
@toc
end
private
def add_to_toc(el, id)
toc_element = Element.new(:toc, el, id: id)
success = false
until success
if @stack.empty?
@toc.children << toc_element
@stack << toc_element
success = true
elsif @stack.last.value.options[:level] < el.options[:level]
@stack.last.children << toc_element
@stack << toc_element
success = true
else
@stack.pop
end
end
end
end
end
end