nanoc-core 4.11.12 → 4.11.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nanoc/core.rb +37 -0
  3. data/lib/nanoc/core/basic_item_rep_collection_view.rb +88 -0
  4. data/lib/nanoc/core/basic_item_rep_view.rb +83 -0
  5. data/lib/nanoc/core/basic_item_view.rb +54 -0
  6. data/lib/nanoc/core/checksummer.rb +2 -0
  7. data/lib/nanoc/core/compilation_item_rep_collection_view.rb +12 -0
  8. data/lib/nanoc/core/compilation_item_rep_view.rb +51 -0
  9. data/lib/nanoc/core/compilation_item_view.rb +47 -0
  10. data/lib/nanoc/core/compilation_phases/abstract.rb +48 -0
  11. data/lib/nanoc/core/compilation_phases/cache.rb +43 -0
  12. data/lib/nanoc/core/compilation_phases/mark_done.rb +23 -0
  13. data/lib/nanoc/core/compilation_phases/notify.rb +19 -0
  14. data/lib/nanoc/core/compilation_phases/recalculate.rb +49 -0
  15. data/lib/nanoc/core/compilation_phases/resume.rb +52 -0
  16. data/lib/nanoc/core/compilation_phases/write.rb +84 -0
  17. data/lib/nanoc/core/compilation_stages/build_reps.rb +36 -0
  18. data/lib/nanoc/core/compilation_stages/calculate_checksums.rb +42 -0
  19. data/lib/nanoc/core/compilation_stages/cleanup.rb +43 -0
  20. data/lib/nanoc/core/compilation_stages/compile_reps.rb +96 -0
  21. data/lib/nanoc/core/compilation_stages/determine_outdatedness.rb +49 -0
  22. data/lib/nanoc/core/compilation_stages/forget_outdated_dependencies.rb +20 -0
  23. data/lib/nanoc/core/compilation_stages/load_stores.rb +35 -0
  24. data/lib/nanoc/core/compilation_stages/postprocess.rb +21 -0
  25. data/lib/nanoc/core/compilation_stages/preprocess.rb +32 -0
  26. data/lib/nanoc/core/compilation_stages/prune.rb +30 -0
  27. data/lib/nanoc/core/compilation_stages/store_post_compilation_state.rb +20 -0
  28. data/lib/nanoc/core/compilation_stages/store_pre_compilation_state.rb +32 -0
  29. data/lib/nanoc/core/compiler.rb +214 -0
  30. data/lib/nanoc/core/compiler_loader.rb +48 -0
  31. data/lib/nanoc/core/config_loader.rb +95 -0
  32. data/lib/nanoc/core/config_view.rb +67 -0
  33. data/lib/nanoc/core/configuration.rb +2 -4
  34. data/lib/nanoc/core/document_view_mixin.rb +87 -0
  35. data/lib/nanoc/core/errors.rb +97 -0
  36. data/lib/nanoc/core/executor.rb +134 -0
  37. data/lib/nanoc/core/feature.rb +92 -0
  38. data/lib/nanoc/core/filter.rb +269 -0
  39. data/lib/nanoc/core/identifiable_collection_view.rb +111 -0
  40. data/lib/nanoc/core/item_collection_with_reps_view.rb +12 -0
  41. data/lib/nanoc/core/item_collection_without_reps_view.rb +12 -0
  42. data/lib/nanoc/core/item_rep_builder.rb +54 -0
  43. data/lib/nanoc/core/item_rep_selector.rb +67 -0
  44. data/lib/nanoc/core/item_rep_writer.rb +85 -0
  45. data/lib/nanoc/core/layout_collection_view.rb +12 -0
  46. data/lib/nanoc/core/layout_view.rb +9 -0
  47. data/lib/nanoc/core/mutable_config_view.rb +16 -0
  48. data/lib/nanoc/core/mutable_document_view_mixin.rb +60 -0
  49. data/lib/nanoc/core/mutable_identifiable_collection_view.rb +19 -0
  50. data/lib/nanoc/core/mutable_item_collection_view.rb +34 -0
  51. data/lib/nanoc/core/mutable_item_view.rb +9 -0
  52. data/lib/nanoc/core/mutable_layout_collection_view.rb +26 -0
  53. data/lib/nanoc/core/mutable_layout_view.rb +9 -0
  54. data/lib/nanoc/core/outdatedness_checker.rb +222 -0
  55. data/lib/nanoc/core/outdatedness_rules/attributes_modified.rb +41 -0
  56. data/lib/nanoc/core/outdatedness_rules/code_snippets_modified.rb +31 -0
  57. data/lib/nanoc/core/outdatedness_rules/content_modified.rb +21 -0
  58. data/lib/nanoc/core/outdatedness_rules/item_collection_extended.rb +20 -0
  59. data/lib/nanoc/core/outdatedness_rules/layout_collection_extended.rb +20 -0
  60. data/lib/nanoc/core/outdatedness_rules/not_written.rb +17 -0
  61. data/lib/nanoc/core/outdatedness_rules/rules_modified.rb +45 -0
  62. data/lib/nanoc/core/outdatedness_rules/uses_always_outdated_filter.rb +26 -0
  63. data/lib/nanoc/core/post_compile_item_collection_view.rb +12 -0
  64. data/lib/nanoc/core/post_compile_item_rep_collection_view.rb +12 -0
  65. data/lib/nanoc/core/post_compile_item_rep_view.rb +33 -0
  66. data/lib/nanoc/core/post_compile_item_view.rb +20 -0
  67. data/lib/nanoc/core/pruner.rb +119 -0
  68. data/lib/nanoc/core/site_loader.rb +102 -0
  69. data/lib/nanoc/core/trivial_error.rb +10 -0
  70. data/lib/nanoc/core/version.rb +1 -1
  71. data/lib/nanoc/core/view.rb +43 -0
  72. data/lib/nanoc/core/view_context_for_compilation.rb +6 -6
  73. metadata +95 -2
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ # @api private
6
+ class CompilerLoader
7
+ def load(site, action_provider: nil)
8
+ action_sequence_store = Nanoc::Core::ActionSequenceStore.new(config: site.config)
9
+
10
+ dependency_store =
11
+ Nanoc::Core::DependencyStore.new(site.items, site.layouts, site.config)
12
+
13
+ objects = site.items.to_a + site.layouts.to_a + site.code_snippets + [site.config]
14
+
15
+ checksum_store =
16
+ Nanoc::Core::ChecksumStore.new(config: site.config, objects: objects)
17
+
18
+ action_provider ||= Nanoc::Core::ActionProvider.named(site.config.action_provider).for(site)
19
+
20
+ outdatedness_store =
21
+ Nanoc::Core::OutdatednessStore.new(config: site.config)
22
+
23
+ compiled_content_cache =
24
+ compiled_content_cache_class.new(config: site.config)
25
+
26
+ params = {
27
+ compiled_content_cache: compiled_content_cache,
28
+ checksum_store: checksum_store,
29
+ action_sequence_store: action_sequence_store,
30
+ dependency_store: dependency_store,
31
+ action_provider: action_provider,
32
+ outdatedness_store: outdatedness_store,
33
+ }
34
+
35
+ Nanoc::Core::Compiler.new(site, params)
36
+ end
37
+
38
+ def compiled_content_cache_class
39
+ feature_name = Nanoc::Core::Feature::BINARY_COMPILED_CONTENT_CACHE
40
+ if Nanoc::Core::Feature.enabled?(feature_name)
41
+ Nanoc::Core::CompiledContentCache
42
+ else
43
+ Nanoc::Core::TextualCompiledContentCache
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ # @api private
6
+ class ConfigLoader
7
+ class NoConfigFileFoundError < ::Nanoc::Core::Error
8
+ def initialize
9
+ super('No configuration file found')
10
+ end
11
+ end
12
+
13
+ class NoParentConfigFileFoundError < ::Nanoc::Core::Error
14
+ def initialize(filename)
15
+ super("There is no parent configuration file at #{filename}")
16
+ end
17
+ end
18
+
19
+ class CyclicalConfigFileError < ::Nanoc::Core::Error
20
+ def initialize(filename)
21
+ super("The parent configuration file at #{filename} includes one of its descendants")
22
+ end
23
+ end
24
+
25
+ # @return [Boolean]
26
+ def self.cwd_is_nanoc_site?
27
+ !config_filename_for_cwd.nil?
28
+ end
29
+
30
+ # @return [String]
31
+ def self.config_filename_for_cwd
32
+ filenames =
33
+ if Nanoc::Core::Feature.enabled?(Nanoc::Core::Feature::TOML)
34
+ %w[nanoc.yaml config.yaml nanoc.toml]
35
+ else
36
+ %w[nanoc.yaml config.yaml]
37
+ end
38
+ candidate = filenames.find { |f| File.file?(f) }
39
+ candidate && File.expand_path(candidate)
40
+ end
41
+
42
+ def new_from_cwd
43
+ # Determine path
44
+ filename = self.class.config_filename_for_cwd
45
+ raise NoConfigFileFoundError if filename.nil?
46
+
47
+ # Read
48
+ config =
49
+ apply_parent_config(
50
+ Nanoc::Core::Configuration.new(
51
+ hash: load_file(filename),
52
+ dir: File.dirname(filename),
53
+ ),
54
+ [filename],
55
+ ).with_defaults
56
+
57
+ # Load environment
58
+ config.with_environment
59
+ end
60
+
61
+ def load_file(filename)
62
+ case File.extname(filename)
63
+ when '.yaml'
64
+ YAML.load_file(filename)
65
+ when '.toml'
66
+ Tomlrb.load_file(filename)
67
+ else
68
+ raise Nanoc::Core::Errors::InternalInconsistency, 'Unhandled config file extension'
69
+ end
70
+ end
71
+
72
+ # @api private
73
+ def apply_parent_config(config, processed_paths = [])
74
+ parent_path = config[:parent_config_file]
75
+ return config if parent_path.nil?
76
+
77
+ # Get absolute path
78
+ parent_path = File.absolute_path(parent_path, File.dirname(processed_paths.last))
79
+ unless File.file?(parent_path)
80
+ raise NoParentConfigFileFoundError.new(parent_path)
81
+ end
82
+
83
+ # Check recursion
84
+ if processed_paths.include?(parent_path)
85
+ raise CyclicalConfigFileError.new(parent_path)
86
+ end
87
+
88
+ # Load
89
+ parent_config = Nanoc::Core::Configuration.new(hash: load_file(parent_path), dir: config.dir)
90
+ full_parent_config = apply_parent_config(parent_config, processed_paths + [parent_path])
91
+ full_parent_config.merge(config.without(:parent_config_file))
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ class ConfigView < ::Nanoc::Core::View
6
+ # @api private
7
+ def initialize(config, context)
8
+ super(context)
9
+ @config = config
10
+ end
11
+
12
+ # @api private
13
+ def _unwrap
14
+ @config
15
+ end
16
+
17
+ # @api private
18
+ def output_dir
19
+ @config.output_dir
20
+ end
21
+
22
+ # @see Hash#fetch
23
+ def fetch(key, fallback = Nanoc::Core::UNDEFINED, &_block)
24
+ @context.dependency_tracker.bounce(_unwrap, attributes: [key])
25
+ @config.fetch(key) do
26
+ if !Nanoc::Core::UNDEFINED.equal?(fallback)
27
+ fallback
28
+ elsif block_given?
29
+ yield(key)
30
+ else
31
+ raise KeyError, "key not found: #{key.inspect}"
32
+ end
33
+ end
34
+ end
35
+
36
+ # @see Hash#key?
37
+ def key?(key)
38
+ @context.dependency_tracker.bounce(_unwrap, attributes: [key])
39
+ @config.key?(key)
40
+ end
41
+
42
+ # @see Hash#[]
43
+ def [](key)
44
+ @context.dependency_tracker.bounce(_unwrap, attributes: [key])
45
+ @config[key]
46
+ end
47
+
48
+ # @see Hash#each
49
+ def each(&block)
50
+ @context.dependency_tracker.bounce(_unwrap, attributes: true)
51
+ @config.each(&block)
52
+ end
53
+
54
+ # @see Configuration#env_name
55
+ def env_name
56
+ @context.dependency_tracker.bounce(_unwrap, attributes: true)
57
+ @config.env_name
58
+ end
59
+
60
+ # @see Hash#dig
61
+ def dig(*keys)
62
+ @context.dependency_tracker.bounce(_unwrap, attributes: keys.take(1))
63
+ @config.dig(*keys)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -6,8 +6,6 @@ module Nanoc
6
6
  class Configuration
