Skip to content

Commit 6121d2b

Browse files
committed
Fixed bugs
1 parent daa137e commit 6121d2b

File tree

2 files changed

+107
-105
lines changed

2 files changed

+107
-105
lines changed

CNAME

Lines changed: 0 additions & 1 deletion
This file was deleted.

_plugins/tocGenerator.rb

Lines changed: 107 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,119 @@
1-
require 'nokogiri'
1+
require 'nokogiri'
22

3-
module Jekyll
4-
module TOCGenerator
5-
TOGGLE_HTML = '<div id="toctitle"><h2>%1</h2>%2</div>'
6-
TOC_CONTAINER_HTML = '<div id="toc-container"><table class="toc" id="toc"><tbody><tr><td>%1<ul>%2</ul></td></tr></tbody></table></div>'
7-
HIDE_HTML = '<span class="toctoggle">[<a id="toctogglelink" class="internal" href="#">%1</a>]</span>'
3+
module Jekyll
4+
module TOCGenerator
5+
TOGGLE_HTML = '<div id="toctitle"><h2>%1</h2>%2</div>'
6+
TOC_CONTAINER_HTML = '<div id="toc-container"><table class="toc" id="toc"><tbody><tr><td>%1<ul>%2</ul></td></tr></tbody></table></div>'
7+
HIDE_HTML = '<span class="toctoggle">[<a id="toctogglelink" class="internal" href="#">%1</a>]</span>'
88

9-
def toc_generate(html)
10-
pageContext = @context.environments.first["page"]
9+
def toc_generate(html)
10+
# No Toc can be specified on every single page
11+
# For example the index page has no table of contents
12+
no_toc = @context.environments.first["page"]["noToc"] || false;
1113

12-
anchorPrefix = pageContext["anchorPrefix"] || 'tocAnchor-'
13-
showAlways = pageContext["showAlways"] || false
14-
saveShowStatus = pageContext["saveShowStatus"] || true
14+
if no_toc
15+
return html
16+
end
1517

16-
# Text labels
17-
contentsLabel = pageContext["contentsLabel"] || 'Contents'
18-
hideLabel = pageContext["hideLabel"] || 'hide'
19-
showText = pageContext["showText"] || 'show'
20-
showHideButton = pageContext["showHideButton"] || true;
18+
config = @context.registers[:site].config
19+
# Minimum number of items needed to show TOC, default 0 (0 means no minimum)
20+
min_items_to_show_toc = config["minItemsToShowToc"] || 0
2121

22-
noToc = pageContext["noToc"] || false;
22+
anchor_prefix = config["anchorPrefix"] || 'tocAnchor-'
2323

24-
if noToc
25-
return html
26-
end
24+
# Text labels
25+
contents_label = config["contentsLabel"] || 'Contents'
26+
hide_label = config["hideLabel"] || 'hide'
27+
show_label = config["showLabel"] || 'show'
28+
show_toggle_button = config["showToggleButton"]
29+
30+
toc_html = ''
31+
toc_level = 1
32+
toc_section = 1
33+
item_number = 1
34+
level_html = ''
35+
36+
doc = Nokogiri::HTML(html)
2737

