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.
@@ -2,6 +2,13 @@
2
2
 
3
3
  source "https://rubygems.org"
4
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"
5
12
  gem "jekyll", "3.8"
6
13
 
7
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", "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: "../"
@@ -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 = JekyllToc::VERSION
9
+ spec.version = Jekyll::TableOfContents::VERSION
8
10
  spec.summary = 'Jekyll Table of Contents plugin'
9
- spec.description = 'A liquid filter plugin for Jekyll which generates a table of contents.'
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|features)/})
17
+ spec.test_files = spec.files.grep(%r{^(test|spec)/})
16
18
  spec.require_paths = ['lib']
17
19
 
18
- spec.required_ruby_version = '>= 2.3'
19
-
20
- spec.add_runtime_dependency 'nokogiri', '~> 1.9'
20
+ spec.required_ruby_version = '>= 2.4'
21
21
 
22
- spec.add_development_dependency 'appraisal'
23
- spec.add_development_dependency 'jekyll', '>= 3.5'
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
- attr_accessor :toc_levels, :no_toc_class, :no_toc_section_class,
8
- :list_class, :sublist_class, :item_class, :item_prefix
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
- PUNCTUATION_REGEXP = /[^\p{Word}\- ]/u
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
- %(<ul class="#{@configuration.list_class}">\n#{build_toc_list(@entries)}</ul>)
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<ul#{ul_attributes}>\n#{build_toc_list(nest_entries)}</ul>\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? Array
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
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module TableOfContents
5
+ VERSION = '0.15.0'
6
+ end
7
+ end
@@ -18,6 +18,6 @@ class TestInjectAnchorsFilter < Minitest::Test
18
18
  def test_does_not_inject_toc
19
19
  html = @parser.inject_anchors_into_html
20
20
 
21
- assert_nil(/<ul class="section-nav">/ =~ html)
21
+ refute_includes(html, %(<ul class="section-nav">))
22
22
  end
23
23
  end
@@ -2,9 +2,9 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
- class TestOptionError < Minitest::Test
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
- doc = Nokogiri::HTML(parser.toc)
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
- doc = Nokogiri::HTML(parser.toc)
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
- doc = Nokogiri::HTML(parser.toc)
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
- doc = Nokogiri::HTML(parser.toc)
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
- assert_match(/<ul class="section-nav">/, html)
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
- assert_nil(%r{<h1>Simple H1</h1>} =~ html)
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
- # ref. https://github.com/toshimaru/jekyll-toc/issues/45
7
- ANGLE_BRACKET_HTML = <<~HTML
8
- <h1>h1</h1>
9
- <h1>&lt;base href&gt;</h1>
10
- <h1>&amp; &lt; &gt;</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(TEST_HTML_1)
67
- doc = Nokogiri::HTML(parser.toc)
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, actual)
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(TEST_HTML_1, 'min_level' => 2, 'max_level' => 5)
90
- doc = Nokogiri::HTML(parser.toc)
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, actual)
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(TEST_HTML_2)
103
- doc = Nokogiri::HTML(parser.toc)
104
- expected = <<~HTML
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, actual)
64
+ assert_equal(expected, parser.build_toc)
123
65
  end
124
66
 
125
67
  def test_decremental_headings1
126
- parser = Jekyll::TableOfContents::Parser.new(TEST_HTML_3)
127
- doc = Nokogiri::HTML(parser.toc)
128
- expected = <<~HTML
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, actual)
87
+ assert_equal(expected, parser.build_toc)
141
88
  end
142
89
 
143
90
  def test_decremental_headings2
144
- parser = Jekyll::TableOfContents::Parser.new(TEST_HTML_4)
145
- doc = Nokogiri::HTML(parser.toc)
146
- expected = <<~HTML
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, doc.css('ul.section-nav').to_s)
117
+ assert_equal(expected, parser.build_toc)
169
118
  end
170
119
 
171
120
  def test_no_toc
172
- parser = Jekyll::TableOfContents::Parser.new(NO_TOC_HTML)
173
- doc = Nokogiri::HTML(parser.toc)
174
- expected = <<~HTML
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, actual)
149
+ assert_equal(expected, parser.build_toc)
197
150
  end
198
151
 
199
152
  def test_japanese_toc
200
- parser = Jekyll::TableOfContents::Parser.new(JAPANESE_HEADINGS_HTML)
201
- doc = Nokogiri::HTML(parser.toc)
202
- expected = <<~HTML
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, actual)
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(ANGLE_BRACKET_HTML)
224
- doc = Nokogiri::HTML(parser.toc)
225
- expected = <<~HTML
181
+ parser = Jekyll::TableOfContents::Parser.new(<<~HTML)
182
+ <h1>h1</h1>
183
+ <h1>&lt;base href&gt;</h1>
184
+ <h1>&amp; &lt; &gt;</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">&lt;base href&gt;</a></li>
229
190
  <li class="toc-entry toc-h1"><a href="#--">&amp; &lt; &gt;</a></li>
230
191
  </ul>
231
192
  HTML
232
- actual = doc.css('ul.section-nav').to_s
233
193
 
234
- assert_equal(expected, actual)
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(TAGS_INSIDE_HEADINGS_HTML)
239
- doc = Nokogiri::HTML(parser.toc)
240
- expected = <<~HTML
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, actual)
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(TEST_HTML_IGNORE)
262
- doc = Nokogiri::HTML(parser.toc)
263
- expected = <<~HTML
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
- actual = doc.css('ul.section-nav').to_s
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(TEST_HTML_IGNORE_2, 'no_toc_section_class' => 'exclude')
303
- doc = Nokogiri::HTML(parser.toc)
304
- expected = <<~HTML
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
- actual = doc.css('ul.section-nav').to_s
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(TEST_HTML_IGNORE_3, 'no_toc_section_class' => ['no_toc_section', 'exclude'])
346
- doc = Nokogiri::HTML(parser.toc)
347
- expected = <<~HTML
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
- actual = doc.css('ul.section-nav').to_s
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(TEST_EXPLICIT_ID)
382
- doc = Nokogiri::HTML(parser.toc)
383
- expected = <<~HTML
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
- actual = doc.css('ul.section-nav').to_s
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(TEST_UNIQ_ID)
407
- doc = Nokogiri::HTML(parser.toc)
408
- expected = <<~HTML
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
- actual = doc.css('ul.section-nav').to_s
416
- assert_equal(expected, actual)
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
- TEST_HTML_1,
357
+ TEST_HTML,
422
358
  'item_class' => 'custom-item', 'list_class' => 'custom-list', 'sublist_class' => 'custom-sublist', 'item_prefix' => 'custom-prefix-'
423
359
  )
424
- doc = Nokogiri::HTML(parser.toc)
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, doc.css('ul.custom-list').to_s)
374
+ assert_equal(expected, parser.build_toc)
442
375
  end
443
376
  end