nanoc3 3.1.0b1 → 3.1.0b2
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/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
|