Skip to content

Commit

Permalink
Merge pull request #20 from kitlawes/master
Browse files Browse the repository at this point in the history
Support nested lists in the toc
  • Loading branch information
toshimaru authored Apr 11, 2017
2 parents 573d310 + c412299 commit 199b194
Showing 1 changed file with 63 additions and 1 deletion.
64 changes: 63 additions & 1 deletion lib/table_of_contents/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,75 @@ def initialize(html)
def build_toc
toc = %Q{<ul class="section-nav">\n}

min_h_num = 6
@entries.each do |entry|
toc << %Q{<li class="toc-entry toc-#{entry[:node_name]}"><a href="##{entry[:id]}#{entry[:uniq]}">#{entry[:text]}</a></li>\n}
h_num = entry[:node_name].delete("h").to_i
min_h_num = [min_h_num, h_num].min
end
toc << build_lis(@entries, min_h_num)

toc << '</ul>'
end

# Returns the list items for entries
def build_lis(entries, min_h_num)
lis = ""
i = 0
while i < entries.length do
entry = entries[i]
curr_h_num = entry[:node_name].delete("h").to_i
if curr_h_num == min_h_num

# If the current entry should not be indented in the list, add the entry to the list
lis << %Q{<li class="toc-entry toc-#{entry[:node_name]}"><a href="##{entry[:id]}#{entry[:uniq]}">#{entry[:text]}</a>}
# If the next entry should be indented in the list, generate a sublist
if i + 1 < entries.length
next_entry = entries[i + 1]
next_h_num = next_entry[:node_name].delete("h").to_i
if next_h_num > min_h_num
lis << %Q{\n}
lis << %Q{<ul>\n}
nest_entries = get_nest_entries(entries[i + 1, entries.length], min_h_num)
lis << build_lis(nest_entries, min_h_num + 1)
lis << %Q{</ul>\n}
i += nest_entries.length
end
end
# Add the closing tag for the current entry in the list
lis << %Q{</li>\n}

elsif curr_h_num > min_h_num

# If the current entry should be indented in the list, generate a sublist
lis << %Q{<ul>\n}
nest_entries = get_nest_entries(entries[i, entries.length], min_h_num)
lis << build_lis(nest_entries, min_h_num + 1)
lis << %Q{</ul>\n}
i += nest_entries.length - 1

end
i += 1
end
lis
end

# Returns the entries in a nested list
# The nested list starts at the first entry in entries (inclusive)
# The nested list ends at the first entry in entries with depth min_h_num or greater (exclusive)
def get_nest_entries(entries, min_h_num)
nest_entries = []
for i in 0..(entries.length - 1)
nest_entry = entries[i]
nest_h_num = nest_entry[:node_name].delete("h").to_i
if nest_h_num > min_h_num
nest_entries.push(nest_entry)
else
break
end
end
nest_entries
end

def inject_anchors_into_html
@entries.each do |entry|
entry[:content_node].add_previous_sibling(%Q{<a id="#{entry[:id]}#{entry[:uniq]}" class="anchor" href="##{entry[:id]}#{entry[:uniq]}" aria-hidden="true"><span class="octicon octicon-link"></span></a>})
Expand Down

0 comments on commit 199b194

Please sign in to comment.