nanoc 4.0.0b3 → 4.0.0b4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +4 -2
  4. data/NEWS.md +10 -0
  5. data/TODO.md +15 -0
  6. data/lib/nanoc/base.rb +4 -27
  7. data/lib/nanoc/base/checksummer.rb +69 -19
  8. data/lib/nanoc/base/compilation/compiler.rb +14 -12
  9. data/lib/nanoc/base/compilation/compiler_dsl.rb +2 -0
  10. data/lib/nanoc/base/compilation/filter.rb +4 -2
  11. data/lib/nanoc/base/compilation/outdatedness_checker.rb +7 -7
  12. data/lib/nanoc/base/compilation/rule.rb +5 -6
  13. data/lib/nanoc/base/compilation/rule_context.rb +16 -34
  14. data/lib/nanoc/base/compilation/rule_memory_calculator.rb +3 -3
  15. data/lib/nanoc/base/compilation/rules_collection.rb +4 -10
  16. data/lib/nanoc/base/context.rb +2 -0
  17. data/lib/nanoc/base/core_ext/array.rb +0 -10
  18. data/lib/nanoc/base/core_ext/hash.rb +0 -10
  19. data/lib/nanoc/base/core_ext/pathname.rb +0 -9
  20. data/lib/nanoc/base/core_ext/string.rb +0 -10
  21. data/lib/nanoc/base/entities.rb +5 -0
  22. data/lib/nanoc/base/entities/content.rb +86 -0
  23. data/lib/nanoc/base/entities/document.rb +56 -0
  24. data/lib/nanoc/base/{source_data → entities}/identifier.rb +12 -1
  25. data/lib/nanoc/base/entities/layout.rb +8 -0
  26. data/lib/nanoc/base/{pattern.rb → entities/pattern.rb} +0 -0
  27. data/lib/nanoc/base/errors.rb +2 -1
  28. data/lib/nanoc/base/result_data/item_rep.rb +13 -278
  29. data/lib/nanoc/base/services.rb +5 -0
  30. data/lib/nanoc/base/services/executor.rb +141 -0
  31. data/lib/nanoc/base/services/item_rep_writer.rb +40 -0
  32. data/lib/nanoc/base/{notification_center.rb → services/notification_center.rb} +0 -0
  33. data/lib/nanoc/base/services/recording_executor.rb +41 -0
  34. data/lib/nanoc/base/{temp_filename_factory.rb → services/temp_filename_factory.rb} +0 -0
  35. data/lib/nanoc/base/source_data/code_snippet.rb +0 -6
  36. data/lib/nanoc/base/source_data/data_source.rb +4 -3
  37. data/lib/nanoc/base/source_data/item.rb +23 -213
  38. data/lib/nanoc/base/source_data/site.rb +0 -1
  39. data/lib/nanoc/base/views.rb +18 -0
  40. data/lib/nanoc/base/views/config.rb +1 -1
  41. data/lib/nanoc/base/views/item.rb +8 -73
  42. data/lib/nanoc/base/views/item_rep.rb +9 -0
  43. data/lib/nanoc/base/views/item_rep_collection.rb +17 -0
  44. data/lib/nanoc/base/views/layout.rb +1 -40
  45. data/lib/nanoc/base/views/mixins/document.rb +76 -0
  46. data/lib/nanoc/base/views/mixins/mutable_document.rb +22 -0
  47. data/lib/nanoc/base/views/mutable_identifiable_collection.rb +1 -1
  48. data/lib/nanoc/base/views/mutable_item.rb +1 -18
  49. data/lib/nanoc/base/views/mutable_item_collection.rb +6 -2
  50. data/lib/nanoc/base/views/mutable_layout.rb +1 -8
  51. data/lib/nanoc/cli/commands/compile.rb +1 -2
  52. data/lib/nanoc/cli/commands/create-site.rb +5 -5
  53. data/lib/nanoc/cli/commands/show-data.rb +11 -1
  54. data/lib/nanoc/data_sources/filesystem.rb +17 -10
  55. data/lib/nanoc/helpers/capturing.rb +1 -2
  56. data/lib/nanoc/helpers/filtering.rb +13 -1
  57. data/lib/nanoc/helpers/rendering.rb +4 -2
  58. data/lib/nanoc/version.rb +1 -1
  59. data/test/base/core_ext/array_spec.rb +0 -7
  60. data/test/base/core_ext/hash_spec.rb +0 -13
  61. data/test/base/core_ext/pathname_spec.rb +0 -33
  62. data/test/base/core_ext/string_spec.rb +0 -10
  63. data/test/base/test_compiler_dsl.rb +3 -3
  64. data/test/base/test_data_source.rb +2 -2
  65. data/test/base/test_item.rb +5 -129
  66. data/test/base/test_item_rep.rb +26 -558
  67. data/test/base/test_layout.rb +2 -26
  68. data/test/base/test_rule.rb +3 -3
  69. data/test/base/test_rule_context.rb +34 -15
  70. data/test/data_sources/test_filesystem.rb +2 -2
  71. data/test/data_sources/test_filesystem_unified.rb +39 -33
  72. data/test/extra/checking/checks/test_html.rb +0 -1
  73. data/test/extra/checking/checks/test_mixed_content.rb +3 -3
  74. data/test/extra/deployers/test_fog.rb +24 -24
  75. data/test/filters/test_less.rb +4 -4
  76. data/test/filters/test_sass.rb +10 -5
  77. data/test/filters/test_xsl.rb +6 -0
  78. data/test/helpers/test_capturing.rb +0 -1
  79. data/test/helpers/test_filtering.rb +5 -19
  80. data/test/helpers/test_tagging.rb +6 -6
  81. metadata +18 -11
  82. data/lib/nanoc/base/compilation/item_rep_proxy.rb +0 -109
  83. data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +0 -97
  84. data/lib/nanoc/base/source_data/layout.rb +0 -111
  85. data/test/base/checksummer_spec.rb +0 -256
  86. data/test/base/test_item_rep_recorder_proxy.rb +0 -17
@@ -3,41 +3,23 @@ module Nanoc::Int
3
3
  # It provides access to the item representation that is being compiled or
4
4
  # routed.
5
5
  #
6
- # The following variables will be available in this rules context:
7
- #
8
- # * `rep` ({Nanoc::Int::ItemRep}) - The current item rep
9
- # * `item` ({Nanoc::Int::Item}) - The current item
10
- # * `site` ({Nanoc::Int::Site}) - The site
11
- # * `config` ({Hash}) - The site configuration
12
- # * `items` ({Array}<{Nanoc::Int::Item}>) - A list of all items
13
- # * `layouts` ({Array}<{Nanoc::Int::Layout}>) - A list of all layouts
14
- #
15
6
  # @api private
16
7
  class RuleContext < Nanoc::Int::Context
17
- # @option params [Nanoc::Int::ItemRep] :rep The item representation that will
18
- # be processed in this rule context
19
- #
20
- # @option params [Nanoc::Int::Compiler] :compiler The compiler that is being
21
- # used to compile the site
22
- #
23
- # @raise [ArgumentError] if the `:rep` or the `:compiler` option is
24
- # missing
8
+ # @option params [Nanoc::Int::ItemRep] :rep
9
+ # @option params [Nanoc::Int::Compiler] :compiler
25
10
  def initialize(params = {})
26
- rep = params.fetch(:rep) do
27
- raise ArgumentError, 'Required :rep option is missing'
28
- end
29
- compiler = params.fetch(:compiler) do
30
- raise ArgumentError, 'Required :compiler option is missing'
31
- end
11
+ rep = params.fetch(:rep)
12
+ compiler = params.fetch(:compiler)
13
+ @_executor = params.fetch(:executor)
32
14
 
33
15
  super({
34
- rep: rep,
35
- item_rep: rep,
36
- item: rep.item,
37
- site: compiler.site,
38
- config: compiler.site.config,
39
- items: compiler.site.items,
40
- layouts: compiler.site.layouts
16
+ item: Nanoc::ItemView.new(rep.item),
17
+ rep: Nanoc::ItemRepView.new(rep),
18
+ item_rep: Nanoc::ItemRepView.new(rep),
19
+ items: Nanoc::ItemCollectionView.new(compiler.site.items),
20
+ layouts: Nanoc::LayoutCollectionView.new(compiler.site.layouts),
21
+ config: Nanoc::ConfigView.new(compiler.site.config),
22
+ site: Nanoc::SiteView.new(compiler.site),
41
23
  })
42
24
  end
43
25
 
@@ -54,7 +36,7 @@ module Nanoc::Int
54
36
  #
55
37
  # @return [void]
56
38
  def filter(filter_name, filter_args = {})
