nanoc 4.0.0b3 → 4.0.0b4
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +4 -2
- data/NEWS.md +10 -0
- data/TODO.md +15 -0
- data/lib/nanoc/base.rb +4 -27
- data/lib/nanoc/base/checksummer.rb +69 -19
- data/lib/nanoc/base/compilation/compiler.rb +14 -12
- data/lib/nanoc/base/compilation/compiler_dsl.rb +2 -0
- data/lib/nanoc/base/compilation/filter.rb +4 -2
- data/lib/nanoc/base/compilation/outdatedness_checker.rb +7 -7
- data/lib/nanoc/base/compilation/rule.rb +5 -6
- data/lib/nanoc/base/compilation/rule_context.rb +16 -34
- data/lib/nanoc/base/compilation/rule_memory_calculator.rb +3 -3
- data/lib/nanoc/base/compilation/rules_collection.rb +4 -10
- data/lib/nanoc/base/context.rb +2 -0
- data/lib/nanoc/base/core_ext/array.rb +0 -10
- data/lib/nanoc/base/core_ext/hash.rb +0 -10
- data/lib/nanoc/base/core_ext/pathname.rb +0 -9
- data/lib/nanoc/base/core_ext/string.rb +0 -10
- data/lib/nanoc/base/entities.rb +5 -0
- data/lib/nanoc/base/entities/content.rb +86 -0
- data/lib/nanoc/base/entities/document.rb +56 -0
- data/lib/nanoc/base/{source_data → entities}/identifier.rb +12 -1
- data/lib/nanoc/base/entities/layout.rb +8 -0
- data/lib/nanoc/base/{pattern.rb → entities/pattern.rb} +0 -0
- data/lib/nanoc/base/errors.rb +2 -1
- data/lib/nanoc/base/result_data/item_rep.rb +13 -278
- data/lib/nanoc/base/services.rb +5 -0
- data/lib/nanoc/base/services/executor.rb +141 -0
- data/lib/nanoc/base/services/item_rep_writer.rb +40 -0
- data/lib/nanoc/base/{notification_center.rb → services/notification_center.rb} +0 -0
- data/lib/nanoc/base/services/recording_executor.rb +41 -0
- data/lib/nanoc/base/{temp_filename_factory.rb → services/temp_filename_factory.rb} +0 -0
- data/lib/nanoc/base/source_data/code_snippet.rb +0 -6
- data/lib/nanoc/base/source_data/data_source.rb +4 -3
- data/lib/nanoc/base/source_data/item.rb +23 -213
- data/lib/nanoc/base/source_data/site.rb +0 -1
- data/lib/nanoc/base/views.rb +18 -0
- data/lib/nanoc/base/views/config.rb +1 -1
- data/lib/nanoc/base/views/item.rb +8 -73
- data/lib/nanoc/base/views/item_rep.rb +9 -0
- data/lib/nanoc/base/views/item_rep_collection.rb +17 -0
- data/lib/nanoc/base/views/layout.rb +1 -40
- data/lib/nanoc/base/views/mixins/document.rb +76 -0
- data/lib/nanoc/base/views/mixins/mutable_document.rb +22 -0
- data/lib/nanoc/base/views/mutable_identifiable_collection.rb +1 -1
- data/lib/nanoc/base/views/mutable_item.rb +1 -18
- data/lib/nanoc/base/views/mutable_item_collection.rb +6 -2
- data/lib/nanoc/base/views/mutable_layout.rb +1 -8
- data/lib/nanoc/cli/commands/compile.rb +1 -2
- data/lib/nanoc/cli/commands/create-site.rb +5 -5
- data/lib/nanoc/cli/commands/show-data.rb +11 -1
- data/lib/nanoc/data_sources/filesystem.rb +17 -10
- data/lib/nanoc/helpers/capturing.rb +1 -2
- data/lib/nanoc/helpers/filtering.rb +13 -1
- data/lib/nanoc/helpers/rendering.rb +4 -2
- data/lib/nanoc/version.rb +1 -1
- data/test/base/core_ext/array_spec.rb +0 -7
- data/test/base/core_ext/hash_spec.rb +0 -13
- data/test/base/core_ext/pathname_spec.rb +0 -33
- data/test/base/core_ext/string_spec.rb +0 -10
- data/test/base/test_compiler_dsl.rb +3 -3
- data/test/base/test_data_source.rb +2 -2
- data/test/base/test_item.rb +5 -129
- data/test/base/test_item_rep.rb +26 -558
- data/test/base/test_layout.rb +2 -26
- data/test/base/test_rule.rb +3 -3
- data/test/base/test_rule_context.rb +34 -15
- data/test/data_sources/test_filesystem.rb +2 -2
- data/test/data_sources/test_filesystem_unified.rb +39 -33
- data/test/extra/checking/checks/test_html.rb +0 -1
- data/test/extra/checking/checks/test_mixed_content.rb +3 -3
- data/test/extra/deployers/test_fog.rb +24 -24
- data/test/filters/test_less.rb +4 -4
- data/test/filters/test_sass.rb +10 -5
- data/test/filters/test_xsl.rb +6 -0
- data/test/helpers/test_capturing.rb +0 -1
- data/test/helpers/test_filtering.rb +5 -19
- data/test/helpers/test_tagging.rb +6 -6
- metadata +18 -11
- data/lib/nanoc/base/compilation/item_rep_proxy.rb +0 -109
- data/lib/nanoc/base/compilation/item_rep_recorder_proxy.rb +0 -97
- data/lib/nanoc/base/source_data/layout.rb +0 -111
- data/test/base/checksummer_spec.rb +0 -256
- 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
|
18
|
-
#
|
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)
|
27
|
-
|
28
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
23
|
-
when
|
22
|
+
case obj
|
23
|
+
when Nanoc::Int::ItemRep
|
24
24
|
@rules_collection.new_rule_memory_for_rep(obj)
|
25
|
-
when
|
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
|
-
|
189
|
-
compilation_rule_for(rep).apply_to(
|
190
|
-
|
191
|
-
make_rule_memory_serializable(
|
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
|
|
data/lib/nanoc/base/context.rb
CHANGED
@@ -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,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
|
File without changes
|
data/lib/nanoc/base/errors.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
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) { @
|
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 = @
|
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
|
-
@
|
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
|
-
!@
|
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
|
-
[
|
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
|
-
#
|
436
|
-
|
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
|