nanoc3 3.0.9 → 3.1.0a1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/NEWS.md +360 -0
- data/README.md +85 -0
- data/Rakefile +2 -2
- data/bin/nanoc3 +0 -4
- data/lib/nanoc3/base/code_snippet.rb +14 -6
- data/lib/nanoc3/base/compiler.rb +68 -49
- data/lib/nanoc3/base/compiler_dsl.rb +70 -29
- data/lib/nanoc3/base/context.rb +47 -0
- data/lib/nanoc3/base/core_ext/array.rb +4 -0
- data/lib/nanoc3/base/core_ext/hash.rb +5 -1
- data/lib/nanoc3/base/core_ext/string.rb +2 -0
- data/lib/nanoc3/base/data_source.rb +132 -96
- data/lib/nanoc3/base/dependency_tracker.rb +160 -185
- data/lib/nanoc3/base/directed_graph.rb +252 -0
- data/lib/nanoc3/base/errors.rb +52 -4
- data/lib/nanoc3/base/filter.rb +43 -28
- data/lib/nanoc3/base/item.rb +93 -25
- data/lib/nanoc3/base/item_rep.rb +166 -55
- data/lib/nanoc3/base/layout.rb +16 -13
- data/lib/nanoc3/base/notification_center.rb +28 -12
- data/lib/nanoc3/base/plugin_registry.rb +158 -0
- data/lib/nanoc3/base/rule.rb +27 -8
- data/lib/nanoc3/base/rule_context.rb +59 -46
- data/lib/nanoc3/base/site.rb +124 -77
- data/lib/nanoc3/base.rb +7 -2
- data/lib/nanoc3/cli/base.rb +4 -1
- data/lib/nanoc3/cli/commands/autocompile.rb +5 -4
- data/lib/nanoc3/cli/commands/compile.rb +28 -7
- data/lib/nanoc3/cli/commands/create_item.rb +1 -1
- data/lib/nanoc3/cli/commands/create_layout.rb +1 -1
- data/lib/nanoc3/cli/commands/create_site.rb +46 -22
- data/lib/nanoc3/cli/commands/debug.rb +100 -0
- data/lib/nanoc3/cli/commands/help.rb +1 -1
- data/lib/nanoc3/cli/commands/info.rb +1 -1
- data/lib/nanoc3/cli/commands/view.rb +85 -0
- data/lib/nanoc3/cli/commands.rb +2 -0
- data/lib/nanoc3/cli/logger.rb +7 -0
- data/lib/nanoc3/cli.rb +0 -3
- data/lib/nanoc3/data_sources/{delicious.rb → deprecated/delicious.rb} +1 -24
- data/lib/nanoc3/data_sources/{last_fm.rb → deprecated/last_fm.rb} +1 -27
- data/lib/nanoc3/data_sources/{twitter.rb → deprecated/twitter.rb} +1 -14
- data/lib/nanoc3/data_sources/filesystem.rb +188 -176
- data/lib/nanoc3/data_sources/filesystem_unified.rb +107 -0
- data/lib/nanoc3/data_sources/filesystem_verbose.rb +80 -0
- data/lib/nanoc3/data_sources.rb +18 -9
- data/lib/nanoc3/extra/core_ext/enumerable.rb +39 -0
- data/lib/nanoc3/extra/core_ext/time.rb +2 -2
- data/lib/nanoc3/extra/core_ext.rb +1 -0
- data/lib/nanoc3/extra/deployers/rsync.rb +49 -3
- data/lib/nanoc3/extra/file_proxy.rb +7 -0
- data/lib/nanoc3/extra/vcs.rb +25 -24
- data/lib/nanoc3/extra/vcses/bazaar.rb +4 -0
- data/lib/nanoc3/extra/vcses/dummy.rb +4 -0
- data/lib/nanoc3/extra/vcses/git.rb +4 -0
- data/lib/nanoc3/extra/vcses/mercurial.rb +4 -0
- data/lib/nanoc3/extra/vcses/subversion.rb +4 -0
- data/lib/nanoc3/extra.rb +4 -1
- data/lib/nanoc3/filters/erb.rb +1 -1
- data/lib/nanoc3/filters/erubis.rb +1 -1
- data/lib/nanoc3/filters/haml.rb +1 -1
- data/lib/nanoc3/filters/kramdown.rb +14 -0
- data/lib/nanoc3/filters/maruku.rb +1 -1
- data/lib/nanoc3/filters/rainpress.rb +1 -1
- data/lib/nanoc3/filters/rdiscount.rb +3 -1
- data/lib/nanoc3/filters.rb +2 -0
- data/lib/nanoc3/helpers/blogging.rb +91 -75
- data/lib/nanoc3/helpers/breadcrumbs.rb +18 -10
- data/lib/nanoc3/helpers/capturing.rb +24 -29
- data/lib/nanoc3/helpers/filtering.rb +20 -17
- data/lib/nanoc3/helpers/html_escape.rb +7 -4
- data/lib/nanoc3/helpers/link_to.rb +51 -41
- data/lib/nanoc3/helpers/rendering.rb +15 -8
- data/lib/nanoc3/helpers/tagging.rb +27 -21
- data/lib/nanoc3/helpers/text.rb +12 -8
- data/lib/nanoc3/helpers/xml_sitemap.rb +13 -15
- data/lib/nanoc3/tasks/deploy/rsync.rake +4 -1
- data/lib/nanoc3/tasks.rb +2 -1
- data/lib/nanoc3.rb +24 -1
- metadata +43 -87
- data/NEWS.rdoc +0 -328
- data/README.rdoc +0 -83
- data/lib/nanoc3/base/plugin.rb +0 -88
- data/lib/nanoc3/base/preprocessor_context.rb +0 -37
- data/lib/nanoc3/data_sources/filesystem_combined.rb +0 -214
- data/lib/nanoc3/data_sources/filesystem_common.rb +0 -22
- data/lib/nanoc3/data_sources/filesystem_compact.rb +0 -256
- data/lib/nanoc3/extra/context.rb +0 -24
- data/lib/nanoc3/package.rb +0 -107
- data/vendor/cri/ChangeLog +0 -0
- data/vendor/cri/LICENSE +0 -19
- data/vendor/cri/NEWS +0 -0
- data/vendor/cri/README +0 -4
- data/vendor/cri/Rakefile +0 -25
- data/vendor/cri/lib/cri/base.rb +0 -153
- data/vendor/cri/lib/cri/command.rb +0 -105
- data/vendor/cri/lib/cri/core_ext/string.rb +0 -41
- data/vendor/cri/lib/cri/core_ext.rb +0 -8
- data/vendor/cri/lib/cri/option_parser.rb +0 -186
- data/vendor/cri/lib/cri.rb +0 -12
- data/vendor/cri/test/test_base.rb +0 -6
- data/vendor/cri/test/test_command.rb +0 -6
- data/vendor/cri/test/test_core_ext.rb +0 -21
- data/vendor/cri/test/test_option_parser.rb +0 -279
data/lib/nanoc3/base/compiler.rb
CHANGED
@@ -2,27 +2,37 @@
|
|
2
2
|
|
3
3
|
module Nanoc3
|
4
4
|
|
5
|
-
#
|
6
|
-
# representations.
|
5
|
+
# Responsible for compiling a site’s item representations.
|
7
6
|
class Compiler
|
8
7
|
|
9
8
|
# The compilation stack. When the compiler begins compiling a rep or a
|
10
9
|
# layout, it will be placed on the stack; when it is done compiling the
|
11
10
|
# rep or layout, it will be removed from the stack.
|
11
|
+
#
|
12
|
+
# @return [Array] The compilation stack
|
12
13
|
attr_reader :stack
|
13
14
|
|
14
15
|
# The list of compilation rules that will be used to compile items. This
|
15
|
-
# array will be filled by Nanoc3::Site#load_data.
|
16
|
+
# array will be filled by {Nanoc3::Site#load_data}.
|
17
|
+
#
|
18
|
+
# @return [Array<Nanoc3::Rule>] The list of item compilation rules
|
16
19
|
attr_reader :item_compilation_rules
|
17
20
|
|
18
21
|
# The list of routing rules that will be used to give all items a path.
|
19
|
-
# This array will be filled by Nanoc3::Site#load_data.
|
22
|
+
# This array will be filled by {Nanoc3::Site#load_data}.
|
23
|
+
#
|
24
|
+
# @return [Array<Nanoc3::Rule>] The list of item routing rules
|
20
25
|
attr_reader :item_routing_rules
|
21
26
|
|
22
|
-
# The hash containing layout-to-filter mapping rules.
|
27
|
+
# The hash containing layout-to-filter mapping rules. This hash is
|
28
|
+
# ordered: iterating over the hash will happen in insertion order.
|
29
|
+
#
|
30
|
+
# @return [Hash] The layout-to-filter mapping rules
|
23
31
|
attr_reader :layout_filter_mapping
|
24
32
|
|
25
|
-
# Creates a new compiler
|
33
|
+
# Creates a new compiler fo the given site
|
34
|
+
#
|
35
|
+
# @param [Nanoc3::Site] site The site this compiler belongs to
|
26
36
|
def initialize(site)
|
27
37
|
@site = site
|
28
38
|
|
@@ -36,25 +46,24 @@ module Nanoc3
|
|
36
46
|
# Compiles (part of) the site and writes out the compiled item
|
37
47
|
# representations.
|
38
48
|
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
# compiled.
|
49
|
+
# @param [Nanoc3::Item] item The item that should be compiled, along with
|
50
|
+
# its dependencies. Pass `nil` if the entire site should be compiled.
|
42
51
|
#
|
43
|
-
#
|
52
|
+
# @option params [Boolean] :force (false) true if the rep should be
|
53
|
+
# compiled even if it is not outdated, false if not
|
44
54
|
#
|
45
|
-
#
|
46
|
-
# outdated, false if not. Defaults to false.
|
55
|
+
# @return [void]
|
47
56
|
def run(item=nil, params={})
|
48
57
|
# Create output directory if necessary
|
49
58
|
FileUtils.mkdir_p(@site.config[:output_dir])
|
50
59
|
|
51
60
|
# Load dependencies
|
52
61
|
dependency_tracker.load_graph
|
53
|
-
|
62
|
+
dependency_tracker.print_graph if $DEBUG
|
54
63
|
|
55
64
|
# Get items and reps to compile
|
56
65
|
if item
|
57
|
-
items = [ item ] + dependency_tracker.
|
66
|
+
items = [ item ] + dependency_tracker.successors_of(item)
|
58
67
|
items.uniq!
|
59
68
|
else
|
60
69
|
items = @site.items
|
@@ -62,7 +71,11 @@ module Nanoc3
|
|
62
71
|
reps = items.map { |i| i.reps }.flatten
|
63
72
|
|
64
73
|
# Prepare dependencies
|
65
|
-
|
74
|
+
if params.has_key?(:force) && params[:force]
|
75
|
+
reps.each { |r| r.force_outdated = true }
|
76
|
+
else
|
77
|
+
dependency_tracker.mark_outdated_items
|
78
|
+
end
|
66
79
|
forget_dependencies_if_outdated(items)
|
67
80
|
|
68
81
|
# Compile reps
|
@@ -74,22 +87,37 @@ module Nanoc3
|
|
74
87
|
dependency_tracker.store_graph
|
75
88
|
end
|
76
89
|
|
77
|
-
#
|
90
|
+
# Finds the first matching compilation rule for the given item
|
91
|
+
# representation.
|
92
|
+
#
|
93
|
+
# @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
|
94
|
+
#
|
95
|
+
# @return [Nanoc3::Rule, nil] The compilation rule for the given item rep,
|
96
|
+
# or nil if no rules have been found
|
78
97
|
def compilation_rule_for(rep)
|
79
98
|
@item_compilation_rules.find do |rule|
|
80
99
|
rule.applicable_to?(rep.item) && rule.rep_name == rep.name
|
81
100
|
end
|
82
101
|
end
|
83
102
|
|
84
|
-
#
|
103
|
+
# Finds the first matching routing rule for the given item representation.
|
104
|
+
#
|
105
|
+
# @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
|
106
|
+
#
|
107
|
+
# @return [Nanoc3::Rule, nil] The routing rule for the given item rep, or
|
108
|
+
# nil if no rules have been found
|
85
109
|
def routing_rule_for(rep)
|
86
110
|
@item_routing_rules.find do |rule|
|
87
111
|
rule.applicable_to?(rep.item) && rule.rep_name == rep.name
|
88
112
|
end
|
89
113
|
end
|
90
114
|
|
91
|
-
#
|
92
|
-
#
|
115
|
+
# Finds the filter name and arguments to use for the given layout.
|
116
|
+
#
|
117
|
+
# @param [Nanoc3::Layout] layout The layout for which to fetch the filter.
|
118
|
+
#
|
119
|
+
# @return [Array, nil] A tuple containing the filter name and the filter
|
120
|
+
# arguments for the given layout.
|
93
121
|
def filter_for_layout(layout)
|
94
122
|
@layout_filter_mapping.each_pair do |layout_identifier, filter_name_and_args|
|
95
123
|
return filter_name_and_args if layout.identifier =~ layout_identifier
|
@@ -99,9 +127,13 @@ module Nanoc3
|
|
99
127
|
|
100
128
|
private
|
101
129
|
|
102
|
-
# Compiles
|
130
|
+
# Compiles the given representations.
|
131
|
+
#
|
132
|
+
# @param [Array] reps The item representations to compile.
|
133
|
+
#
|
134
|
+
# @return [void]
|
103
135
|
def compile_reps(reps)
|
104
|
-
active_reps, skipped_reps = reps.partition { |rep| rep.outdated? || rep.item.
|
136
|
+
active_reps, skipped_reps = reps.partition { |rep| rep.outdated? || rep.item.outdated_due_to_dependencies? }
|
105
137
|
inactive_reps = []
|
106
138
|
compiled_reps = []
|
107
139
|
|
@@ -162,10 +194,12 @@ module Nanoc3
|
|
162
194
|
# Compiles the given item representation.
|
163
195
|
#
|
164
196
|
# This method should not be called directly; please use
|
165
|
-
# Nanoc3::Compiler#run instead, and pass this item representation's item
|
166
|
-
# its first argument.
|
197
|
+
# {Nanoc3::Compiler#run} instead, and pass this item representation's item
|
198
|
+
# as its first argument.
|
167
199
|
#
|
168
|
-
#
|
200
|
+
# @param [Nanoc3::ItemRep] rep The rep that is to be compiled
|
201
|
+
#
|
202
|
+
# @return [void]
|
169
203
|
def compile_rep(rep)
|
170
204
|
# Start
|
171
205
|
Nanoc3::NotificationCenter.post(:compilation_started, rep)
|
@@ -183,43 +217,28 @@ module Nanoc3
|
|
183
217
|
Nanoc3::NotificationCenter.post(:compilation_ended, rep)
|
184
218
|
end
|
185
219
|
|
186
|
-
# Returns the dependency tracker for this site
|
220
|
+
# Returns the dependency tracker for this site, creating it first if it
|
221
|
+
# does not yet exist.
|
222
|
+
#
|
223
|
+
# @return [Nanoc3::DependencyTracker] The dependency tracker for this site
|
187
224
|
def dependency_tracker
|
188
225
|
@dependency_tracker ||= Nanoc3::DependencyTracker.new(@site.items)
|
189
226
|
end
|
190
227
|
|
191
|
-
# Marks the necessary items as outdated.
|
192
|
-
def mark_outdated_items(reps, force)
|
193
|
-
if force
|
194
|
-
reps.each { |r| r.force_outdated = true }
|
195
|
-
else
|
196
|
-
dependency_tracker.mark_outdated_items
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
228
|
# Clears the list of dependencies for items that will be recompiled.
|
229
|
+
#
|
230
|
+
# @param [Array<Nanoc3::Item>] items The list of items for which to forget
|
231
|
+
# the dependencies
|
232
|
+
#
|
233
|
+
# @return [void]
|
201
234
|
def forget_dependencies_if_outdated(items)
|
202
235
|
items.each do |i|
|
203
|
-
if i.outdated? || i.
|
236
|
+
if i.outdated? || i.outdated_due_to_dependencies?
|
204
237
|
dependency_tracker.forget_dependencies_for(i)
|
205
238
|
end
|
206
239
|
end
|
207
240
|
end
|
208
241
|
|
209
|
-
# Prints the dependency graph.
|
210
|
-
def print_dependency_graph
|
211
|
-
graph = dependency_tracker.instance_eval { @graph }
|
212
|
-
puts "DEPENDENCY GRAPH:"
|
213
|
-
graph.each_pair do |key, values|
|
214
|
-
puts "#{key.inspect} depends on:"
|
215
|
-
values.each do |value|
|
216
|
-
puts " #{value.inspect}"
|
217
|
-
end
|
218
|
-
puts " (nothing!)" if values.empty?
|
219
|
-
puts
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
242
|
end
|
224
243
|
|
225
244
|
end
|
@@ -2,17 +2,22 @@
|
|
2
2
|
|
3
3
|
module Nanoc3
|
4
4
|
|
5
|
-
#
|
6
|
-
# rules file.
|
5
|
+
# Contains methods that will be executed by the site’s `Rules` file.
|
7
6
|
class CompilerDSL
|
8
7
|
|
9
8
|
# Creates a new compiler DSL for the given compiler.
|
9
|
+
#
|
10
|
+
# @param [Nanoc3::Site] site The site this DSL belongs to
|
10
11
|
def initialize(site)
|
11
12
|
@site = site
|
12
13
|
end
|
13
14
|
|
14
15
|
# Creates a preprocessor block that will be executed after all data is
|
15
16
|
# loaded, but before the site is compiled.
|
17
|
+
#
|
18
|
+
# @yield The block that will be executed before site compilation starts
|
19
|
+
#
|
20
|
+
# @return [void]
|
16
21
|
def preprocess(&block)
|
17
22
|
@site.preprocessor = block
|
18
23
|
end
|
@@ -21,21 +26,32 @@ module Nanoc3
|
|
21
26
|
# given identifier, which may either be a string containing the *
|
22
27
|
# wildcard, or a regular expression.
|
23
28
|
#
|
24
|
-
# This rule will be applicable to reps with a name equal to
|
25
|
-
#
|
29
|
+
# This rule will be applicable to reps with a name equal to `:default`;
|
30
|
+
# this can be changed by giving an explicit `:rep` parameter.
|
26
31
|
#
|
27
32
|
# An item rep will be compiled by calling the given block and passing the
|
28
33
|
# rep as a block argument.
|
29
34
|
#
|
30
|
-
#
|
35
|
+
# @param [String] identifier A pattern matching identifiers of items that
|
36
|
+
# should be compiled using this rule
|
37
|
+
#
|
38
|
+
# @option params [Symbol] :rep (:default) The name of the representation
|
39
|
+
# that should be compiled using this rule
|
31
40
|
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
41
|
+
# @yield The block that will be executed when an item matching this
|
42
|
+
# compilation rule needs to be compiled
|
43
|
+
#
|
44
|
+
# @return [void]
|
45
|
+
#
|
46
|
+
# @example Compiling the default rep of the `/foo/` item
|
47
|
+
# compile '/foo/' do
|
48
|
+
# rep.filter :erb
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# @example Compiling the `:raw` rep of the `/bar/` item
|
52
|
+
# compile '/bar/', :rep => :raw do
|
53
|
+
# # do nothing
|
54
|
+
# end
|
39
55
|
def compile(identifier, params={}, &block)
|
40
56
|
# Require block
|
41
57
|
raise ArgumentError.new("#compile requires a block") unless block_given?
|
@@ -49,24 +65,35 @@ module Nanoc3
|
|
49
65
|
end
|
50
66
|
|
51
67
|
# Creates a routing rule for all items whose identifier match the
|
52
|
-
# given identifier, which may either be a string containing the
|
68
|
+
# given identifier, which may either be a string containing the `*`
|
53
69
|
# wildcard, or a regular expression.
|
54
70
|
#
|
55
|
-
# This rule will be applicable to reps with a name equal to
|
56
|
-
# this can be changed by
|
71
|
+
# This rule will be applicable to reps with a name equal to `:default`;
|
72
|
+
# this can be changed by giving an explicit `:rep` parameter.
|
57
73
|
#
|
58
74
|
# The path of an item rep will be determined by calling the given block
|
59
75
|
# and passing the rep as a block argument.
|
60
76
|
#
|
61
|
-
#
|
77
|
+
# @param [String] identifier A pattern matching identifiers of items that
|
78
|
+
# should be routed using this rule
|
62
79
|
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
80
|
+
# @option params [Symbol] :rep (:default) The name of the representation
|
81
|
+
# that should be routed using this rule
|
82
|
+
#
|
83
|
+
# @yield The block that will be executed when an item matching this
|
84
|
+
# compilation rule needs to be routed
|
85
|
+
#
|
86
|
+
# @return [void]
|
87
|
+
#
|
88
|
+
# @example Routing the default rep of the `/foo/` item
|
89
|
+
# route '/foo/' do
|
90
|
+
# item.identifier + 'index.html'
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# @example Routing the `:raw` rep of the `/bar/` item
|
94
|
+
# route '/bar/', :rep => :raw do
|
95
|
+
# '/raw' + item.identifier + 'index.txt'
|
96
|
+
# end
|
70
97
|
def route(identifier, params={}, &block)
|
71
98
|
# Require block
|
72
99
|
raise ArgumentError.new("#route requires a block") unless block_given?
|
@@ -85,18 +112,32 @@ module Nanoc3
|
|
85
112
|
# using the filter specified in the second argument. The params hash
|
86
113
|
# contains filter arguments that will be passed to the filter.
|
87
114
|
#
|
88
|
-
#
|
115
|
+
# @param [String] identifier A pattern matching identifiers of layouts
|
116
|
+
# that should be filtered using this rule
|
117
|
+
#
|
118
|
+
# @param [Symbol] filter_name The name of the filter that should be run
|
119
|
+
# when processing the layout
|
120
|
+
#
|
121
|
+
# @param [Hash] params Extra filter arguments that should be passed to the
|
122
|
+
# filter when processing the layout (see {Nanoc3::Filter#run})
|
123
|
+
#
|
124
|
+
# @return [void]
|
125
|
+
#
|
126
|
+
# @example Specifying the filter to use for a layout
|
127
|
+
# layout '/default/', :erb
|
89
128
|
#
|
90
|
-
#
|
91
|
-
#
|
129
|
+
# @example Using custom filter arguments for a layout
|
130
|
+
# layout '/custom/', :haml, :format => :html5
|
92
131
|
def layout(identifier, filter_name, params={})
|
93
132
|
@site.compiler.layout_filter_mapping[identifier_to_regex(identifier)] = [ filter_name, params ]
|
94
133
|
end
|
95
134
|
|
96
135
|
private
|
97
136
|
|
98
|
-
# Converts the given identifier, which can contain the '*'
|
99
|
-
#
|
137
|
+
# Converts the given identifier, which can contain the '*' or '+'
|
138
|
+
# wildcard characters, matching zero or more resp. one or more
|
139
|
+
# characters, to a regex. For example, 'foo/*/bar' is transformed
|
140
|
+
# into /^foo\/(.*?)\/bar$/ and 'foo+' is transformed into /^foo(.+?)/.
|
100
141
|
def identifier_to_regex(identifier)
|
101
142
|
if identifier.is_a? String
|
102
143
|
# Add leading/trailing slashes if necessary
|
@@ -104,7 +145,7 @@ module Nanoc3
|
|
104
145
|
new_identifier[/^/] = '/' if identifier[0,1] != '/'
|
105
146
|
new_identifier[/$/] = '/' unless [ '*', '/' ].include?(identifier[-1,1])
|
106
147
|
|
107
|
-
/^#{new_identifier.gsub('*', '(.*?)')}$/
|
148
|
+
/^#{new_identifier.gsub('*', '(.*?)').gsub('+', '(.+?)')}$/
|
108
149
|
else
|
109
150
|
identifier
|
110
151
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Nanoc3
|
4
|
+
|
5
|
+
# Provides a context and a binding for use in filters such as the ERB and
|
6
|
+
# Haml ones.
|
7
|
+
class Context
|
8
|
+
|
9
|
+
# Creates a new context based off the contents of the hash.
|
10
|
+
#
|
11
|
+
# Each pair in the hash will be converted to an instance variable and an
|
12
|
+
# instance method. For example, passing the hash `{ :foo => 'bar' }` will
|
13
|
+
# cause `@foo` to have the value `"bar"`, and the instance method `#foo`
|
14
|
+
# to return the same value `"bar"`.
|
15
|
+
#
|
16
|
+
# @param [Hash] hash A list of key-value pairs to make available
|
17
|
+
#
|
18
|
+
# @example Defining a context and accessing values
|
19
|
+
#
|
20
|
+
# context = Nanoc3::Context.new(
|
21
|
+
# :name => 'Max Payne',
|
22
|
+
# :location => 'in a cheap motel'
|
23
|
+
# )
|
24
|
+
# context.instance_eval do
|
25
|
+
# "I am #{name} and I am hiding #{@location}."
|
26
|
+
# end
|
27
|
+
# # => "I am Max Payne and I am hiding in a cheap motel."
|
28
|
+
def initialize(hash)
|
29
|
+
hash.each_pair do |key, value|
|
30
|
+
# Build instance variable
|
31
|
+
instance_variable_set('@' + key.to_s, value)
|
32
|
+
|
33
|
+
# Define method
|
34
|
+
metaclass = (class << self ; self ; end)
|
35
|
+
metaclass.send(:define_method, key) { value }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a binding for this instance.
|
40
|
+
#
|
41
|
+
# @return [Binding] A binding for this instance
|
42
|
+
def get_binding
|
43
|
+
binding
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module Nanoc3::ArrayExtensions
|
4
4
|
|
5
5
|
# Returns a new array where all items' keys are recursively converted to symbols by calling #symbolize_keys.
|
6
|
+
#
|
7
|
+
# @return [Array] The converted array
|
6
8
|
def symbolize_keys
|
7
9
|
inject([]) do |array, element|
|
8
10
|
array + [ element.respond_to?(:symbolize_keys) ? element.symbolize_keys : element ]
|
@@ -10,6 +12,8 @@ module Nanoc3::ArrayExtensions
|
|
10
12
|
end
|
11
13
|
|
12
14
|
# Returns a new array where all items' keys are recursively converted to strings by calling #stringify_keys.
|
15
|
+
#
|
16
|
+
# @return [Array] The converted array
|
13
17
|
def stringify_keys
|
14
18
|
inject([]) do |array, element|
|
15
19
|
array + [ element.respond_to?(:stringify_keys) ? element.stringify_keys : element ]
|
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
module Nanoc3::HashExtensions
|
4
4
|
|
5
|
-
# Returns a new hash where all keys are recursively converted
|
5
|
+
# Returns a new hash where all keys are recursively converted to symbols.
|
6
|
+
#
|
7
|
+
# @return [Hash] The converted hash
|
6
8
|
def symbolize_keys
|
7
9
|
inject({}) do |hash, (key, value)|
|
8
10
|
hash.merge(key.to_sym => value.respond_to?(:symbolize_keys) ? value.symbolize_keys : value)
|
@@ -10,6 +12,8 @@ module Nanoc3::HashExtensions
|
|
10
12
|
end
|
11
13
|
|
12
14
|
# Returns a new hash where all keys are recursively converted to strings.
|
15
|
+
#
|
16
|
+
# @return [Hash] The converted hash
|
13
17
|
def stringify_keys
|
14
18
|
inject({}) do |hash, (key, value)|
|
15
19
|
hash.merge(key.to_s => value.respond_to?(:stringify_keys) ? value.stringify_keys : value)
|