57
- rep.filter(filter_name, filter_args)
39
+ @_executor.filter(rep.unwrap, filter_name, filter_args)
58
40
  end
59
41
 
60
42
  # Layouts the current representation (calls {Nanoc::Int::ItemRep#layout} with
@@ -66,8 +48,8 @@ module Nanoc::Int
66
48
  # should be laid out with
67
49
  #
68
50
  # @return [void]
69
- def layout(layout_identifier)
70
- rep.layout(layout_identifier)
51
+ def layout(layout_identifier, extra_filter_args = nil)
52
+ @_executor.layout(rep.unwrap, layout_identifier, extra_filter_args)
71
53
  end
72
54
 
73
55
  # Creates a snapshot of the current compiled item content. Calls
@@ -79,7 +61,7 @@ module Nanoc::Int
79
61
  #
80
62
  # @return [void]
81
63
  def snapshot(snapshot_name)
82
- rep.snapshot(snapshot_name)
64
+ @_executor.snapshot(rep.unwrap, snapshot_name)
83
65
  end
84
66
  end
85
67
  end
@@ -19,10 +19,10 @@ module Nanoc::Int
19
19
  # @return [Array] The caluclated rule memory for the given object
20
20
  def [](obj)
21
21
  result =
22
- case obj.type
23
- when :item_rep
22
+ case obj
23
+ when Nanoc::Int::ItemRep
24
24
  @rules_collection.new_rule_memory_for_rep(obj)
25
- when :layout
25
+ when Nanoc::Int::Layout
26
26
  @rules_collection.new_rule_memory_for_layout(obj)
27
27
  else
28
28
  raise "Do not know how to calculate the rule memory for #{obj.inspect}"
@@ -170,12 +170,6 @@ module Nanoc::Int
170
170
  :rules
171
171
  end
172
172
 
173
- # @return [String] The checksum for this object. If its contents change,
174
- # the checksum will change as well.
175
- def __nanoc_checksum
176
- Nanoc::Int::Checksummer.calc(self)
177
- end
178
-
179
173
  def inspect
180
174
  "<#{self.class}>"
181
175
  end
@@ -185,10 +179,10 @@ module Nanoc::Int
185
179
  #
186
180
  # @return [Array] The rule memory for the given item representation
187
181
  def new_rule_memory_for_rep(rep)
188
- recording_proxy = rep.to_recording_proxy
189
- compilation_rule_for(rep).apply_to(recording_proxy, compiler: @compiler)
190
- recording_proxy.rule_memory << [:write, rep.path]
191
- make_rule_memory_serializable(recording_proxy.rule_memory)
182
+ executor = Nanoc::Int::RecordingExecutor.new
183
+ compilation_rule_for(rep).apply_to(rep, executor: executor, compiler: @compiler)
184
+ executor.record_write(rep, rep.path)
185
+ make_rule_memory_serializable(executor.rule_memory)
192
186
  end
193
187
  memoize :new_rule_memory_for_rep
194
188
 
@@ -1,6 +1,8 @@
1
1
  module Nanoc::Int
2
2
  # Provides a context and a binding for use in filters such as the ERB and
3
3
  # Haml ones.
4
+ #
5
+ # @api private
4
6
  class Context
5
7
  # Creates a new context based off the contents of the hash.
6
8
  #
@@ -33,16 +33,6 @@ module Nanoc::ArrayExtensions
33
33
  end
34
34
  end
35
35
  end
36
-
37
- # Calculates the checksum for this array. Any change to this array will
38
- # result in a different checksum.
39
- #
40
- # @return [String] The checksum for this array
41
- #
42
- # @api private
43
- def __nanoc_checksum
44
- Nanoc::Int::Checksummer.calc(self)
45
- end
46
36
  end
47
37
 
48
38
  # @api private
@@ -35,16 +35,6 @@ module Nanoc::HashExtensions
35
35
  end
36
36
  end
37
37
  end
38
-
39
- # Calculates the checksum for this hash. Any change to this hash will result
40
- # in a different checksum.
41
- #
42
- # @return [String] The checksum for this hash
43
- #
44
- # @api private
45
- def __nanoc_checksum
46
- Nanoc::Int::Checksummer.calc(self)
47
- end
48
38
  end
49
39
 
50
40
  # @api private
@@ -1,14 +1,5 @@
1
1
  # @api private
2
2
  module Nanoc::PathnameExtensions
