nanoc 2.0.4 → 2.1

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.
Files changed (99) hide show
  1. data/ChangeLog +31 -1
  2. data/LICENSE +1 -1
  3. data/README +63 -3
  4. data/Rakefile +59 -12
  5. data/bin/nanoc +7 -199
  6. data/lib/nanoc.rb +83 -12
  7. data/lib/nanoc/base/asset.rb +113 -0
  8. data/lib/nanoc/base/asset_defaults.rb +21 -0
  9. data/lib/nanoc/base/asset_rep.rb +277 -0
  10. data/lib/nanoc/base/binary_filter.rb +44 -0
  11. data/lib/nanoc/base/code.rb +41 -0
  12. data/lib/nanoc/base/compiler.rb +46 -34
  13. data/lib/nanoc/base/core_ext/hash.rb +51 -7
  14. data/lib/nanoc/base/core_ext/string.rb +8 -0
  15. data/lib/nanoc/base/data_source.rb +253 -20
  16. data/lib/nanoc/base/defaults.rb +30 -0
  17. data/lib/nanoc/base/enhancements.rb +9 -84
  18. data/lib/nanoc/base/filter.rb +109 -6
  19. data/lib/nanoc/base/layout.rb +91 -0
  20. data/lib/nanoc/base/notification_center.rb +66 -0
  21. data/lib/nanoc/base/page.rb +94 -126
  22. data/lib/nanoc/base/page_defaults.rb +20 -0
  23. data/lib/nanoc/base/page_rep.rb +318 -0
  24. data/lib/nanoc/base/plugin.rb +57 -9
  25. data/lib/nanoc/base/proxies/asset_proxy.rb +29 -0
  26. data/lib/nanoc/base/proxies/asset_rep_proxy.rb +26 -0
  27. data/lib/nanoc/base/proxies/layout_proxy.rb +25 -0
  28. data/lib/nanoc/base/proxies/page_proxy.rb +35 -0
  29. data/lib/nanoc/base/proxies/page_rep_proxy.rb +28 -0
  30. data/lib/nanoc/base/proxy.rb +37 -0
  31. data/lib/nanoc/base/router.rb +72 -0
  32. data/lib/nanoc/base/site.rb +219 -88
  33. data/lib/nanoc/base/template.rb +64 -0
  34. data/lib/nanoc/binary_filters/image_science_thumbnail.rb +28 -0
  35. data/lib/nanoc/cli.rb +1 -0
  36. data/lib/nanoc/cli/base.rb +219 -0
  37. data/lib/nanoc/cli/cli.rb +16 -0
  38. data/lib/nanoc/cli/command.rb +105 -0
  39. data/lib/nanoc/cli/commands/autocompile.rb +80 -0
  40. data/lib/nanoc/cli/commands/compile.rb +273 -0
  41. data/lib/nanoc/cli/commands/create_layout.rb +85 -0
  42. data/lib/nanoc/cli/commands/create_page.rb +85 -0
  43. data/lib/nanoc/cli/commands/create_site.rb +327 -0
  44. data/lib/nanoc/cli/commands/create_template.rb +76 -0
  45. data/lib/nanoc/cli/commands/help.rb +69 -0
  46. data/lib/nanoc/cli/commands/info.rb +114 -0
  47. data/lib/nanoc/cli/commands/switch.rb +141 -0
  48. data/lib/nanoc/cli/commands/update.rb +91 -0
  49. data/lib/nanoc/cli/ext.rb +37 -0
  50. data/lib/nanoc/cli/logger.rb +66 -0
  51. data/lib/nanoc/cli/option_parser.rb +168 -0
  52. data/lib/nanoc/data_sources/filesystem.rb +645 -224
  53. data/lib/nanoc/data_sources/filesystem_combined.rb +495 -0
  54. data/lib/nanoc/extra/auto_compiler.rb +265 -0
  55. data/lib/nanoc/extra/context.rb +22 -0
  56. data/lib/nanoc/extra/core_ext/hash.rb +54 -0
  57. data/lib/nanoc/extra/core_ext/time.rb +13 -0
  58. data/lib/nanoc/extra/file_proxy.rb +29 -0
  59. data/lib/nanoc/extra/vcs.rb +48 -0
  60. data/lib/nanoc/extra/vcses/bazaar.rb +21 -0
  61. data/lib/nanoc/extra/vcses/dummy.rb +20 -0
  62. data/lib/nanoc/extra/vcses/git.rb +21 -0
  63. data/lib/nanoc/extra/vcses/mercurial.rb +21 -0
  64. data/lib/nanoc/extra/vcses/subversion.rb +21 -0
  65. data/lib/nanoc/filters/bluecloth.rb +13 -0
  66. data/lib/nanoc/filters/erb.rb +6 -22
  67. data/lib/nanoc/filters/erubis.rb +14 -0
  68. data/lib/nanoc/filters/haml.rb +7 -23
  69. data/lib/nanoc/filters/markaby.rb +5 -5
  70. data/lib/nanoc/filters/maruku.rb +14 -0
  71. data/lib/nanoc/filters/old.rb +19 -0
  72. data/lib/nanoc/filters/rdiscount.rb +13 -0
  73. data/lib/nanoc/filters/rdoc.rb +5 -4
  74. data/lib/nanoc/filters/redcloth.rb +14 -0
  75. data/lib/nanoc/filters/rubypants.rb +14 -0
  76. data/lib/nanoc/filters/sass.rb +13 -0
  77. data/lib/nanoc/helpers/blogging.rb +170 -0
  78. data/lib/nanoc/helpers/capturing.rb +59 -0
  79. data/lib/nanoc/helpers/html_escape.rb +23 -0
  80. data/lib/nanoc/helpers/link_to.rb +69 -0
  81. data/lib/nanoc/helpers/render.rb +47 -0
  82. data/lib/nanoc/helpers/tagging.rb +52 -0
  83. data/lib/nanoc/helpers/xml_sitemap.rb +58 -0
  84. data/lib/nanoc/routers/default.rb +54 -0
  85. data/lib/nanoc/routers/no_dirs.rb +66 -0
  86. data/lib/nanoc/routers/versioned.rb +79 -0
  87. metadata +112 -22
  88. data/lib/nanoc/base/auto_compiler.rb +0 -132
  89. data/lib/nanoc/base/layout_processor.rb +0 -33
  90. data/lib/nanoc/base/page_proxy.rb +0 -31
  91. data/lib/nanoc/base/plugin_manager.rb +0 -33
  92. data/lib/nanoc/data_sources/database.rb +0 -259
  93. data/lib/nanoc/data_sources/trivial.rb +0 -145
  94. data/lib/nanoc/filters/markdown.rb +0 -13
  95. data/lib/nanoc/filters/smartypants.rb +0 -13
  96. data/lib/nanoc/filters/textile.rb +0 -13
  97. data/lib/nanoc/layout_processors/erb.rb +0 -35
  98. data/lib/nanoc/layout_processors/haml.rb +0 -38
  99. data/lib/nanoc/layout_processors/markaby.rb +0 -16