7
7
  include Nanoc::Core::ContractsSupport
8
8
 
9
- NONE = Object.new.freeze
10
-
11
9
  # The default configuration for a data source. A data source's
12
10
  # configuration overrides these options.
13
11
  DEFAULT_DATA_SOURCE_CONFIG = {
@@ -104,9 +102,9 @@ module Nanoc
104
102
  end
105
103
 
106
104
  contract C::Any, C::Maybe[C::Any], C::Maybe[C::Func[C::None => C::Any]] => C::Any
107
- def fetch(key, fallback = NONE, &_block)
105
+ def fetch(key, fallback = Nanoc::Core::UNDEFINED, &_block)
108
106
  @wrapped.fetch(key) do
109
- if !fallback.equal?(NONE)
107
+ if !Nanoc::Core::UNDEFINED.equal?(fallback)
110
108
  fallback
111
109
  elsif block_given?
112
110
  yield(key)
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ module DocumentViewMixin
6
+ # @api private
7
+ def initialize(document, context)
8
+ super(context)
9
+ @document = document
10
+ end
11
+
12
+ # @api private
13
+ def _unwrap
14
+ @document
15
+ end
16
+
17
+ # @see Object#==
18
+ def ==(other)
19
+ other.respond_to?(:identifier) && identifier == other.identifier
20
+ end
21
+
22
+ # @see Object#eql?
23
+ def eql?(other)
24
+ other.is_a?(self.class) && identifier.eql?(other.identifier)
25
+ end
26
+
27
+ # @see Object#hash
28
+ def hash
29
+ self.class.hash ^ identifier.hash
30
+ end
31
+
32
+ # @return [Nanoc::Core::Identifier]
33
+ def identifier
34
+ _unwrap.identifier
35
+ end
36
+
37
+ # @see Hash#[]
38
+ def [](key)
39
+ @context.dependency_tracker.bounce(_unwrap, attributes: [key])
40
+ _unwrap.attributes[key]
41
+ end
42
+
43
+ # @return [Hash]
44
+ def attributes
45
+ # TODO: Refine dependencies
46
+ @context.dependency_tracker.bounce(_unwrap, attributes: true)
47
+ _unwrap.attributes
48
+ end
49
+
50
+ # @see Hash#fetch
51
+ def fetch(key, fallback = Nanoc::Core::UNDEFINED, &_block)
52
+ @context.dependency_tracker.bounce(_unwrap, attributes: [key])
53
+
54
+ if _unwrap.attributes.key?(key)
55
+ _unwrap.attributes[key]
56
+ elsif !Nanoc::Core::UNDEFINED.equal?(fallback)
57
+ fallback
58
+ elsif block_given?
59
+ yield(key)
60
+ else
61
+ raise KeyError, "key not found: #{key.inspect}"
62
+ end
63
+ end
64
+
65
+ # @see Hash#key?
66
+ def key?(key)
67
+ @context.dependency_tracker.bounce(_unwrap, attributes: [key])
68
+ _unwrap.attributes.key?(key)
69
+ end
70
+
71
+ # @api private
72
+ def reference
73
+ _unwrap.reference
74
+ end
75
+
76
+ # @api private
77
+ def raw_content
78
+ @context.dependency_tracker.bounce(_unwrap, raw_content: true)
79
+ _unwrap.content.string
80
+ end
81
+
82
+ def inspect
83
+ "<#{self.class} identifier=#{_unwrap.identifier}>"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -24,6 +24,31 @@ module Nanoc
24
24
  end
25
25
  end
26
26
 
27
+ # Error that is raised when compilation of an item rep fails. The
28
+ # underlying error is available by calling `#unwrap`.
29
+ class CompilationError < ::Nanoc::Core::Error
30
+ attr_reader :item_rep
31
+
32
+ def initialize(wrapped, item_rep)
33
+ @wrapped = wrapped
34
+ @item_rep = item_rep
35
+ end
36
+
37
+ def unwrap
38
+ @wrapped
39
+ end
40
+ end
41
+
42
+ # Error that is raised when a site is loaded that uses a data source with
43
+ # an unknown identifier.
44
+ class UnknownDataSource < ::Nanoc::Core::Error
45
+ # @param [String] data_source_name The data source name for which no
46
+ # data source could be found
47
+ def initialize(data_source_name)
48
+ super("The data source specified in the site’s configuration file, “#{data_source_name}”, does not exist.")
49
+ end
50
+ end
51
+
27
52
  # Error that is raised when an rep cannot be compiled because it depends
28
53
  # on other representations.
29
54
  class UnmetDependency < ::Nanoc::Core::Error
@@ -44,6 +69,25 @@ module Nanoc
44
69
  end
45
70
  end
46
71
 
72
+ # Error that is raised during site compilation when an item (directly or
73
+ # indirectly) includes its own item content, leading to endless recursion.
74
+ class DependencyCycle < ::Nanoc::Core::Error
75
+ def initialize(stack)
76
+ start_idx = stack.index(stack.last)
77
+ cycle = stack[start_idx..-2]
78
+
79
+ msg_bits = []
80
+ msg_bits << 'The site cannot be compiled because there is a dependency cycle:'
81
+ msg_bits << ''
82
+ cycle.each.with_index do |r, i|
83
+ msg_bits << " (#{i + 1}) item #{r.item.identifier}, rep #{r.name.inspect}, uses compiled content of"
84
+ end
85
+ msg_bits << msg_bits.pop + ' (1)'
86
+
87
+ super(msg_bits.map { |x| x + "\n" }.join(''))
88
+ end
89
+ end
90
+
47
91
  # Error that is raised when the compiled content of a binary item is attempted to be accessed.
48
92
  class CannotGetCompiledContentOfBinaryItem < ::Nanoc::Core::Error
49
93
  # @param [Nanoc::Core::ItemRep] rep The binary item representation whose compiled content was attempted to be accessed
@@ -51,6 +95,59 @@ module Nanoc
51
95
  super("You cannot access the compiled content of a binary item representation (but you can access the path). The offending item rep is #{rep}.")
52
96
  end
53
97
  end
98
+
99
+ # Error that is raised when attempting to call #parent or #children on an item with a legacy identifier.
100
+ class CannotGetParentOrChildrenOfNonLegacyItem < ::Nanoc::Core::Error
101
+ def initialize(identifier)
102
+ super("You cannot get the parent or children of an item that has a “full” identifier (#{identifier}). Getting the parent or children of an item is only possible for items that have a legacy identifier.")
103
+ end
104
+ end
105
+
106
+ # Error that is raised during site compilation when an item uses a layout
107
+ # that is not present in the site.
108
+ class UnknownLayout < ::Nanoc::Core::Error
109
+ # @param [String] layout_identifier The layout identifier for which no
110
+ # layout could be found
111
+ def initialize(layout_identifier)
112
+ super("The site does not have a layout with identifier “#{layout_identifier}”.")
113
+ end
114
+ end
115
+
116
+ # Error that is raised when a binary item is attempted to be laid out.
117
+ class CannotLayoutBinaryItem < ::Nanoc::Core::Error
118
+ # @param [Nanoc::Core::ItemRep] rep The item representation that was attempted
119
+ # to be laid out
120
+ def initialize(rep)
121
+ super("The “#{rep.item.identifier}” item (rep “#{rep.name}”) cannot be laid out because it is a binary item. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.")
122
+ end
123
+ end
124
+
125
+ # Error that is raised when a textual filter is attempted to be applied to
126
+ # a binary item representation.
127
+ class CannotUseTextualFilter < ::Nanoc::Core::Error
128
+ # @param [Nanoc::Core::ItemRep] rep The item representation that was
129
+ # attempted to be filtered
130
+ #
131
+ # @param [Class] filter_class The filter class that was used
132
+ def initialize(rep, filter_class)
133
+ 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.")
134
+ end
135
+ end
136
+
137
+ # Error that is raised when a binary filter is attempted to be applied to
138
+ # a textual item representation.
139
+ class CannotUseBinaryFilter < ::Nanoc::Core::Error
140
+ # @param [Nanoc::Core::ItemRep] rep The item representation that was
141
+ # attempted to be filtered
142
+ #
143
+ # @param [Class] filter_class The filter class that was used
144
+ def initialize(rep, filter_class)
145
+ 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. If you are getting this error for an item that should be textual instead of binary, make sure that its extension is included in the text_extensions array in the site configuration.")
146
+ end
147
+ end
148
+
149
+ class InternalInconsistency < ::Nanoc::Core::Error
150
+ end
54
151
  end
55
152
  end
56
153
  end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nanoc
4
+ module Core
5
+ class Executor
6
+ def initialize(rep, compilation_context, dependency_tracker)
7
+ @rep = rep
8
+ @compilation_context = compilation_context
9
+ @dependency_tracker = dependency_tracker
10
+ end
11
+
12
+ def filter(filter_name, filter_args = {})
13
+ filter = filter_for_filtering(filter_name)
14
+
15
+ begin
16
+ Nanoc::Core::NotificationCenter.post(:filtering_started, @rep, filter_name)
17
+
18
+ # Run filter
19
+ last = @compilation_context.compiled_content_store.get_current(@rep)
20
+ source = last.binary? ? last.filename : last.string
21
+ filter_args.freeze
22
+ result = filter.setup_and_run(source, filter_args)
23
+ last =
24
+ if filter.class.to_binary?
25
+ Nanoc::Core::BinaryContent.new(filter.output_filename).tap(&:freeze)
26
+ else
27
+ Nanoc::Core::TextualContent.new(result).tap(&:freeze)
28
+ end
29
+
30
+ # Store
31
+ @compilation_context.compiled_content_store.set_current(@rep, last)
32
+ ensure
33
+ Nanoc::Core::NotificationCenter.post(:filtering_ended, @rep, filter_name)
34
+ end
35
+ end
36
+
37
+ def layout(layout_identifier, extra_filter_args = nil)
38
+ layout = find_layout(layout_identifier)
39
+ filter_name_and_args = @compilation_context.filter_name_and_args_for_layout(layout)
40
+ filter_name = filter_name_and_args.name
41
+ if filter_name.nil?
42
+ raise ::Nanoc::Core::Error, "Cannot find rule for layout matching #{layout_identifier}"
43
+ end
44
+
45
+ filter_args = filter_name_and_args.args
46
+ filter_args = filter_args.merge(extra_filter_args || {})
47
+ filter_args.freeze
48
+
49
+ # Check whether item can be laid out
50
+ last = @compilation_context.compiled_content_store.get_current(@rep)
51
+ raise Nanoc::Core::Errors::CannotLayoutBinaryItem.new(@rep) if last.binary?
52
+
53
+ # Create filter
54
+ klass = Nanoc::Core::Filter.named!(filter_name)
55
+ layout_view = Nanoc::Core::LayoutView.new(layout, view_context)
56
+ filter = klass.new(assigns.merge(layout: layout_view))
57
+
58
+ # Visit
59
+ @dependency_tracker.bounce(layout, raw_content: true)
60
+
61
+ begin
62
+ Nanoc::Core::NotificationCenter.post(:filtering_started, @rep, filter_name)
63
+
64
+ # Layout
65
+ content = layout.content
66
+ arg = content.binary? ? content.filename : content.string
67
+ res = filter.setup_and_run(arg, filter_args)
68
+
69
+ # Store
70
+ last = Nanoc::Core::TextualContent.new(res).tap(&:freeze)
71
+ @compilation_context.compiled_content_store.set_current(@rep, last)
72
+ ensure
73
+ Nanoc::Core::NotificationCenter.post(:filtering_ended, @rep, filter_name)
74
+ end
75
+ end
76
+
77
+ def snapshot(snapshot_name)
78
+ last = @compilation_context.compiled_content_store.get_current(@rep)
79
+ @compilation_context.compiled_content_store.set(@rep, snapshot_name, last)
80
+ Nanoc::Core::NotificationCenter.post(:snapshot_created, @rep, snapshot_name)
81
+ end
82
+
83
+ def assigns
84
+ view_context.assigns_for(@rep, site: @compilation_context.site)
85
+ end
86
+
87
+ def layouts
88
+ @compilation_context.site.layouts
89
+ end
90
+
91
+ def find_layout(arg)
92
+ req_id = arg.__nanoc_cleaned_identifier
93
+ layout = layouts[req_id]
94
+ return layout if layout
95
+
96
+ if use_globs?
97
+ pat = Nanoc::Core::Pattern.from(arg)
98
+ layout = layouts.find { |l| pat.match?(l.identifier) }
99
+ return layout if layout
100
+ end
101
+
102
+ raise Nanoc::Core::Errors::UnknownLayout.new(arg)
103
+ end
104
+
105
+ def filter_for_filtering(filter_name)
106
+ klass = Nanoc::Core::Filter.named!(filter_name)
107
+
108
+ last = @compilation_context.compiled_content_store.get_current(@rep)
109
+ if klass.from_binary? && !last.binary?
110
+ raise Nanoc::Core::Errors::CannotUseBinaryFilter.new(@rep, klass)
111
+ elsif !klass.from_binary? && last.binary?
112
+ raise Nanoc::Core::Errors::CannotUseTextualFilter.new(@rep, klass)
113
+ end
114
+
115
+ klass.new(assigns)
116
+ end
117
+
118
+ def use_globs?
119
+ @compilation_context.site.config[:string_pattern_type] == 'glob'
120
+ end
121
+
122
+ def view_context
123
+ @_view_context ||=
124
+ Nanoc::Core::ViewContextForCompilation.new(
125
+ reps: @compilation_context.reps,
126
+ items: @compilation_context.site.items,
127
+ dependency_tracker: @dependency_tracker,
128
+ compilation_context: @compilation_context,
129
+ compiled_content_store: @compilation_context.compiled_content_store,
130
+ )
131
+ end
132
+ end
133
+ end
134
+ end