nanoc-toolbox 0.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.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/lib/nanoc/toolbox/helpers/navigation.rb +200 -0
- data/lib/nanoc/toolbox/helpers.rb +5 -0
- data/lib/nanoc/toolbox/version.rb +5 -0
- data/lib/nanoc/toolbox.rb +7 -0
- data/nanoc-toolbox.gemspec +25 -0
- metadata +103 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
module Nanoc::Toolbox::Helpers
|
2
|
+
|
3
|
+
# NANOC Helper for the Navigation related stuff.
|
4
|
+
# This module contains functionality for generating navigation menus for your
|
5
|
+
# pages, like navigation menu, breadcrumbs or a table of for a given Item
|
6
|
+
#
|
7
|
+
# @author Anouar ADLANI <anouar@adlani.com>
|
8
|
+
module Navigation
|
9
|
+
# Generate a navigation menu for a given item.
|
10
|
+
# The menu will be generated form the identifier of the root. The root itself
|
11
|
+
# will not be rendered. It generate the menu by parsing all the descendent of
|
12
|
+
# the passed item.
|
13
|
+
#
|
14
|
+
# @param [String] identifier - the identifier string of the root element
|
15
|
+
# @param [Hash] params - The Optional parameters
|
16
|
+
# @option params [Interger] :depth (3) maximum depth of the rendered menu
|
17
|
+
# @option params [String] :collection_tag ('ol') collection englobing tag name
|
18
|
+
# @option params [String] :item_tag ('li') item englobing tag name
|
19
|
+
#
|
20
|
+
# @return [String] The output ready to be displayed by the caller
|
21
|
+
def navigation_for(identifier, params={})
|
22
|
+
# Parse params or set to default values
|
23
|
+
params[:depth] ||= 3
|
24
|
+
params[:collection_tag] ||= 'ol'
|
25
|
+
params[:item_tag] ||= 'li'
|
26
|
+
|
27
|
+
# Decrease the depth level
|
28
|
+
params[:depth] -= 1
|
29
|
+
|
30
|
+
# Get root item for which we need to draw the navigation
|
31
|
+
root = @items.find { |i| i.identifier == identifier }
|
32
|
+
|
33
|
+
# Do not render if there is no child
|
34
|
+
return nil unless root.children
|
35
|
+
|
36
|
+
# Find all sections, and render them
|
37
|
+
sections = find_item_tree(root)
|
38
|
+
render_menu(sections, params)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# Generate a Table of Content for a given item. The toc will be generated
|
43
|
+
# form the item content. The parsing is done with Nokogiri through XPath.
|
44
|
+
# By default this helper method await for the following structure
|
45
|
+
#
|
46
|
+
# @param [String] identifier - the identifier string of the root element
|
47
|
+
# @param [Hash] params - The Optional parameters
|
48
|
+
# @option params [Interger] :depth (3) maximum depth of the rendered menu
|
49
|
+
# @option params [String] :collection_tag ('ol') collection englobing tag name
|
50
|
+
# @option params [String] :item_tag ('li') item englobing tag name
|
51
|
+
#
|
52
|
+
# @return [String] The output ready to be displayed by the caller
|
53
|
+
#
|
54
|
+
# @see http://nokogiri.org/
|
55
|
+
def toc_for(item_rep, params={})
|
56
|
+
require 'nokogiri'
|
57
|
+
|
58
|
+
# Parse params or set to default values
|
59
|
+
params[:depth] ||= 3
|
60
|
+
params[:collection_tag] ||= 'ol'
|
61
|
+
params[:item_tag] ||= 'li'
|
62
|
+
params[:path] ||= 'div[@class="section"]'
|
63
|
+
params[:class] ||= 'toc'
|
64
|
+
|
65
|
+
# Retreive the parsed content and init nokogiri
|
66
|
+
compiled_content = @item_rep.instance_eval { @content[:pre] }
|
67
|
+
doc = Nokogiri::HTML(compiled_content)
|
68
|
+
doc_root = doc.xpath('/html/body').first
|
69
|
+
|
70
|
+
# Find all sections, and render them
|
71
|
+
sections = find_toc_sections(doc_root, "#{params[:path]}", 2)
|
72
|
+
render_menu(sections, params)
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Generate a Breadcrumb for a given item. The breadcrumbs, is starting with
|
77
|
+
# the root item and ending with the item itself.
|
78
|
+
#
|
79
|
+
# Requires the Helper: Nanoc3::Helpers::Breadcrumbs
|
80
|
+
#
|
81
|
+
# @param [String] identifier - the identifier string of element
|
82
|
+
# @param [Hash] params - The Optional parameters
|
83
|
+
# @option params [String] :collection_tag ('ol') collection englobing tag name
|
84
|
+
# @option params [String] :item_tag ('li') item englobing tag name
|
85
|
+
#
|
86
|
+
# @return [String] The output ready to be displayed by the caller
|
87
|
+
#
|
88
|
+
# @see Nanoc3::Helpers::Breadcrumbs#breadcrumbs_for_identifier
|
89
|
+
def breadcrumb_for(identifier, params={})
|
90
|
+
|
91
|
+
# Parse params or set to default values
|
92
|
+
params[:collection_tag] ||= 'ul'
|
93
|
+
params[:item_tag] ||= 'li'
|
94
|
+
|
95
|
+
# Retreive the breadcrumbs trail and format them
|
96
|
+
sections = find_breadcrumbs_trail(identifier)
|
97
|
+
render_menu(sections, params)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Render a Hash to a HTML List by default
|
101
|
+
#
|
102
|
+
# Hash like :
|
103
|
+
# [{:title => 'Title', :link => 'http://example.com', :subsections => [{}, {}, ...]},{...}]
|
104
|
+
#
|
105
|
+
# Results to an output like the following (by default):
|
106
|
+
# <ul>
|
107
|
+
# <li>
|
108
|
+
# <a href="http://example.com">Title</a>
|
109
|
+
# <ul>
|
110
|
+
# <li><a href="">Title</a></li>
|
111
|
+
# </ul>
|
112
|
+
# </li>
|
113
|
+
# <li><a href="http://example.com">Title</a></li>
|
114
|
+
# <li><a href="http://example.com">Title</a></li>
|
115
|
+
# </ul>
|
116
|
+
#
|
117
|
+
# @param [Array] items - The array of links that need to be rendered
|
118
|
+
# @param [Hash] params - The Optional parameters
|
119
|
+
# @option params [String] :collection_tag ('ol') collection englobing tag name
|
120
|
+
# @option params [String] :item_tag ('li') item englobing tag name
|
121
|
+
#
|
122
|
+
# @return [String] The output ready to be displayed by the caller
|
123
|
+
def render_menu(items, params={})
|
124
|
+
|
125
|
+
# Parse params or set to default values
|
126
|
+
params[:depth] ||= 3
|
127
|
+
params[:collection_tag] ||= 'ol'
|
128
|
+
params[:item_tag] ||= 'li'
|
129
|
+
|
130
|
+
# Decrease the depth level
|
131
|
+
params[:depth] -= 1
|
132
|
+
|
133
|
+
out = items.map { |item|
|
134
|
+
output = ""
|
135
|
+
|
136
|
+
# Render only if there is depth left
|
137
|
+
if params[:depth].to_i >= 0 && item[:subsections] && item[:subsections]
|
138
|
+
output = render_menu(item[:subsections], params)
|
139
|
+
params[:depth] += 1 # Increase the depth level after the call of navigation_for
|
140
|
+
end
|
141
|
+
content_tag(params[:item_tag], link_to(item[:title], item[:link]) + output)
|
142
|
+
}
|
143
|
+
content_tag(params[:collection_tag], out.join())
|
144
|
+
end
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
# Helper method that wrap a content within an HTML Tag
|
149
|
+
def content_tag(name, content="", &block)
|
150
|
+
"<#{name}>#{content}</#{name}>"
|
151
|
+
end
|
152
|
+
|
153
|
+
# Recursive method that extract from an XPath pattern the document structure
|
154
|
+
# and return the "permalinks" to each sections in an Array of Hash that
|
155
|
+
# could be used by the rendering method. The structure is deducted by the
|
156
|
+
# H1-6 header within the html element defined by the XPATH
|
157
|
+
def find_toc_sections(section, section_xpath, title_level=1)
|
158
|
+
return {} unless section.xpath(section_xpath)
|
159
|
+
|
160
|
+
sections = section.xpath(section_xpath).map do |subsection|
|
161
|
+
header = subsection.xpath("h#{title_level}").first
|
162
|
+
sub_id = subsection['id']
|
163
|
+
sub_title = header.inner_html if header
|
164
|
+
subsections = {}
|
165
|
+
if subsection.xpath("#{section_xpath}") && title_level <= 6
|
166
|
+
subsections = find_toc_sections(subsection, "#{section_xpath}", title_level+1)
|
167
|
+
end
|
168
|
+
{ :title => sub_title, :link => '#'+sub_id, :subsections => subsections }
|
169
|
+
end
|
170
|
+
sections
|
171
|
+
end
|
172
|
+
|
173
|
+
# Recursive method that extract from an XPath pattern the document structure
|
174
|
+
# and return the "permalinks" in a Array of Hash that could be used by the
|
175
|
+
# rendering method
|
176
|
+
def find_item_tree(root)
|
177
|
+
return nil unless root.children
|
178
|
+
|
179
|
+
# For each child call the find_item_tree on it and then render the generate the hash
|
180
|
+
sections = root.children.map do |child|
|
181
|
+
subsections = find_item_tree(child)
|
182
|
+
|
183
|
+
{ :title => (child[:short_title] || child[:title] || child.identifier),
|
184
|
+
:link => relative_path_to(child),
|
185
|
+
:subsections => subsections }
|
186
|
+
end
|
187
|
+
sections
|
188
|
+
end
|
189
|
+
|
190
|
+
def find_breadcrumbs_trail(root)
|
191
|
+
sections = breadcrumbs_for_identifier(root).map do |child|
|
192
|
+
|
193
|
+
{ :title => (child[:short_title] || child[:title] || child.identifier),
|
194
|
+
:link => relative_path_to(child),
|
195
|
+
:subsections => nil }
|
196
|
+
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/nanoc/toolbox/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "nanoc-toolbox"
|
6
|
+
s.version = Nanoc::Toolbox::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Anouar ADLANI"]
|
9
|
+
s.email = ["anouar@adlani.com"]
|
10
|
+
s.homepage = "http://rubygems.org/gems/nanoc-tools"
|
11
|
+
s.summary = "A collection of helper and filters for nanoc"
|
12
|
+
s.description = ""
|
13
|
+
|
14
|
+
|
15
|
+
s.required_rubygems_version = ">= 1.3.6"
|
16
|
+
s.rubyforge_project = "nanoc-toolbox"
|
17
|
+
|
18
|
+
s.add_dependency "nanoc", ">= 3.1.6"
|
19
|
+
|
20
|
+
s.add_development_dependency "bundler", ">= 1.0.0"
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
24
|
+
s.require_path = 'lib'
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nanoc-toolbox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Anouar ADLANI
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-06 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: nanoc
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 3
|
30
|
+
- 1
|
31
|
+
- 6
|
32
|
+
version: 3.1.6
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: bundler
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 1
|
45
|
+
- 0
|
46
|
+
- 0
|
47
|
+
version: 1.0.0
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
description: ""
|
51
|
+
email:
|
52
|
+
- anouar@adlani.com
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- .gitignore
|
61
|
+
- Gemfile
|
62
|
+
- Rakefile
|
63
|
+
- lib/nanoc/toolbox.rb
|
64
|
+
- lib/nanoc/toolbox/helpers.rb
|
65
|
+
- lib/nanoc/toolbox/helpers/navigation.rb
|
66
|
+
- lib/nanoc/toolbox/version.rb
|
67
|
+
- nanoc-toolbox.gemspec
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://rubygems.org/gems/nanoc-tools
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
version: "0"
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
segments:
|
91
|
+
- 1
|
92
|
+
- 3
|
93
|
+
- 6
|
94
|
+
version: 1.3.6
|
95
|
+
requirements: []
|
96
|
+
|
97
|
+
rubyforge_project: nanoc-toolbox
|
98
|
+
rubygems_version: 1.3.7
|
99
|
+
signing_key:
|
100
|
+
specification_version: 3
|
101
|
+
summary: A collection of helper and filters for nanoc
|
102
|
+
test_files: []
|
103
|
+
|