data/lib/nanoc.rb CHANGED
@@ -1,24 +1,95 @@
1
1
  module Nanoc
2
2
 
3
- VERSION = '2.0.4'
3
+ # The current nanoc version.
4
+ VERSION = '2.1'
4
5
 
5
- def self.load_file(*path)
6
+ # Generic error. Superclass for all nanoc-specific errors.
7
+ class Error < RuntimeError ; end
8
+
9
+ module Errors # :nodoc:
10
+
11
+ # Error that is raised when a site is loaded that uses a data source with
12
+ # an unknown identifier.
13
+ class UnknownDataSourceError < Error ; end
14
+
15
+ # Error that is raised when a site is loaded that uses a data source with
16
+ # an unknown identifier.
17
+ class UnknownRouterError < Error ; end
18
+
19
+ # Error that is raised during site compilation when a page uses a layout
20
+ # that is not present in the site.
21
+ class UnknownLayoutError < Error ; end
22
+
23
+ # Error that is raised during site compilation when a page uses a filter
24
+ # that is not known.
25
+ class UnknownFilterError < Error ; end
26
+
27
+ # Error that is raised during site compilation when a layout is compiled
28
+ # for which the filter cannot be determined. This is similar to the
29
+ # UnknownFilterError, but specific for filters for layouts.
30
+ class CannotDetermineFilterError < Error ; end
31
+
32
+ # Error that is raised during site compilation when a page (directly or
33
+ # indirectly) includes its own page content, leading to endless recursion.
34
+ class RecursiveCompilationError < Error ; end
35
+
36
+ # Error that is raised when a certain function or feature is used that is
37
+ # no longer supported by nanoc.
38
+ class NoLongerSupportedError < Error ; end
39
+
40
+ end
41
+
42
+ module BinaryFilters # :nodoc:
43
+ end
44
+
45
+ module DataSources # :nodoc:
46
+ end
47
+
48
+ module Helpers # :nodoc:
49
+ end
50
+
51
+ module Extra # :nodoc:
52
+ end
53
+
54
+ module Filters # :nodoc:
55
+ end
56
+
57
+ module Routers # :nodoc:
58
+ end
59
+
60
+ # Requires the given Ruby files at the specified path.
61
+ #
62
+ # +path+:: An array containing path segments. This path is relative to the
63
+ # directory this file (nanoc.rb) is in. Can contain wildcards.
64
+ def self.load(*path)
6
65
  full_path = [ File.dirname(__FILE__), 'nanoc' ] + path
