middleman-toc 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f854b8ef57495ea5b094ed90d3b4e509e0978c21
4
+ data.tar.gz: fc7e54f5ded46ca96834fae5b8c969caf283689d
5
+ SHA512:
6
+ metadata.gz: 908ae6a3625b281fd30f68dab7b49ac61b6c555f460e034bcaed39282248d0506e793873cddc2ce2b9116030f9a6bf5fa460e221f632df4e7d5298986e3d0a3e
7
+ data.tar.gz: 295f8764e0986ab0309231b77b882e4668e9e5eccfb1447b3f1ed10eb5feff9cc8eafe135352978e4aca12bd27c0e8eec6195de884688f9638dc076baadf9ee1
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+ gem 'middleman'
5
+
6
+ group :test do
7
+ gem 'rspec'
8
+ gem 'mocha'
9
+ end
@@ -0,0 +1,140 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ middleman-toc (0.0.1)
5
+ titleize
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (4.1.8)
11
+ i18n (~> 0.6, >= 0.6.9)
12
+ json (~> 1.7, >= 1.7.7)
13
+ minitest (~> 5.1)
14
+ thread_safe (~> 0.1)
15
+ tzinfo (~> 1.1)
16
+ celluloid (0.16.0)
17
+ timers (~> 4.0.0)
18
+ chunky_png (1.3.3)
19
+ coffee-script (2.3.0)
20
+ coffee-script-source
21
+ execjs
22
+ coffee-script-source (1.8.0)
23
+ compass (1.0.1)
24
+ chunky_png (~> 1.2)
25
+ compass-core (~> 1.0.1)
26
+ compass-import-once (~> 1.0.5)
27
+ rb-fsevent (>= 0.9.3)
28
+ rb-inotify (>= 0.9)
29
+ sass (>= 3.3.13, < 3.5)
30
+ compass-core (1.0.1)
31
+ multi_json (~> 1.0)
32
+ sass (>= 3.3.0, < 3.5)
33
+ compass-import-once (1.0.5)
34
+ sass (>= 3.2, < 3.5)
35
+ diff-lcs (1.2.5)
36
+ erubis (2.7.0)
37
+ execjs (2.2.2)
38
+ ffi (1.9.6)
39
+ haml (4.0.6)
40
+ tilt
41
+ hike (1.2.3)
42
+ hitimes (1.2.2)
43
+ hooks (0.4.0)
44
+ uber (~> 0.0.4)
45
+ i18n (0.6.11)
46
+ json (1.8.2)
47
+ kramdown (1.5.0)
48
+ listen (2.8.5)
49
+ celluloid (>= 0.15.2)
50
+ rb-fsevent (>= 0.9.3)
51
+ rb-inotify (>= 0.9)
52
+ metaclass (0.0.4)
53
+ middleman (3.3.7)
54
+ coffee-script (~> 2.2)
55
+ compass (>= 1.0.0, < 2.0.0)
56
+ compass-import-once (= 1.0.5)
57
+ execjs (~> 2.0)
58
+ haml (>= 4.0.5)
59
+ kramdown (~> 1.2)
60
+ middleman-core (= 3.3.7)
61
+ middleman-sprockets (>= 3.1.2)
62
+ sass (>= 3.4.0, < 4.0)
63
+ uglifier (~> 2.5)
64
+ middleman-core (3.3.7)
65
+ activesupport (~> 4.1.0)
66
+ bundler (~> 1.1)
67
+ erubis
68
+ hooks (~> 0.3)
69
+ i18n (~> 0.6.9)
70
+ listen (>= 2.7.9, < 3.0)
71
+ padrino-helpers (~> 0.12.3)
72
+ rack (>= 1.4.5, < 2.0)
73
+ rack-test (~> 0.6.2)
74
+ thor (>= 0.15.2, < 2.0)
75
+ tilt (~> 1.4.1, < 2.0)
76
+ middleman-sprockets (3.4.1)
77
+ middleman-core (>= 3.3)
78
+ sprockets (~> 2.12.1)
79
+ sprockets-helpers (~> 1.1.0)
80
+ sprockets-sass (~> 1.3.0)
81
+ minitest (5.5.1)
82
+ mocha (1.1.0)
83
+ metaclass (~> 0.0.1)
84
+ multi_json (1.10.1)
85
+ padrino-helpers (0.12.4)
86
+ i18n (~> 0.6, >= 0.6.7)
87
+ padrino-support (= 0.12.4)
88
+ tilt (~> 1.4.1)
89
+ padrino-support (0.12.4)
90
+ activesupport (>= 3.1)
91
+ rack (1.6.0)
92
+ rack-test (0.6.2)
93
+ rack (>= 1.0)
94
+ rb-fsevent (0.9.4)
95
+ rb-inotify (0.9.5)
96
+ ffi (>= 0.5.0)
97
+ rspec (3.1.0)
98
+ rspec-core (~> 3.1.0)
99
+ rspec-expectations (~> 3.1.0)
100
+ rspec-mocks (~> 3.1.0)
101
+ rspec-core (3.1.7)
102
+ rspec-support (~> 3.1.0)
103
+ rspec-expectations (3.1.2)
104
+ diff-lcs (>= 1.2.0, < 2.0)
105
+ rspec-support (~> 3.1.0)
106
+ rspec-mocks (3.1.3)
107
+ rspec-support (~> 3.1.0)
108
+ rspec-support (3.1.2)
109
+ sass (3.4.9)
110
+ sprockets (2.12.3)
111
+ hike (~> 1.2)
112
+ multi_json (~> 1.0)
113
+ rack (~> 1.0)
114
+ tilt (~> 1.1, != 1.3.0)
115
+ sprockets-helpers (1.1.0)
116
+ sprockets (~> 2.0)
117
+ sprockets-sass (1.3.1)
118
+ sprockets (~> 2.0)
119
+ tilt (~> 1.1)
120
+ thor (0.19.1)
121
+ thread_safe (0.3.4)
122
+ tilt (1.4.1)
123
+ timers (4.0.1)
124
+ hitimes
125
+ titleize (1.3.0)
126
+ tzinfo (1.2.2)
127
+ thread_safe (~> 0.1)
128
+ uber (0.0.12)
129
+ uglifier (2.6.1)
130
+ execjs (>= 0.3.0)
131
+ json (>= 1.8.0)
132
+
133
+ PLATFORMS
134
+ ruby
135
+
136
+ DEPENDENCIES
137
+ middleman
138
+ middleman-toc!
139
+ mocha
140
+ rspec
@@ -0,0 +1,3 @@
1
+ # Middleman Table of Contents
2
+
3
+ Render a table of contents. See http://ruby-for-beginners.rubymonstas.org
@@ -0,0 +1,183 @@
1
+ require 'middleman'
2
+ require 'middleman_toc/extension'
3
+ require 'forwardable'
4
+
5
+ class MiddlemanToc
6
+ module Indent
7
+ def indent(string)
8
+ string.split("\n").map { |line| "#{' ' * (level)}#{line}" }.join("\n")
9
+ end
10
+ end
11
+
12
+ class Paths < Struct.new(:sitemap)
13
+ def prev(path)
14
+ path = paths[index(path) - 1]
15
+ "#{path.sub('.', '')}.html" if path
16
+ end
17
+
18
+ def next(path)
19
+ path = paths[index(path) + 1]
20
+ "#{path.sub('.', '')}.html" if path
21
+ end
22
+
23
+ def select(dir)
24
+ paths.select { |path| path =~ %r(#{dir}/) }.reject { |path| path =~ %r(#{dir}/.+/) }
25
+ end
26
+
27
+ def paths
28
+ @paths ||= begin
29
+ paths = sitemap.resources.map(&:path)
30
+ paths = paths.select { |path| path =~ /.html$/ }
31
+ paths = paths.map { |path| "./#{path.sub(/.html$/, '')}" }
32
+ paths = paths + paths.map { |path| ::File.dirname(path) } - ['.']
33
+ paths.sort.unshift('./index').uniq
34
+ end
35
+ end
36
+
37
+ def index(path)
38
+ paths.index("./#{path.sub('.html', '')}")
39
+ end
40
+ end
41
+
42
+ class Tree
43
+ extend Forwardable
44
+ include Indent
45
+
46
+ def_delegators :@children, :empty?
47
+ attr_reader :level, :path, :children, :active
48
+
49
+ def initialize(level, path)
50
+ @level = level
51
+ @path = path
52
+ @children = []
53
+ end
54
+
55
+ def <<(child)
56
+ children << child
57
+ end
58
+
59
+ def activate(active)
60
+ children.each { |child| child.activate(active) }
61
+ @active = level == 1 || active == path || children.any?(&:active?)
62
+ end
63
+
64
+ def render
65
+ "<ul#{' class="active"' if active}>\n#{indent(children.map(&:render).join("\n"))}\n</ul>"
66
+ end
67
+ end
68
+
69
+ class Page < Struct.new(:level, :page, :path, :directory?)
70
+ include Indent
71
+
72
+ attr_reader :active, :active
73
+
74
+ def activate(active)
75
+ @active = active == path
76
+ end
77
+
78
+ def render
79
+ html = title
80
+ html = link("/#{path}.html", html) if File.file?(filename)
81
+ html = item(html)
82
+ html
83
+ end
84
+
85
+ def link(href, content)
86
+ %(<a href="#{href}">#{content}</a>)
87
+ end
88
+
89
+ def item(content)
90
+ %(<li#{%( class="#{classes}") if classes}>#{content}</li>)
91
+ end
92
+
93
+ def active?
94
+ # current == path
95
+ @active
96
+ end
97
+
98
+ def classes
99
+ classes = []
100
+ classes << 'active' if active?
101
+ classes << 'directory' if directory?
102
+ classes.join(' ')
103
+ end
104
+
105
+ def title
106
+ title = page_title if page
107
+ title || path_title
108
+ end
109
+
110
+ def page_title
111
+ if page.data.title
112
+ page.data.title
113
+ else
114
+ html = page.render(layout: false, no_images: true)
115
+ matches = html.match(/<h.+>(.*?)<\/h1>/)
116
+ matches[1] if matches
117
+ end
118
+ end
119
+
120
+ def path_title
121
+ path.sub(/[\d]{2}-/, '').titleize
122
+ end
123
+
124
+ def filename
125
+ "source/#{path}.md"
126
+ end
127
+ end
128
+
129
+ class Link < Struct.new(:href, :content, :options)
130
+ def render
131
+ %(<a href="#{href}" class="#{options[:class]}">#{content}</a>)
132
+ end
133
+ end
134
+
135
+ attr_reader :sitemap, :paths, :tree
136
+
137
+ def initialize(sitemap)
138
+ @sitemap = sitemap
139
+ @paths = Paths.new(sitemap)
140
+ @tree = build('.')
141
+ end
142
+
143
+ def render(current_path)
144
+ tree.activate(current_path.sub('.html', ''))
145
+ tree.render
146
+ end
147
+
148
+ def prev(current_path)
149
+ page = page_for(current_path)
150
+ href = paths.prev(page.path)
151
+ Link.new(href, 'Previous', class: 'prev').render if href
152
+ end
153
+
154
+ def next(current_path)
155
+ page = page_for(current_path)
156
+ href = paths.next(page.path)
157
+ Link.new(href, 'Next', class: 'next').render if href
158
+ end
159
+
160
+ private
161
+
162
+ def build(dir, level = 1)
163
+ tree = Tree.new(level, dir.sub('./', ''))
164
+ paths.select(dir).each do |path|
165
+ child = build(path, level + 1)
166
+ path = path.sub('./', '')
167
+ page = page_for("#{path}.html")
168
+ tree.children << Page.new(level, page, path, !child.empty?)
169
+ tree << child unless child.empty?
170
+ end
171
+ tree
172
+ end
173
+
174
+ def page_for(path)
175
+ sitemap.find_resource_by_path(path)
176
+ end
177
+
178
+ def title_for(path)
179
+ File.read(path)
180
+ end
181
+ end
182
+
183
+ Middleman::Extensions.register(:toc, MiddlemanToc::Extension)
@@ -0,0 +1,10 @@
1
+ require 'middleman_toc/helpers'
2
+
3
+ class MiddlemanToc
4
+ class Extension < ::Middleman::Extension
5
+ # option :ignore, ['sitemap.xml', 'robots.txt'], 'Ignored files and directories.'
6
+ # option :titles, { 'index.md' => 'Home' }, 'Default link titles.'
7
+
8
+ self.defined_helpers = [Helpers]
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ class MiddlemanToc
2
+ module Helpers
3
+ def _toc
4
+ @_toc ||= MiddlemanToc.new(sitemap)
5
+ end
6
+
7
+ def toc
8
+ _toc.render(current_page.path)
9
+ end
10
+
11
+ def prev_page
12
+ _toc.prev(current_page.path)
13
+ end
14
+
15
+ def next_page
16
+ _toc.next(current_page.path)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ class MiddlemanToc
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'middleman-toc'
2
+ require 'middleman-core/configuration'
3
+
4
+ RSpec.configure do |c|
5
+ c.expect_with :rspec
6
+ c.mock_with :mocha
7
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Middleman::Toc do
4
+ let(:titles) { ['Title 1', 'Title 2', 'Title 2-1', 'Title 2-2', 'Book'] }
5
+ let(:paths) { %w(1.html 2.html 2/2-1.html 2/2-2.html index.html) }
6
+ let(:pages) { paths.map { |path| stub(path: path) } }
7
+ let(:sitemap) { stub(resources: pages) }
8
+ let(:toc) { Middleman::Toc.new(sitemap) }
9
+
10
+ subject { toc.render }
11
+
12
+ before do
13
+ pages.map do |page|
14
+ sitemap.stubs(:find_resource_by_path).with(page.path).returns(page)
15
+ page.stubs(:data).returns(stub(title: nil))
16
+ File.stubs(:file?).with("source/#{page.path.sub('html', 'md')}").returns(page.path != '2.html')
17
+ end
18
+ end
19
+
20
+ describe 'with a directory that has an equivalent file' do
21
+ end
22
+
23
+ describe 'with page data title attribute set' do
24
+ before do
25
+ pages.map.with_index do |resource, ix|
26
+ resource.stubs(:data).returns(stub(title: "Data: #{titles[ix]}"))
27
+ end
28
+ end
29
+
30
+ it 'uses the page data title attribute' do
31
+ expect(subject).to include('<a href="1.html">Data: Title 1</a>')
32
+ end
33
+ end
34
+
35
+ describe 'with page data title attribute not set' do
36
+ before do
37
+ pages.map.with_index do |resource, ix|
38
+ resource.stubs(:render).returns("<h1>Html: #{titles[ix]}</h1>")
39
+ end
40
+ end
41
+
42
+ it 'renders and parses the page for a <h1> tag' do
43
+ puts subject
44
+ expect(subject).to include('<a href="1.html">Html: Title 1</a>')
45
+ end
46
+ end
47
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: middleman-toc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sven Fuchs
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: titleize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email: me@svenfuchs.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - Gemfile
34
+ - Gemfile.lock
35
+ - README.md
36
+ - lib/middleman_toc.rb
37
+ - lib/middleman_toc/extension.rb
38
+ - lib/middleman_toc/helpers.rb
39
+ - lib/middleman_toc/version.rb
40
+ - spec/spec_helper.rb
41
+ - spec/toc_spec.rb
42
+ homepage: https://github.com/svenfuchs/middleman-toc
43
+ licenses: []
44
+ metadata: {}
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project: "[none]"
61
+ rubygems_version: 2.2.2
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Middleman Table of Contents
65
+ test_files: []
66
+ has_rdoc: