Class: Jekyll::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/pro_generate_toc.rb

Instance Method Summary collapse

Constructor Details

#initialize(html, options = {}) ⇒ Parser



22
23
24
25
# File 'lib/pro_generate_toc.rb', line 22

def initialize(html, options = {})
      @doc = Nokogiri::HTML::DocumentFragment.parse(html)
      @entries = parse_content
end

Instance Method Details

#build_toc_listObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/pro_generate_toc.rb', line 58

def build_toc_list
  entries = @entries;
  i = 0
  limit = 3
  hasToggle = 0
  toc_list = +''
  min_h_num = @entries.map { |e| e[:h_num] }.min

  while i < entries.count
    entry = entries[i]
    if entry[:h_num] == min_h_num
      next_i = i + 1
      if next_i <= limit
          toc_list << %(<li><a href="#" class="js-go-to" data-target="##{entry[:id]}">#{next_i}. #{entry[:text]}</a>)

          if next_i < entries.count && entries[next_i][:h_num] > min_h_num
            nest_entries = get_nest_entries(entries[next_i, entries.count], min_h_num)
            toc_list << %(\n<ul id="pro-sidebar-sub" class="js-scroll-nav list-group">\n#{build_toc_list(nest_entries)}</ul>\n)
            i += nest_entries.count
          end
      else
        hasToggle += 1
        toc_list << %(<li id="sidebar-collapse" class="collapse"><a href="#" class="js-go-to" data-target="##{entry[:id]}">#{next_i}. #{entry[:text]}</a>)
      end

      toc_list << %(</li>\n)
    elsif entry[:h_num] > min_h_num
      nest_entries = get_nest_entries(entries[i, entries.count], min_h_num)
      toc_list << build_toc_list(nest_entries)
      i += nest_entries.count - 1
    end
    i += 1
  end
  if hasToggle > 0
     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>)
  end
  toc_list
end

#get_nest_entries(entries, min_h_num) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/pro_generate_toc.rb', line 97

def get_nest_entries(entries, min_h_num)
  entries.inject([]) do |nest_entries, entry|
    break nest_entries if entry[:h_num] == min_h_num

    nest_entries << entry
  end
end

#parse_contentObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/pro_generate_toc.rb', line 26

def parse_content
  headers = Hash.new(0)

  (@doc.css(toc_headings) - @doc.css(toc_headings_within))
    .reject { |n| n.classes.include?('no_toc_section') }
    .inject([]) do |entries, node|
    text = node.text
    id = node.attribute('id') || 'ryan-id'

    suffix_num = headers[id]
    headers[id] += 1

    entries << {
      id: suffix_num.zero? ? id : "#{id}-#{suffix_num}",
      text: CGI.escapeHTML(text),
      node_name: node.name,
      header_content: node.children.first,
      h_num: node.name.delete('h').to_i
    }
  end
end

#toc_headingsObject



48
49
50
51
# File 'lib/pro_generate_toc.rb', line 48

def toc_headings
    @toc_levels = 2..2
    @toc_levels.map { |level| "h#{level}" }.join(',')
end

#toc_headings_withinObject



53
54
55
56
# File 'lib/pro_generate_toc.rb', line 53

def toc_headings_within
    @toc_levels = 2..2
    @toc_levels.map { |level| ".no_toc_section h#{level}" }.join(',')
end