3
- # Calculates the checksum for the file referenced to by this pathname. Any
4
- # change to the file contents will result in a different checksum.
5
- #
6
- # @return [String] The checksum for this file
7
- #
8
- # @api private
9
- def __nanoc_checksum
10
- Nanoc::Int::Checksummer.calc(self)
11
- end
12
3
  end
13
4
 
14
5
  # @api private
@@ -6,16 +6,6 @@ module Nanoc::StringExtensions
6
6
  def __nanoc_cleaned_identifier
7
7
  "/#{self}/".gsub(/^\/+|\/+$/, '/')
8
8
  end
9
-
10
- # Calculates the checksum for this string. Any change to this string will
11
- # result in a different checksum.
12
- #
13
- # @return [String] The checksum for this string
14
- #
15
- # @api private
16
- def __nanoc_checksum
17
- Nanoc::Int::Checksummer.calc(self)
18
- end
19
9
  end
20
10
 
21
11
  # @api private
@@ -0,0 +1,5 @@
1
+ require_relative 'entities/content'
2
+ require_relative 'entities/document'
3
+ require_relative 'entities/identifier'
4
+ require_relative 'entities/layout'
5
+ require_relative 'entities/pattern'
@@ -0,0 +1,86 @@
1
+ module Nanoc
2
+ module Int
3
+ # Abstract content.
4
+ #
5
+ # The filename is the full filename on the default filesystem. It can be
6
+ # nil. It is used by filters such as Sass, which look up items on the
7
+ # filesystem.
8
+ #
9
+ # @abstract
10
+ #
11
+ # @api private
12
+ class Content
13
+ # @return [String, nil]
14
+ attr_reader :filename
15
+
16
+ # @param [String, nil] filename
17
+ def initialize(filename)
18
+ if filename && !filename.start_with?('/')
19
+ raise ArgumentError, 'Content filename is not absolute'
20
+ end
21
+
22
+ @filename = filename
23
+ end
24
+
25
+ def freeze
26
+ super
27
+ @filename.freeze
28
+ end
29
+
30
+ # @param [String] content The uncompiled item content (if it is textual
31
+ # content) or the path to the filename containing the content (if this
32
+ # is binary content).
33
+ #
34
+ # @option params [Boolean] :binary (false) Whether or not this item is
35
+ # binary
36
+ #
37
+ # @option params [String] :filename (nil) Absolute path to the file
38
+ # containing this content (if any)
39
+ def self.create(content, params = {})
40
+ if content.nil?
41
+ raise ArgumentError, 'Cannot create nil content'
42
+ elsif content.is_a?(Nanoc::Int::Content)
43
+ content
44
+ elsif params.fetch(:binary, false)
45
+ Nanoc::Int::BinaryContent.new(content)
46
+ else
47
+ Nanoc::Int::TextualContent.new(content, filename: params[:filename])
48
+ end
49
+ end
50
+
51
+ # @abstract
52
+ #
53
+ # @return [Boolean]
54
+ def binary?
55
+ raise NotImplementedError
56
+ end
57
+ end
58
+
59
+ # @api private
60
+ class TextualContent < Content
61
+ # @return [String]
62
+ attr_reader :string
63
+
64
+ def initialize(string, params = {})
65
+ super(params[:filename])
66
+ @string = string
67
+ end
68
+
69
+ def freeze
70
+ super
71
+ @string.freeze
72
+ end
73
+
74
+ def binary?
75
+ false
76
+ end
77
+ end
78
+
79
+ # @api private
80
+ class BinaryContent < Content
81
+ def binary?
82
+ true
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,56 @@
1
+ module Nanoc
2
+ module Int
3
+ # @api private
4
+ class Document
5
+ # @return [Nanoc::Int::Content]
6
+ attr_reader :content
7
+
8
+ # @return [Hash]
9
+ attr_reader :attributes
10
+
11
+ # @return [Nanoc::Identifier]
12
+ attr_accessor :identifier
13
+
14
+ # @param [String, Nanoc::Int::Content] content
15
+ #
16
+ # @param [Hash] attributes
17
+ #
18
+ # @param [String, Nanoc::Identifier] identifier
19
+ def initialize(content, attributes, identifier)
20
+ @content = Nanoc::Int::Content.create(content)
21
+ @attributes = attributes.__nanoc_symbolize_keys_recursively
22
+ @identifier = Nanoc::Identifier.from(identifier)
23
+ end
24
+
25
+ # @return [void]
26
+ def freeze
27
+ super
28
+ attributes.__nanoc_freeze_recursively
29
+ content.freeze
30
+ end
31
+
32
+ # @abstract
33
+ #
34
+ # @return Unique reference to this object
35
+ def reference
36
+ raise NotImplementedError
37
+ end
38
+
39
+ def inspect
40
+ "<#{self.class} identifier=\"#{identifier}\">"
41
+ end
42
+
43
+ def hash
44
+ self.class.hash ^ identifier.hash
45
+ end
46
+
47
+ def eql?(other)
48
+ self.class == other.class && identifier == other.identifier
49
+ end
50
+
51
+ def ==(other)
52
+ self.eql?(other)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -84,7 +84,7 @@ module Nanoc
84
84
  extname = File.extname(@string)