7
66
  Dir[File.join(full_path)].each { |f| require f }
8
67
  end
9
68
 
10
69
  end
11
70
 
71
+ # Load requirements
72
+ begin ; require 'rubygems' ; rescue LoadError ; end
73
+ require 'yaml'
74
+ require 'fileutils'
75
+
12
76
  # Load base
13
- Nanoc.load_file('base', 'enhancements.rb')
14
- Nanoc.load_file('base', 'core_ext', '*.rb')
15
- Nanoc.load_file('base', 'plugin.rb')
16
- Nanoc.load_file('base', '*.rb')
77
+ Nanoc.load('base', 'enhancements.rb')
78
+ Nanoc.load('base', 'defaults.rb')
79
+ Nanoc.load('base', 'proxy.rb')
80
+ Nanoc.load('base', 'proxies', '*.rb')
81
+ Nanoc.load('base', 'core_ext', '*.rb')
82
+ Nanoc.load('base', 'plugin.rb')
83
+ Nanoc.load('base', '*.rb')
17
84
 
18
- # Load plugins
19
- Nanoc.load_file('data_sources', '*.rb')
20
- Nanoc.load_file('filters', '*.rb')
21
- Nanoc.load_file('layout_processors', '*.rb')
85
+ # Load extra's
86
+ Nanoc.load('extra', 'core_ext', '*.rb')
87
+ Nanoc.load('extra', '*.rb')
88
+ Nanoc.load('extra', 'vcses', '*.rb')
22
89
 
