class Amber::Render::TableOfContents
TABLE OF CONTENTS
Public Class Methods
new(html, options = {})
click to toggle source
options:
:content_selector (css selector for headings, nokogiri backend only) :href_base -- use this href for the toc links :numeric_prefix -- prefix toc entries and headings with numeric counter (e.g. 1.1.0, 1.2.0, ...)
# File lib/amber/render/table_of_contents.rb, line 23 def initialize(html, options = {}) @html = html @toc = TocItem.new @levels = {"h1" => 0, "h2" => 0, "h3" => 0, "h4" => 0} @heading_anchors = {} @options = options @options[:tag] ||= 'ol' @parsed = nil end
Public Instance Methods
to_html()
click to toggle source
# File lib/amber/render/table_of_contents.rb, line 33 def to_html parse_doc unless @parsed # override this! end
to_toc()
click to toggle source
# File lib/amber/render/table_of_contents.rb, line 38 def to_toc parse_doc unless @parsed # override this! end
Private Instance Methods
anchor_text(heading_text)
click to toggle source
returns anchor text from heading text. e.g. First Heading! => first-heading
if there are duplicates, they get numbered:
heading => heading heading => heading-2 heading => heading-3
# File lib/amber/render/table_of_contents.rb, line 68 def anchor_text(heading_text) text = nameize(strip_html_tags(heading_text)) text_with_suffix = text i = 2 while @heading_anchors[text_with_suffix] text_with_suffix = "#{text}-#{i}" i+=1 end @heading_anchors[text_with_suffix] = true text_with_suffix end
each_heading(html, &block)
click to toggle source
# File lib/amber/render/table_of_contents.rb, line 128 def each_heading(html, &block) raise 'override me' end
increment_level(heading)
click to toggle source
keeps a counter of the latest heading at each level
# File lib/amber/render/table_of_contents.rb, line 121 def increment_level(heading) @levels[heading] += 1 @levels["h2"] = 0 if heading == "h1" @levels["h3"] = 0 if heading == "h1" || heading == "h2" @levels["h4"] = 0 if heading == "h1" || heading == "h2" || heading == "h3" end
level_text()
click to toggle source
prefix headings with text like 1.2.1, if :numeric_prefix => true
# File lib/amber/render/table_of_contents.rb, line 114 def level_text [@levels["h1"], @levels["h2"], @levels["h3"], @levels["h4"]].join(".").gsub(/\.0/, "") end
nameize(str)
click to toggle source
convert any string to one suitable for a url. resist the urge to translit non-ascii slugs to ascii. it is always much better to keep strings as utf8.
# File lib/amber/render/table_of_contents.rb, line 85 def nameize(str) str = str.dup str.gsub!(/&(\w{2,6}?|#[0-9A-Fa-f]{2,6});/,'') # remove html entitities str.gsub!(/[^- [[:word:]]]/u, '') # remove non-word characters (using unicode definition of a word char) str.strip! str.downcase! # upper case characters in urls are confusing str.gsub!(/\ +/u, '-') # spaces to dashes, preferred separator char everywhere CGI.escape(str) end
parse_doc()
click to toggle source
# File lib/amber/render/table_of_contents.rb, line 45 def parse_doc each_heading(@html) do |heading, heading_text| heading_anchor = anchor_text(heading_text) heading_text = strip_anchors(heading_text) if @options[:numeric_prefix] increment_level(heading) heading_text = level_text + " " + heading_text end @toc.add_heading(heading, heading_text, heading_anchor) '<a name="%s"></a>%s' % [heading_anchor, heading_text] end @parsed = true end
strip_anchors(html)
click to toggle source
remove <a name='x'></a> from html, but leaves all other tags in place.
# File lib/amber/render/table_of_contents.rb, line 101 def strip_anchors(html) Nokogiri::HTML::DocumentFragment.parse(html, 'UTF-8').children.collect{|child| if child.name == "text" child.inner_text elsif child.name != 'a' || !child.attributes.detect{|atr| atr[0] == 'name'} child.to_s end }.join end