85
85
  string =
86
86
  if extname.size > 0
87
- @string[0..-extname.size-1]
87
+ @string[0..-extname.size - 1]
88
88
  else
89
89
  @string
90
90
  end
@@ -106,6 +106,17 @@ module Nanoc
106
106
  with_ext('')
107
107
  end
108
108
 
109
+ # @return [String] The extension, without a leading dot.
110
+ def ext
111
+ unless full?
112
+ raise Nanoc::Int::Errors::Generic,
113
+ 'Cannot use #ext on identifier that does not include the file extension'
114
+ end
115
+
116
+ s = File.extname(@string)
117
+ s && s[1..-1]
118
+ end
119
+
109
120
  def to_s
110
121
  @string
111
122
  end
@@ -0,0 +1,8 @@
1
+ module Nanoc::Int
2
+ # @api private
3
+ class Layout < ::Nanoc::Int::Document
4
+ def reference
5
+ [:layout, identifier]
6
+ end
7
+ end
8
+ end
File without changes
@@ -153,7 +153,8 @@ module Nanoc::Int
153
153
  #
154
154
  # @param [Symbol] snapshot The requested snapshot
155
155
  def initialize(item_rep, snapshot)
156
- @item_rep, @snapshot = item_rep, snapshot
156
+ @item_rep = item_rep
157
+ @snapshot = snapshot
157
158
  super("The “#{item_rep.inspect}” item rep does not have a snapshot “#{snapshot.inspect}”")
158
159
  end
159
160
  end
@@ -10,10 +10,7 @@ module Nanoc::Int
10
10
  #
11
11
  # @api private
12
12
  module Private
13
- # @return [Hash] A hash containing the assigns that will be used in the
14
- # next filter or layout operation. The keys (symbols) will be made
15
- # available during the next operation.
16
- attr_accessor :assigns
13
+ attr_accessor :content_snapshots
17
14
 
18
15
  # @return [Boolean] true if this representation has already been
19
16
  # compiled during the current or last compilation session; false
@@ -38,72 +35,6 @@ module Nanoc::Int
38
35
  # @api private
39
36
  attr_accessor :paths
40
37
 
41
- # @return [Hash<Symbol,String>] A hash containing the paths to the
42
- # temporary _files_ that filters write binary content to. This is only
43
- # used when the item representation is binary. The keys correspond
44
- # with the snapshot names, and the values with the filename. When
45
- # writing the item representation, the file corresponding with the
46
- # requested snapshot (usually `:last`) will be copied from
47
- # `filenames[snapshot]` to `raw_paths[snapshot]`.
48
- #
49
- # @api private
50
- attr_reader :temporary_filenames
51
-
52
- # @return [Hash<Symbol,String>] A hash containing the content at all
53
- # snapshots. The keys correspond with the snapshot names, and the
54
- # values with the content.
55
- #
56
- # @api private
57
- attr_accessor :content
58
-
59
- # Writes the item rep's compiled content to the rep's output file.
60
- #
61
- # This method will send two notifications: one before writing the item
62
- # representation, and one after. These notifications can be used for
63
- # generating diffs, for example.
64
- #
65
- # @api private
66
- #
67
- # @param [Symbol, nil] snapshot The name of the snapshot to write.
68
- #
69
- # @return [void]
70
- def write(snapshot = :last)
71
- # Get raw path
72
- raw_path = self.raw_path(snapshot: snapshot)
73
- return if raw_path.nil?
74
-
75
- # Create parent directory
76
- FileUtils.mkdir_p(File.dirname(raw_path))
77
-
78
- # Check if file will be created
79
- is_created = !File.file?(raw_path)
80
-
81
- # Notify
82
- Nanoc::Int::NotificationCenter.post(:will_write_rep, self, snapshot)
83
-
84
- if self.binary?
85
- temp_path = temporary_filenames[:last]
86
- else
87
- temp_path = temp_filename
88
- File.open(temp_path, 'w') { |io| io.write(@content[:last]) }
89
- end
90
-
91
- # Check whether content was modified
92
- is_modified = is_created || !FileUtils.identical?(raw_path, temp_path)
93
-
94
- # Write
95
- FileUtils.cp(temp_path, raw_path) if is_modified
96
-
97
- # Notify
98
- Nanoc::Int::NotificationCenter.post(:rep_written, self, raw_path, is_created, is_modified)
99
- end
100
-
101
- TMP_TEXT_ITEMS_DIR = 'text_items'
102
-
103
- def temp_filename
104
- Nanoc::Int::TempFilenameFactory.instance.create(TMP_TEXT_ITEMS_DIR)
105
- end
106
-
107
38
  # Resets the compilation progress for this item representation. This is