23
- # Get global binding
24
- $nanoc_binding = binding
90
+ # Load plugins
91
+ Nanoc.load('data_sources', '*.rb')
92
+ Nanoc.load('filters', '*.rb')
93
+ Nanoc.load('binary_filters', '*.rb')
94
+ Nanoc.load('routers', '*.rb')
95
+ Nanoc.load('helpers', '*.rb')
@@ -0,0 +1,113 @@
1
+ module Nanoc
2
+
3
+ # A Nanoc::Asset represents an asset in a nanoc site. It has a file object
4
+ # (File instance) and attributes, as well as a path. It can also store the
5
+ # modification time to speed up compilation.
6
+ #
7
+ # Each asset has a list of asset representations or reps (Nanoc::AssetRep);
8
+ # compiling an asset actually compiles all of its assets.
9
+ class Asset
10
+
11
+ # Defaults values for assets.
12
+ DEFAULTS = {
13
+ :extension => 'dat',
14
+ :binary => true,
15
+ :filters => []
16
+ }
17
+
18
+ # The Nanoc::Site this asset belongs to.
19
+ attr_accessor :site
20
+
21
+ # This assets's file.
22
+ attr_reader :file
23
+
24
+ # A hash containing this asset's attributes.
25
+ attr_accessor :attributes
26
+
27
+ # This asset's path.
28
+ attr_reader :path
29
+
30
+ # The time when this asset was last modified.
31
+ attr_reader :mtime
32
+
33
+ # This asset's list of asset representations.
34
+ attr_reader :reps
35
+
36
+ # Creates a new asset.
37
+ #
38
+ # +file+:: An instance of File representing the uncompiled asset.
39
+ #
40
+ # +attributes+:: A hash containing this asset's attributes.
41
+ #
42
+ # +path+:: This asset's path.
43
+ #
44
+ # +mtime+:: The time when this asset was last modified.
45
+ def initialize(file, attributes, path, mtime=nil)
46
+ # Set primary attributes
47
+ @file = file
48
+ @attributes = attributes.clean
49
+ @path = path.cleaned_path
50
+ @mtime = mtime
51
+ end
52
+
53
+ # Builds the individual asset representations (Nanoc::AssetRep) for this
54
+ # asset.
55
+ def build_reps
56
+ # Get list of rep names
57
+ rep_names_default = (@site.asset_defaults.attributes[:reps] || {}).keys
58
+ rep_names_this = (@attributes[:reps] || {}).keys + [ :default ]
59
+ rep_names = rep_names_default | rep_names_this
60
+
61
+ # Get list of reps
62
+ reps = rep_names.inject({}) do |memo, rep_name|
63
+ rep = (@attributes[:reps] || {})[rep_name]
64
+ is_bad = (@attributes[:reps] || {}).has_key?(rep_name) && rep.nil?
65
+ is_bad ? memo : memo.merge(rep_name => rep || {})
66
+ end
67
+
68
+ # Build reps
69
+ @reps = []
70
+ reps.each_pair do |name, attrs|
71
+ @reps << AssetRep.new(self, attrs, name)
72
+ end
73
+ end
74
+
75
+ # Returns a proxy (Nanoc::AssetProxy) for this asset.
76
+ def to_proxy
77
+ @proxy ||= AssetProxy.new(self)
78
+ end
79
+
80
+ # Returns the attribute with the given name.
81
+ def attribute_named(name)
82
+ return @attributes[name] if @attributes.has_key?(name)
83
+ return @site.asset_defaults.attributes[name] if @site.asset_defaults.attributes.has_key?(name)
84
+ return DEFAULTS[name]
85
+ end
86
+
87
+ # Saves the asset in the database, creating it if it doesn't exist yet or
88
+ # updating it if it already exists. Tells the site's data source to save
89
+ # the asset.
90
+ def save
91
+ @site.data_source.loading do
92
+ @site.data_source.save_asset(self)
93
+ end
94
+ end
95
+
96
+ # Moves the asset to a new path. Tells the site's data source to move the
97
+ # asset.
98
+ def move_to(new_path)
99
+ @site.data_source.loading do
100
+ @site.data_source.move_asset(self, new_path)
101
+ end
102
+ end
103
+
104
+ # Deletes the asset. Tells the site's data source to delete the asset.
105
+ def delete
106
+ @site.data_source.loading do
107
+ @site.data_source.delete_asset(self)
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,21 @@
1
+ module Nanoc
2
+
3
+ # Nanoc::AssetDefaults represent the default attributes for all assets in
4
+ # the site. If a specific asset attribute is requested, but not found, then
5
+ # the asset defaults will be queried for this attribute. (If the attribute
6
+ # doesn't even exist in the asset defaults, hardcoded defaults will be
7
+ # used.)
8
+ class AssetDefaults < Defaults
9
+
10
+ # Saves the asset defaults in the database, creating it if it doesn't
11
+ # exist yet or updating it if it already exists. Tells the site's data
12
+ # source to save the asset defaults.
13
+ def save
14
+ @site.data_source.loading do
15
+ @site.data_source.save_asset_defaults(self)
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,277 @@
1
+ module Nanoc
2
+
3
+ # A Nanoc::AssetRep is a single representation (rep) of an asset
4
+ # (Nanoc::Asset). An asset can have multiple representations. A
5
+ # representation has its own attributes and its own output file. A single
6
+ # asset can therefore have multiple output files, each run through a
7
+ # different set of filters with a different layout.
8
+ #
9
+ # An asset representation is observable. The following events will be
10
+ # notified:
11
+ #
12
+ # * :compilation_started
13
+ # * :compilation_ended
14
+ # * :filtering_started
15
+ # * :filtering_ended
16
+ #
17
+ # The compilation-related events have one parameters (the page
18
+ # representation); the filtering-related events have two (the page
19
+ # representation, and a symbol containing the filter class name).
20
+ class AssetRep
21
+
22
+ # The asset (Nanoc::Asset) to which this representation belongs.
23
+ attr_reader :asset
24
+
25
+ # A hash containing this asset representation's attributes.
26
+ attr_accessor :attributes
27
+
28
+ # This asset representation's unique name.
29
+ attr_reader :name
30
+
31
+ # Creates a new asset representation for the given asset and with the
32
+ # given attributes.
33
+ #
34
+ # +asset+:: The asset (Nanoc::Asset) to which the new representation will
35
+ # belong.
36
+ #
37
+ # +attributes+:: A hash containing the new asset representation's
38
+ # attributes. This hash must have been run through
39
+ # Hash#clean before using it here.
40
+ #
41
+ # +name+:: The unique name for the new asset representation.
42
+ def initialize(asset, attributes, name)
43
+ # Set primary attributes
44
+ @asset = asset
45
+ @attributes = attributes
46
+ @name = name
47
+
48
+ # Reset flags
49
+ @compiled = false
50
+ @modified = false
51
+ @created = false
52
+
53
+ # Reset stages
54
+ @filtered = false
55
+ end
56
+
57
+ # Returns a proxy (Nanoc::AssetRepProxy) for this asset representation.
58
+ def to_proxy
59
+ @proxy ||= AssetRepProxy.new(self)
60
+ end
61
+
62
+ # Returns true if this asset rep's output file was created during the last
63
+ # compilation session, or false if the output file did already exist.
64
+ def created?
65
+ @created
66
+ end
67
+
68
+ # Returns true if this asset rep's output file was modified during the
69
+ # last compilation session, or false if the output file wasn't changed.
70
+ def modified?
71
+ @modified
72
+ end
73
+
74
+ # Returns true if this page rep has been compiled, false otherwise.
75
+ def compiled?
76
+ @compiled
77
+ end
78
+
79
+ # Returns the path to the output file, including the path to the output
80
+ # directory specified in the site configuration, and including the
81
+ # filename and extension.
82
+ def disk_path
83
+ @disk_path ||= @asset.site.router.disk_path_for(self)
84
+ end
85
+
86
+ # Returns the path to the output file as it would be used in a web
87
+ # browser: starting with a slash (representing the web root), and only
88
+ # including the filename and extension if they cannot be ignored (i.e.
89
+ # they are not in the site configuration's list of index files).
90
+ def web_path
91
+ compile(false, false)
92
+
93
+ @web_path ||= @asset.site.router.web_path_for(self)
94
+ end
95
+
96
+ # Returns true if this asset rep's output file is outdated and must be
97
+ # regenerated, false otherwise.
98
+ def outdated?
99
+ # Outdated if we don't know
100
+ return true if @asset.mtime.nil?
101
+
102
+ # Outdated if compiled file doesn't exist
103
+ return true if !File.file?(disk_path)
104
+
105
+ # Get compiled mtime
106
+ compiled_mtime = File.stat(disk_path).mtime
107
+
108
+ # Outdated if file too old
109
+ return true if @asset.mtime > compiled_mtime
110
+
111
+ # Outdated if asset defaults outdated
112
+ return true if @asset.site.asset_defaults.mtime.nil?
113
+ return true if @asset.site.asset_defaults.mtime > compiled_mtime
114
+
115
+ # Outdated if code outdated
116
+ return true if @asset.site.code.mtime.nil?
117
+ return true if @asset.site.code.mtime > compiled_mtime
118
+
119
+ return false
120
+ end
121
+
122
+ # Returns the attribute with the given name. This method will look in
123
+ # several places for the requested attribute:
124
+ #
125
+ # 1. This asset representation's attributes;
126
+ # 2. The attributes of this asset representation's asset;
127
+ # 3. The asset defaults' representation corresponding to this asset
128
+ # representation;
129
+ # 4. The asset defaults in general;
130
+ # 5. The hardcoded asset defaults, if everything else fails.
131
+ def attribute_named(name)
132
+ # Check in here
133
+ return @attributes[name] if @attributes.has_key?(name)
134
+
135
+ # Check in asset
136
+ return @asset.attributes[name] if @asset.attributes.has_key?(name)
137
+
138
+ # Check in asset defaults' asset rep
139
+ asset_default_reps = @asset.site.asset_defaults.attributes[:reps] || {}
140
+ asset_default_rep = asset_default_reps[@name] || {}
141
+ return asset_default_rep[name] if asset_default_rep.has_key?(name)
142
+
143
+ # Check in site defaults (global)
144
+ asset_defaults_attrs = @asset.site.asset_defaults.attributes
145
+ return asset_defaults_attrs[name] if asset_defaults_attrs.has_key?(name)
146
+
147
+ # Check in hardcoded defaults
148
+ return Nanoc::Asset::DEFAULTS[name]
149
+ end
150
+
151
+ # Compiles the asset representation and writes the result to the disk.
152
+ # This method should not be called directly; please use
153
+ # Nanoc::Compiler#run instead, and pass this asset representation's asset
154
+ # as its first argument.
155
+ #
156
+ # The asset representation will only be compiled if it wasn't compiled
157
+ # before yet. To force recompilation of the asset rep, forgetting any
158
+ # progress, set +from_scratch+ to true.
159
+ #
160
+ # +even_when_not_outdated+:: true if the asset rep should be compiled even
161
+ # if it is not outdated, false if not.
162
+ #
163
+ # +from_scratch+:: true if the asset rep should be filtered again even if
164
+ # it has already been filtered, false otherwise.
165
+ def compile(even_when_not_outdated, from_scratch)
166
+ # Don't compile if already compiled
167
+ return if @compiled and !from_scratch
168
+
169
+ # Skip unless outdated
170
+ unless outdated? or even_when_not_outdated
171
+ Nanoc::NotificationCenter.post(:compilation_started, self)
172
+ Nanoc::NotificationCenter.post(:compilation_ended, self)
173
+ return
174
+ end
175
+
176
+ # Reset flags
177
+ @compiled = false
178
+ @modified = false
179
+ @created = !File.file?(self.disk_path)
180
+
181
+ # Forget progress if requested
182
+ @filtered = false if from_scratch
183
+
184
+ # Start
185
+ @asset.site.compiler.stack.push(self)
186
+ Nanoc::NotificationCenter.post(:compilation_started, self)
187
+
188
+ # Compile
189
+ unless @filtered
190
+ if attribute_named(:binary) == true
191
+ compile_binary
192
+ else
193
+ compile_textual
194
+ end
195
+ end
196
+ @compiled = true
197
+
198
+ # Stop
199
+ @asset.site.compiler.stack.pop
200
+ Nanoc::NotificationCenter.post(:compilation_ended, self)
201
+ end
202
+
203
+ private
204
+
205
+ # Computes and returns the MD5 digest for the given file.
206
+ def digest(file)
207
+ # Create hash
208
+ incr_digest = Digest::MD5.new()
209
+
210
+ # Collect data
211
+ file.rewind
212
+ incr_digest << file.read(1000) until file.eof?
213
+
214
+ # Calculate hex hash
215
+ incr_digest.hexdigest
216
+ end
217
+
218
+ # Compiles the asset rep, treating its contents as binary data.
219
+ def compile_binary
220
+ # Calculate digest before
221
+ digest_before = File.file?(disk_path) ? digest(File.open(disk_path, 'r')) : nil
222
+
223
+ # Run filters
224
+ current_file = @asset.file
225
+ attribute_named(:filters).each do |filter_name|
226
+ # Free resources so that this filter won't fail
227
+ GC.start
228
+
229
+ # Create filter
230
+ klass = Nanoc::BinaryFilter.named(filter_name)
231
+ raise Nanoc::Errors::UnknownFilterError.new(filter_name) if klass.nil?
232
+ filter = klass.new(self.to_proxy, @asset.to_proxy, @asset.site)
233
+
234
+ # Run filter
235
+ Nanoc::NotificationCenter.post(:filtering_started, self, klass.identifier)
236
+ current_file = filter.run(current_file)
237
+ Nanoc::NotificationCenter.post(:filtering_ended, self, klass.identifier)
238
+ end
239
+
240
+ # Write asset
241
+ FileUtils.mkdir_p(File.dirname(self.disk_path))
242
+ FileUtils.cp(current_file.path, disk_path)
243
+
244
+ # Calculate digest after
245
+ digest_after = digest(current_file)
246
+ @modified = (digest_after != digest_before)
247
+ end
248
+
249
+ # Compiles the asset rep, treating its contents as textual data.
250
+ def compile_textual
251
+ # Get content
252
+ current_content = @asset.file.read
253
+
254
+ # Check modified
255
+ @modified = @created ? true : File.read(self.disk_path) != current_content
256
+
257
+ # Run filters
258
+ attribute_named(:filters).each do |filter_name|
259
+ # Create filter
260
+ klass = Nanoc::Filter.named(filter_name)
261
+ raise Nanoc::Errors::UnknownFilterError.new(filter_name) if klass.nil?
262
+ filter = klass.new(self)
263
+
264
+ # Run filter
265
+ Nanoc::NotificationCenter.post(:filtering_started, self, klass.identifier)
266
+ current_content = filter.run(current_content)
267
+ Nanoc::NotificationCenter.post(:filtering_ended, self, klass.identifier)
268
+ end
269
+
270
+ # Write asset
271
+ FileUtils.mkdir_p(File.dirname(self.disk_path))
272
+ File.open(self.disk_path, 'w') { |io| io.write(current_content) }
273
+ end
274
+
275
+ end
276
+
277
+ end