jekyll-toc 0.8.0.beta2 → 0.8.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b22b1a38ade3692df275b45f909d15c6c08c86a9
4
- data.tar.gz: 10c79cce93cbdfe9c1f563b89357aa4b22f5e95c
2
+ SHA256:
3
+ metadata.gz: ff793cf0c346ce007f527e7441cad059b4ee01d05cf5ff632c163c75031af6f7
4
+ data.tar.gz: 000f6cddbd70c9b906caed9182bbefca8ca2127afc9568cebd7fcb5ef636e9f1
5
5
  SHA512:
6
- metadata.gz: 4cf2f7ece01ba18e9c3df914974f395e1f9133da89380e73bf5cad9d82e20b2dcdd81b6f813854cc0dead5af0f79e72924f200b8cf5fc66bc48023b56859ecb5
7
- data.tar.gz: 2bf2aa4519199fd01957562b769f14fe22ff0586d5a44c61a8e33180716508b1274967ffe37766e7d1fb63ec47876b82cd1b36d2d64d7b46a69358315fd0c783
6
+ metadata.gz: 065f6561458207ea00a1512fc78499a77e753c807d9a8fa17b4a2a47b0c89e31eae4f8ff7f4a6a3cf69a85dcd5700dda0fd7e46d34395dd480fb390da6978cc9
7
+ data.tar.gz: 2e54f2d06c29eb9afcab58d5f960007e45c6955f42fdee6642ba18055dfd46016b42f7df70d9dffcbc7d763f71f969b00bc5c8342a292be2539b79145b7fb1c3
data/README.md CHANGED
@@ -5,17 +5,18 @@
5
5
  [![Code Climate](https://codeclimate.com/github/toshimaru/jekyll-toc/badges/gpa.svg)](https://codeclimate.com/github/toshimaru/jekyll-toc)
6
6
  [![Test Coverage](https://api.codeclimate.com/v1/badges/cd56b207f327603662a1/test_coverage)](https://codeclimate.com/github/toshimaru/jekyll-toc/test_coverage)
7
7
 
8
- # Table of Contents
8
+ ## Table of Contents
9
9
 
10
10
  - [Installation](#installation)
11
11
  - [Usage](#usage)
12
12
  - [Generated HTML](#generated-html)
13
13
  - [Customization](#customization)
14
14
  - [Skip TOC](#skip-toc)
15
+ - [Skip TOC Section](#skip-toc-section)
15
16
  - [TOC levels](#toc-levels)
16
17
  - [CSS Styling](#css-styling)
17
18
 
18
- # Installation
19
+ ## Installation
19
20
 
20
21
  Add jekyll-toc plugin in your site's `Gemfile`, and run `bundle install`.
21
22
 
@@ -40,14 +41,14 @@ toc: true
40
41
  ---
41
42
  ```
42
43
 
43
- # Usage
44
+ ## Usage
44
45
 
45
46
  There are three Liquid filters, which can be applied to HTML content,
46
47
  e.g. the Liquid variable `content` available in Jekyll's templates.
47
48
 
48
- ## 1. Basic Usage
49
+ ### 1. Basic Usage
49
50
 
50
- ### `toc` filter
51
+ #### `toc` filter
51
52
 
52
53
  Add the `toc` filter to your site's `{{ content }}` (e.g. `_layouts/post.html`).
53
54
 
@@ -57,17 +58,17 @@ Add the `toc` filter to your site's `{{ content }}` (e.g. `_layouts/post.html`).
57
58
 
58
59
  This filter places the TOC directly above the content.
59
60
 
60
- ## 2. Advanced Usage
61
+ ### 2. Advanced Usage
61
62
 
62
63
  If you'd like separated TOC and content, you can use `toc_only` and `inject_anchors` filters.
63
64
 
64
- ### `toc_only` filter
65
+ #### `toc_only` filter
65
66
 
66
67
  Generates the TOC itself as described [below](#generated-table-of-contents-html).
67
68
  Mostly useful in cases where the TOC should _not_ be placed immediately
68
69
  above the content but at some other place of the page, i.e. an aside.
69
70
 
70
- ### `inject_anchors` filter
71
+ #### `inject_anchors` filter
71
72
 
72
73
  Injects HTML anchors into the content without actually outputing the
73
74
  TOC itself. They are of the form:
@@ -81,7 +82,7 @@ TOC itself. They are of the form:
81
82
  This is only useful when the TOC itself should be placed at some other
82
83
  location with the `toc_only` filter.
83
84
 
84
- ## Generated HTML
85
+ ### Generated HTML
85
86
 
86
87
  ![screenshot](https://user-images.githubusercontent.com/803398/28401295-0dcfb7ca-6d54-11e7-892b-2f2e6ca755a7.png)
87
88
 
@@ -109,42 +110,30 @@ jekyll-toc generates an unordered list. The HTML output is as follows.
109
110
  </ul>
110
111
  ```
111
112
 
112
- ## Customization
113
+ ### Customization
113
114
 
114
- ### Skip TOC
115
+ #### Skip TOC
115
116
 
116
- The heding is ignored in the toc when you add `no_toc` to the class.
117
+ The heading is ignored in the toc when you add `no_toc` to the class.
117
118
 
118
119
  ```html
119
120
  <h1>h1</h1>
120
- <h1 class="no_toc">This heding is ignored in the toc</h1>
121
+ <h1 class="no_toc">This heading is ignored in the toc</h1>
121
122
  <h2>h2</h2>
122
123
  ```
123
124
 
124
- ### TOC levels
125
-
126
- The toc levels can be configured on `_config.yml`.
127
-
128
- ```yml
129
- toc:
130
- min_level: 2 # default: 1
131
- max_level: 5 # default: 6
132
- ```
133
-
134
- The default level range is `<h1>` to `<h6>`.
135
-
136
- ### Ignore within
125
+ #### Skip TOC Section
137
126
 
138
127
  It can be configured to ignore elements within a selector:
139
128
 
140
129
  ```yml
141
130
  toc:
142
- ignore_within: .exclude
131
+ no_toc_section_class: no_toc_within # default: no_toc_section
143
132
  ```
144
133
 
145
134
  ```html
146
135
  <h1>h1</h1>
147
- <div class="exclude">
136
+ <div class="no_toc_within">
148
137
  <h2>h2</h2>
149
138
  <h3>h3</h3>
150
139
  </div>
@@ -153,21 +142,33 @@ toc:
153
142
 
154
143
  Which would result in only the `<h1>` & `<h4>` within the example being included in the TOC.
155
144
 
156
- ### CSS Styling
145
+ #### TOC levels
146
+
147
+ The toc levels can be configured on `_config.yml`.
148
+
149
+ ```yml
150
+ toc:
151
+ min_level: 2 # default: 1
152
+ max_level: 5 # default: 6
153
+ ```
154
+
155
+ The default level range is `<h1>` to `<h6>`.
156
+
157
+ #### CSS Styling
157
158
 
158
159
  The toc can be modified with CSS. The sample CSS is the following.
159
160
 
160
161
  ```css
161
162
  .section-nav {
162
- background-color: #FFF;
163
+ background-color: #fff;
163
164
  margin: 5px 0;
164
165
  padding: 10px 30px;
165
- border: 1px solid #E8E8E8;
166
+ border: 1px solid #e8e8e8;
166
167
  border-radius: 3px;
167
168
  }
168
169
  ```
169
170
 
170
- ![screen shot](https://user-images.githubusercontent.com/803398/28401455-0ba60868-6d55-11e7-8159-0ae7591aee66.png)
171
+ ![screenshot](https://user-images.githubusercontent.com/803398/28401455-0ba60868-6d55-11e7-8159-0ae7591aee66.png)
171
172
 
172
173
  Each TOC `li` entry has two CSS classes for further styling.
173
174
  The general `toc-entry` is applied to all `li` elements in the `ul.section-nav`.
@@ -4,9 +4,11 @@ module Jekyll
4
4
  module TableOfContents
5
5
  # Parse html contents and generate table of contents
6
6
  class Parser
7
+ NO_TOC_CLASS_NAME = 'no_toc'
7
8
  PUNCTUATION_REGEXP = /[^\p{Word}\- ]/u
8
9
 
9
10
  DEFAULT_CONFIG = {
11
+ 'no_toc_section_class' => 'no_toc_section',
10
12
  'min_level' => 1,
11
13
  'max_level' => 6
12
14
  }.freeze
@@ -14,11 +16,15 @@ module Jekyll
14
16
  def initialize(html, options = {})
15
17
  @doc = Nokogiri::HTML::DocumentFragment.parse(html)
16
18
  options = generate_option_hash(options)
17
- @toc_levels = options["min_level"]..options["max_level"]
18
- @ignore_within = options["ignore_within"]
19
+ @toc_levels = options['min_level']..options['max_level']
20
+ @no_toc_section_class = options['no_toc_section_class']
19
21
  @entries = parse_content
20
22
  end
21
23
 
24
+ def toc
25
+ build_toc + inject_anchors_into_html
26
+ end
27
+
22
28
  def build_toc
23
29
  %(<ul class="section-nav">\n#{build_toc_list(@entries)}</ul>)
24
30
  end
@@ -31,38 +37,26 @@ module Jekyll
31
37
  @doc.inner_html
32
38
  end
33
39
 
34
- def toc
35
- build_toc + inject_anchors_into_html
36
- end
37
-
38
40
  private
39
41
 
40
42
  # parse logic is from html-pipeline toc_filter
41
43
  # https://github.com/jch/html-pipeline/blob/v1.1.0/lib/html/pipeline/toc_filter.rb
42
44
  def parse_content
43
- entries = []
44
45
  headers = Hash.new(0)
45
46
 
46
- if @ignore_within
47
- @doc.css(@ignore_within).remove
48
- end
49
-
50
- # TODO: Use kramdown auto ids
51
- @doc.css(toc_headings).reject { |n| n.classes.include?('no_toc') }.each do |node|
47
+ (@doc.css(toc_headings) - @doc.css(toc_headings_in_no_toc_section))
48
+ .reject { |n| n.classes.include?(NO_TOC_CLASS_NAME) }
49
+ .inject([]) do |entries, node|
52
50
  text = node.text
53
- id = if node.attribute('id')
54
- node.attribute('id')
55
- else
56
- text
57
- .downcase
58
- .gsub(PUNCTUATION_REGEXP, '') # remove punctuation
59
- .tr(' ', '-') # replace spaces with dash
60
- end
51
+ id = node.attribute('id') || text
52
+ .downcase
53
+ .gsub(PUNCTUATION_REGEXP, '') # remove punctuation
54
+ .tr(' ', '-') # replace spaces with dash
61
55
 
62
56
  uniq = headers[id] > 0 ? "-#{headers[id]}" : ''
63
57
  headers[id] += 1
64
58
  header_content = node.children.first
65
- next unless header_content
59
+ next entries unless header_content
66
60
 
67
61
  entries << {
68
62
  id: id,
@@ -73,8 +67,6 @@ module Jekyll
73
67
  h_num: node.name.delete('h').to_i
74
68
  }
75
69
  end
76
-
77
- entries
78
70
  end
79
71
 
80
72
  # Returns the list items for entries
@@ -117,6 +109,7 @@ module Jekyll
117
109
  def get_nest_entries(entries, min_h_num)
118
110
  entries.inject([]) do |nest_entries, entry|
119
111
  break nest_entries if entry[:h_num] == min_h_num
112
+
120
113
  nest_entries << entry
121
114
  end
122
115
  end
@@ -125,6 +118,10 @@ module Jekyll
125
118
  @toc_levels.map { |level| "h#{level}" }.join(',')
126
119
  end
127
120
 
121
+ def toc_headings_in_no_toc_section
122
+ @toc_levels.map { |level| ".#{@no_toc_section_class} h#{level}" }.join(',')
123
+ end
124
+
128
125
  def generate_option_hash(options)
129
126
  DEFAULT_CONFIG.merge(options)
130
127
  rescue TypeError
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module JekyllToc
2
- VERSION = '0.8.0.beta2'.freeze
2
+ VERSION = '0.8.0.rc1'.freeze
3
3
  end
@@ -86,7 +86,7 @@ class TestVariousTocHtml < Minitest::Test
86
86
  end
87
87
 
88
88
  def test_nested_toc_with_min_and_max
89
- parser = Jekyll::TableOfContents::Parser.new(TEST_HTML_1, { "min_level" => 2, "max_level" => 5 })
89
+ parser = Jekyll::TableOfContents::Parser.new(TEST_HTML_1, { 'min_level' => 2, 'max_level' => 5 })
90
90
  doc = Nokogiri::HTML(parser.toc)
91
91
  expected = <<-HTML
92
92
  <ul class="section-nav">
@@ -248,7 +248,44 @@ class TestVariousTocHtml < Minitest::Test
248
248
  assert_equal(expected, actual)
249
249
  end
250
250
 
251
- TEST_HTML_IGNORE = <<-HTML
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
+ 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
264
+ <ul class="section-nav">
265
+ <li class="toc-entry toc-h1">
266
+ <a href="#h1">h1</a>
267
+ <ul>
268
+ <li class="toc-entry toc-h3">
269
+ <a href="#h3">h3</a>
270
+ <ul>
271
+ <li class="toc-entry toc-h6"><a href="#h6">h6</a></li>
272
+ </ul>
273
+ </li>
274
+ </ul>
275
+ </li>
276
+ </ul>
277
+ HTML
278
+ actual = doc.css('ul.section-nav').to_s
279
+ assert_equal(expected, actual)
280
+
281
+ html = parser.inject_anchors_into_html
282
+ assert_match(%r{<h1>.+</h1>}m, html)
283
+ assert_match(%r{<h3>.+</h3>}m, html)
284
+ assert_match(%r{<h6>.+</h6>}m, html)
285
+ assert_includes(html, '<h2>h2</h2>')
286
+ end
287
+
288
+ TEST_HTML_IGNORE_2 = <<-HTML
252
289
  <h1>h1</h1>
253
290
  <div class="exclude">
254
291
  <h2>h2</h2>
@@ -256,13 +293,13 @@ TEST_HTML_IGNORE = <<-HTML
256
293
  <h3>h3</h3>
257
294
  <div class="exclude">
258
295
  <h4>h4</h4>
259
- <h4>h5</h4>
296
+ <h5>h5</h5>
260
297
  </div>
261
298
  <h6>h6</h6>
262
- HTML
299
+ HTML
263
300
 
264
- def test_nested_toc_with_ignore_within_option
265
- parser = Jekyll::TableOfContents::Parser.new(TEST_HTML_IGNORE, { "ignore_within" => '.exclude'})
301
+ 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' })
266
303
  doc = Nokogiri::HTML(parser.toc)
267
304
  expected = <<-HTML
268
305
  <ul class="section-nav">
@@ -280,8 +317,15 @@ HTML
280
317
  </ul>
281
318
  HTML
282
319
  actual = doc.css('ul.section-nav').to_s
283
-
284
320
  assert_equal(expected, actual)
321
+
322
+ html = parser.inject_anchors_into_html
323
+ assert_match(%r{<h1>.+</h1>}m, html)
324
+ assert_match(%r{<h3>.+</h3>}m, html)
325
+ assert_match(%r{<h6>.+</h6>}m, html)
326
+ assert_includes(html, '<h2>h2</h2>')
327
+ assert_includes(html, '<h4>h4</h4>')
328
+ assert_includes(html, '<h5>h5</h5>')
285
329
  end
286
330
 
287
331
  TEST_EXPLICIT_ID = <<-HTML
@@ -291,7 +335,7 @@ HTML
291
335
  HTML
292
336
 
293
337
  def test_toc_with_explicit_id
294
- parser = Jekyll::TableOfContents::Parser.new(TEST_EXPLICIT_ID, { "ignore_within" => '.exclude'})
338
+ parser = Jekyll::TableOfContents::Parser.new(TEST_EXPLICIT_ID)
295
339
  doc = Nokogiri::HTML(parser.toc)
296
340
  expected = <<-HTML
297
341
  <ul class="section-nav">
@@ -300,7 +344,12 @@ HTML
300
344
  <li class="toc-entry toc-h1"><a href="#third">h3</a></li>
301
345
  </ul>
302
346
  HTML
347
+ actual = doc.css('ul.section-nav').to_s
348
+ assert_equal(expected, actual)
303
349
 
304
- assert_equal(expected, doc.css('ul.section-nav').to_s)
350
+ html = parser.inject_anchors_into_html
351
+ assert_includes(html, %(<a id="h1" class="anchor" href="#h1" aria-hidden="true">))
352
+ assert_includes(html, %(<a id="second" class="anchor" href="#second" aria-hidden="true">))
353
+ assert_includes(html, %(<a id="third" class="anchor" href="#third" aria-hidden="true">))
305
354
  end
306
355
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-toc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0.beta2
4
+ version: 0.8.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - toshimaru
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-10-10 00:00:00.000000000 Z
12
+ date: 2018-10-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  version: 1.3.1
159
159
  requirements: []
160
160
  rubyforge_project:
161
- rubygems_version: 2.5.2.3
161
+ rubygems_version: 2.7.6
162
162
  signing_key:
163
163
  specification_version: 4
164
164
  summary: Jekyll Table of Contents plugin