108
39
  # necessary when an unmet dependency is detected during compilation.
109
40
  #
@@ -113,17 +44,6 @@ module Nanoc::Int
113
44
  def forget_progress
114
45
  initialize_content
115
46
  end
116
-
117
- # Returns the type of this object. Will always return `:item_rep`,
118
- # because this is an item rep. For layouts, this method returns
119
- # `:layout`.
120
- #
121
- # @api private
122
- #
123
- # @return [Symbol] :item_rep
124
- def type
125
- :item_rep
126
- end
127
47
  end
128
48
 
129
49
  include Private
@@ -134,10 +54,6 @@ module Nanoc::Int
134
54
  # @return [Symbol] The representation's unique name
135
55
  attr_reader :name
136
56
 
137
- # @return [Boolean] true if this rep is currently binary; false otherwise
138
- attr_reader :binary
139
- alias_method :binary?, :binary
140
-
141
57
  # @return [Array] A list of snapshots, represented as arrays where the
142
58
  # first element is the snapshot name (a Symbol) and the last element is
143
59
  # a Boolean indicating whether the snapshot is final or not
@@ -154,13 +70,9 @@ module Nanoc::Int
154
70
  @item = item
155
71
  @name = name
156
72
 
157
- # Set binary
158
- @binary = @item.binary?
159
-
160
73
  # Set default attributes
161
74
  @raw_paths = {}
162
75
  @paths = {}
163
- @assigns = {}
164
76
  @snapshots = []
165
77
  initialize_content
166
78
 
@@ -168,6 +80,10 @@ module Nanoc::Int
168
80
  @compiled = false
169
81
  end
170
82
 
83
+ def binary?
84
+ @content_snapshots[:last].binary?
85
+ end
86
+
171
87
  # Returns the compiled content from a given snapshot.
172
88
  #
173
89
  # @option params [String] :snapshot The name of the snapshot from which to
@@ -179,16 +95,12 @@ module Nanoc::Int
179
95
  # default snapshot if no snapshot is specified)
180
96
  def compiled_content(params = {})
181
97
  # Make sure we're not binary
182
- if item.binary?
98
+ if binary?
183
99
  raise Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem.new(self)
184
100
  end
185
101
 
186
- # Notify
187
- Nanoc::Int::NotificationCenter.post(:visit_started, item)
188
- Nanoc::Int::NotificationCenter.post(:visit_ended, item)
189
-
190
102
  # Get name of last pre-layout snapshot
191
- snapshot_name = params.fetch(:snapshot) { @content[:pre] ? :pre : :last }
103
+ snapshot_name = params.fetch(:snapshot) { @content_snapshots[:pre] ? :pre : :last }
192
104
  is_moving = [:pre, :post, :last].include?(snapshot_name)
193
105
 
194
106
  # Check existance of snapshot
@@ -205,12 +117,12 @@ module Nanoc::Int
205
117
  when :pre
206
118
  snapshot.nil? || !snapshot[-1]
207
119
  end
208
- is_usable_snapshot = @content[snapshot_name] && (self.compiled? || !is_still_moving)
120
+ is_usable_snapshot = @content_snapshots[snapshot_name] && (self.compiled? || !is_still_moving)
209
121
  unless is_usable_snapshot
