Module: RogerStyleGuide::Helpers::TocHelper
- Defined in:
- lib/roger_style_guide/helpers/toc_helper.rb
Overview
Methods for generating Table of Contents
Constant Summary collapse
- DEFAULT_MATCH =
rubocop:disable Metrics/MethodLength, rubocop:disable Metrics/CyclomaticComplexity, rubocop:disable Metrics/PerceivedComplexity, rubocop:disable Metrics/AbcSize
/html.erb\Z/
- DEFAULT_MAX_DEPTH =
1000
- DEFAULT_LINKER =
lambda do |url, name, level| "<a href='#{url}' class='level-#{level}' target='fbody'>#{name}</a>" end
Instance Method Summary collapse
-
#display_tree(tree, options = {}, level = 0) ⇒ Object
Display the tree.
-
#humanize_path(path) ⇒ Object
Convert path into human readable name.
-
#link_to_template(path, name = nil, level = nil, linker = DEFAULT_LINKER) ⇒ Object
Path will be used to generate the real link Name_path can be used to use a different string as link name.
-
#toc(path = nil, options = {}) ⇒ Object
Generate a table of contents for a certain path getting all files that match the ‘match` regexp and go `max_depth` levels deep.
-
#traverse_tree(path, max_depth = DFEAULT_MAX_DEPTH, match = DEFAULT_MATCH, level = 0) ⇒ Object
Build a tree.
Instance Method Details
#display_tree(tree, options = {}, level = 0) ⇒ Object
Display the tree
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/roger_style_guide/helpers/toc_helper.rb', line 105 def display_tree(tree, = {}, level = 0) return "" unless tree linker = [:linker] || DEFAULT_LINKER output = [] output << "<ul class='level-#{level}'>" tree[:children].each do |entry| output << "<li>" if entry[:type] == :file output << link_to_template(entry[:path], entry[:name], level, linker) else if entry[:children].length == 1 && entry[:children][0][:type] == :file && entry[:children][0][:name] == entry[:name] output << link_to_template(entry[:children][0][:path], entry[:name], level, linker) else # Check if there is a file exactly named like the current entry. # if there is we'll pluck the file out of the child list and link # the directory entry directly. modified_entry = { children: entry[:children].dup } if child = entry[:children].find { |c| c[:type] == :file && c[:name] == entry[:name] } modified_entry[:children].delete(child) output << link_to_template(child[:path], entry[:name], level, linker) else output << "<span class='title-#{level}'>#{entry[:name]}</span>" end output << display_tree(modified_entry, , level + 1) end end output << "</li>" end output << "</ul>" output.join("\n") end |
#humanize_path(path) ⇒ Object
Convert path into human readable name
59 60 61 |
# File 'lib/roger_style_guide/helpers/toc_helper.rb', line 59 def humanize_path(path) File.basename(path).split(".", 2).first.capitalize end |
#link_to_template(path, name = nil, level = nil, linker = DEFAULT_LINKER) ⇒ Object
Path will be used to generate the real link Name_path can be used to use a different string as link name
50 51 52 53 54 55 56 |
# File 'lib/roger_style_guide/helpers/toc_helper.rb', line 50 def link_to_template(path, name = nil, level = nil, linker = DEFAULT_LINKER) # Strip of html path url = path.to_s.gsub(env["roger.project"].html_path.to_s, "").gsub(/html\.erb$/, "html") name ||= humanize_path(path) linker.call(url, name, level) end |
#toc(path = nil, options = {}) ⇒ Object
Generate a table of contents for a certain path getting all files that match the ‘match` regexp and go `max_depth` levels deep.
Options are:
-
match [Regexp] (/html.erbZ/) What files to match
-
max_depth [Integer] (1000) How many directory levels deep should we go
-
linker [lambda {|url, name| … }] A lambda writing out the <a .. > tag.
Will output html in this structure:
“‘ <ul class=“level-0”>
<li>
<span class='title-0'>Name</span>
<ul class="level-1">
<li><a href='URL'>NAME</a>
</ul>
</li>
</ul> “‘
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/roger_style_guide/helpers/toc_helper.rb', line 35 def toc(path = nil, = {}) = { match: DEFAULT_MATCH, max_depth: DEFAULT_MAX_DEPTH, linker: DEFAULT_LINKER }.update() path ||= env["roger.project"].html_path tree = traverse_tree(path, [:max_depth], [:match]) display_tree(tree, ) end |
#traverse_tree(path, max_depth = DFEAULT_MAX_DEPTH, match = DEFAULT_MATCH, level = 0) ⇒ Object
Build a tree
-
Path: The path to get the entries from
-
Match: Files to match (use regexp). Will only match the File.basename
-
Max_depth: How deep should we traverse the tree?
-
Level: keep track of how deep we are in the recursino
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 96 97 98 99 100 |
# File 'lib/roger_style_guide/helpers/toc_helper.rb', line 71 def traverse_tree(path, max_depth = DFEAULT_MAX_DEPTH, match = DEFAULT_MATCH, level = 0) result = { name: humanize_path(path), path: path, children: [], type: :dir } path = Pathname.new(path) # Don't go deeper if we reached max_depth return if level >= max_depth path.entries.sort.each do |entry| entry_path = path + entry # Normalize paths, removing all "." and "_" files next if entry.to_s.start_with?(".") || entry.to_s.start_with?("_") # Check match next if entry_path.file? && !entry.to_s.match(match) if entry_path.directory? subdir = traverse_tree(entry_path, max_depth, match, level + 1) result[:children] << subdir if subdir else result[:children] << { name: humanize_path(entry), path: path + entry, type: :file } end end # If we don't have children we're not going to be visible. return if result[:children].empty? result end |