nanoc 4.0.2 → 4.1.0a1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +17 -0
- data/Gemfile +50 -46
- data/Gemfile.lock +365 -0
- data/Guardfile +3 -0
- data/NEWS.md +21 -0
- data/README.md +1 -1
- data/lib/nanoc/base.rb +3 -15
- data/lib/nanoc/base/checksummer.rb +3 -14
- data/lib/nanoc/base/compilation/compiler.rb +112 -283
- data/lib/nanoc/base/compilation/compiler_dsl.rb +29 -37
- data/lib/nanoc/base/compilation/dependency_tracker.rb +25 -170
- data/lib/nanoc/base/compilation/filter.rb +3 -4
- data/lib/nanoc/base/compilation/item_rep_repo.rb +33 -0
- data/lib/nanoc/base/compilation/outdatedness_checker.rb +39 -53
- data/lib/nanoc/base/compilation/rule.rb +13 -24
- data/lib/nanoc/base/compilation/rule_context.rb +29 -15
- data/lib/nanoc/base/entities.rb +10 -0
- data/lib/nanoc/base/{source_data → entities}/code_snippet.rb +1 -4
- data/lib/nanoc/base/{source_data → entities}/configuration.rb +1 -1
- data/lib/nanoc/base/entities/content.rb +8 -9
- data/lib/nanoc/base/{identifiable_collection.rb → entities/identifiable_collection.rb} +0 -0
- data/lib/nanoc/base/entities/identifier.rb +11 -2
- data/lib/nanoc/base/{source_data → entities}/item.rb +0 -18
- data/lib/nanoc/base/{result_data → entities}/item_rep.rb +15 -13
- data/lib/nanoc/base/entities/rule_memory.rb +54 -0
- data/lib/nanoc/base/entities/rule_memory_action.rb +19 -0
- data/lib/nanoc/base/entities/rule_memory_actions.rb +3 -0
- data/lib/nanoc/base/entities/rule_memory_actions/filter.rb +22 -0
- data/lib/nanoc/base/entities/rule_memory_actions/layout.rb +22 -0
- data/lib/nanoc/base/entities/rule_memory_actions/snapshot.rb +26 -0
- data/lib/nanoc/base/entities/rules_collection.rb +120 -0
- data/lib/nanoc/base/{source_data → entities}/site.rb +11 -10
- data/lib/nanoc/base/repos.rb +2 -0
- data/lib/nanoc/base/repos/checksum_store.rb +3 -9
- data/lib/nanoc/base/repos/compiled_content_cache.rb +0 -5
- data/lib/nanoc/base/{source_data → repos}/data_source.rb +3 -6
- data/lib/nanoc/base/repos/dependency_store.rb +118 -0
- data/lib/nanoc/base/repos/rule_memory_store.rb +1 -5
- data/lib/nanoc/base/repos/site_loader.rb +0 -28
- data/lib/nanoc/base/repos/store.rb +0 -12
- data/lib/nanoc/base/services.rb +8 -0
- data/lib/nanoc/base/services/compiler_loader.rb +49 -0
- data/lib/nanoc/base/services/executor.rb +4 -4
- data/lib/nanoc/base/services/item_rep_builder.rb +30 -0
- data/lib/nanoc/base/services/item_rep_router.rb +55 -0
- data/lib/nanoc/base/services/item_rep_selector.rb +39 -0
- data/lib/nanoc/base/services/item_rep_writer.rb +2 -0
- data/lib/nanoc/base/services/postprocessor.rb +26 -0
- data/lib/nanoc/base/services/preprocessor.rb +26 -0
- data/lib/nanoc/base/services/recording_executor.rb +36 -22
- data/lib/nanoc/base/services/rule_memory_calculator.rb +84 -0
- data/lib/nanoc/base/services/rules_loader.rb +29 -0
- data/lib/nanoc/base/views.rb +6 -0
- data/lib/nanoc/base/views/config_view.rb +8 -2
- data/lib/nanoc/base/views/identifiable_collection_view.rb +5 -4
- data/lib/nanoc/base/views/item_rep_collection_view.rb +7 -6
- data/lib/nanoc/base/views/item_rep_view.rb +13 -12
- data/lib/nanoc/base/views/item_view.rb +18 -12
- data/lib/nanoc/base/views/layout_view.rb +1 -1
- data/lib/nanoc/base/views/mixins/document_view_mixin.rb +2 -1
- data/lib/nanoc/base/views/mutable_identifiable_collection_view.rb +1 -1
- data/lib/nanoc/base/views/mutable_item_collection_view.rb +4 -7
- data/lib/nanoc/base/views/post_compile_item_collection_view.rb +8 -0
- data/lib/nanoc/base/views/post_compile_item_view.rb +7 -0
- data/lib/nanoc/base/views/site_view.rb +3 -2
- data/lib/nanoc/base/views/view.rb +12 -0
- data/lib/nanoc/base/views/view_context.rb +12 -0
- data/lib/nanoc/cli/commands/compile.rb +13 -15
- data/lib/nanoc/cli/commands/create-site.rb +15 -0
- data/lib/nanoc/cli/commands/prune.rb +1 -1
- data/lib/nanoc/cli/commands/shell.rb +3 -3
- data/lib/nanoc/cli/commands/show-data.rb +5 -5
- data/lib/nanoc/cli/commands/show-rules.rb +2 -1
- data/lib/nanoc/cli/error_handler.rb +28 -30
- data/lib/nanoc/cli/stream_cleaners/ansi_colors.rb +1 -1
- data/lib/nanoc/data_sources/filesystem.rb +1 -1
- data/lib/nanoc/extra/checking/check.rb +8 -7
- data/lib/nanoc/extra/checking/checks/external_links.rb +14 -1
- data/lib/nanoc/extra/checking/runner.rb +1 -1
- data/lib/nanoc/extra/deployer.rb +3 -3
- data/lib/nanoc/extra/piper.rb +5 -5
- data/lib/nanoc/extra/pruner.rb +8 -7
- data/lib/nanoc/filters/relativize_paths.rb +48 -32
- data/lib/nanoc/filters/sass/sass_filesystem_importer.rb +0 -1
- data/lib/nanoc/helpers/blogging.rb +15 -7
- data/lib/nanoc/helpers/capturing.rb +56 -13
- data/lib/nanoc/helpers/link_to.rb +2 -2
- data/lib/nanoc/helpers/tagging.rb +5 -10
- data/lib/nanoc/helpers/text.rb +9 -11
- data/lib/nanoc/version.rb +1 -1
- data/nanoc-4.0.2.gem +0 -0
- data/tags +1175 -0
- data/test/base/test_compiler.rb +48 -98
- data/test/base/test_compiler_dsl.rb +113 -39
- data/test/base/test_dependency_tracker.rb +80 -79
- data/test/base/test_outdatedness_checker.rb +39 -26
- data/test/base/test_site.rb +0 -97
- data/test/cli/commands/test_compile.rb +2 -3
- data/test/extra/checking/checks/test_external_links.rb +25 -0
- data/test/extra/deployers/test_fog.rb +12 -6
- data/test/filters/test_erb.rb +1 -1
- data/test/filters/test_erubis.rb +1 -1
- data/test/filters/test_haml.rb +1 -1
- data/test/filters/test_less.rb +4 -4
- data/test/filters/test_sass.rb +1 -0
- data/test/filters/test_xsl.rb +7 -8
- data/test/helper.rb +0 -2
- data/test/helpers/test_blogging.rb +26 -23
- data/test/helpers/test_capturing.rb +131 -12
- data/test/helpers/test_filtering.rb +6 -6
- data/test/helpers/test_link_to.rb +1 -1
- data/test/helpers/test_rendering.rb +16 -24
- data/test/helpers/test_tagging.rb +13 -10
- data/test/helpers/test_xml_sitemap.rb +25 -21
- metadata +36 -14
- data/lib/nanoc/base/compilation/rule_memory_calculator.rb +0 -35
- data/lib/nanoc/base/compilation/rules_collection.rb +0 -245
- data/test/base/test_rule_context.rb +0 -78
@@ -91,6 +91,21 @@ checks:
|
|
91
91
|
# E.g.:
|
92
92
|
# exclude: ['^/server_status']
|
93
93
|
exclude: []
|
94
|
+
|
95
|
+
# Configuration for the “external_links” checker, which checks whether all
|
96
|
+
# external links are valid.
|
97
|
+
external_links:
|
98
|
+
# A list of patterns, specified as regular expressions, to exclude from the check.
|
99
|
+
# If an external link matches this pattern, the validity check will be skipped.
|
100
|
+
# E.g.:
|
101
|
+
# exclude: ['^http://example.com$']
|
102
|
+
exclude: []
|
103
|
+
|
104
|
+
# A list of file patterns, specified as regular expressions, to exclude from the check.
|
105
|
+
# If a file matches this pattern, the links from this file will not be checked.
|
106
|
+
# E.g.:
|
107
|
+
# exclude_files: ['blog/page']
|
108
|
+
exclude_files: []
|
94
109
|
EOS
|
95
110
|
|
96
111
|
DEFAULT_RULES = <<EOS unless defined? DEFAULT_RULES
|
@@ -23,9 +23,9 @@ module Nanoc::CLI::Commands
|
|
23
23
|
|
24
24
|
def self.env_for_site(site)
|
25
25
|
{
|
26
|
-
items: Nanoc::ItemCollectionView.new(site.items),
|
27
|
-
layouts: Nanoc::LayoutCollectionView.new(site.layouts),
|
28
|
-
config: Nanoc::ConfigView.new(site.config),
|
26
|
+
items: Nanoc::ItemCollectionView.new(site.items, nil),
|
27
|
+
layouts: Nanoc::LayoutCollectionView.new(site.layouts, nil),
|
28
|
+
config: Nanoc::ConfigView.new(site.config, nil),
|
29
29
|
}
|
30
30
|
end
|
31
31
|
end
|
@@ -17,11 +17,11 @@ module Nanoc::CLI::Commands
|
|
17
17
|
|
18
18
|
# Get dependency tracker
|
19
19
|
compiler = site.compiler
|
20
|
-
compiler.
|
21
|
-
|
20
|
+
compiler.load_stores
|
21
|
+
dependency_store = compiler.dependency_store
|
22
22
|
|
23
23
|
# Print data
|
24
|
-
print_item_dependencies(items,
|
24
|
+
print_item_dependencies(items, dependency_store)
|
25
25
|
print_item_rep_paths(items)
|
26
26
|
print_item_rep_outdatedness(items, compiler)
|
27
27
|
print_layouts(layouts, compiler)
|
@@ -56,13 +56,13 @@ module Nanoc::CLI::Commands
|
|
56
56
|
puts
|
57
57
|
end
|
58
58
|
|
59
|
-
def print_item_dependencies(items,
|
59
|
+
def print_item_dependencies(items, dependency_store)
|
60
60
|
print_header('Item dependencies')
|
61
61
|
|
62
62
|
sorted_with_prev(items) do |item, prev|
|
63
63
|
puts if prev
|
64
64
|
puts "item #{item.identifier} depends on:"
|
65
|
-
predecessors =
|
65
|
+
predecessors = dependency_store.objects_causing_outdatedness_of(item).sort_by { |i| i ? i.identifier : '' }
|
66
66
|
predecessors.each do |pred|
|
67
67
|
type =
|
68
68
|
case pred
|
@@ -12,6 +12,7 @@ module Nanoc::CLI::Commands
|
|
12
12
|
|
13
13
|
@c = Nanoc::CLI::ANSIStringColorizer
|
14
14
|
@rules = site.compiler.rules_collection
|
15
|
+
@reps = site.compiler.reps
|
15
16
|
|
16
17
|
site.items.sort_by(&:identifier).each { |e| explain_item(e) }
|
17
18
|
site.layouts.sort_by(&:identifier).each { |e| explain_layout(e) }
|
@@ -20,7 +21,7 @@ module Nanoc::CLI::Commands
|
|
20
21
|
def explain_item(item)
|
21
22
|
puts "#{@c.c('Item ' + item.identifier, :bold, :yellow)}:"
|
22
23
|
|
23
|
-
item.
|
24
|
+
@reps[item].each do |rep|
|
24
25
|
rule = @rules.compilation_rule_for(rep)
|
25
26
|
puts " Rep #{rep.name}: #{rule ? rule.pattern : '(none)'}"
|
26
27
|
end
|
@@ -3,23 +3,23 @@ module Nanoc::CLI
|
|
3
3
|
#
|
4
4
|
# @api private
|
5
5
|
class ErrorHandler
|
6
|
-
# @
|
6
|
+
# @param [Nanoc::CLI::Command, nil] command The command that is
|
7
7
|
# currently being executed, or nil if there is none
|
8
|
-
def initialize(
|
9
|
-
@command =
|
8
|
+
def initialize(command: nil)
|
9
|
+
@command = command
|
10
10
|
end
|
11
11
|
|
12
12
|
# Enables error handling in the given block.
|
13
13
|
#
|
14
|
-
# @
|
14
|
+
# @param [Nanoc::CLI::Command, nil] command The command that is
|
15
15
|
# currently being executed, or nil if there is none
|
16
16
|
#
|
17
17
|
# @return [void]
|
18
|
-
def self.handle_while(
|
18
|
+
def self.handle_while(command: nil, &block)
|
19
19
|
if @disabled
|
20
20
|
yield
|
21
21
|
else
|
22
|
-
new(
|
22
|
+
new(command: command).handle_while(&block)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -247,9 +247,9 @@ module Nanoc::CLI
|
|
247
247
|
defined?(Bundler) && Bundler::SharedHelpers.in_bundle?
|
248
248
|
end
|
249
249
|
|
250
|
-
def write_section_header(stream, title,
|
250
|
+
def write_section_header(stream, title, verbose: false)
|
251
251
|
stream.puts
|
252
|
-
if
|
252
|
+
if verbose
|
253
253
|
stream.puts '===== ' + title.upcase + ':'
|
254
254
|
else
|
255
255
|
stream.puts "\e[1m\e[31m" + title + ':' + "\e[0m"
|
@@ -257,16 +257,16 @@ module Nanoc::CLI
|
|
257
257
|
stream.puts
|
258
258
|
end
|
259
259
|
|
260
|
-
def write_error_message(stream, error,
|
261
|
-
write_section_header(stream, 'Message',
|
260
|
+
def write_error_message(stream, error, verbose: false)
|
261
|
+
write_section_header(stream, 'Message', verbose: verbose)
|
262
262
|
|
263
263
|
stream.puts "#{error.class}: #{error.message}"
|
264
264
|
resolution = resolution_for(error)
|
265
265
|
stream.puts "#{resolution}" if resolution
|
266
266
|
end
|
267
267
|
|
268
|
-
def write_compilation_stack(stream, _error,
|
269
|
-
write_section_header(stream, 'Compilation stack',
|
268
|
+
def write_compilation_stack(stream, _error, verbose: false)
|
269
|
+
write_section_header(stream, 'Compilation stack', verbose: verbose)
|
270
270
|
|
271
271
|
if stack.empty?
|
272
272
|
stream.puts ' (empty)'
|
@@ -281,16 +281,14 @@ module Nanoc::CLI
|
|
281
281
|
end
|
282
282
|
end
|
283
283
|
|
284
|
-
def write_stack_trace(stream, error,
|
285
|
-
|
284
|
+
def write_stack_trace(stream, error, verbose: false)
|
285
|
+
write_section_header(stream, 'Stack trace', verbose: verbose)
|
286
286
|
|
287
|
-
|
288
|
-
|
289
|
-
count = is_verbose ? -1 : 10
|
287
|
+
count = verbose ? -1 : 10
|
290
288
|
error.backtrace[0...count].each_with_index do |item, index|
|
291
289
|
stream.puts " #{index}. #{item}"
|
292
290
|
end
|
293
|
-
if !
|
291
|
+
if !verbose && error.backtrace.size > count
|
294
292
|
stream.puts " ... #{error.backtrace.size - count} more lines omitted. See full crash log for details."
|
295
293
|
end
|
296
294
|
end
|
@@ -303,41 +301,41 @@ module Nanoc::CLI
|
|
303
301
|
stream.puts 'A detailed crash log has been written to ./crash.log.'
|
304
302
|
end
|
305
303
|
|
306
|
-
def write_version_information(stream,
|
307
|
-
write_section_header(stream, 'Version information',
|
304
|
+
def write_version_information(stream, verbose: false)
|
305
|
+
write_section_header(stream, 'Version information', verbose: verbose)
|
308
306
|
stream.puts Nanoc.version_information
|
309
307
|
end
|
310
308
|
|
311
|
-
def write_system_information(stream,
|
309
|
+
def write_system_information(stream, verbose: false)
|
312
310
|
uname = `uname -a`
|
313
|
-
write_section_header(stream, 'System information',
|
311
|
+
write_section_header(stream, 'System information', verbose: verbose)
|
314
312
|
stream.puts uname
|
315
313
|
rescue Errno::ENOENT
|
316
314
|
end
|
317
315
|
|
318
|
-
def write_installed_gems(stream,
|
319
|
-
write_section_header(stream, 'Installed gems',
|
316
|
+
def write_installed_gems(stream, verbose: false)
|
317
|
+
write_section_header(stream, 'Installed gems', verbose: verbose)
|
320
318
|
gems_and_versions.each do |g|
|
321
319
|
stream.puts " #{g.first} #{g.last.join(', ')}"
|
322
320
|
end
|
323
321
|
end
|
324
322
|
|
325
|
-
def write_environment(stream,
|
326
|
-
write_section_header(stream, 'Environment',
|
323
|
+
def write_environment(stream, verbose: false)
|
324
|
+
write_section_header(stream, 'Environment', verbose: verbose)
|
327
325
|
ENV.sort.each do |e|
|
328
326
|
stream.puts "#{e.first} => #{e.last.inspect}"
|
329
327
|
end
|
330
328
|
end
|
331
329
|
|
332
|
-
def write_gemfile_lock(stream,
|
330
|
+
def write_gemfile_lock(stream, verbose: false)
|
333
331
|
if File.exist?('Gemfile.lock')
|
334
|
-
write_section_header(stream, 'Gemfile.lock',
|
332
|
+
write_section_header(stream, 'Gemfile.lock', verbose: verbose)
|
335
333
|
stream.puts File.read('Gemfile.lock')
|
336
334
|
end
|
337
335
|
end
|
338
336
|
|
339
|
-
def write_load_paths(stream,
|
340
|
-
write_section_header(stream, 'Load paths',
|
337
|
+
def write_load_paths(stream, verbose: false)
|
338
|
+
write_section_header(stream, 'Load paths', verbose: verbose)
|
341
339
|
$LOAD_PATH.each_with_index do |i, index|
|
342
340
|
stream.puts " #{index}. #{i}"
|
343
341
|
end
|
@@ -192,7 +192,7 @@ module Nanoc::DataSources
|
|
192
192
|
# Returns the extension(s) of filename. Supports multiple extensions.
|
193
193
|
# Includes the leading period.
|
194
194
|
def ext_of(filename)
|
195
|
-
filename =~ extension_regex ?
|
195
|
+
filename =~ extension_regex ? Regexp.last_match[1] : ''
|
196
196
|
end
|
197
197
|
|
198
198
|
# Returns a regex that is used for determining the extension of a file
|
@@ -19,11 +19,14 @@ module Nanoc::Extra::Checking
|
|
19
19
|
end
|
20
20
|
output_filenames = Dir[output_dir + '/**/*'].select { |f| File.file?(f) }
|
21
21
|
|
22
|
+
# FIXME: ugly
|
23
|
+
view_context = site.compiler.create_view_context
|
24
|
+
|
22
25
|
context = {
|
23
|
-
items: Nanoc::ItemCollectionView.new(site.items),
|
24
|
-
layouts: Nanoc::LayoutCollectionView.new(site.layouts),
|
25
|
-
config: Nanoc::ConfigView.new(site.config),
|
26
|
-
site: Nanoc::SiteView.new(site), # TODO: remove me
|
26
|
+
items: Nanoc::ItemCollectionView.new(site.items, view_context),
|
27
|
+
layouts: Nanoc::LayoutCollectionView.new(site.layouts, view_context),
|
28
|
+
config: Nanoc::ConfigView.new(site.config, view_context),
|
29
|
+
site: Nanoc::SiteView.new(site, view_context), # TODO: remove me
|
27
30
|
output_filenames: output_filenames,
|
28
31
|
}
|
29
32
|
|
@@ -40,9 +43,7 @@ module Nanoc::Extra::Checking
|
|
40
43
|
raise NotImplementedError.new('Nanoc::Extra::Checking::Check subclasses must implement #run')
|
41
44
|
end
|
42
45
|
|
43
|
-
def add_issue(desc,
|
44
|
-
subject = params.fetch(:subject, nil)
|
45
|
-
|
46
|
+
def add_issue(desc, subject: nil)
|
46
47
|
@issues << Issue.new(desc, subject, self.class)
|
47
48
|
end
|
48
49
|
end
|
@@ -14,7 +14,7 @@ module ::Nanoc::Extra::Checking::Checks
|
|
14
14
|
def run
|
15
15
|
# Find all broken external hrefs
|
16
16
|
# TODO: de-duplicate this (duplicated in internal links check)
|
17
|
-
filenames = output_filenames.select { |f| File.extname(f) == '.html' }
|
17
|
+
filenames = output_filenames.select { |f| File.extname(f) == '.html' && !excluded_file?(f) }
|
18
18
|
hrefs_with_filenames = ::Nanoc::Extra::LinkCollector.new(filenames, :external).filenames_per_href
|
19
19
|
results = select_invalid(hrefs_with_filenames.keys)
|
20
20
|
|
@@ -89,6 +89,9 @@ module ::Nanoc::Extra::Checking::Checks
|
|
89
89
|
return Result.new(href, 'invalid URI')
|
90
90
|
end
|
91
91
|
|
92
|
+
# Skip excluded URLs
|
93
|
+
return nil if self.excluded?(href)
|
94
|
+
|
92
95
|
# Skip non-HTTP URLs
|
93
96
|
return nil if url.scheme !~ /^https?$/
|
94
97
|
|
@@ -161,5 +164,15 @@ module ::Nanoc::Extra::Checking::Checks
|
|
161
164
|
end
|
162
165
|
http.request(req)
|
163
166
|
end
|
167
|
+
|
168
|
+
def excluded?(href)
|
169
|
+
excludes = @config.fetch(:checks, {}).fetch(:external_links, {}).fetch(:exclude, [])
|
170
|
+
excludes.any? { |pattern| Regexp.new(pattern).match(href) }
|
171
|
+
end
|
172
|
+
|
173
|
+
def excluded_file?(file)
|
174
|
+
excludes = @config.fetch(:checks, {}).fetch(:external_links, {}).fetch(:exclude_files, [])
|
175
|
+
excludes.any? { |pattern| Regexp.new(pattern).match(file) }
|
176
|
+
end
|
164
177
|
end
|
165
178
|
end
|
data/lib/nanoc/extra/deployer.rb
CHANGED
@@ -25,12 +25,12 @@ module Nanoc::Extra
|
|
25
25
|
#
|
26
26
|
# @return [Hash] config The deployer configuration
|
27
27
|
#
|
28
|
-
# @
|
28
|
+
# @param [Boolean] dry_run true if the deployer should
|
29
29
|
# only show what would be deployed instead actually deploying
|
30
|
-
def initialize(source_path, config,
|
30
|
+
def initialize(source_path, config, dry_run: false)
|
31
31
|
@source_path = source_path
|
32
32
|
@config = config
|
33
|
-
@dry_run =
|
33
|
+
@dry_run = dry_run
|
34
34
|
end
|
35
35
|
|
36
36
|
# Performs the actual deployment.
|
data/lib/nanoc/extra/piper.rb
CHANGED
@@ -14,11 +14,11 @@ module Nanoc::Extra
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
# @
|
18
|
-
# @
|
19
|
-
def initialize(
|
20
|
-
@stdout =
|
21
|
-
@stderr =
|
17
|
+
# @param [IO] stdout
|
18
|
+
# @param [IO] stderr
|
19
|
+
def initialize(stdout: $stdout, stderr: $stderr)
|
20
|
+
@stdout = stdout
|
21
|
+
@stderr = stderr
|
22
22
|
end
|
23
23
|
|
24
24
|
# @param [Array<String>] cmd
|
data/lib/nanoc/extra/pruner.rb
CHANGED
@@ -9,13 +9,15 @@ module Nanoc::Extra
|
|
9
9
|
|
10
10
|
# @param [Nanoc::Int::Site] site The site for which a pruner is created
|
11
11
|
#
|
12
|
-
# @
|
12
|
+
# @param [Boolean] dry_run true if the files to be deleted
|
13
13
|
# should only be printed instead of actually deleted, false if the files
|
14
14
|
# should actually be deleted.
|
15
|
-
|
15
|
+
#
|
16
|
+
# @param [Enumerable<String>] exclude
|
17
|
+
def initialize(site, dry_run: false, exclude: [])
|
16
18
|
@site = site
|
17
|
-
@dry_run =
|
18
|
-
@exclude =
|
19
|
+
@dry_run = dry_run
|
20
|
+
@exclude = exclude
|
19
21
|
end
|
20
22
|
|
21
23
|
# Prunes all output files not managed by Nanoc.
|
@@ -25,9 +27,8 @@ module Nanoc::Extra
|
|
25
27
|
require 'find'
|
26
28
|
|
27
29
|
# Get compiled files
|
28
|
-
|
29
|
-
|
30
|
-
end
|
30
|
+
# FIXME: requires #build_reps to have been called
|
31
|
+
all_raw_paths = site.compiler.reps.map(&:raw_path)
|
31
32
|
compiled_files = all_raw_paths.flatten.compact.select { |f| File.file?(f) }
|
32
33
|
|
33
34
|
# Get present files and dirs
|
@@ -35,30 +35,9 @@ module Nanoc::Filters
|
|
35
35
|
# Filter
|
36
36
|
case params[:type]
|
37
37
|
when :css
|
38
|
-
|
39
|
-
content.gsub(/url\((['"]?)(\/(?:[^\/].*?)?)\1\)/) do
|
40
|
-
'url(' + $1 + relative_path_to($2) + $1 + ')'
|
41
|
-
end
|
38
|
+
relativize_css(content)
|
42
39
|
when :html, :xml, :xhtml
|
43
|
-
|
44
|
-
namespaces = params[:namespaces] || {}
|
45
|
-
|
46
|
-
require 'nokogiri'
|
47
|
-
case params[:type]
|
48
|
-
when :html
|
49
|
-
klass = ::Nokogiri::HTML
|
50
|
-
when :xml
|
51
|
-
klass = ::Nokogiri::XML
|
52
|
-
when :xhtml
|
53
|
-
klass = ::Nokogiri::XML
|
54
|
-
# FIXME: cleanup because it is ugly
|
55
|
-
# this cleans the XHTML namespace to process fragments and full
|
56
|
-
# documents in the same way. At least, Nokogiri adds this namespace
|
57
|
-
# if detects the `html` element.
|
58
|
-
content = content.sub(%r{(<html[^>]+)xmlns="http://www.w3.org/1999/xhtml"}, '\1')
|
59
|
-
end
|
60
|
-
|
61
|
-
nokogiri_process(content, selectors, namespaces, klass, params[:type])
|
40
|
+
relativize_html_like(content, params)
|
62
41
|
else
|
63
42
|
raise RuntimeError.new(
|
64
43
|
'The relativize_paths needs to know the type of content to ' \
|
@@ -69,6 +48,38 @@ module Nanoc::Filters
|
|
69
48
|
|
70
49
|
protected
|
71
50
|
|
51
|
+
def relativize_css(content)
|
52
|
+
# FIXME: parse CSS the proper way using csspool or something
|
53
|
+
content.gsub(/url\((['"]?)(\/(?:[^\/].*?)?)\1\)/) do
|
54
|
+
quote = Regexp.last_match[1]
|
55
|
+
path = Regexp.last_match[2]
|
56
|
+
'url(' + quote + relative_path_to(path) + quote + ')'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def relativize_html_like(content, params)
|
61
|
+
selectors = params.fetch(:select, SELECTORS)
|
62
|
+
namespaces = params.fetch(:namespaces, {})
|
63
|
+
type = params.fetch(:type)
|
64
|
+
|
65
|
+
require 'nokogiri'
|
66
|
+
case type
|
67
|
+
when :html
|
68
|
+
klass = ::Nokogiri::HTML
|
69
|
+
when :xml
|
70
|
+
klass = ::Nokogiri::XML
|
71
|
+
when :xhtml
|
72
|
+
klass = ::Nokogiri::XML
|
73
|
+
# FIXME: cleanup because it is ugly
|
74
|
+
# this cleans the XHTML namespace to process fragments and full
|
75
|
+
# documents in the same way. At least, Nokogiri adds this namespace
|
76
|
+
# if detects the `html` element.
|
77
|
+
content = content.sub(%r{(<html[^>]+)xmlns="http://www.w3.org/1999/xhtml"}, '\1')
|
78
|
+
end
|
79
|
+
|
80
|
+
nokogiri_process(content, selectors, namespaces, klass, type)
|
81
|
+
end
|
82
|
+
|
72
83
|
def nokogiri_process(content, selectors, namespaces, klass, type)
|
73
84
|
# Ensure that all prefixes are strings
|
74
85
|
namespaces = namespaces.reduce({}) { |new, (prefix, uri)| new.merge(prefix.to_s => uri) }
|
@@ -77,14 +88,7 @@ module Nanoc::Filters
|
|
77
88
|
selectors.map { |sel| "descendant-or-self::#{sel}" }.each do |selector|
|
78
89
|
doc.xpath(selector, namespaces).each do |node|
|
79
90
|
if node.name == 'comment'
|
80
|
-
|
81
|
-
content = content.sub(%r{^(\s*\[.+?\]>\s*)(.+?)(\s*<!\[endif\])}m) do |_m|
|
82
|
-
fragment = nokogiri_process($2, selectors, namespaces, klass, type)
|
83
|
-
$1 + fragment + $3
|
84
|
-
end
|
85
|
-
comment = Nokogiri::XML::Comment.new(doc, content)
|
86
|
-
# Works w/ Nokogiri 1.5.5 but fails w/ Nokogiri 1.5.2
|
87
|
-
node.replace(comment)
|
91
|
+
nokogiri_process_comment(node, doc, selectors, namespaces, klass, type)
|
88
92
|
elsif self.path_is_relativizable?(node.content)
|
89
93
|
node.content = relative_path_to(node.content)
|
90
94
|
end
|
@@ -93,8 +97,20 @@ module Nanoc::Filters
|
|
93
97
|
doc.send("to_#{type}")
|
94
98
|
end
|
95
99
|
|
100
|
+
def nokogiri_process_comment(node, doc, selectors, namespaces, klass, type)
|
101
|
+
content = node.content.dup.sub(%r{^(\s*\[.+?\]>\s*)(.+?)(\s*<!\[endif\])}m) do |_m|
|
102
|
+
beginning = Regexp.last_match[1]
|
103
|
+
body = Regexp.last_match[2]
|
104
|
+
ending = Regexp.last_match[3]
|
105
|
+
|
106
|
+
beginning + nokogiri_process(body, selectors, namespaces, klass, type) + ending
|
107
|
+
end
|
108
|
+
|
109
|
+
node.replace(Nokogiri::XML::Comment.new(doc, content))
|
110
|
+
end
|
111
|
+
|
96
112
|
def path_is_relativizable?(s)
|
97
|
-
s
|
113
|
+
s.start_with?('/')
|
98
114
|
end
|
99
115
|
end
|
100
116
|
end
|