210
122
  raise Nanoc::Int::Errors::UnmetDependency.new(self)
211
123
  end
212
124
 
213
- @content[snapshot_name]
125
+ @content_snapshots[snapshot_name].string
214
126
  end
215
127
 
216
128
  # Checks whether content exists at a given snapshot.
@@ -220,7 +132,7 @@ module Nanoc::Int
220
132
  #
221
133
  # @since 3.2.0
222
134
  def snapshot?(snapshot_name)
223
- !@content[snapshot_name].nil?
135
+ !@content_snapshots[snapshot_name].nil?
224
136
  end
225
137
  alias_method :has_snapshot?, :snapshot?
226
138
 
@@ -232,9 +144,6 @@ module Nanoc::Int
232
144
  #
233
145
  # @return [String] The item rep’s path
234
146
  def raw_path(params = {})
235
- Nanoc::Int::NotificationCenter.post(:visit_started, item)
236
- Nanoc::Int::NotificationCenter.post(:visit_ended, item)
237
-
238
147
  snapshot_name = params[:snapshot] || :last
239
148
  @raw_paths[snapshot_name]
240
149
  end
@@ -249,180 +158,17 @@ module Nanoc::Int
249
158
  #
250
159
  # @return [String] The item rep’s path
251
160
  def path(params = {})
252
- Nanoc::Int::NotificationCenter.post(:visit_started, item)
253
- Nanoc::Int::NotificationCenter.post(:visit_ended, item)
254
-
255
161
  snapshot_name = params[:snapshot] || :last
256
162
  @paths[snapshot_name]
257
163
  end
258
164
 
