Sha256: 3a12a52986f62701d20e42a68e1b7a1af004ddcfa2f02bed544cba10897d19c8

Contents?: true

Size: 1.91 KB

Versions: 1

Compression:

Stored size: 1.91 KB

Contents

module Kitabu
  class Toc
    # Return the table of contents in hash format.
    #
    attr_reader :toc

    private_class_method :new
    attr_reader :buffer # :nodoc:
    attr_reader :attrs # :nodoc:
    attr_accessor :content # :nodoc:

    # Traverse every title and add a +id+ attribute.
    # Return the modified content.
    #
    def self.normalize(content)
      counter = {}
      html = Nokogiri::HTML.parse(content)
      html.search("h2, h3, h4, h5, h6").each do |tag|
        title = tag.inner_text
        permalink = title.to_permalink

        counter[permalink] ||= 0
        counter[permalink] += 1

        permalink = "#{permalink}-#{counter[permalink]}" if counter[permalink] > 1

        tag.set_attribute("id", permalink)
      end

      html = html.to_xhtml
      html.force_encoding("UTF-8") if html.encoding_aware?

      _, content = *html.match(/<body>(.*?)<\/body>/m)
      content
    end

    # Traverse every title normalizing its content as a permalink.
    #
    def self.generate(content)
      content = normalize(content)
      listener = new
      listener.content = content
      Stream.new(content, listener).parse
      listener
    end

    def initialize # :nodoc:
      @toc = []
      @counters = {}
    end

    def tag(node) # :nodoc:
      toc << {
        :level     => node.name.gsub(/[^\d]/, "").to_i,
        :text      => node.text,
        :permalink => node["id"]
      }
    end

    # Return a hash with all normalized attributes.
    #
    def to_hash
      {
        :content => content,
        :html => to_html,
        :toc => toc
      }
    end

    # Return the table of contents in HTML format.
    #
    def to_html
      String.new.tap do |html|
        toc.each do |options|
          html << %[<div class="level#{options[:level]} #{options[:permalink]}"><a href="##{options[:permalink]}"><span>#{CGI.escape_html(options[:text])}</span></a></div>]
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
kitabu-1.0.0.rc1 lib/kitabu/toc.rb