jekyll-toc 0.12.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +19 -0
- data/.github/workflows/ci.yml +32 -0
- data/.github/workflows/coverage.yml +22 -0
- data/.github/workflows/rubocop.yml +19 -0
- data/.rubocop.yml +24 -9
- data/Appraisals +5 -9
- data/Gemfile +10 -0
- data/LICENSE.md +1 -1
- data/README.md +106 -29
- data/gemfiles/jekyll_3.8.gemfile +7 -0
- data/gemfiles/jekyll_3.9.gemfile +14 -0
- data/gemfiles/jekyll_4.0.gemfile +14 -0
- data/gemfiles/jekyll_4.1.gemfile +14 -0
- data/jekyll-toc.gemspec +9 -15
- data/lib/table_of_contents/configuration.rb +4 -2
- data/lib/table_of_contents/helper.rb +17 -0
- data/lib/table_of_contents/parser.rb +12 -8
- data/lib/table_of_contents/version.rb +7 -0
- data/test/parser/test_inject_anchors_filter.rb +1 -1
- data/test/parser/{test_option_error.rb → test_invalid_options.rb} +6 -14
- data/test/parser/test_ordered_list.rb +76 -0
- data/test/parser/test_toc_only_filter.rb +2 -2
- data/test/parser/test_various_toc_html.rb +147 -214
- data/test/test_configuration.rb +15 -13
- data/test/test_helper.rb +2 -2
- data/test/test_toc_tag.rb +1 -1
- metadata +29 -119
- data/.travis.yml +0 -22
- data/gemfiles/jekyll_3.6.gemfile +0 -7
- data/gemfiles/jekyll_3.7.gemfile +0 -7
- data/lib/version.rb +0 -5
data/gemfiles/jekyll_3.8.gemfile
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "appraisal"
|
6
|
+
gem "minitest-reporters"
|
7
|
+
gem "minitest"
|
8
|
+
gem "pry"
|
9
|
+
gem "rake"
|
10
|
+
gem "rubocop", "~> 0.81"
|
11
|
+
gem "simplecov", "~> 0.17.1"
|
12
|
+
gem "jekyll", "3.9"
|
13
|
+
|
14
|
+
gemspec path: "../"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "appraisal"
|
6
|
+
gem "minitest-reporters"
|
7
|
+
gem "minitest"
|
8
|
+
gem "pry"
|
9
|
+
gem "rake"
|
10
|
+
gem "rubocop", "~> 0.81"
|
11
|
+
gem "simplecov", "~> 0.17.1"
|
12
|
+
gem "jekyll", "4.0"
|
13
|
+
|
14
|
+
gemspec path: "../"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "appraisal"
|
6
|
+
gem "minitest-reporters"
|
7
|
+
gem "minitest"
|
8
|
+
gem "pry"
|
9
|
+
gem "rake"
|
10
|
+
gem "rubocop", "~> 0.81"
|
11
|
+
gem "simplecov", "~> 0.17.1"
|
12
|
+
gem "jekyll", "4.1"
|
13
|
+
|
14
|
+
gemspec path: "../"
|
data/jekyll-toc.gemspec
CHANGED
@@ -1,30 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
lib = File.expand_path('../lib', __FILE__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require 'version'
|
5
|
+
require 'table_of_contents/version'
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
8
|
spec.name = 'jekyll-toc'
|
7
|
-
spec.version =
|
9
|
+
spec.version = Jekyll::TableOfContents::VERSION
|
8
10
|
spec.summary = 'Jekyll Table of Contents plugin'
|
9
|
-
spec.description = '
|
11
|
+
spec.description = 'Jekyll (Ruby static website generator) plugin which generates a Table of Contents for the page.'
|
10
12
|
spec.authors = %w(toshimaru torbjoernk)
|
11
13
|
spec.email = 'me@toshimaru.net'
|
12
14
|
spec.files = `git ls-files -z`.split("\x0")
|
13
15
|
spec.homepage = 'https://github.com/toshimaru/jekyll-toc'
|
14
16
|
spec.license = 'MIT'
|
15
|
-
spec.test_files = spec.files.grep(%r{^(test|spec
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
16
18
|
spec.require_paths = ['lib']
|
17
19
|
|
18
|
-
spec.required_ruby_version = '>= 2.
|
19
|
-
|
20
|
-
spec.add_runtime_dependency 'nokogiri', '~> 1.9'
|
20
|
+
spec.required_ruby_version = '>= 2.4'
|
21
21
|
|
22
|
-
spec.
|
23
|
-
spec.
|
24
|
-
spec.add_development_dependency 'minitest', '~> 5.11'
|
25
|
-
spec.add_development_dependency 'minitest-reporters'
|
26
|
-
spec.add_development_dependency 'pry'
|
27
|
-
spec.add_development_dependency 'rake'
|
28
|
-
spec.add_development_dependency 'rubocop'
|
29
|
-
spec.add_development_dependency 'simplecov'
|
22
|
+
spec.add_dependency 'jekyll', '>= 3.8'
|
23
|
+
spec.add_dependency 'nokogiri', '~> 1.10'
|
30
24
|
end
|
@@ -4,12 +4,13 @@ module Jekyll
|
|
4
4
|
module TableOfContents
|
5
5
|
# jekyll-toc configuration class
|
6
6
|
class Configuration
|
7
|
-
|
8
|
-
|
7
|
+
attr_reader :toc_levels, :no_toc_class, :ordered_list, :no_toc_section_class,
|
8
|
+
:list_class, :sublist_class, :item_class, :item_prefix
|
9
9
|
|
10
10
|
DEFAULT_CONFIG = {
|
11
11
|
'min_level' => 1,
|
12
12
|
'max_level' => 6,
|
13
|
+
'ordered_list' => false,
|
13
14
|
'no_toc_section_class' => 'no_toc_section',
|
14
15
|
'list_class' => 'section-nav',
|
15
16
|
'sublist_class' => '',
|
@@ -21,6 +22,7 @@ module Jekyll
|
|
21
22
|
options = generate_option_hash(options)
|
22
23
|
|
23
24
|
@toc_levels = options['min_level']..options['max_level']
|
25
|
+
@ordered_list = options['ordered_list']
|
24
26
|
@no_toc_class = 'no_toc'
|
25
27
|
@no_toc_section_class = options['no_toc_section_class']
|
26
28
|
@list_class = options['list_class']
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module TableOfContents
|
5
|
+
# helper methods for Parser
|
6
|
+
module Helper
|
7
|
+
PUNCTUATION_REGEXP = /[^\p{Word}\- ]/u.freeze
|
8
|
+
|
9
|
+
def generate_toc_id(text)
|
10
|
+
text = text.downcase
|
11
|
+
.gsub(PUNCTUATION_REGEXP, '') # remove punctuation
|
12
|
+
.tr(' ', '-') # replace spaces with dash
|
13
|
+
CGI.escape(text)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'table_of_contents/helper'
|
4
|
+
|
3
5
|
module Jekyll
|
4
6
|
module TableOfContents
|
5
7
|
# Parse html contents and generate table of contents
|
6
8
|
class Parser
|
7
|
-
|
9
|
+
include ::Jekyll::TableOfContents::Helper
|
8
10
|
|
9
11
|
def initialize(html, options = {})
|
10
12
|
@doc = Nokogiri::HTML::DocumentFragment.parse(html)
|
@@ -17,11 +19,12 @@ module Jekyll
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def build_toc
|
20
|
-
%(
|
22
|
+
%(<#{list_tag} class="#{@configuration.list_class}">\n#{build_toc_list(@entries)}</#{list_tag}>)
|
21
23
|
end
|
22
24
|
|
23
25
|
def inject_anchors_into_html
|
24
26
|
@entries.each do |entry|
|
27
|
+
# NOTE: `entry[:id]` is automatically URL encoded by Nokogiri
|
25
28
|
entry[:header_content].add_previous_sibling(
|
26
29
|
%(<a class="anchor" href="##{entry[:id]}" aria-hidden="true"><span class="octicon octicon-link"></span></a>)
|
27
30
|
)
|
@@ -41,10 +44,7 @@ module Jekyll
|
|
41
44
|
.reject { |n| n.classes.include?(@configuration.no_toc_class) }
|
42
45
|
.inject([]) do |entries, node|
|
43
46
|
text = node.text
|
44
|
-
id = node.attribute('id') || text
|
45
|
-
.downcase
|
46
|
-
.gsub(PUNCTUATION_REGEXP, '') # remove punctuation
|
47
|
-
.tr(' ', '-') # replace spaces with dash
|
47
|
+
id = node.attribute('id') || generate_toc_id(text)
|
48
48
|
|
49
49
|
suffix_num = headers[id]
|
50
50
|
headers[id] += 1
|
@@ -74,7 +74,7 @@ module Jekyll
|
|
74
74
|
next_i = i + 1
|
75
75
|
if next_i < entries.count && entries[next_i][:h_num] > min_h_num
|
76
76
|
nest_entries = get_nest_entries(entries[next_i, entries.count], min_h_num)
|
77
|
-
toc_list << %(\n
|
77
|
+
toc_list << %(\n<#{list_tag}#{ul_attributes}>\n#{build_toc_list(nest_entries)}</#{list_tag}>\n)
|
78
78
|
i += nest_entries.count
|
79
79
|
end
|
80
80
|
# Add the closing tag for the current entry in the list
|
@@ -107,7 +107,7 @@ module Jekyll
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def toc_headings_in_no_toc_section
|
110
|
-
if @configuration.no_toc_section_class.is_a?
|
110
|
+
if @configuration.no_toc_section_class.is_a?(Array)
|
111
111
|
@configuration.no_toc_section_class.map { |cls| toc_headings_within(cls) }.join(',')
|
112
112
|
else
|
113
113
|
toc_headings_within(@configuration.no_toc_section_class)
|
@@ -121,6 +121,10 @@ module Jekyll
|
|
121
121
|
def ul_attributes
|
122
122
|
@ul_attributes ||= @configuration.sublist_class.empty? ? '' : %( class="#{@configuration.sublist_class}")
|
123
123
|
end
|
124
|
+
|
125
|
+
def list_tag
|
126
|
+
@list_tag ||= @configuration.ordered_list ? 'ol' : 'ul'
|
127
|
+
end
|
124
128
|
end
|
125
129
|
end
|
126
130
|
end
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
|
-
class
|
5
|
+
class TestInvalidOptions < Minitest::Test
|
6
6
|
BASE_HTML = '<h1>h1</h1>'
|
7
|
-
EXPECTED_HTML = <<~HTML
|
7
|
+
EXPECTED_HTML = <<~HTML.chomp
|
8
8
|
<ul class="section-nav">
|
9
9
|
<li class="toc-entry toc-h1"><a href="#h1">h1</a></li>
|
10
10
|
</ul>
|
@@ -12,29 +12,21 @@ class TestOptionError < Minitest::Test
|
|
12
12
|
|
13
13
|
def test_option_is_nil
|
14
14
|
parser = Jekyll::TableOfContents::Parser.new(BASE_HTML, nil)
|
15
|
-
|
16
|
-
expected = EXPECTED_HTML
|
17
|
-
assert_equal(expected, doc.css('ul.section-nav').to_s)
|
15
|
+
assert_equal(EXPECTED_HTML, parser.build_toc)
|
18
16
|
end
|
19
17
|
|
20
18
|
def test_option_is_epmty_string
|
21
19
|
parser = Jekyll::TableOfContents::Parser.new(BASE_HTML, '')
|
22
|
-
|
23
|
-
expected = EXPECTED_HTML
|
24
|
-
assert_equal(expected, doc.css('ul.section-nav').to_s)
|
20
|
+
assert_equal(EXPECTED_HTML, parser.build_toc)
|
25
21
|
end
|
26
22
|
|
27
23
|
def test_option_is_string
|
28
24
|
parser = Jekyll::TableOfContents::Parser.new(BASE_HTML, 'string')
|
29
|
-
|
30
|
-
expected = EXPECTED_HTML
|
31
|
-
assert_equal(expected, doc.css('ul.section-nav').to_s)
|
25
|
+
assert_equal(EXPECTED_HTML, parser.build_toc)
|
32
26
|
end
|
33
27
|
|
34
28
|
def test_option_is_array
|
35
29
|
parser = Jekyll::TableOfContents::Parser.new(BASE_HTML, [])
|
36
|
-
|
37
|
-
expected = EXPECTED_HTML
|
38
|
-
assert_equal(expected, doc.css('ul.section-nav').to_s)
|
30
|
+
assert_equal(EXPECTED_HTML, parser.build_toc)
|
39
31
|
end
|
40
32
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestOrderedList < Minitest::Test
|
6
|
+
include TestHelpers
|
7
|
+
|
8
|
+
def test_default_configuration
|
9
|
+
configuration = Jekyll::TableOfContents::Configuration.new({})
|
10
|
+
|
11
|
+
refute(configuration.ordered_list)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_disabled_ordered_list
|
15
|
+
configuration = Jekyll::TableOfContents::Configuration.new('ordered_list' => false)
|
16
|
+
|
17
|
+
refute(configuration.ordered_list)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_enabled_ordered_list
|
21
|
+
configuration = Jekyll::TableOfContents::Configuration.new('ordered_list' => true)
|
22
|
+
|
23
|
+
assert(configuration.ordered_list)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_basic_ordered_list_top_heading
|
27
|
+
parse_with_ordered_list
|
28
|
+
html = @parser.toc
|
29
|
+
|
30
|
+
assert_match(/^<ol class="section-nav">/, html)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_ordered_list_sub_headings
|
34
|
+
parse_with_ordered_list
|
35
|
+
html = @parser.toc
|
36
|
+
|
37
|
+
assert_match(/<ol>\n<li class="toc-entry/, html)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_ordered_list_top_heading_with_classes
|
41
|
+
parse_with_ordered_list_and_classes
|
42
|
+
html = @parser.toc
|
43
|
+
|
44
|
+
assert_match(/^<ol class="top-list-class">/, html)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_ordered_list_sub_headings_with_classes
|
48
|
+
parse_with_ordered_list_and_classes
|
49
|
+
html = @parser.toc
|
50
|
+
|
51
|
+
assert_match(/<ol class="sublist-class">/, html)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_ordered_list_subheadings_with_classes_nested_structure
|
55
|
+
parse_with_ordered_list_and_classes
|
56
|
+
html = @parser.toc
|
57
|
+
|
58
|
+
occurrences = html.scan(/<ol class="sublist-class">/).count
|
59
|
+
|
60
|
+
assert_equal(5, occurrences)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def parse_with_ordered_list
|
66
|
+
read_html_and_create_parser('ordered_list' => true)
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_with_ordered_list_and_classes
|
70
|
+
read_html_and_create_parser(
|
71
|
+
'ordered_list' => true,
|
72
|
+
'list_class' => 'top-list-class',
|
73
|
+
'sublist_class' => 'sublist-class'
|
74
|
+
)
|
75
|
+
end
|
76
|
+
end
|
@@ -12,12 +12,12 @@ class TestTOCOnlyFilter < Minitest::Test
|
|
12
12
|
def test_injects_toc_container
|
13
13
|
html = @parser.build_toc
|
14
14
|
|
15
|
-
|
15
|
+
assert_includes(html, %(<ul class="section-nav">))
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_does_not_return_content
|
19
19
|
html = @parser.build_toc
|
20
20
|
|
21
|
-
|
21
|
+
refute_includes(html, %(<h1>Simple H1</h1>))
|
22
22
|
end
|
23
23
|
end
|
@@ -3,75 +3,19 @@
|
|
3
3
|
require 'test_helper'
|
4
4
|
|
5
5
|
class TestVariousTocHtml < Minitest::Test
|
6
|
-
|
7
|
-
ANGLE_BRACKET_HTML = <<~HTML
|
8
|
-
<h1>h1</h1>
|
9
|
-
<h1><base href></h1>
|
10
|
-
<h1>& < ></h1>
|
11
|
-
HTML
|
12
|
-
|
13
|
-
NO_TOC_HTML = <<~HTML
|
14
|
-
<h1>h1</h1>
|
15
|
-
<h1 class="no_toc">no_toc h1</h1>
|
16
|
-
<h2>h2</h2>
|
17
|
-
<h2 class="no_toc">no_toc h2</h2>
|
18
|
-
<h3>h3</h3>
|
19
|
-
<h3 class="no_toc">no_toc h3</h3>
|
20
|
-
<h4>h4</h4>
|
21
|
-
<h4 class="no_toc">no_toc h4</h4>
|
22
|
-
HTML
|
23
|
-
|
24
|
-
JAPANESE_HEADINGS_HTML = <<~HTML
|
25
|
-
<h1>あ</h1>
|
26
|
-
<h2>い</h2>
|
27
|
-
<h3>う</h3>
|
28
|
-
HTML
|
29
|
-
|
30
|
-
TAGS_INSIDE_HEADINGS_HTML = <<~HTML
|
31
|
-
<h2><strong>h2</strong></h2>
|
32
|
-
<h2><em>h2</em></h2>
|
33
|
-
HTML
|
34
|
-
|
35
|
-
TEST_HTML_1 = <<~HTML
|
36
|
-
<h1>h1</h1>
|
37
|
-
<h3>h3</h3>
|
38
|
-
<h6>h6</h6>
|
39
|
-
HTML
|
40
|
-
|
41
|
-
TEST_HTML_2 = <<~HTML
|
6
|
+
TEST_HTML = <<~HTML
|
42
7
|
<h1>h1</h1>
|
43
8
|
<h3>h3</h3>
|
44
|
-
<h2>h2</h2>
|
45
|
-
<h6>h6</h6>
|
46
|
-
HTML
|
47
|
-
|
48
|
-
TEST_HTML_3 = <<~HTML
|
49
9
|
<h6>h6</h6>
|
50
|
-
<h5>h5</h5>
|
51
|
-
<h4>h4</h4>
|
52
|
-
<h3>h3</h3>
|
53
|
-
<h2>h2</h2>
|
54
|
-
<h1>h1</h1>
|
55
|
-
HTML
|
56
|
-
|
57
|
-
TEST_HTML_4 = <<~HTML
|
58
|
-
<h1>h1</h1>
|
59
|
-
<h3>h3</h3>
|
60
|
-
<h2>h2</h2>
|
61
|
-
<h4>h4</h4>
|
62
|
-
<h5>h5</h5>
|
63
10
|
HTML
|
64
11
|
|
65
12
|
def test_nested_toc
|
66
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
67
|
-
|
68
|
-
expected = <<~HTML
|
13
|
+
parser = Jekyll::TableOfContents::Parser.new(TEST_HTML)
|
14
|
+
expected = <<~HTML.chomp
|
69
15
|
<ul class="section-nav">
|
70
|
-
<li class="toc-entry toc-h1">
|
71
|
-
<a href="#h1">h1</a>
|
16
|
+
<li class="toc-entry toc-h1"><a href="#h1">h1</a>
|
72
17
|
<ul>
|
73
|
-
<li class="toc-entry toc-h3">
|
74
|
-
<a href="#h3">h3</a>
|
18
|
+
<li class="toc-entry toc-h3"><a href="#h3">h3</a>
|
75
19
|
<ul>
|
76
20
|
<li class="toc-entry toc-h6"><a href="#h6">h6</a></li>
|
77
21
|
</ul>
|
@@ -80,35 +24,34 @@ class TestVariousTocHtml < Minitest::Test
|
|
80
24
|
</li>
|
81
25
|
</ul>
|
82
26
|
HTML
|
83
|
-
actual = doc.css('ul.section-nav').to_s
|
84
27
|
|
85
|
-
assert_equal(expected,
|
28
|
+
assert_equal(expected, parser.build_toc)
|
86
29
|
end
|
87
30
|
|
88
31
|
def test_nested_toc_with_min_and_max
|
89
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
90
|
-
|
91
|
-
expected = <<~HTML
|
32
|
+
parser = Jekyll::TableOfContents::Parser.new(TEST_HTML, 'min_level' => 2, 'max_level' => 5)
|
33
|
+
expected = <<~HTML.chomp
|
92
34
|
<ul class="section-nav">
|
93
35
|
<li class="toc-entry toc-h3"><a href="#h3">h3</a></li>
|
94
36
|
</ul>
|
95
37
|
HTML
|
96
|
-
actual = doc.css('ul.section-nav').to_s
|
97
38
|
|
98
|
-
assert_equal(expected,
|
39
|
+
assert_equal(expected, parser.build_toc)
|
99
40
|
end
|
100
41
|
|
101
42
|
def test_complex_nested_toc
|
102
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
103
|
-
|
104
|
-
|
43
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
44
|
+
<h1>h1</h1>
|
45
|
+
<h3>h3</h3>
|
46
|
+
<h2>h2</h2>
|
47
|
+
<h6>h6</h6>
|
48
|
+
HTML
|
49
|
+
expected = <<~HTML.chomp
|
105
50
|
<ul class="section-nav">
|
106
|
-
<li class="toc-entry toc-h1">
|
107
|
-
<a href="#h1">h1</a>
|
51
|
+
<li class="toc-entry toc-h1"><a href="#h1">h1</a>
|
108
52
|
<ul>
|
109
53
|
<li class="toc-entry toc-h3"><a href="#h3">h3</a></li>
|
110
|
-
<li class="toc-entry toc-h2">
|
111
|
-
<a href="#h2">h2</a>
|
54
|
+
<li class="toc-entry toc-h2"><a href="#h2">h2</a>
|
112
55
|
<ul>
|
113
56
|
<li class="toc-entry toc-h6"><a href="#h6">h6</a></li>
|
114
57
|
</ul>
|
@@ -117,15 +60,20 @@ class TestVariousTocHtml < Minitest::Test
|
|
117
60
|
</li>
|
118
61
|
</ul>
|
119
62
|
HTML
|
120
|
-
actual = doc.css('ul.section-nav').to_s
|
121
63
|
|
122
|
-
assert_equal(expected,
|
64
|
+
assert_equal(expected, parser.build_toc)
|
123
65
|
end
|
124
66
|
|
125
67
|
def test_decremental_headings1
|
126
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
127
|
-
|
128
|
-
|
68
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
69
|
+
<h6>h6</h6>
|
70
|
+
<h5>h5</h5>
|
71
|
+
<h4>h4</h4>
|
72
|
+
<h3>h3</h3>
|
73
|
+
<h2>h2</h2>
|
74
|
+
<h1>h1</h1>
|
75
|
+
HTML
|
76
|
+
expected = <<~HTML.chomp
|
129
77
|
<ul class="section-nav">
|
130
78
|
<li class="toc-entry toc-h6"><a href="#h6">h6</a></li>
|
131
79
|
<li class="toc-entry toc-h5"><a href="#h5">h5</a></li>
|
@@ -135,25 +83,26 @@ class TestVariousTocHtml < Minitest::Test
|
|
135
83
|
<li class="toc-entry toc-h1"><a href="#h1">h1</a></li>
|
136
84
|
</ul>
|
137
85
|
HTML
|
138
|
-
actual = doc.css('ul.section-nav').to_s
|
139
86
|
|
140
|
-
assert_equal(expected,
|
87
|
+
assert_equal(expected, parser.build_toc)
|
141
88
|
end
|
142
89
|
|
143
90
|
def test_decremental_headings2
|
144
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
145
|
-
|
146
|
-
|
91
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
92
|
+
<h1>h1</h1>
|
93
|
+
<h3>h3</h3>
|
94
|
+
<h2>h2</h2>
|
95
|
+
<h4>h4</h4>
|
96
|
+
<h5>h5</h5>
|
97
|
+
HTML
|
98
|
+
expected = <<~HTML.chomp
|
147
99
|
<ul class="section-nav">
|
148
|
-
<li class="toc-entry toc-h1">
|
149
|
-
<a href="#h1">h1</a>
|
100
|
+
<li class="toc-entry toc-h1"><a href="#h1">h1</a>
|
150
101
|
<ul>
|
151
102
|
<li class="toc-entry toc-h3"><a href="#h3">h3</a></li>
|
152
|
-
<li class="toc-entry toc-h2">
|
153
|
-
<a href="#h2">h2</a>
|
103
|
+
<li class="toc-entry toc-h2"><a href="#h2">h2</a>
|
154
104
|
<ul>
|
155
|
-
<li class="toc-entry toc-h4">
|
156
|
-
<a href="#h4">h4</a>
|
105
|
+
<li class="toc-entry toc-h4"><a href="#h4">h4</a>
|
157
106
|
<ul>
|
158
107
|
<li class="toc-entry toc-h5"><a href="#h5">h5</a></li>
|
159
108
|
</ul>
|
@@ -165,22 +114,27 @@ class TestVariousTocHtml < Minitest::Test
|
|
165
114
|
</ul>
|
166
115
|
HTML
|
167
116
|
|
168
|
-
assert_equal(expected,
|
117
|
+
assert_equal(expected, parser.build_toc)
|
169
118
|
end
|
170
119
|
|
171
120
|
def test_no_toc
|
172
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
173
|
-
|
174
|
-
|
121
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
122
|
+
<h1>h1</h1>
|
123
|
+
<h1 class="no_toc">no_toc h1</h1>
|
124
|
+
<h2>h2</h2>
|
125
|
+
<h2 class="no_toc">no_toc h2</h2>
|
126
|
+
<h3>h3</h3>
|
127
|
+
<h3 class="no_toc">no_toc h3</h3>
|
128
|
+
<h4>h4</h4>
|
129
|
+
<h4 class="no_toc">no_toc h4</h4>
|
130
|
+
HTML
|
131
|
+
expected = <<~HTML.chomp
|
175
132
|
<ul class="section-nav">
|
176
|
-
<li class="toc-entry toc-h1">
|
177
|
-
<a href="#h1">h1</a>
|
133
|
+
<li class="toc-entry toc-h1"><a href="#h1">h1</a>
|
178
134
|
<ul>
|
179
|
-
<li class="toc-entry toc-h2">
|
180
|
-
<a href="#h2">h2</a>
|
135
|
+
<li class="toc-entry toc-h2"><a href="#h2">h2</a>
|
181
136
|
<ul>
|
182
|
-
<li class="toc-entry toc-h3">
|
183
|
-
<a href="#h3">h3</a>
|
137
|
+
<li class="toc-entry toc-h3"><a href="#h3">h3</a>
|
184
138
|
<ul>
|
185
139
|
<li class="toc-entry toc-h4"><a href="#h4">h4</a></li>
|
186
140
|
</ul>
|
@@ -191,21 +145,21 @@ class TestVariousTocHtml < Minitest::Test
|
|
191
145
|
</li>
|
192
146
|
</ul>
|
193
147
|
HTML
|
194
|
-
actual = doc.css('ul.section-nav').to_s
|
195
148
|
|
196
|
-
assert_equal(expected,
|
149
|
+
assert_equal(expected, parser.build_toc)
|
197
150
|
end
|
198
151
|
|
199
152
|
def test_japanese_toc
|
200
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
201
|
-
|
202
|
-
|
153
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
154
|
+
<h1>あ</h1>
|
155
|
+
<h2>い</h2>
|
156
|
+
<h3>う</h3>
|
157
|
+
HTML
|
158
|
+
expected = <<~HTML.chomp
|
203
159
|
<ul class="section-nav">
|
204
|
-
<li class="toc-entry toc-h1">
|
205
|
-
<a href="#%E3%81%82">あ</a>
|
160
|
+
<li class="toc-entry toc-h1"><a href="#%E3%81%82">あ</a>
|
206
161
|
<ul>
|
207
|
-
<li class="toc-entry toc-h2">
|
208
|
-
<a href="#%E3%81%84">い</a>
|
162
|
+
<li class="toc-entry toc-h2"><a href="#%E3%81%84">い</a>
|
209
163
|
<ul>
|
210
164
|
<li class="toc-entry toc-h3"><a href="#%E3%81%86">う</a></li>
|
211
165
|
</ul>
|
@@ -214,59 +168,61 @@ class TestVariousTocHtml < Minitest::Test
|
|
214
168
|
</li>
|
215
169
|
</ul>
|
216
170
|
HTML
|
217
|
-
actual = doc.css('ul.section-nav').to_s
|
218
171
|
|
219
|
-
assert_equal(expected,
|
172
|
+
assert_equal(expected, parser.build_toc)
|
173
|
+
html_with_anchors = parser.inject_anchors_into_html
|
174
|
+
assert_match(%r{<a class="anchor" href="#%E3%81%82" aria-hidden="true"><span.*span></a>あ}, html_with_anchors)
|
175
|
+
assert_match(%r{<a class="anchor" href="#%E3%81%84" aria-hidden="true"><span.*span></a>い}, html_with_anchors)
|
176
|
+
assert_match(%r{<a class="anchor" href="#%E3%81%86" aria-hidden="true"><span.*span></a>う}, html_with_anchors)
|
220
177
|
end
|
221
178
|
|
179
|
+
# ref. https://github.com/toshimaru/jekyll-toc/issues/45
|
222
180
|
def test_angle_bracket
|
223
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
224
|
-
|
225
|
-
|
181
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
182
|
+
<h1>h1</h1>
|
183
|
+
<h1><base href></h1>
|
184
|
+
<h1>& < ></h1>
|
185
|
+
HTML
|
186
|
+
expected = <<~HTML.chomp
|
226
187
|
<ul class="section-nav">
|
227
188
|
<li class="toc-entry toc-h1"><a href="#h1">h1</a></li>
|
228
189
|
<li class="toc-entry toc-h1"><a href="#base-href"><base href></a></li>
|
229
190
|
<li class="toc-entry toc-h1"><a href="#--">& < ></a></li>
|
230
191
|
</ul>
|
231
192
|
HTML
|
232
|
-
actual = doc.css('ul.section-nav').to_s
|
233
193
|
|
234
|
-
assert_equal(expected,
|
194
|
+
assert_equal(expected, parser.build_toc)
|
235
195
|
end
|
236
196
|
|
237
197
|
def test_tags_inside_heading
|
238
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
239
|
-
|
240
|
-
|
198
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
199
|
+
<h2><strong>h2</strong></h2>
|
200
|
+
<h2><em>h2</em></h2>
|
201
|
+
HTML
|
202
|
+
expected = <<~HTML.chomp
|
241
203
|
<ul class="section-nav">
|
242
204
|
<li class="toc-entry toc-h2"><a href="#h2">h2</a></li>
|
243
205
|
<li class="toc-entry toc-h2"><a href="#h2-1">h2</a></li>
|
244
206
|
</ul>
|
245
207
|
HTML
|
246
|
-
actual = doc.css('ul.section-nav').to_s
|
247
208
|
|
248
|
-
assert_equal(expected,
|
209
|
+
assert_equal(expected, parser.build_toc)
|
249
210
|
end
|
250
211
|
|
251
|
-
TEST_HTML_IGNORE = <<~HTML
|
252
|
-
<h1>h1</h1>
|
253
|
-
<div class="no_toc_section">
|
254
|
-
<h2>h2</h2>
|
255
|
-
</div>
|
256
|
-
<h3>h3</h3>
|
257
|
-
<h6>h6</h6>
|
258
|
-
HTML
|
259
|
-
|
260
212
|
def test_nested_toc_with_no_toc_section_class
|
261
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
262
|
-
|
263
|
-
|
213
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
214
|
+
<h1>h1</h1>
|
215
|
+
<div class="no_toc_section">
|
216
|
+
<h2>h2</h2>
|
217
|
+
</div>
|
218
|
+
<h3>h3</h3>
|
219
|
+
<h6>h6</h6>
|
220
|
+
HTML
|
221
|
+
expected = <<~HTML.chomp
|
264
222
|
<ul class="section-nav">
|
265
|
-
<li class="toc-entry toc-h1">
|
266
|
-
<a href="#h1">h1</a>
|
223
|
+
<li class="toc-entry toc-h1"><a href="#h1">h1</a>
|
267
224
|
<ul>
|
268
|
-
<li class="toc-entry toc-h3">
|
269
|
-
<a href="#h3">h3</a>
|
225
|
+
<li class="toc-entry toc-h3"><a href="#h3">h3</a>
|
270
226
|
<ul>
|
271
227
|
<li class="toc-entry toc-h6"><a href="#h6">h6</a></li>
|
272
228
|
</ul>
|
@@ -275,8 +231,7 @@ class TestVariousTocHtml < Minitest::Test
|
|
275
231
|
</li>
|
276
232
|
</ul>
|
277
233
|
HTML
|
278
|
-
|
279
|
-
assert_equal(expected, actual)
|
234
|
+
assert_equal(expected, parser.build_toc)
|
280
235
|
|
281
236
|
html = parser.inject_anchors_into_html
|
282
237
|
assert_match(%r{<h1>.+</h1>}m, html)
|
@@ -285,29 +240,24 @@ class TestVariousTocHtml < Minitest::Test
|
|
285
240
|
assert_includes(html, '<h2>h2</h2>')
|
286
241
|
end
|
287
242
|
|
288
|
-
TEST_HTML_IGNORE_2 = <<~HTML
|
289
|
-
<h1>h1</h1>
|
290
|
-
<div class="exclude">
|
291
|
-
<h2>h2</h2>
|
292
|
-
</div>
|
293
|
-
<h3>h3</h3>
|
294
|
-
<div class="exclude">
|
295
|
-
<h4>h4</h4>
|
296
|
-
<h5>h5</h5>
|
297
|
-
</div>
|
298
|
-
<h6>h6</h6>
|
299
|
-
HTML
|
300
|
-
|
301
243
|
def test_nested_toc_with_no_toc_section_class_option
|
302
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
303
|
-
|
304
|
-
|
244
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML, 'no_toc_section_class' => 'exclude')
|
245
|
+
<h1>h1</h1>
|
246
|
+
<div class="exclude">
|
247
|
+
<h2>h2</h2>
|
248
|
+
</div>
|
249
|
+
<h3>h3</h3>
|
250
|
+
<div class="exclude">
|
251
|
+
<h4>h4</h4>
|
252
|
+
<h5>h5</h5>
|
253
|
+
</div>
|
254
|
+
<h6>h6</h6>
|
255
|
+
HTML
|
256
|
+
expected = <<~HTML.chomp
|
305
257
|
<ul class="section-nav">
|
306
|
-
<li class="toc-entry toc-h1">
|
307
|
-
<a href="#h1">h1</a>
|
258
|
+
<li class="toc-entry toc-h1"><a href="#h1">h1</a>
|
308
259
|
<ul>
|
309
|
-
<li class="toc-entry toc-h3">
|
310
|
-
<a href="#h3">h3</a>
|
260
|
+
<li class="toc-entry toc-h3"><a href="#h3">h3</a>
|
311
261
|
<ul>
|
312
262
|
<li class="toc-entry toc-h6"><a href="#h6">h6</a></li>
|
313
263
|
</ul>
|
@@ -316,8 +266,7 @@ class TestVariousTocHtml < Minitest::Test
|
|
316
266
|
</li>
|
317
267
|
</ul>
|
318
268
|
HTML
|
319
|
-
|
320
|
-
assert_equal(expected, actual)
|
269
|
+
assert_equal(expected, parser.build_toc)
|
321
270
|
|
322
271
|
html = parser.inject_anchors_into_html
|
323
272
|
assert_match(%r{<h1>.+</h1>}m, html)
|
@@ -328,29 +277,24 @@ class TestVariousTocHtml < Minitest::Test
|
|
328
277
|
assert_includes(html, '<h5>h5</h5>')
|
329
278
|
end
|
330
279
|
|
331
|
-
TEST_HTML_IGNORE_3 = <<~HTML
|
332
|
-
<h1>h1</h1>
|
333
|
-
<div class="no_toc_section">
|
334
|
-
<h2>h2</h2>
|
335
|
-
</div>
|
336
|
-
<h3>h3</h3>
|
337
|
-
<div class="exclude">
|
338
|
-
<h4>h4</h4>
|
339
|
-
<h5>h5</h5>
|
340
|
-
</div>
|
341
|
-
<h6>h6</h6>
|
342
|
-
HTML
|
343
|
-
|
344
280
|
def test_multiple_no_toc_section_classes
|
345
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
346
|
-
|
347
|
-
|
281
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML, 'no_toc_section_class' => ['no_toc_section', 'exclude'])
|
282
|
+
<h1>h1</h1>
|
283
|
+
<div class="no_toc_section">
|
284
|
+
<h2>h2</h2>
|
285
|
+
</div>
|
286
|
+
<h3>h3</h3>
|
287
|
+
<div class="exclude">
|
288
|
+
<h4>h4</h4>
|
289
|
+
<h5>h5</h5>
|
290
|
+
</div>
|
291
|
+
<h6>h6</h6>
|
292
|
+
HTML
|
293
|
+
expected = <<~HTML.chomp
|
348
294
|
<ul class="section-nav">
|
349
|
-
<li class="toc-entry toc-h1">
|
350
|
-
<a href="#h1">h1</a>
|
295
|
+
<li class="toc-entry toc-h1"><a href="#h1">h1</a>
|
351
296
|
<ul>
|
352
|
-
<li class="toc-entry toc-h3">
|
353
|
-
<a href="#h3">h3</a>
|
297
|
+
<li class="toc-entry toc-h3"><a href="#h3">h3</a>
|
354
298
|
<ul>
|
355
299
|
<li class="toc-entry toc-h6"><a href="#h6">h6</a></li>
|
356
300
|
</ul>
|
@@ -359,8 +303,7 @@ class TestVariousTocHtml < Minitest::Test
|
|
359
303
|
</li>
|
360
304
|
</ul>
|
361
305
|
HTML
|
362
|
-
|
363
|
-
assert_equal(expected, actual)
|
306
|
+
assert_equal(expected, parser.build_toc)
|
364
307
|
|
365
308
|
html = parser.inject_anchors_into_html
|
366
309
|
assert_match(%r{<h1>.+</h1>}m, html)
|
@@ -371,24 +314,20 @@ class TestVariousTocHtml < Minitest::Test
|
|
371
314
|
assert_includes(html, '<h5>h5</h5>')
|
372
315
|
end
|
373
316
|
|
374
|
-
TEST_EXPLICIT_ID = <<~HTML
|
375
|
-
<h1>h1</h1>
|
376
|
-
<h1 id="second">h2</h1>
|
377
|
-
<h1 id="third">h3</h1>
|
378
|
-
HTML
|
379
|
-
|
380
317
|
def test_toc_with_explicit_id
|
381
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
382
|
-
|
383
|
-
|
318
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
319
|
+
<h1>h1</h1>
|
320
|
+
<h1 id="second">h2</h1>
|
321
|
+
<h1 id="third">h3</h1>
|
322
|
+
HTML
|
323
|
+
expected = <<~HTML.chomp
|
384
324
|
<ul class="section-nav">
|
385
325
|
<li class="toc-entry toc-h1"><a href="#h1">h1</a></li>
|
386
326
|
<li class="toc-entry toc-h1"><a href="#second">h2</a></li>
|
387
327
|
<li class="toc-entry toc-h1"><a href="#third">h3</a></li>
|
388
328
|
</ul>
|
389
329
|
HTML
|
390
|
-
|
391
|
-
assert_equal(expected, actual)
|
330
|
+
assert_equal(expected, parser.build_toc)
|
392
331
|
|
393
332
|
html = parser.inject_anchors_into_html
|
394
333
|
assert_includes(html, %(<a class="anchor" href="#h1" aria-hidden="true">))
|
@@ -396,39 +335,33 @@ class TestVariousTocHtml < Minitest::Test
|
|
396
335
|
assert_includes(html, %(<a class="anchor" href="#third" aria-hidden="true">))
|
397
336
|
end
|
398
337
|
|
399
|
-
TEST_UNIQ_ID = <<~HTML
|
400
|
-
<h1>h1</h1>
|
401
|
-
<h1>h1</h1>
|
402
|
-
<h1>h1</h1>
|
403
|
-
HTML
|
404
|
-
|
405
338
|
def test_anchor_is_uniq
|
406
|
-
parser = Jekyll::TableOfContents::Parser.new(
|
407
|
-
|
408
|
-
|
339
|
+
parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
|
340
|
+
<h1>h1</h1>
|
341
|
+
<h1>h1</h1>
|
342
|
+
<h1>h1</h1>
|
343
|
+
HTML
|
344
|
+
expected = <<~HTML.chomp
|
409
345
|
<ul class="section-nav">
|
410
346
|
<li class="toc-entry toc-h1"><a href="#h1">h1</a></li>
|
411
347
|
<li class="toc-entry toc-h1"><a href="#h1-1">h1</a></li>
|
412
348
|
<li class="toc-entry toc-h1"><a href="#h1-2">h1</a></li>
|
413
349
|
</ul>
|
414
350
|
HTML
|
415
|
-
|
416
|
-
assert_equal(expected,
|
351
|
+
|
352
|
+
assert_equal(expected, parser.build_toc)
|
417
353
|
end
|
418
354
|
|
419
355
|
def test_custom_css_classes
|
420
356
|
parser = Jekyll::TableOfContents::Parser.new(
|
421
|
-
|
357
|
+
TEST_HTML,
|
422
358
|
'item_class' => 'custom-item', 'list_class' => 'custom-list', 'sublist_class' => 'custom-sublist', 'item_prefix' => 'custom-prefix-'
|
423
359
|
)
|
424
|
-
|
425
|
-
expected = <<~HTML
|
360
|
+
expected = <<~HTML.chomp
|
426
361
|
<ul class="custom-list">
|
427
|
-
<li class="custom-item custom-prefix-h1">
|
428
|
-
<a href="#h1">h1</a>
|
362
|
+
<li class="custom-item custom-prefix-h1"><a href="#h1">h1</a>
|
429
363
|
<ul class="custom-sublist">
|
430
|
-
<li class="custom-item custom-prefix-h3">
|
431
|
-
<a href="#h3">h3</a>
|
364
|
+
<li class="custom-item custom-prefix-h3"><a href="#h3">h3</a>
|
432
365
|
<ul class="custom-sublist">
|
433
366
|
<li class="custom-item custom-prefix-h6"><a href="#h6">h6</a></li>
|
434
367
|
</ul>
|
@@ -438,6 +371,6 @@ class TestVariousTocHtml < Minitest::Test
|
|
438
371
|
</ul>
|
439
372
|
HTML
|
440
373
|
|
441
|
-
assert_equal(expected,
|
374
|
+
assert_equal(expected, parser.build_toc)
|
442
375
|
end
|
443
376
|
end
|