pro_generate_toc 1.0.0 → 1.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 83cc3e4482e272e458314b0cae3cd6ae40a4e73498a5bff1cecb587dfb2b9023
4
- data.tar.gz: 5ed5dea8383d01e8f4361ce26c82470fcf472c020f1fefc7e0c0508909908b90
3
+ metadata.gz: 20c443feeb75b14f1a1ea055f0550b89374f9f10321e40f787ccf072d563440d
4
+ data.tar.gz: c0e1e14f0806d7dffd6ef73275564a9365cd4fb4758ae2b8358dfbe308758ed4
5
5
  SHA512:
6
- metadata.gz: 3847e92f9f9a148afb055dd476f00d01c27d3650ee7ec0f81cd4ab062520c384a87b43121317c5694a03c15681060fc17a52b44b9ebebeefb1747d2d118d499b
7
- data.tar.gz: bbf73de4b1fa4ed2f0fcf55acee7f57cbb4929399a5648ac9f04c5e23839b2227548d3568e282e7556c28f79a2e0959f470f546604e79e50d66721a07c5f52cc
6
+ metadata.gz: '07997e5b1c543a65b8dbaceca25ef9fbb98d6644b715fa1bd7701d4a90c9dac2b2ce599ebe8b15a9c56f87782d6337d8e4b6c01cea4e80f2bdda3fc2412894d8'
7
+ data.tar.gz: d329775c7a913b8167c7cf30bfdfa05c01c51297b5228588855fec9c945f27a818da199c9152b51b0e556af947291b13344700b033339bd7f952ce6553b682ea
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # pro_generate_toc
@@ -0,0 +1,105 @@
1
+ require 'nokogiri'
2
+
3
+ module Jekyll
4
+ class RenderTocPro < Liquid::Tag
5
+ def render(context)
6
+ @doc = Nokogiri::HTML::DocumentFragment.parse(context.registers[:page]['content'])
7
+
8
+ %(<ul id="pro-sidebar" class="js-scroll-nav list-group">\n#{Parser.new(@doc).build_toc_list}</ul>)
9
+ end
10
+ end
11
+ module TableOfContentsFilter
12
+ def pro_toc(html)
13
+ @doc = Nokogiri::HTML::DocumentFragment.parse(html)
14
+
15
+ %(<ul id="pro-sidebar" class="js-scroll-nav list-group">\n#{Parser.new(@doc).build_toc_list}</ul>)
16
+ end
17
+ end
18
+ class Parser
19
+ def initialize(html, options = {})
20
+ @doc = Nokogiri::HTML::DocumentFragment.parse(html)
21
+ @entries = parse_content
22
+ end
23
+ def parse_content
24
+ headers = Hash.new(0)
25
+
26
+ (@doc.css(toc_headings) - @doc.css(toc_headings_within))
27
+ .reject { |n| n.classes.include?('no_toc_section') }
28
+ .inject([]) do |entries, node|
29
+ text = node.text
30
+ id = node.attribute('id') || 'ryan-id'
31
+
32
+ suffix_num = headers[id]
33
+ headers[id] += 1
34
+
35
+ entries << {
36
+ id: suffix_num.zero? ? id : "#{id}-#{suffix_num}",
37
+ text: CGI.escapeHTML(text),
38
+ node_name: node.name,
39
+ header_content: node.children.first,
40
+ h_num: node.name.delete('h').to_i
41
+ }
42
+ end
43
+ end
44
+
45
+ def toc_headings
46
+ @toc_levels = 2..2
47
+ @toc_levels.map { |level| "h#{level}" }.join(',')
48
+ end
49
+
50
+ def toc_headings_within
51
+ @toc_levels = 2..2
52
+ @toc_levels.map { |level| ".no_toc_section h#{level}" }.join(',')
53
+ end
54
+
55
+ def build_toc_list
56
+ entries = @entries;
57
+ i = 0
58
+ limit = 3
59
+ hasToggle = 0
60
+ toc_list = +''
61
+ min_h_num = @entries.map { |e| e[:h_num] }.min
62
+
63
+ while i < entries.count
64
+ entry = entries[i]
65
+ if entry[:h_num] == min_h_num
66
+ next_i = i + 1
67
+ if next_i <= limit
68
+ toc_list << %(<li><a href="#" class="js-go-to" data-target="##{entry[:id]}">#{next_i}. #{entry[:text]}</a>)
69
+
70
+ if next_i < entries.count && entries[next_i][:h_num] > min_h_num
71
+ nest_entries = get_nest_entries(entries[next_i, entries.count], min_h_num)
72
+ toc_list << %(\n<ul id="pro-sidebar-sub" class="js-scroll-nav list-group">\n#{build_toc_list(nest_entries)}</ul>\n)
73
+ i += nest_entries.count
74
+ end
75
+ else
76
+ hasToggle += 1
77
+ toc_list << %(<li id="sidebar-collapse" class="collapse"><a href="#" class="js-go-to" data-target="##{entry[:id]}">#{next_i}. #{entry[:text]}</a>)
78
+ end
79
+
80
+ toc_list << %(</li>\n)
81
+ elsif entry[:h_num] > min_h_num
82
+ nest_entries = get_nest_entries(entries[i, entries.count], min_h_num)
83
+ toc_list << build_toc_list(nest_entries)
84
+ i += nest_entries.count - 1
85
+ end
86
+ i += 1
87
+ end
88
+ if hasToggle > 0
89
+ toc_list << %(<div id="blog-sidebar-loadmore" data-toggle="collapse" data-target="#sidebar-collapse" aria-expanded="false" aria-controls="sidebar-collapse" style="text-align: center; cursor: pointer; color: #407bff"><i class="fa"></i></div>)
90
+ end
91
+ toc_list
92
+ end
93
+
94
+ def get_nest_entries(entries, min_h_num)
95
+ entries.inject([]) do |nest_entries, entry|
96
+ break nest_entries if entry[:h_num] == min_h_num
97
+
98
+ nest_entries << entry
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ Liquid::Template.register_filter(Jekyll::TableOfContentsFilter)
105
+ Liquid::Template.register_tag('render_toc', Jekyll::RenderTocPro)
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'pro_generate_toc'
3
+ spec.version = '1.0.1'
4
+ spec.summary = 'Jekyll Table of Contents plugin'
5
+ spec.description = 'Jekyll (Ruby static website generator) plugin which generates a Table of Contents for the page.'
6
+ spec.authors = %w[Ryan]
7
+ spec.email = 'sonnb@mageplaza.com'
8
+ spec.homepage = 'https://mageplaza.com'
9
+ spec.license = 'Ryan'
10
+ spec.require_paths = ['lib']
11
+
12
+ spec.metadata['homepage_uri'] = spec.homepage
13
+ spec.metadata['source_code_uri'] = spec.homepage
14
+ spec.metadata['changelog_uri'] = spec.homepage
15
+ spec.metadata['rubygems_mfa_required'] = 'true'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pro_generate_toc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan
@@ -16,7 +16,10 @@ email: sonnb@mageplaza.com
16
16
  executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
- files: []
19
+ files:
20
+ - README.md
21
+ - lib/pro_generate_toc.rb
22
+ - pro_generate_toc.gemspec
20
23
  homepage: https://mageplaza.com
21
24
  licenses:
22
25
  - Ryan