28-
tocHTML = ''
29-
tocLevel = 1
30-
tocSection = 1
31-
itemNumber = 1
32-
levelHTML = ''
33-
34-
doc = Nokogiri::HTML(html)
35-
36-
# Find H1 tag and all its H2 siblings until next H1
37-
# TODO This XPATH expression can greatly improved
38-
doc.css('h1').each do |h1|
39-
ct = h1.xpath('count(following-sibling::h1)')
40-
h2s = h1.xpath("following-sibling::h2[count(following-sibling::h1)=#{ct}]")
41-
42-
levelHTML = '';
43-
innerSection = 0;
44-
45-
h2s.map.each do |h2|
46-
innerSection += 1;
47-
anchorId = anchorPrefix + tocLevel.to_s + '-' + tocSection.to_s + '-' + innerSection.to_s
48-
# Insert before element the anchor used by TOC
49-
h2.before("<a name=\"#{anchorId}\"></a>")
50-
51-
levelHTML += createLevelHTML(anchorId,
52-
tocLevel + 1,
53-
tocSection + innerSection,
54-
itemNumber.to_s + '.' + innerSection.to_s,
55-
h2.text,
56-
'')
57-
end
58-
if levelHTML.length > 0
59-
levelHTML = '<ul>' + levelHTML + '</ul>';
60-
end
61-
anchorId = anchorPrefix + tocLevel.to_s + '-' + tocSection.to_s;
38+
# Find H1 tag and all its H2 siblings until next H1
39+
doc.css('h1').each do |h1|
40+
# TODO This XPATH expression can greatly improved
41+
ct = h1.xpath('count(following-sibling::h1)')
42+
h2s = h1.xpath("following-sibling::h2[count(following-sibling::h1)=#{ct}]")
43+
44+
level_html = '';
45+
inner_section = 0;
46+
47+
h2s.map.each do |h2|
48+
inner_section += 1;
49+
anchor_id = anchor_prefix + toc_level.to_s + '-' + toc_section.to_s + '-' + inner_section.to_s
6250
# Insert before element the anchor used by TOC
63-
h1.before("<a name=\"#{anchorId}\"></a>")
64-
65-
tocHTML += createLevelHTML(anchorId,
66-
tocLevel,
67-
tocSection,
68-
itemNumber,
69-
h1.text,
70-
levelHTML);
71-
72-
tocSection += 1 + innerSection;
73-
itemNumber += 1;
74-
end
75-
76-
if tocHTML.length > 0
77-
hideHTML = '';
78-
if (showHideButton)
79-
hideHTML = HIDE_HTML.gsub('%1', hideLabel)
80-
end
81-
82-
hasOnlyOneTocItem = tocLevel == 1 && tocSection <= 2;
83-
show = showAlways ? true : !hasOnlyOneTocItem;
84-
85-
if (show)
86-
replacedToggleHTML = TOGGLE_HTML
87-
.gsub('%1', contentsLabel)
88-
.gsub('%2', hideHTML);
89-
tocTable = TOC_CONTAINER_HTML
90-
.gsub('%1', replacedToggleHTML)
91-
.gsub('%2', tocHTML);
92-
doc.css('body').children.before(tocTable)
93-
end
94-
doc.css('body').children.to_xhtml(indent:3, indent_text:" ")
95-
else
96-
return html
51+
h2.before("<a name=\"#{anchor_id}\"></a>")
52+
53+
level_html += create_level_html(anchor_id,
54+
toc_level + 1,
55+
toc_section + inner_section,
56+
item_number.to_s + '.' + inner_section.to_s,
57+
h2.text,
58+
'')
59+
end
60+
if level_html.length > 0
61+
level_html = '<ul>' + level_html + '</ul>';
62+
end
63+
anchor_id = anchor_prefix + toc_level.to_s + '-' + toc_section.to_s;
64+
# Insert before element the anchor used by TOC
65+
h1.before("<a name=\"#{anchor_id}\"></a>")
66+
67+
toc_html += create_level_html(anchor_id,
68+
toc_level,
69+
toc_section,
70+
item_number,
71+
h1.text,
72+
level_html);
73+
74+
toc_section += 1 + inner_section;
75+
item_number += 1;
76+
end
77+
78+
# for convenience item_number starts from 1
79+
# so we decrement it to obtain the index count
80+
toc_index_count = item_number - 1
81+
82+
if toc_html.length > 0
83+
hide_html = '';
84+
if (show_toggle_button)
85+
hide_html = HIDE_HTML.gsub('%1', hide_label)
86+
end
87+
88+
if min_items_to_show_toc <= toc_index_count
89+
replaced_toggle_html = TOGGLE_HTML
90+
.gsub('%1', contents_label)
91+
.gsub('%2', hide_html);
92+
toc_table = TOC_CONTAINER_HTML
93+
.gsub('%1', replaced_toggle_html)
94+
.gsub('%2', toc_html);
95+
doc.css('body').children.before(toc_table)
9796
end
98-
end
99-
100-
private
101-
102-
def createLevelHTML(anchorId, tocLevel, tocSection, tocNumber, tocText, tocInner)
103-
link = '<a href="#%1"><span class="tocnumber">%2</span> <span class="toctext">%3</span></a>%4'
104-
.gsub('%1', anchorId.to_s)
105-
.gsub('%2', tocNumber.to_s)
106-
.gsub('%3', tocText)
107-
.gsub('%4', tocInner ? tocInner : '');
108-
'<li class="toclevel-%1 tocsection-%2">%3</li>'
109-
.gsub('%1', tocLevel.to_s)
110-
.gsub('%2', tocSection.to_s)
111-
.gsub('%3', link)
97+
doc.css('body').children.to_xhtml(indent:3, indent_text:" ")
98+
else
99+
return html
112100
end
113-
end
101+
end
102+
103+
private
104+
105+
def create_level_html(anchor_id, toc_level, toc_section, tocNumber, tocText, tocInner)
106+
link = '<a href="#%1"><span class="tocnumber">%2</span> <span class="toctext">%3</span></a>%4'
107+
.gsub('%1', anchor_id.to_s)
108+
.gsub('%2', tocNumber.to_s)
109+
.gsub('%3', tocText)
110+
.gsub('%4', tocInner ? tocInner : '');
111+
'<li class="toc_level-%1 toc_section-%2">%3</li>'
112+
.gsub('%1', toc_level.to_s)
113+
.gsub('%2', toc_section.to_s)
114+
.gsub('%3', link)
114115
end
116+
end
117+
end
115118

116-
Liquid::Template.register_filter(Jekyll::TOCGenerator)
119+
Liquid::Template.register_filter(Jekyll::TOCGenerator)

0 commit comments

Comments
 (0)