nanoc3 3.1.0b1 → 3.1.0b2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/nanoc3.rb +1 -1
- data/lib/nanoc3/base/core_ext/string.rb +18 -0
- data/lib/nanoc3/base/dependency_tracker.rb +8 -6
- data/lib/nanoc3/base/directed_graph.rb +52 -140
- data/lib/nanoc3/base/errors.rb +13 -13
- data/lib/nanoc3/base/filter.rb +1 -1
- data/lib/nanoc3/base/item.rb +6 -4
- data/lib/nanoc3/base/item_rep.rb +29 -9
- data/lib/nanoc3/base/site.rb +4 -4
- data/lib/nanoc3/cli/base.rb +3 -1
- data/lib/nanoc3/cli/commands/create_site.rb +55 -16
- data/lib/nanoc3/cli/commands/debug.rb +21 -35
- data/lib/nanoc3/extra/auto_compiler.rb +17 -27
- data/lib/nanoc3/filters/bluecloth.rb +6 -0
- data/lib/nanoc3/filters/coderay.rb +4 -0
- data/lib/nanoc3/filters/colorize_syntax.rb +36 -0
- data/lib/nanoc3/filters/erb.rb +6 -0
- data/lib/nanoc3/filters/erubis.rb +6 -0
- data/lib/nanoc3/filters/haml.rb +6 -0
- data/lib/nanoc3/filters/kramdown.rb +6 -0
- data/lib/nanoc3/filters/less.rb +6 -0
- data/lib/nanoc3/filters/markaby.rb +6 -0
- data/lib/nanoc3/filters/maruku.rb +6 -0
- data/lib/nanoc3/filters/rainpress.rb +6 -0
- data/lib/nanoc3/filters/rdiscount.rb +6 -0
- data/lib/nanoc3/filters/rdoc.rb +6 -0
- data/lib/nanoc3/filters/redcloth.rb +6 -0
- data/lib/nanoc3/filters/relativize_paths.rb +12 -0
- data/lib/nanoc3/filters/rubypants.rb +6 -0
- data/lib/nanoc3/filters/sass.rb +6 -0
- data/lib/nanoc3/helpers/blogging.rb +12 -5
- data/lib/nanoc3/helpers/breadcrumbs.rb +16 -9
- metadata +3 -3
data/lib/nanoc3.rb
CHANGED
@@ -9,6 +9,24 @@ module Nanoc3::StringExtensions
|
|
9
9
|
"/#{self}/".gsub(/^\/+|\/+$/, '/')
|
10
10
|
end
|
11
11
|
|
12
|
+
# Replaces Unicode characters with their ASCII decompositions if the
|
13
|
+
# environment does not support Unicode.
|
14
|
+
#
|
15
|
+
# This method is not suited for general usage. If you need similar
|
16
|
+
# functionality, consider using the Iconv library instead.
|
17
|
+
#
|
18
|
+
# @return [String] The decomposed string
|
19
|
+
def make_compatible_with_env
|
20
|
+
# Check whether environment supports Unicode
|
21
|
+
# TODO this is ugly, and there most likely are better ways to do this
|
22
|
+
is_unicode_supported = %w( LC_ALL LC_CTYPE LANG ).any? { |e| ENV[e] =~ /UTF/ }
|
23
|
+
return self if is_unicode_supported
|
24
|
+
|
25
|
+
# Decompose if necessary
|
26
|
+
# TODO this decomposition is not generally usable
|
27
|
+
self.gsub(/“|”/, '"').gsub(/‘|’/, '\'').gsub('…', '...')
|
28
|
+
end
|
29
|
+
|
12
30
|
end
|
13
31
|
|
14
32
|
class String
|
@@ -27,6 +27,10 @@ module Nanoc3
|
|
27
27
|
# stored
|
28
28
|
attr_accessor :filename
|
29
29
|
|
30
|
+
# @return [Array<Nanoc3::Item>] The list of items that is being tracked
|
31
|
+
# by the dependency tracker
|
32
|
+
attr_reader :items
|
33
|
+
|
30
34
|
# The version of the file format used to store dependencies.
|
31
35
|
STORE_VERSION = 2
|
32
36
|
|
@@ -217,14 +221,14 @@ module Nanoc3
|
|
217
221
|
|
218
222
|
# Mark successors of outdated items as outdated
|
219
223
|
require 'set'
|
220
|
-
processed = Set.new
|
221
224
|
unprocessed = @items.select { |i| i.outdated? }
|
225
|
+
seen = Set.new(unprocessed)
|
222
226
|
until unprocessed.empty?
|
223
227
|
item = unprocessed.shift
|
224
|
-
processed << item
|
225
228
|
|
226
229
|
self.direct_successors_of(item).each do |successor|
|
227
|
-
next if
|
230
|
+
next if seen.include?(successor)
|
231
|
+
seen << successor
|
228
232
|
|
229
233
|
successor.outdated_due_to_dependencies = true
|
230
234
|
unprocessed << successor
|
@@ -241,9 +245,7 @@ module Nanoc3
|
|
241
245
|
#
|
242
246
|
# @return [void]
|
243
247
|
def forget_dependencies_for(item)
|
244
|
-
@graph.
|
245
|
-
@graph.remove_edge(v, item)
|
246
|
-
end
|
248
|
+
@graph.delete_edges_to(item)
|
247
249
|
end
|
248
250
|
|
249
251
|
# Prints the dependency graph in human-readable form.
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
module Nanoc3
|
4
6
|
|
5
7
|
# Represents a directed graph. It is used by the dependency tracker for
|
6
|
-
# storing and querying dependencies between items.
|
7
|
-
# will be stored as an adjacency matrix. For this, the
|
8
|
-
# {Nanoc3::DirectedGraph::SquareBooleanMatrix} class is used.
|
8
|
+
# storing and querying dependencies between items.
|
9
9
|
#
|
10
10
|
# @example Creating and using a directed graph
|
11
11
|
#
|
@@ -33,82 +33,6 @@ module Nanoc3
|
|
33
33
|
# # => %w( b c )
|
34
34
|
class DirectedGraph
|
35
35
|
|
36
|
-
# A square matrix that contains boolean values. It is used as an adjacency
|
37
|
-
# matrix by the {Nanoc3::DirectedGraph} class.
|
38
|
-
#
|
39
|
-
# This class is a helper class, which means that it is not used directly
|
40
|
-
# by nanoc. Future versions of nanoc may no longer contain this class. Do
|
41
|
-
# not depend on this class to be available.
|
42
|
-
class SquareBooleanMatrix
|
43
|
-
|
44
|
-
# Creates a new matrix with the given number of rows/columns.
|
45
|
-
#
|
46
|
-
# @param [Number] size The number of elements along both sides of the
|
47
|
-
# matrix (in other words, the square root of the number of elements)
|
48
|
-
def initialize(size)
|
49
|
-
@size = size
|
50
|
-
end
|
51
|
-
|
52
|
-
# Gets the value at the given x/y coordinates.
|
53
|
-
#
|
54
|
-
# @param [Number] x The X coordinate
|
55
|
-
# @param [Number] y The Y coordinate
|
56
|
-
#
|
57
|
-
# @return The value at the given coordinates
|
58
|
-
def [](x, y)
|
59
|
-
@data ||= {}
|
60
|
-
@data[x] ||= {}
|
61
|
-
@data[x].has_key?(y) ? @data[x][y] : false
|
62
|
-
end
|
63
|
-
|
64
|
-
# Sets the value at the given x/y coordinates.
|
65
|
-
#
|
66
|
-
# @param [Number] x The X coordinate
|
67
|
-
# @param [Number] y The Y coordinate
|
68
|
-
# @param value The value to set at the given coordinates
|
69
|
-
#
|
70
|
-
# @return [void]
|
71
|
-
def []=(x, y, value)
|
72
|
-
@data ||= {}
|
73
|
-
@data[x] ||= {}
|
74
|
-
@data[x][y] = value
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns a string representing this matrix in ASCII art.
|
78
|
-
#
|
79
|
-
# @return [String] The string representation of this matrix
|
80
|
-
def to_s
|
81
|
-
s = ''
|
82
|
-
|
83
|
-
# Calculate column width
|
84
|
-
width = (@size-1).to_s.size
|
85
|
-
|
86
|
-
# Add header
|
87
|
-
s << ' ' + ' '*width + ' '
|
88
|
-
@size.times { |i| s << '| ' + format("%#{width}i", i) + ' ' }
|
89
|
-
s << "\n"
|
90
|
-
|
91
|
-
# Add rows
|
92
|
-
@size.times do |x|
|
93
|
-
# Add line
|
94
|
-
s << '-' + '-'*width + '-'
|
95
|
-
@size.times { |i| s << '+-' + '-'*width + '-' }
|
96
|
-
s << "\n"
|
97
|
-
|
98
|
-
# Add actual row
|
99
|
-
s << ' ' + format("%#{width}i", x)+ ' '
|
100
|
-
@size.times do |y|
|
101
|
-
s << '| ' + format("%#{width}s", self[x, y] ? '*' : ' ') + ' '
|
102
|
-
end
|
103
|
-
s << "\n"
|
104
|
-
end
|
105
|
-
|
106
|
-
# Done
|
107
|
-
s
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
36
|
# The list of vertices in this graph.
|
113
37
|
#
|
114
38
|
# @return [Array]
|
@@ -117,10 +41,16 @@ module Nanoc3
|
|
117
41
|
# Creates a new directed graph with the given vertices.
|
118
42
|
def initialize(vertices)
|
119
43
|
@vertices = vertices
|
120
|
-
generate_indices
|
121
|
-
invalidate_successor_predecessor_cache
|
122
44
|
|
123
|
-
@
|
45
|
+
@from_graph = {}
|
46
|
+
@to_graph = {}
|
47
|
+
|
48
|
+
@vertice_indexes = {}
|
49
|
+
vertices.each_with_index do |v, i|
|
50
|
+
@vertice_indexes[v] = i
|
51
|
+
end
|
52
|
+
|
53
|
+
invalidate_caches
|
124
54
|
end
|
125
55
|
|
126
56
|
# Adds an edge from the first vertex to the second vertex.
|
@@ -130,9 +60,13 @@ module Nanoc3
|
|
130
60
|
#
|
131
61
|
# @return [void]
|
132
62
|
def add_edge(from, to)
|
133
|
-
|
134
|
-
@
|
135
|
-
|
63
|
+
@from_graph[from] ||= Set.new
|
64
|
+
@from_graph[from] << to
|
65
|
+
|
66
|
+
@to_graph[to] ||= Set.new
|
67
|
+
@to_graph[to] << from
|
68
|
+
|
69
|
+
invalidate_caches
|
136
70
|
end
|
137
71
|
|
138
72
|
# Removes the edge from the first vertex to the second vertex. If the
|
@@ -143,9 +77,26 @@ module Nanoc3
|
|
143
77
|
#
|
144
78
|
# @return [void]
|
145
79
|
def remove_edge(from, to)
|
146
|
-
|
147
|
-
@
|
148
|
-
|
80
|
+
@from_graph[from] ||= Set.new
|
81
|
+
@from_graph[from].delete(to)
|
82
|
+
|
83
|
+
@to_graph[to] ||= Set.new
|
84
|
+
@to_graph[to].delete(from)
|
85
|
+
|
86
|
+
invalidate_caches
|
87
|
+
end
|
88
|
+
|
89
|
+
# Deletes all edges going to the given vertex.
|
90
|
+
#
|
91
|
+
# @param to Vertex to which all edges should be removed
|
92
|
+
#
|
93
|
+
# @return [void]
|
94
|
+
def delete_edges_to(to)
|
95
|
+
@to_graph[to] ||= Set.new
|
96
|
+
@to_graph[to].each do |from|
|
97
|
+
@from_graph[from].delete(to)
|
98
|
+
end
|
99
|
+
@to_graph.delete(to)
|
149
100
|
end
|
150
101
|
|
151
102
|
# Returns the direct predecessors of the given vertex, i.e. the vertices
|
@@ -155,12 +106,7 @@ module Nanoc3
|
|
155
106
|
#
|
156
107
|
# @return [Array] Direct predecessors of the given vertex
|
157
108
|
def direct_predecessors_of(to)
|
158
|
-
@
|
159
|
-
@vertices.select do |from|
|
160
|
-
from_index, to_index = indices_of(from, to)
|
161
|
-
@matrix[from_index, to_index] == true
|
162
|
-
end
|
163
|
-
end
|
109
|
+
@to_graph[to].to_a
|
164
110
|
end
|
165
111
|
|
166
112
|
# Returns the direct successors of the given vertex, i.e. the vertices y
|
@@ -170,12 +116,7 @@ module Nanoc3
|
|
170
116
|
#
|
171
117
|
# @return [Array] Direct successors of the given vertex
|
172
118
|
def direct_successors_of(from)
|
173
|
-
@
|
174
|
-
@vertices.select do |to|
|
175
|
-
from_index, to_index = indices_of(from, to)
|
176
|
-
@matrix[from_index, to_index] == true
|
177
|
-
end
|
178
|
-
end
|
119
|
+
@from_graph[from].to_a
|
179
120
|
end
|
180
121
|
|
181
122
|
# Returns the predecessors of the given vertex, i.e. the vertices x for
|
@@ -204,59 +145,30 @@ module Nanoc3
|
|
204
145
|
# @return [Array] The list of all edges in this graph.
|
205
146
|
def edges
|
206
147
|
result = []
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
from_index, to_index = indices_of(from, to)
|
211
|
-
next if @matrix[from_index, to_index] == false
|
212
|
-
|
213
|
-
result << [ from_index, to_index ]
|
148
|
+
@vertices.each_with_index do |v, i|
|
149
|
+
direct_successors_of(v).map { |v2| @vertice_indexes[v2] }.each do |i2|
|
150
|
+
result << [ i, i2 ]
|
214
151
|
end
|
215
152
|
end
|
216
|
-
|
217
153
|
result
|
218
154
|
end
|
219
155
|
|
220
|
-
# Returns a string representing this graph in ASCII art (or, to be more
|
221
|
-
# precise, the string representation of the matrix backing this graph).
|
222
|
-
#
|
223
|
-
# @return [String] The string representation of this graph
|
224
|
-
def to_s
|
225
|
-
@matrix.to_s
|
226
|
-
end
|
227
|
-
|
228
156
|
private
|
229
157
|
|
230
|
-
#
|
231
|
-
|
232
|
-
|
233
|
-
@
|
234
|
-
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
# Invalidates the cache that contains successors and predecessors (both
|
239
|
-
# direct and indirect).
|
240
|
-
def invalidate_successor_predecessor_cache
|
241
|
-
@successors = {}
|
242
|
-
@direct_successors = {}
|
243
|
-
@predecessors = {}
|
244
|
-
@direct_predecessors = {}
|
245
|
-
end
|
246
|
-
|
247
|
-
# Returns an array of indices for the given vertices. Raises an error if
|
248
|
-
# one or more given objects are not vertices.
|
249
|
-
def indices_of(*vertices)
|
250
|
-
vertices.map { |v| @indices[v] or raise RuntimeError, "#{v.inspect} not a vertex" }
|
158
|
+
# Invalidates cached data. This method should be called when the internal
|
159
|
+
# graph representation is changed.
|
160
|
+
def invalidate_caches
|
161
|
+
@predecessors = {}
|
162
|
+
@successors = {}
|
251
163
|
end
|
252
164
|
|
253
165
|
# Recursively finds vertices, starting at the vertex start, using the
|
254
166
|
# given method, which should be a symbol to a method that takes a vertex
|
255
167
|
# and returns related vertices (e.g. predecessors, successors).
|
256
168
|
def recursively_find_vertices(start, method)
|
257
|
-
all_vertices =
|
169
|
+
all_vertices = Set.new
|
258
170
|
|
259
|
-
processed_vertices =
|
171
|
+
processed_vertices = Set.new
|
260
172
|
unprocessed_vertices = [ start ]
|
261
173
|
|
262
174
|
until unprocessed_vertices.empty?
|
@@ -272,7 +184,7 @@ module Nanoc3
|
|
272
184
|
end
|
273
185
|
end
|
274
186
|
|
275
|
-
all_vertices
|
187
|
+
all_vertices.to_a
|
276
188
|
end
|
277
189
|
|
278
190
|
end
|
data/lib/nanoc3/base/errors.rb
CHANGED
@@ -16,7 +16,7 @@ module Nanoc3
|
|
16
16
|
# @param [String] data_source_name The data source name for which no
|
17
17
|
# data source could be found
|
18
18
|
def initialize(data_source_name)
|
19
|
-
super("The data source specified in the site
|
19
|
+
super("The data source specified in the site’s configuration file, “#{data_source_name}”, does not exist.".make_compatible_with_env)
|
20
20
|
end
|
21
21
|
|
22
22
|
end
|
@@ -28,7 +28,7 @@ module Nanoc3
|
|
28
28
|
# @param [String] layout_identifier The layout identifier for which no
|
29
29
|
# layout could be found
|
30
30
|
def initialize(layout_identifier)
|
31
|
-
super("The site does not have a layout with identifier
|
31
|
+
super("The site does not have a layout with identifier “#{layout_identifier}”.".make_compatible_with_env)
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
@@ -40,7 +40,7 @@ module Nanoc3
|
|
40
40
|
# @param [Symbol] filter_name The filter name for which no filter could
|
41
41
|
# be found
|
42
42
|
def initialize(filter_name)
|
43
|
-
super("The requested filter,
|
43
|
+
super("The requested filter, “#{filter_name}”, does not exist.".make_compatible_with_env)
|
44
44
|
end
|
45
45
|
|
46
46
|
end
|
@@ -53,7 +53,7 @@ module Nanoc3
|
|
53
53
|
# @param [String] layout_identifier The identifier of the layout for
|
54
54
|
# which the filter could not be determined
|
55
55
|
def initialize(layout_identifier)
|
56
|
-
super("The filter to be used for the
|
56
|
+
super("The filter to be used for the “#{layout_identifier}” layout could not be determined. Make sure the layout does have a filter.".make_compatible_with_env)
|
57
57
|
end
|
58
58
|
|
59
59
|
end
|
@@ -70,7 +70,7 @@ module Nanoc3
|
|
70
70
|
# example, if the given type is `"site"`, plural would be `false`; if
|
71
71
|
# the given type is `"items"`, plural would be `true`.
|
72
72
|
def initialize(type, plural)
|
73
|
-
super("#{type} #{plural ? 'are' : 'is'} not available yet. You may be missing a Nanoc3::Site#load_data call.")
|
73
|
+
super("#{type} #{plural ? 'are' : 'is'} not available yet. You may be missing a Nanoc3::Site#load_data call.".make_compatible_with_env)
|
74
74
|
end
|
75
75
|
|
76
76
|
end
|
@@ -82,7 +82,7 @@ module Nanoc3
|
|
82
82
|
# @param [Array<Nanoc3::ItemRep>] reps A list of item representations
|
83
83
|
# that mutually depend on each other
|
84
84
|
def initialize(reps)
|
85
|
-
super("The site cannot be compiled because the following items mutually depend on each other: #{reps.inspect}.")
|
85
|
+
super("The site cannot be compiled because the following items mutually depend on each other: #{reps.inspect}.".make_compatible_with_env)
|
86
86
|
end
|
87
87
|
|
88
88
|
end
|
@@ -92,7 +92,7 @@ module Nanoc3
|
|
92
92
|
class NoRulesFileFound < Generic
|
93
93
|
|
94
94
|
def initialize
|
95
|
-
super("This site does not have a rules file, which is required for nanoc sites.")
|
95
|
+
super("This site does not have a rules file, which is required for nanoc sites.".make_compatible_with_env)
|
96
96
|
end
|
97
97
|
|
98
98
|
end
|
@@ -104,7 +104,7 @@ module Nanoc3
|
|
104
104
|
# @param [Nanoc3::Item] item The item for which no compilation rule
|
105
105
|
# could be found
|
106
106
|
def initialize(item)
|
107
|
-
super("No compilation rules were found for the
|
107
|
+
super("No compilation rules were found for the “#{item.identifier}” item.".make_compatible_with_env)
|
108
108
|
end
|
109
109
|
|
110
110
|
end
|
@@ -116,7 +116,7 @@ module Nanoc3
|
|
116
116
|
# @param [Nanoc3::Item] item The item for which no routing rule could be
|
117
117
|
# found
|
118
118
|
def initialize(rep)
|
119
|
-
super("No routing rules were found for the
|
119
|
+
super("No routing rules were found for the “#{rep.item.identifier}” item (rep “#{rep.name}”).".make_compatible_with_env)
|
120
120
|
end
|
121
121
|
|
122
122
|
end
|
@@ -133,7 +133,7 @@ module Nanoc3
|
|
133
133
|
# compiled
|
134
134
|
def initialize(rep)
|
135
135
|
@rep = rep
|
136
|
-
super("The
|
136
|
+
super("The “#{rep.item.identifier}” item (rep “#{rep.name}”) cannot currently be compiled yet due to an unmet dependency.".make_compatible_with_env)
|
137
137
|
end
|
138
138
|
|
139
139
|
end
|
@@ -144,7 +144,7 @@ module Nanoc3
|
|
144
144
|
# @param [Nanoc3::ItemRep] The item representation that was attempted to
|
145
145
|
# be laid out
|
146
146
|
def initialize(rep)
|
147
|
-
super("The
|
147
|
+
super("The “{rep.item.identifier}” item (rep “#{rep.name}”) cannot be laid out because it is a binary item.".make_compatible_with_env)
|
148
148
|
end
|
149
149
|
|
150
150
|
end
|
@@ -158,7 +158,7 @@ module Nanoc3
|
|
158
158
|
#
|
159
159
|
# @param [Class] filter_class The filter class that was used
|
160
160
|
def initialize(rep, filter_class)
|
161
|
-
super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because textual filters cannot be used on binary items.")
|
161
|
+
super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because textual filters cannot be used on binary items.".make_compatible_with_env)
|
162
162
|
end
|
163
163
|
|
164
164
|
end
|
@@ -172,7 +172,7 @@ module Nanoc3
|
|
172
172
|
#
|
173
173
|
# @param [Class] filter_class The filter class that was used
|
174
174
|
def initialize(rep, filter_class)
|
175
|
-
super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because binary filters cannot be used on textual items.")
|
175
|
+
super("The “#{filter_class.inspect}” filter cannot be used to filter the “#{rep.item.identifier}” item (rep “#{rep.name}”), because binary filters cannot be used on textual items.".make_compatible_with_env)
|
176
176
|
end
|
177
177
|
|
178
178
|
end
|
data/lib/nanoc3/base/filter.rb
CHANGED
@@ -94,7 +94,7 @@ module Nanoc3
|
|
94
94
|
#
|
95
95
|
# @param [String] content_or_filename The unprocessed content that should
|
96
96
|
# be filtered (if the item is a textual item) or the path to the file that
|
97
|
-
# should be fitlered (if the item is a
|
97
|
+
# should be fitlered (if the item is a binary item)
|
98
98
|
#
|
99
99
|
# @param [Hash] params A hash containing parameters. Filter subclasses can
|
100
100
|
# use these parameters to allow modifying the filter's behaviour.
|
data/lib/nanoc3/base/item.rb
CHANGED
@@ -111,14 +111,16 @@ module Nanoc3
|
|
111
111
|
# from which the compiled content should be fetched. By default, the
|
112
112
|
# compiled content will be fetched from the default representation.
|
113
113
|
#
|
114
|
-
# @option params [String] :snapshot
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
114
|
+
# @option params [String] :snapshot The name of the snapshot from which to
|
115
|
+
# fetch the compiled content. By default, the returned compiled content
|
116
|
+
# will be the content compiled right before the first layout call (if
|
117
|
+
# any).
|
118
118
|
#
|
119
119
|
# @return [String] The compiled content of the given rep (or the default
|
120
120
|
# rep if no rep is specified) at the given snapshot (or the default
|
121
121
|
# snapshot if no snapshot is specified)
|
122
|
+
#
|
123
|
+
# @see ItemRep#compiled_content
|
122
124
|
def compiled_content(params={})
|
123
125
|
# Get rep
|
124
126
|
rep_name = params[:rep] || :default
|
data/lib/nanoc3/base/item_rep.rb
CHANGED
@@ -192,6 +192,11 @@ module Nanoc3
|
|
192
192
|
snapshot_name ||= :last
|
193
193
|
end
|
194
194
|
|
195
|
+
# Check presence of snapshot
|
196
|
+
if @content[snapshot_name].nil?
|
197
|
+
warn "WARNING: The “#{self.item.identifier}” item (rep “#{self.name}”) does not have the requested snapshot named #{snapshot_name.inspect}.\n\n* Make sure that you are requesting the correct snapshot.\n* It is not possible to request the compiled content of a binary item representation; if this item is marked as binary even though you believe it should be textual, you may need to add the extension of this item to the site configuration’s `text_extensions` array.".make_compatible_with_env
|
198
|
+
end
|
199
|
+
|
195
200
|
# Get content
|
196
201
|
@content[snapshot_name]
|
197
202
|
end
|
@@ -333,6 +338,9 @@ module Nanoc3
|
|
333
338
|
File.open(self.raw_path, 'w') { |io| io.write(@content[:last]) }
|
334
339
|
@written = true
|
335
340
|
|
341
|
+
# Generate diff
|
342
|
+
generate_diff
|
343
|
+
|
336
344
|
# Check if file was modified
|
337
345
|
@modified = File.read(self.raw_path) != @old_content
|
338
346
|
end
|
@@ -346,20 +354,18 @@ module Nanoc3
|
|
346
354
|
# content in `diff(1)` format, or nil if there is no previous compiled
|
347
355
|
# content
|
348
356
|
def diff
|
349
|
-
# Check if content can be diffed
|
350
357
|
# TODO allow binary diffs
|
351
|
-
return nil if self.binary?
|
352
358
|
|
353
|
-
|
354
|
-
if @old_content.nil? or self.raw_path.nil?
|
359
|
+
if self.binary?
|
355
360
|
nil
|
356
361
|
else
|
357
|
-
|
362
|
+
@diff_thread.join if @diff_thread
|
363
|
+
@diff
|
358
364
|
end
|
359
365
|
end
|
360
366
|
|
361
367
|
def inspect
|
362
|
-
"<#{self.class}:0x#{self.object_id.to_s(16)} name=#{self.name} binary=#{self.binary?} item.identifier=#{self.item.identifier}>"
|
368
|
+
"<#{self.class}:0x#{self.object_id.to_s(16)} name=#{self.name} binary=#{self.binary?} raw_path=#{self.raw_path} item.identifier=#{self.item.identifier}>"
|
363
369
|
end
|
364
370
|
|
365
371
|
private
|
@@ -390,6 +396,18 @@ module Nanoc3
|
|
390
396
|
[ filter, filter_name, filter_args ]
|
391
397
|
end
|
392
398
|
|
399
|
+
def generate_diff
|
400
|
+
if @old_content.nil? or self.raw_path.nil?
|
401
|
+
@diff = nil
|
402
|
+
else
|
403
|
+
@diff_thread = Thread.new do
|
404
|
+
@diff = diff_strings(@old_content, @content[:last])
|
405
|
+
sleep 2
|
406
|
+
@diff_thread = nil
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
393
411
|
def diff_strings(a, b)
|
394
412
|
# TODO Rewrite this string-diffing method in pure Ruby. It should not
|
395
413
|
# use the "diff" executable, because this will most likely not work on
|
@@ -406,9 +424,11 @@ module Nanoc3
|
|
406
424
|
new_file.write(b)
|
407
425
|
|
408
426
|
# Diff
|
409
|
-
|
410
|
-
|
411
|
-
|
427
|
+
cmd = [ 'diff', '-u', old_file.path, new_file.path ]
|
428
|
+
Open3.popen3(*cmd) do |stdin, stdout, stderr|
|
429
|
+
result = stdout.read
|
430
|
+
return (result == '' ? nil : result)
|
431
|
+
end
|
412
432
|
end
|
413
433
|
end
|
414
434
|
rescue Errno::ENOENT
|
data/lib/nanoc3/base/site.rb
CHANGED
@@ -28,7 +28,7 @@ module Nanoc3
|
|
28
28
|
# The default configuration for a data source. A data source's
|
29
29
|
# configuration overrides these options.
|
30
30
|
DEFAULT_DATA_SOURCE_CONFIG = {
|
31
|
-
:type => '
|
31
|
+
:type => 'filesystem_unified',
|
32
32
|
:items_root => '/',
|
33
33
|
:layouts_root => '/',
|
34
34
|
:config => {}
|
@@ -161,8 +161,8 @@ module Nanoc3
|
|
161
161
|
return if instance_variable_defined?(:@data_loaded) && @data_loaded && !force
|
162
162
|
|
163
163
|
# Load all data
|
164
|
-
data_sources.each { |ds| ds.use }
|
165
164
|
load_code_snippets(force)
|
165
|
+
data_sources.each { |ds| ds.use }
|
166
166
|
load_rules
|
167
167
|
load_items
|
168
168
|
load_layouts
|
@@ -230,7 +230,7 @@ module Nanoc3
|
|
230
230
|
@code_snippets = Dir['lib/**/*.rb'].sort.map do |filename|
|
231
231
|
Nanoc3::CodeSnippet.new(
|
232
232
|
File.read(filename),
|
233
|
-
filename
|
233
|
+
filename,
|
234
234
|
File.stat(filename).mtime
|
235
235
|
)
|
236
236
|
end
|
@@ -252,7 +252,7 @@ module Nanoc3
|
|
252
252
|
@rules_mtime = File.stat(rules_filename).mtime
|
253
253
|
|
254
254
|
# Load DSL
|
255
|
-
dsl.instance_eval(@rules)
|
255
|
+
dsl.instance_eval(@rules, "./#{rules_filename}")
|
256
256
|
end
|
257
257
|
|
258
258
|
# Loads this site’s items, sets up item child-parent relationships and
|
data/lib/nanoc3/cli/base.rb
CHANGED
@@ -203,8 +203,10 @@ module Nanoc3::CLI
|
|
203
203
|
def handle_option(option)
|
204
204
|
case option
|
205
205
|
when :version
|
206
|
+
gem_info = defined?(Gem) ? "with RubyGems #{Gem::VERSION}" : "without RubyGems"
|
207
|
+
|
206
208
|
puts "nanoc #{Nanoc3::VERSION} (c) 2007-2010 Denis Defreyne."
|
207
|
-
puts "Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) running on #{RUBY_PLATFORM}"
|
209
|
+
puts "Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) running on #{RUBY_PLATFORM} #{gem_info}"
|
208
210
|
exit 0
|
209
211
|
when :verbose
|
210
212
|
Nanoc3::CLI::Logger.instance.level = :low
|
@@ -4,6 +4,56 @@ module Nanoc3::CLI::Commands
|
|
4
4
|
|
5
5
|
class CreateSite < Cri::Command
|
6
6
|
|
7
|
+
class << self
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# Converts the given array to YAML format
|
12
|
+
def array_to_yaml(array)
|
13
|
+
'[ ' + array.map { |s| "'" + s + "'" }.join(', ') + ' ]'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
DEFAULT_CONFIG = <<EOS
|
19
|
+
# A list of file extensions that nanoc will consider to be textual rather than
|
20
|
+
# binary. If an item with an extension not in this list is found, the file
|
21
|
+
# will be considered as binary.
|
22
|
+
text_extensions: #{array_to_yaml(Nanoc3::Site::DEFAULT_CONFIG[:text_extensions])}
|
23
|
+
|
24
|
+
# The path to the directory where all generated files will be written to. This
|
25
|
+
# can be an absolute path starting with a slash, but it can also be path
|
26
|
+
# relative to the site directory.
|
27
|
+
output_dir: #{Nanoc3::Site::DEFAULT_CONFIG[:output_dir]}
|
28
|
+
|
29
|
+
# A list of index filenames, i.e. names of files that will be served by a web
|
30
|
+
# server when a directory is requested. Usually, index files are named
|
31
|
+
# “index.hml”, but depending on the web server, this may be something else,
|
32
|
+
# such as “default.htm”. This list is used by nanoc to generate pretty URLs.
|
33
|
+
index_filenames: #{array_to_yaml(Nanoc3::Site::DEFAULT_CONFIG[:index_filenames])}
|
34
|
+
|
35
|
+
# The data sources where nanoc loads its data from. This is an array of
|
36
|
+
# hashes; each array element represents a single data source. By default,
|
37
|
+
# there is only a single data source that reads data from the “content/” and
|
38
|
+
# “layout/” directories in the site directory.
|
39
|
+
data_sources:
|
40
|
+
-
|
41
|
+
# The type is the identifier of the data source. By default, this will be
|
42
|
+
# `filesystem_unified`.
|
43
|
+
type: #{Nanoc3::Site::DEFAULT_DATA_SOURCE_CONFIG[:type]}
|
44
|
+
|
45
|
+
# The path where items should be mounted (comparable to mount points in
|
46
|
+
# Unix-like systems). This is “/” by default, meaning that items will have
|
47
|
+
# “/” prefixed to their identifiers. If the items root were “/en/”
|
48
|
+
# instead, an item at content/about.html would have an identifier of
|
49
|
+
# “/en/about/” instead of just “/about/”.
|
50
|
+
items_root: #{Nanoc3::Site::DEFAULT_DATA_SOURCE_CONFIG[:items_root]}
|
51
|
+
|
52
|
+
# The path where layouts should be mounted. The layouts root behaves the
|
53
|
+
# same as the items root, but applies to layouts rather than items.
|
54
|
+
layouts_root: #{Nanoc3::Site::DEFAULT_DATA_SOURCE_CONFIG[:layouts_root]}
|
55
|
+
EOS
|
56
|
+
|
7
57
|
DEFAULT_RULES = <<EOS
|
8
58
|
#!/usr/bin/env ruby
|
9
59
|
|
@@ -262,18 +312,7 @@ EOS
|
|
262
312
|
FileUtils.mkdir_p('output')
|
263
313
|
|
264
314
|
# Create config
|
265
|
-
File.open('config.yaml', 'w')
|
266
|
-
io.write(YAML.dump(
|
267
|
-
'output_dir' => 'output',
|
268
|
-
'data_sources' => [
|
269
|
-
{
|
270
|
-
'type' => data_source,
|
271
|
-
'items_root' => '/',
|
272
|
-
'layouts_root' => '/'
|
273
|
-
}
|
274
|
-
]
|
275
|
-
))
|
276
|
-
end
|
315
|
+
File.open('config.yaml', 'w') { |io| io.write(DEFAULT_CONFIG.make_compatible_with_env) }
|
277
316
|
Nanoc3::NotificationCenter.post(:file_created, 'config.yaml')
|
278
317
|
|
279
318
|
# Create rakefile
|
@@ -284,7 +323,7 @@ EOS
|
|
284
323
|
|
285
324
|
# Create rules
|
286
325
|
File.open('Rules', 'w') do |io|
|
287
|
-
io.write DEFAULT_RULES
|
326
|
+
io.write DEFAULT_RULES.make_compatible_with_env
|
288
327
|
end
|
289
328
|
Nanoc3::NotificationCenter.post(:file_created, 'Rules')
|
290
329
|
end
|
@@ -310,14 +349,14 @@ EOS
|
|
310
349
|
|
311
350
|
# Create home page
|
312
351
|
data_source.create_item(
|
313
|
-
DEFAULT_ITEM,
|
352
|
+
DEFAULT_ITEM.make_compatible_with_env,
|
314
353
|
{ :title => "Home" },
|
315
354
|
'/'
|
316
355
|
)
|
317
356
|
|
318
357
|
# Create stylesheet
|
319
358
|
data_source.create_item(
|
320
|
-
DEFAULT_STYLESHEET,
|
359
|
+
DEFAULT_STYLESHEET.make_compatible_with_env,
|
321
360
|
{},
|
322
361
|
'/stylesheet/',
|
323
362
|
:extension => '.css'
|
@@ -325,7 +364,7 @@ EOS
|
|
325
364
|
|
326
365
|
# Create layout
|
327
366
|
data_source.create_layout(
|
328
|
-
DEFAULT_LAYOUT,
|
367
|
+
DEFAULT_LAYOUT.make_compatible_with_env,
|
329
368
|
{},
|
330
369
|
'/default/'
|
331
370
|
)
|
@@ -42,27 +42,34 @@ module Nanoc3::CLI::Commands
|
|
42
42
|
reps = items.map { |i| i.reps }.flatten
|
43
43
|
layouts = @base.site.layouts
|
44
44
|
|
45
|
-
#
|
46
|
-
|
47
|
-
|
45
|
+
# Get dependency tracker
|
46
|
+
# FIXME clean this up
|
47
|
+
dependency_tracker = @base.site.compiler.send(:dependency_tracker)
|
48
|
+
dependency_tracker.load_graph
|
48
49
|
|
49
50
|
# Print items
|
50
51
|
puts '=== Items'
|
51
52
|
puts
|
52
53
|
row = 0
|
53
54
|
items.sort_by { |i| i.identifier }.each do |item|
|
55
|
+
puts "item #{item.identifier}:"
|
56
|
+
|
57
|
+
# Print item dependencies
|
58
|
+
puts " dependencies:"
|
59
|
+
predecessors = dependency_tracker.direct_predecessors_of(item).sort_by { |i| i.identifier }
|
60
|
+
predecessors.each do |pred|
|
61
|
+
puts " #{pred.identifier}"
|
62
|
+
end
|
63
|
+
puts " (nothing)" if predecessors.empty?
|
64
|
+
|
65
|
+
# Print item representations
|
66
|
+
puts " representations:"
|
54
67
|
item.reps.sort_by { |r| r.name.to_s }.each do |rep|
|
55
|
-
#
|
56
|
-
filler = (row % 3 == 0 ? '· ' : ' ')
|
57
|
-
row += 1
|
58
|
-
|
59
|
-
# Print rep
|
60
|
-
puts "* %s %s -> %s" % [
|
61
|
-
fill(item.identifier, identifier_length, filler),
|
62
|
-
fill(rep.name.to_s, rep_name_length, ' '),
|
63
|
-
rep.raw_path || '-'
|
64
|
-
]
|
68
|
+
puts " #{rep.name} -> #{rep.raw_path || '(not written)'}"
|
65
69
|
end
|
70
|
+
|
71
|
+
# Done
|
72
|
+
puts
|
66
73
|
end
|
67
74
|
puts
|
68
75
|
|
@@ -70,31 +77,10 @@ module Nanoc3::CLI::Commands
|
|
70
77
|
puts '=== Layouts'
|
71
78
|
puts
|
72
79
|
layouts.each do |layout|
|
73
|
-
puts "
|
80
|
+
puts "layout #{layout.identifier}"
|
74
81
|
end
|
75
82
|
end
|
76
83
|
|
77
|
-
private
|
78
|
-
|
79
|
-
# Returns a string that is exactly `length` long, starting with `text` and
|
80
|
-
# filling up any unused space by repeating the string `filler`.
|
81
|
-
def fill(text, length, filler)
|
82
|
-
res = text.dup
|
83
|
-
|
84
|
-
filler_length = (length - 1 - text.length)
|
85
|
-
if filler_length >= 0
|
86
|
-
# Append spacer to ensure alignment
|
87
|
-
spacer_length = text.size % filler.length
|
88
|
-
filler_length -= spacer_length
|
89
|
-
res << ' ' * (spacer_length + 1)
|
90
|
-
|
91
|
-
# Append leader
|
92
|
-
res << filler*(filler_length/filler.length)
|
93
|
-
end
|
94
|
-
|
95
|
-
res
|
96
|
-
end
|
97
|
-
|
98
84
|
end
|
99
85
|
|
100
86
|
end
|
@@ -43,23 +43,25 @@ module Nanoc3::Extra
|
|
43
43
|
r.raw_path == site.config[:output_dir] + path
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
# Recompile rep
|
47
|
+
site.compiler.run(rep.item) if rep
|
48
|
+
|
49
|
+
# Get paths by appending index filenames
|
50
|
+
if path =~ /\/$/
|
51
|
+
possible_paths = site.config[:index_filenames].map { |f| path + f }
|
48
52
|
else
|
49
|
-
|
50
|
-
if path =~ /\/$/
|
51
|
-
possible_paths = site.config[:index_filenames].map { |f| path + f }
|
52
|
-
else
|
53
|
-
possible_paths = [ path ]
|
54
|
-
end
|
55
|
-
|
56
|
-
# Find matching file
|
57
|
-
modified_path = possible_paths.find { |f| File.file?(site.config[:output_dir] + f) }
|
58
|
-
modified_path ||= path
|
59
|
-
|
60
|
-
# Serve using Rack::File
|
61
|
-
file_server.call(env.merge('PATH_INFO' => modified_path))
|
53
|
+
possible_paths = [ path ]
|
62
54
|
end
|
55
|
+
|
56
|
+
# Find matching file
|
57
|
+
modified_path = possible_paths.find { |f| File.file?(site.config[:output_dir] + f) }
|
58
|
+
modified_path ||= path
|
59
|
+
|
60
|
+
# Serve using Rack::File
|
61
|
+
puts "*** serving file #{modified_path}"
|
62
|
+
res = file_server.call(env.merge('PATH_INFO' => modified_path))
|
63
|
+
puts "*** done serving file #{modified_path}"
|
64
|
+
res
|
63
65
|
end
|
64
66
|
rescue StandardError, ScriptError => e
|
65
67
|
# Add compilation stack to env
|
@@ -92,18 +94,6 @@ module Nanoc3::Extra
|
|
92
94
|
@file_server ||= ::Rack::File.new(site.config[:output_dir])
|
93
95
|
end
|
94
96
|
|
95
|
-
def serve(rep)
|
96
|
-
# Recompile rep
|
97
|
-
site.compiler.run(rep.item, :force => true)
|
98
|
-
|
99
|
-
# Build response
|
100
|
-
[
|
101
|
-
200,
|
102
|
-
{ 'Content-Type' => mime_type_of(rep.raw_path, 'text/html') },
|
103
|
-
[ rep.content_at_snapshot(:last) ]
|
104
|
-
]
|
105
|
-
end
|
106
|
-
|
107
97
|
end
|
108
98
|
|
109
99
|
end
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class BlueCloth < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [BlueCloth](http://deveiate.org/projects/BlueCloth).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'bluecloth'
|
8
14
|
|
@@ -3,9 +3,13 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class CodeRay < Nanoc3::Filter
|
5
5
|
|
6
|
+
# @deprecated Use the `:colorize_syntax` filter instead.
|
6
7
|
def run(content, params={})
|
7
8
|
require 'coderay'
|
8
9
|
|
10
|
+
# Warn
|
11
|
+
warn 'The :coderay filter is deprecated; consider using the :colorize_syntax filter instead.'
|
12
|
+
|
9
13
|
# Check params
|
10
14
|
raise ArgumentError, "CodeRay filter requires a :language argument which is missing" if params[:language].nil?
|
11
15
|
|
@@ -3,8 +3,44 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class ColorizeSyntax < Nanoc3::Filter
|
5
5
|
|
6
|
+
# The default colorizer to use for a language if the colorizer for that
|
7
|
+
# language is not overridden.
|
6
8
|
DEFAULT_COLORIZER = :coderay
|
7
9
|
|
10
|
+
# Syntax-highlights code blocks in the given content. Code blocks should
|
11
|
+
# be enclosed in `pre` elements that contain a `code` element. The code
|
12
|
+
# element should have a class starting with `language-` and followed by
|
13
|
+
# the programming language, as specified by HTML5.
|
14
|
+
#
|
15
|
+
# Options for individual colorizers will be taken from the {#run}
|
16
|
+
# options’ value for the given colorizer. For example, if the filter is
|
17
|
+
# invoked with a `:coderay => coderay_options_hash` option, the
|
18
|
+
# `coderay_options_hash` hash will be passed to the CodeRay colorizer.
|
19
|
+
#
|
20
|
+
# Currently, only the `:coderay` and `:pygmentize` colorizers are
|
21
|
+
# implemented. Additional colorizer implementations are welcome!
|
22
|
+
#
|
23
|
+
# @example Content that will be highlighted
|
24
|
+
#
|
25
|
+
# <pre><code class="language-ruby">
|
26
|
+
# def foo
|
27
|
+
# "asdf"
|
28
|
+
# end
|
29
|
+
# </code></pre>
|
30
|
+
#
|
31
|
+
# @example Invoking the filter with custom parameters
|
32
|
+
#
|
33
|
+
# filter :colorize_syntax,
|
34
|
+
# :colorizers => { :ruby => :coderay },
|
35
|
+
# :coderay => { :line_numbers => :list }
|
36
|
+
#
|
37
|
+
# @param [String] content The content to filter
|
38
|
+
#
|
39
|
+
# @option params [Hash] :colorizers (DEFAULT_COLORIZER) A hash containing
|
40
|
+
# a mapping of programming languages (symbols, not strings) onto
|
41
|
+
# colorizers (symbols).
|
42
|
+
#
|
43
|
+
# @return [String] The filtered content
|
8
44
|
def run(content, params={})
|
9
45
|
require 'nokogiri'
|
10
46
|
|
data/lib/nanoc3/filters/erb.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class ERB < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [ERB](http://ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'erb'
|
8
14
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Erubis < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [Erubis](http://www.kuwata-lab.com/erubis/).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'erubis'
|
8
14
|
|
data/lib/nanoc3/filters/haml.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Haml < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [Haml](http://haml-lang.com/).
|
7
|
+
# Parameters passed to this filter will be passed on to Haml.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'haml'
|
8
14
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Kramdown < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [Kramdown](http://kramdown.rubyforge.org/).
|
7
|
+
# Parameters passed to this filter will be passed on to Kramdown.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'kramdown'
|
8
14
|
|
data/lib/nanoc3/filters/less.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Less < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [LESS](http://lesscss.org/).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'less'
|
8
14
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Markaby < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [Markaby](http://markaby.rubyforge.org/).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'markaby'
|
8
14
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Maruku < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [Maruku](http://maruku.rubyforge.org/).
|
7
|
+
# Parameters passed to this filter will be passed on to Maruku.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'maruku'
|
8
14
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Rainpress < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [Rainpress](http://code.google.com/p/rainpress/).
|
7
|
+
# Parameters passed to this filter will be passed on to Rainpress.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'rainpress'
|
8
14
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class RDiscount < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [RDiscount](http://github.com/rtomayko/rdiscount).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'rdiscount'
|
8
14
|
|
data/lib/nanoc3/filters/rdoc.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class RDoc < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [RDoc::Markup](http://rdoc.rubyforge.org/RDoc/Markup.html).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
begin
|
8
14
|
# new RDoc
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class RedCloth < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [RedCloth](http://redcloth.org/).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'redcloth'
|
8
14
|
|
@@ -6,11 +6,23 @@ module Nanoc3::Filters
|
|
6
6
|
require 'nanoc3/helpers/link_to'
|
7
7
|
include Nanoc3::Helpers::LinkTo
|
8
8
|
|
9
|
+
# Relativizes all paths in the given content, which can be either HTML or
|
10
|
+
# CSS. This filter is quite useful if a site needs to be hosted in a
|
11
|
+
# subdirectory instead of a subdomain. In HTML, all `href` and `src`
|
12
|
+
# attributes will be relativized. In CSS, all `url()` references will be
|
13
|
+
# relativized.
|
14
|
+
#
|
15
|
+
# @param [String] content The content to filter
|
16
|
+
#
|
17
|
+
# @option params [Symbol] :type The type of content to filter; can be either `:html` or `:css`.
|
18
|
+
#
|
19
|
+
# @return [String] The filtered content
|
9
20
|
def run(content, params={})
|
10
21
|
# Set assigns so helper function can be used
|
11
22
|
@item_rep = assigns[:item_rep] if @item_rep.nil?
|
12
23
|
|
13
24
|
# Filter
|
25
|
+
# TODO use nokogiri or csspool instead of regular expressions
|
14
26
|
case params[:type]
|
15
27
|
when :html
|
16
28
|
content.gsub(/(<[^>]+\s+(src|href))=(['"]?)(\/.*?)\3([ >])/) do
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class RubyPants < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [RubyPants](http://chneukirchen.org/blog/static/projects/rubypants.html).
|
7
|
+
# This method takes no options.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'rubypants'
|
8
14
|
|
data/lib/nanoc3/filters/sass.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module Nanoc3::Filters
|
4
4
|
class Sass < Nanoc3::Filter
|
5
5
|
|
6
|
+
# Runs the content through [Sass](http://sass-lang.com/).
|
7
|
+
# Parameters passed to this filter will be passed on to Sass.
|
8
|
+
#
|
9
|
+
# @param [String] content The content to filter
|
10
|
+
#
|
11
|
+
# @return [String] The filtered content
|
6
12
|
def run(content, params={})
|
7
13
|
require 'sass'
|
8
14
|
|
@@ -64,6 +64,11 @@ module Nanoc3::Helpers
|
|
64
64
|
# non-outputted items in a feed; such items could have their custom feed
|
65
65
|
# path set to the blog path instead, for example.
|
66
66
|
#
|
67
|
+
# * `custom_url_in_feed` — The url that will be used instead of the
|
68
|
+
# normal url in the feed (generated from the site’s base url + the item
|
69
|
+
# rep’s path). This can be useful when building a link-blog where the
|
70
|
+
# URL of article is a remote location.
|
71
|
+
#
|
67
72
|
# * `updated_at` — The time when the article was last modified. If this
|
68
73
|
# attribute is not present, the `created_at` attribute will be used as
|
69
74
|
# the time when the article was last modified.
|
@@ -255,12 +260,14 @@ module Nanoc3::Helpers
|
|
255
260
|
raise RuntimeError.new('Cannot build Atom feed: site configuration has no base_url')
|
256
261
|
end
|
257
262
|
|
258
|
-
# Get path
|
259
|
-
path = item[:custom_path_in_feed] || item.path
|
260
|
-
return nil if path.nil?
|
261
|
-
|
262
263
|
# Build URL
|
263
|
-
|
264
|
+
if item[:custom_url_in_feed]
|
265
|
+
item[:custom_url_in_feed]
|
266
|
+
elsif item[:custom_path_in_feed]
|
267
|
+
@site.config[:base_url] + item[:custom_path_in_feed]
|
268
|
+
elsif item.path
|
269
|
+
@site.config[:base_url] + item.path
|
270
|
+
end
|
264
271
|
end
|
265
272
|
|
266
273
|
# Returns the URL of the feed. It will return the custom feed URL if set,
|
@@ -15,17 +15,24 @@ module Nanoc3::Helpers
|
|
15
15
|
# @return [Array] The breadcrumbs, starting with the root item and ending
|
16
16
|
# with the item itself
|
17
17
|
def breadcrumbs_trail
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
current_identifier = current_identifier.sub(/[^\/]+\/$/, '')
|
18
|
+
breadcrumbs_for_identifier(@item.identifier)
|
19
|
+
end
|
20
|
+
|
21
|
+
def item_with_identifier(identifier)
|
22
|
+
@identifier_cache ||= {}
|
23
|
+
@identifier_cache[identifier] ||= begin
|
24
|
+
@items.find { |i| i.identifier == identifier }
|
26
25
|
end
|
26
|
+
end
|
27
27
|
|
28
|
-
|
28
|
+
def breadcrumbs_for_identifier(identifier)
|
29
|
+
@breadcrumbs_cache ||= {}
|
30
|
+
@breadcrumbs_cache[identifier] ||= begin
|
31
|
+
head = (identifier == '/' ? [] : breadcrumbs_for_identifier(identifier.sub(/[^\/]+\/$/, '')) )
|
32
|
+
tail = [ item_with_identifier(identifier) ]
|
33
|
+
|
34
|
+
head + tail
|
35
|
+
end
|
29
36
|
end
|
30
37
|
|
31
38
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 3
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 3.1.
|
8
|
+
- 0b2
|
9
|
+
version: 3.1.0b2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Denis Defreyne
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-22 00:00:00 +01:00
|
18
18
|
default_executable: nanoc3
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|