259
- # Runs the item content through the given filter with the given arguments.
260
- # This method will replace the content of the `:last` snapshot with the
261
- # filtered content of the last snapshot.
262
- #
263
- # This method is supposed to be called only in a compilation rule block
264
- # (see {Nanoc::Int::CompilerDSL#compile}).
265
- #
266
- # @see Nanoc::Int::ItemRepProxy#filter
267
- #
268
- # @param [Symbol] filter_name The name of the filter to run the item
269
- # representations' content through
270
- #
271
- # @param [Hash] filter_args The filter arguments that should be passed to
272
- # the filter's #run method
273
- #
274
- # @return [void]
275
- def filter(filter_name, filter_args = {})
276
- # Get filter class
277
- klass = filter_named(filter_name)
278
- raise Nanoc::Int::Errors::UnknownFilter.new(filter_name) if klass.nil?
279
-
280
- # Check whether filter can be applied
281
- if klass.from_binary? && !self.binary?
282
- raise Nanoc::Int::Errors::CannotUseBinaryFilter.new(self, klass)
283
- elsif !klass.from_binary? && self.binary?
284
- raise Nanoc::Int::Errors::CannotUseTextualFilter.new(self, klass)
285
- end
286
-
287
- begin
288
- # Notify start
289
- Nanoc::Int::NotificationCenter.post(:filtering_started, self, filter_name)
290
-
291
- # Create filter
292
- filter = klass.new(assigns)
293
-
294
- # Run filter
295
- source = self.binary? ? temporary_filenames[:last] : @content[:last]
296
- result = filter.setup_and_run(source, filter_args)
297
- if klass.to_binary?
298
- temporary_filenames[:last] = filter.output_filename
299
- else
300
- @content[:last] = result
301
- @content[:last].freeze
302
- end
303
- @binary = klass.to_binary?
304
-
305
- # Check whether file was written
306
- if self.binary? && !File.file?(filter.output_filename)
307
- raise "The #{filter_name.inspect} filter did not write anything to the required output file, #{filter.output_filename}."
308
- end
309
-
310
- # Create snapshot
311
- snapshot(@content[:post] ? :post : :pre, final: false) unless self.binary?
312
- ensure
313
- # Notify end
314
- Nanoc::Int::NotificationCenter.post(:filtering_ended, self, filter_name)
315
- end
316
- end
317
-
318
- # Lays out the item using the given layout. This method will replace the
319
- # content of the `:last` snapshot with the laid out content of the last
320
- # snapshot.
321
- #
322
- # This method is supposed to be called only in a compilation rule block
323
- # (see {Nanoc::Int::CompilerDSL#compile}).
324
- #
325
- # @see Nanoc::Int::ItemRepProxy#layout
326
- #
327
- # @param [Nanoc::Int::Layout] layout The layout to use
328
- #
329
- # @param [Symbol] filter_name The name of the filter to layout the item
330
- # representations' content with
331
- #
332
- # @param [Hash] filter_args The filter arguments that should be passed to
333
- # the filter's #run method
334
- #
335
- # @return [void]
336
- def layout(layout, filter_name, filter_args)
337
- # Check whether item can be laid out
338
- raise Nanoc::Int::Errors::CannotLayoutBinaryItem.new(self) if self.binary?
339
-
340
- # Create "pre" snapshot
341
- if @content[:post].nil?
342
- snapshot(:pre, final: true)
343
- end
344
-
345
- # Create filter
346
- klass = filter_named(filter_name)
347
- raise Nanoc::Int::Errors::UnknownFilter.new(filter_name) if klass.nil?
348
- filter = klass.new(assigns.merge({ layout: layout }))
349
-
350
- # Visit
351
- Nanoc::Int::NotificationCenter.post(:visit_started, layout)
352
- Nanoc::Int::NotificationCenter.post(:visit_ended, layout)
353
-
354
- begin
355
- # Notify start
356
- Nanoc::Int::NotificationCenter.post(:processing_started, layout)
357
- Nanoc::Int::NotificationCenter.post(:filtering_started, self, filter_name)
358
-
359
- # Layout
360
- @content[:last] = filter.setup_and_run(layout.raw_content, filter_args)
361
-
362
- # Create "post" snapshot
363
- snapshot(:post, final: false)
364
- ensure
365
- # Notify end
366
- Nanoc::Int::NotificationCenter.post(:filtering_ended, self, filter_name)
367
- Nanoc::Int::NotificationCenter.post(:processing_ended, layout)
368
- end
369
- end
370
-
371
- # Creates a snapshot of the current compiled item content.
372
- #
373
- # @param [Symbol] snapshot_name The name of the snapshot to create
374
- #
375
- # @option params [Boolean] :final (true) True if this is the final time
376
- # the snapshot will be updated; false if it is a non-final moving
377
- # snapshot (such as `:pre`, `:post` or `:last`)
378
- #
379
- # @return [void]
380
- def snapshot(snapshot_name, params = {})
381
- is_final = params.fetch(:final, true)
382
-
383
- unless self.binary?
384
- @content[snapshot_name] = @content[:last]
385
- end
386
-
387
- if snapshot_name == :pre && is_final
388
- snapshots << [:pre, true]
389
- end
390
-
391
- write(snapshot_name) if is_final
392
- end
393
-
394
- # Returns a recording proxy that is used for determining whether the
395
- # compilation has changed, and thus whether the item rep needs to be
396
- # recompiled.
397
- #
398
- # @api private
399
- #
400
- # @return [Nanoc::Int::ItemRepRecorderProxy] The recording proxy
401
- def to_recording_proxy
402
- Nanoc::Int::ItemRepRecorderProxy.new(self)
403
- end
404
-
405
- # Returns false because this item is not yet a proxy, and therefore does
406
- # need to be wrapped in a proxy during compilation.
407
- #
408
- # @api private
409
- #
410
- # @return [false]
411
- #
412
- # @see Nanoc::Int::ItemRepRecorderProxy#proxy?
413
- # @see Nanoc::Int::ItemRepProxy#proxy?
414
- def proxy?
415
- false
416
- end
417
- alias_method :is_proxy?, :proxy?
418
-
419
165
  # Returns an object that can be used for uniquely identifying objects.
420
166
  #
421
167
  # @api private
422
168
  #
423
169
  # @return [Object] An unique reference to this object
424
170
  def reference
425
- [type, item.identifier, name]
171
+ [:item_rep, item.identifier, name]
426
172
  end
427
173
 
428
174
  def inspect
@@ -432,19 +178,8 @@ module Nanoc::Int
432
178
  private
433
179
 
434
180
  def initialize_content
435
- # Initialize content and filenames
436
- if self.binary?
437
- @temporary_filenames = { last: @item.raw_filename }
438
- @content = {}
439
- else
440
- @content = { last: @item.raw_content }
441
- @content[:last].freeze
442
- @temporary_filenames = {}
443
- end
444
- end
445
-
446
- def filter_named(name)
447
- Nanoc::Filter.named(name)
181
+ # FIXME: Where is :raw?
182
+ @content_snapshots = { last: @item.content }
448
183
  end
449
184
  end
450
185
  end