nanoc3 3.2.4 → 3.3.0

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 (211) hide show
  1. metadata +14 -313
  2. data/.gemtest +0 -0
  3. data/ChangeLog +0 -3
  4. data/Gemfile +0 -29
  5. data/LICENSE +0 -19
  6. data/NEWS.md +0 -449
  7. data/README.md +0 -108
  8. data/Rakefile +0 -14
  9. data/bin/nanoc3 +0 -12
  10. data/doc/yardoc_templates/default/layout/html/footer.erb +0 -10
  11. data/lib/nanoc3.rb +0 -28
  12. data/lib/nanoc3/base.rb +0 -49
  13. data/lib/nanoc3/base/compilation/checksum_store.rb +0 -57
  14. data/lib/nanoc3/base/compilation/compiled_content_cache.rb +0 -62
  15. data/lib/nanoc3/base/compilation/compiler.rb +0 -455
  16. data/lib/nanoc3/base/compilation/compiler_dsl.rb +0 -214
  17. data/lib/nanoc3/base/compilation/dependency_tracker.rb +0 -196
  18. data/lib/nanoc3/base/compilation/filter.rb +0 -165
  19. data/lib/nanoc3/base/compilation/item_rep_proxy.rb +0 -102
  20. data/lib/nanoc3/base/compilation/item_rep_recorder_proxy.rb +0 -88
  21. data/lib/nanoc3/base/compilation/outdatedness_checker.rb +0 -223
  22. data/lib/nanoc3/base/compilation/outdatedness_reasons.rb +0 -46
  23. data/lib/nanoc3/base/compilation/rule.rb +0 -73
  24. data/lib/nanoc3/base/compilation/rule_context.rb +0 -84
  25. data/lib/nanoc3/base/compilation/rule_memory_calculator.rb +0 -40
  26. data/lib/nanoc3/base/compilation/rule_memory_store.rb +0 -53
  27. data/lib/nanoc3/base/compilation/rules_collection.rb +0 -231
  28. data/lib/nanoc3/base/context.rb +0 -47
  29. data/lib/nanoc3/base/core_ext.rb +0 -6
  30. data/lib/nanoc3/base/core_ext/array.rb +0 -62
  31. data/lib/nanoc3/base/core_ext/hash.rb +0 -63
  32. data/lib/nanoc3/base/core_ext/pathname.rb +0 -26
  33. data/lib/nanoc3/base/core_ext/string.rb +0 -46
  34. data/lib/nanoc3/base/directed_graph.rb +0 -275
  35. data/lib/nanoc3/base/errors.rb +0 -174
  36. data/lib/nanoc3/base/memoization.rb +0 -67
  37. data/lib/nanoc3/base/notification_center.rb +0 -84
  38. data/lib/nanoc3/base/ordered_hash.rb +0 -200
  39. data/lib/nanoc3/base/plugin_registry.rb +0 -165
  40. data/lib/nanoc3/base/result_data/item_rep.rb +0 -488
  41. data/lib/nanoc3/base/source_data/code_snippet.rb +0 -58
  42. data/lib/nanoc3/base/source_data/configuration.rb +0 -24
  43. data/lib/nanoc3/base/source_data/data_source.rb +0 -234
  44. data/lib/nanoc3/base/source_data/item.rb +0 -301
  45. data/lib/nanoc3/base/source_data/layout.rb +0 -130
  46. data/lib/nanoc3/base/source_data/site.rb +0 -361
  47. data/lib/nanoc3/base/store.rb +0 -135
  48. data/lib/nanoc3/cli.rb +0 -133
  49. data/lib/nanoc3/cli/command.rb +0 -139
  50. data/lib/nanoc3/cli/commands/autocompile.rb +0 -60
  51. data/lib/nanoc3/cli/commands/compile.rb +0 -280
  52. data/lib/nanoc3/cli/commands/create_item.rb +0 -62
  53. data/lib/nanoc3/cli/commands/create_layout.rb +0 -75
  54. data/lib/nanoc3/cli/commands/create_site.rb +0 -410
  55. data/lib/nanoc3/cli/commands/debug.rb +0 -119
  56. data/lib/nanoc3/cli/commands/info.rb +0 -98
  57. data/lib/nanoc3/cli/commands/nanoc.rb +0 -37
  58. data/lib/nanoc3/cli/commands/update.rb +0 -72
  59. data/lib/nanoc3/cli/commands/view.rb +0 -84
  60. data/lib/nanoc3/cli/commands/watch.rb +0 -125
  61. data/lib/nanoc3/cli/error_handler.rb +0 -193
  62. data/lib/nanoc3/cli/logger.rb +0 -91
  63. data/lib/nanoc3/data_sources.rb +0 -29
  64. data/lib/nanoc3/data_sources/deprecated/delicious.rb +0 -42
  65. data/lib/nanoc3/data_sources/deprecated/last_fm.rb +0 -87
  66. data/lib/nanoc3/data_sources/deprecated/twitter.rb +0 -38
  67. data/lib/nanoc3/data_sources/filesystem.rb +0 -299
  68. data/lib/nanoc3/data_sources/filesystem_unified.rb +0 -116
  69. data/lib/nanoc3/data_sources/filesystem_verbose.rb +0 -86
  70. data/lib/nanoc3/extra.rb +0 -22
  71. data/lib/nanoc3/extra/auto_compiler.rb +0 -103
  72. data/lib/nanoc3/extra/chick.rb +0 -125
  73. data/lib/nanoc3/extra/core_ext.rb +0 -4
  74. data/lib/nanoc3/extra/core_ext/enumerable.rb +0 -33
  75. data/lib/nanoc3/extra/core_ext/time.rb +0 -19
  76. data/lib/nanoc3/extra/deployers.rb +0 -11
  77. data/lib/nanoc3/extra/deployers/rsync.rb +0 -114
  78. data/lib/nanoc3/extra/file_proxy.rb +0 -40
  79. data/lib/nanoc3/extra/validators.rb +0 -12
  80. data/lib/nanoc3/extra/validators/links.rb +0 -264
  81. data/lib/nanoc3/extra/validators/w3c.rb +0 -95
  82. data/lib/nanoc3/extra/vcs.rb +0 -66
  83. data/lib/nanoc3/extra/vcses.rb +0 -17
  84. data/lib/nanoc3/extra/vcses/bazaar.rb +0 -25
  85. data/lib/nanoc3/extra/vcses/dummy.rb +0 -24
  86. data/lib/nanoc3/extra/vcses/git.rb +0 -25
  87. data/lib/nanoc3/extra/vcses/mercurial.rb +0 -25
  88. data/lib/nanoc3/extra/vcses/subversion.rb +0 -25
  89. data/lib/nanoc3/filters.rb +0 -53
  90. data/lib/nanoc3/filters/asciidoc.rb +0 -38
  91. data/lib/nanoc3/filters/bluecloth.rb +0 -19
  92. data/lib/nanoc3/filters/coderay.rb +0 -21
  93. data/lib/nanoc3/filters/colorize_syntax.rb +0 -261
  94. data/lib/nanoc3/filters/erb.rb +0 -35
  95. data/lib/nanoc3/filters/erubis.rb +0 -27
  96. data/lib/nanoc3/filters/haml.rb +0 -27
  97. data/lib/nanoc3/filters/kramdown.rb +0 -20
  98. data/lib/nanoc3/filters/less.rb +0 -53
  99. data/lib/nanoc3/filters/markaby.rb +0 -20
  100. data/lib/nanoc3/filters/maruku.rb +0 -20
  101. data/lib/nanoc3/filters/mustache.rb +0 -24
  102. data/lib/nanoc3/filters/rainpress.rb +0 -19
  103. data/lib/nanoc3/filters/rdiscount.rb +0 -22
  104. data/lib/nanoc3/filters/rdoc.rb +0 -33
  105. data/lib/nanoc3/filters/redcarpet.rb +0 -27
  106. data/lib/nanoc3/filters/redcloth.rb +0 -47
  107. data/lib/nanoc3/filters/relativize_paths.rb +0 -45
  108. data/lib/nanoc3/filters/rubypants.rb +0 -20
  109. data/lib/nanoc3/filters/sass.rb +0 -66
  110. data/lib/nanoc3/filters/slim.rb +0 -25
  111. data/lib/nanoc3/filters/typogruby.rb +0 -23
  112. data/lib/nanoc3/filters/uglify_js.rb +0 -42
  113. data/lib/nanoc3/helpers.rb +0 -16
  114. data/lib/nanoc3/helpers/blogging.rb +0 -319
  115. data/lib/nanoc3/helpers/breadcrumbs.rb +0 -40
  116. data/lib/nanoc3/helpers/capturing.rb +0 -138
  117. data/lib/nanoc3/helpers/filtering.rb +0 -50
  118. data/lib/nanoc3/helpers/html_escape.rb +0 -55
  119. data/lib/nanoc3/helpers/link_to.rb +0 -151
  120. data/lib/nanoc3/helpers/rendering.rb +0 -140
  121. data/lib/nanoc3/helpers/tagging.rb +0 -71
  122. data/lib/nanoc3/helpers/text.rb +0 -44
  123. data/lib/nanoc3/helpers/xml_sitemap.rb +0 -76
  124. data/lib/nanoc3/tasks.rb +0 -10
  125. data/lib/nanoc3/tasks/clean.rake +0 -16
  126. data/lib/nanoc3/tasks/clean.rb +0 -29
  127. data/lib/nanoc3/tasks/deploy/rsync.rake +0 -14
  128. data/lib/nanoc3/tasks/validate.rake +0 -92
  129. data/nanoc3.gemspec +0 -49
  130. data/tasks/doc.rake +0 -16
  131. data/tasks/test.rake +0 -44
  132. data/test/base/core_ext/array_spec.rb +0 -73
  133. data/test/base/core_ext/hash_spec.rb +0 -98
  134. data/test/base/core_ext/pathname_spec.rb +0 -27
  135. data/test/base/core_ext/string_spec.rb +0 -37
  136. data/test/base/test_checksum_store.rb +0 -35
  137. data/test/base/test_code_snippet.rb +0 -31
  138. data/test/base/test_compiler.rb +0 -316
  139. data/test/base/test_compiler_dsl.rb +0 -161
  140. data/test/base/test_context.rb +0 -31
  141. data/test/base/test_data_source.rb +0 -46
  142. data/test/base/test_dependency_tracker.rb +0 -262
  143. data/test/base/test_directed_graph.rb +0 -283
  144. data/test/base/test_filter.rb +0 -83
  145. data/test/base/test_item.rb +0 -179
  146. data/test/base/test_item_rep.rb +0 -553
  147. data/test/base/test_layout.rb +0 -59
  148. data/test/base/test_memoization.rb +0 -90
  149. data/test/base/test_notification_center.rb +0 -34
  150. data/test/base/test_outdatedness_checker.rb +0 -394
  151. data/test/base/test_plugin.rb +0 -30
  152. data/test/base/test_rule.rb +0 -19
  153. data/test/base/test_rule_context.rb +0 -65
  154. data/test/base/test_site.rb +0 -190
  155. data/test/cli/commands/test_compile.rb +0 -33
  156. data/test/cli/commands/test_create_item.rb +0 -14
  157. data/test/cli/commands/test_create_layout.rb +0 -28
  158. data/test/cli/commands/test_create_site.rb +0 -24
  159. data/test/cli/commands/test_help.rb +0 -12
  160. data/test/cli/commands/test_info.rb +0 -11
  161. data/test/cli/commands/test_update.rb +0 -10
  162. data/test/cli/test_cli.rb +0 -102
  163. data/test/cli/test_error_handler.rb +0 -29
  164. data/test/cli/test_logger.rb +0 -10
  165. data/test/data_sources/test_filesystem.rb +0 -433
  166. data/test/data_sources/test_filesystem_unified.rb +0 -536
  167. data/test/data_sources/test_filesystem_verbose.rb +0 -357
  168. data/test/extra/core_ext/test_enumerable.rb +0 -30
  169. data/test/extra/core_ext/test_time.rb +0 -15
  170. data/test/extra/deployers/test_rsync.rb +0 -232
  171. data/test/extra/test_auto_compiler.rb +0 -417
  172. data/test/extra/test_file_proxy.rb +0 -19
  173. data/test/extra/test_vcs.rb +0 -22
  174. data/test/extra/validators/test_links.rb +0 -51
  175. data/test/extra/validators/test_w3c.rb +0 -47
  176. data/test/filters/test_asciidoc.rb +0 -22
  177. data/test/filters/test_bluecloth.rb +0 -18
  178. data/test/filters/test_coderay.rb +0 -44
  179. data/test/filters/test_colorize_syntax.rb +0 -283
  180. data/test/filters/test_erb.rb +0 -99
  181. data/test/filters/test_erubis.rb +0 -70
  182. data/test/filters/test_haml.rb +0 -96
  183. data/test/filters/test_kramdown.rb +0 -18
  184. data/test/filters/test_less.rb +0 -113
  185. data/test/filters/test_markaby.rb +0 -24
  186. data/test/filters/test_maruku.rb +0 -18
  187. data/test/filters/test_mustache.rb +0 -25
  188. data/test/filters/test_rainpress.rb +0 -29
  189. data/test/filters/test_rdiscount.rb +0 -31
  190. data/test/filters/test_rdoc.rb +0 -18
  191. data/test/filters/test_redcarpet.rb +0 -63
  192. data/test/filters/test_redcloth.rb +0 -33
  193. data/test/filters/test_relativize_paths.rb +0 -332
  194. data/test/filters/test_rubypants.rb +0 -18
  195. data/test/filters/test_sass.rb +0 -229
  196. data/test/filters/test_slim.rb +0 -35
  197. data/test/filters/test_typogruby.rb +0 -21
  198. data/test/filters/test_uglify_js.rb +0 -30
  199. data/test/gem_loader.rb +0 -11
  200. data/test/helper.rb +0 -179
  201. data/test/helpers/test_blogging.rb +0 -754
  202. data/test/helpers/test_breadcrumbs.rb +0 -81
  203. data/test/helpers/test_capturing.rb +0 -41
  204. data/test/helpers/test_filtering.rb +0 -106
  205. data/test/helpers/test_html_escape.rb +0 -32
  206. data/test/helpers/test_link_to.rb +0 -249
  207. data/test/helpers/test_rendering.rb +0 -89
  208. data/test/helpers/test_tagging.rb +0 -87
  209. data/test/helpers/test_text.rb +0 -24
  210. data/test/helpers/test_xml_sitemap.rb +0 -103
  211. data/test/tasks/test_clean.rb +0 -67
@@ -1,165 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Nanoc3
4
-
5
- # The class responsible for keeping track of all loaded plugins, such as
6
- # filters ({Nanoc3::Filter}), data sources ({Nanoc3::DataSource}) and VCSes
7
- # ({Nanoc3::Extra::VCS}).
8
- class PluginRegistry
9
-
10
- # A module that contains class methods for plugins. It provides functions
11
- # for setting identifiers, registering plugins and finding plugins. Plugin
12
- # classes should extend this module.
13
- module PluginMethods
14
-
15
- # Sets the identifiers for this plugin.
16
- #
17
- # @param [Array<Symbol>] identifier A list of identifiers to assign to
18
- # this plugin.
19
- #
20
- # @return [void]
21
- def identifiers(*identifiers)
22
- register(self, *identifiers)
23
- end
24
-
25
- # Sets the identifier for this plugin.
26
- #
27
- # @param [Symbol] identifier An identifier to assign to this plugin.
28
- #
29
- # @return [void]
30
- def identifier(identifier)
31
- register(self, identifier)
32
- end
33
-
34
- # Registers the given class as a plugin with the given identifier.
35
- #
36
- # @param [Class, String] class_or_name The class to register, or a
37
- # string containing the class name to register.
38
- #
39
- # @param [Array<Symbol>] identifiers A list of identifiers to assign to
40
- # this plugin.
41
- #
42
- # @return [void]
43
- def register(class_or_name, *identifiers)
44
- # Find plugin class
45
- klass = self
46
- klass = klass.superclass while klass.superclass.respond_to?(:register)
47
-
48
- # Register
49
- registry = Nanoc3::PluginRegistry.instance
50
- registry.register(klass, class_or_name, *identifiers)
51
- end
52
-
53
- # Returns the plugin with the given name (identifier)
54
- #
55
- # @param [String] name The name of the plugin class to find
56
- #
57
- # @return [Class] The plugin class with the given name
58
- def named(name)
59
- Nanoc3::Plugin.find(self, name)
60
- end
61
-
62
- end
63
-
64
- # Returns the shared {PluginRegistry} instance, creating it if none exists
65
- # yet.
66
- #
67
- # @return [Nanoc3::PluginRegistry] The shared plugin registry
68
- def self.instance
69
- @instance ||= self.new
70
- end
71
-
72
- # Creates a new plugin registry. This should usually not be necessary; it
73
- # is recommended to use the shared instance (obtained from
74
- # {Nanoc3::PluginRegistry.instance}).
75
- def initialize
76
- @map = {}
77
- end
78
-
79
- # Registers the given class as a plugin.
80
- #
81
- # @param [Class] superclass The superclass of the plugin. For example:
82
- # {Nanoc3::Filter}, {Nanoc3::Extra::VCS}.
83
- #
84
- # @param [Class, String] class_or_name The class to register. This can be
85
- # a string, in which case it will be automatically converted to a proper
86
- # class at lookup. For example: `Nanoc3::Filters::ERB`,
87
- # `"Nanoc3::Filters::Haml"`.
88
- #
89
- # @param [Symbol] identifiers One or more symbols identifying the class.
90
- # For example: `:haml`, :`erb`.
91
- #
92
- # @return [void]
93
- def register(superclass, class_or_name, *identifiers)
94
- @map[superclass] ||= {}
95
-
96
- identifiers.each do |identifier|
97
- @map[superclass][identifier.to_sym] = class_or_name
98
- end
99
- end
100
-
101
- # Finds the plugin that is a subclass of the given class and has the given
102
- # name.
103
- #
104
- # @param [Symbol] name The name of the plugin to return
105
- #
106
- # @return [Class, nil] The plugin with the given name
107
- def find(klass, name)
108
- # Initialize
109
- @map[klass] ||= {}
110
-
111
- # Lookup
112
- class_or_name = @map[klass][name.to_sym]
113
-
114
- # Get class
115
- if class_or_name.is_a?(String)
116
- class_or_name.scan(/\w+/).inject(klass) { |memo, part| memo.const_get(part) }
117
- else
118
- class_or_name
119
- end
120
- end
121
-
122
- # Returns a list of all plugins. The returned list of plugins is an array
123
- # with array elements in the following format:
124
- #
125
- # { :class => ..., :superclass => ..., :identifiers => ... }
126
- #
127
- # @return [Array<Hash>] A list of all plugins in the format described
128
- def all
129
- plugins = []
130
- @map.each_pair do |superclass, submap|
131
- submap.each_pair do |identifier, klass|
132
- # Find existing plugin
133
- existing_plugin = plugins.find do |p|
134
- p[:class] == klass && p[:superclass] == superclass
135
- end
136
-
137
- if existing_plugin
138
- # Add identifier to existing plugin
139
- existing_plugin[:identifiers] << identifier
140
- existing_plugin[:identifiers] = existing_plugin[:identifiers].sort_by { |s| s.to_s }
141
- else
142
- # Create new plugin
143
- plugins << {
144
- :class => klass,
145
- :superclass => superclass,
146
- :identifiers => [ identifier ]
147
- }
148
- end
149
- end
150
- end
151
-
152
- plugins
153
- end
154
-
155
- # @deprecated Use {Nanoc3::PluginRegistry#find} instead
156
- def named(name)
157
- find(self, name)
158
- end
159
-
160
- end
161
-
162
- # @deprecated Use {Nanoc3::PluginRegistry.instance} instead
163
- Plugin = PluginRegistry.instance
164
-
165
- end
@@ -1,488 +0,0 @@
1
- # encoding: utf-8
2
-
3
- module Nanoc3
4
-
5
- # A single representation (rep) of an item ({Nanoc3::Item}). An item can
6
- # have multiple representations. A representation has its own output file.
7
- # A single item can therefore have multiple output files, each run through
8
- # a different set of filters with a different layout.
9
- class ItemRep
10
-
11
- # Contains all deprecated methods. Mixed into {Nanoc3::ItemRep}.
12
- module Deprecated
13
-
14
- # @deprecated Modify the {#raw_paths} attribute instead
15
- def raw_path=(raw_path)
16
- raw_paths[:last] = raw_path
17
- end
18
-
19
- # @deprecated Modify the {#paths} attribute instead
20
- def path=(path)
21
- paths[:last] = path
22
- end
23
-
24
- # @deprecated Use {Nanoc3::ItemRep#compiled_content} instead.
25
- def content_at_snapshot(snapshot=:pre)
26
- compiled_content(:snapshot => snapshot)
27
- end
28
-
29
- # @deprecated
30
- def created
31
- raise NotImplementedError, "Nanoc3::ItemRep#created is no longer implemented"
32
- end
33
-
34
- # @deprecated
35
- def created?
36
- raise NotImplementedError, "Nanoc3::ItemRep#created? is no longer implemented"
37
- end
38
-
39
- # @deprecated
40
- def modified
41
- raise NotImplementedError, "Nanoc3::ItemRep#modified is no longer implemented"
42
- end
43
-
44
- # @deprecated
45
- def modified?
46
- raise NotImplementedError, "Nanoc3::ItemRep#modified? is no longer implemented"
47
- end
48
-
49
- # @deprecated
50
- def written
51
- raise NotImplementedError, "Nanoc3::ItemRep#written is no longer implemented"
52
- end
53
-
54
- # @deprecated
55
- def written?
56
- raise NotImplementedError, "Nanoc3::ItemRep#written? is no longer implemented"
57
- end
58
-
59
- end
60
-
61
- # Contains all private methods. Mixed into {Nanoc3::ItemRep}.
62
- module Private
63
-
64
- # @return [Hash] A hash containing the assigns that will be used in the
65
- # next filter or layout operation. The keys (symbols) will be made
66
- # available during the next operation.
67
- attr_accessor :assigns
68
-
69
- # @return [Boolean] true if this representation has already been
70
- # compiled during the current or last compilation session; false
71
- # otherwise
72
- #
73
- # @api private
74
- attr_accessor :compiled
75
- alias_method :compiled?, :compiled
76
-
77
- # @return [Hash<Symbol,String>] A hash containing the raw paths (paths
78
- # including the path to the output directory and the filename) for all
79
- # snapshots. The keys correspond with the snapshot names, and the
80
- # values with the path.
81
- #
82
- # @api private
83
- attr_accessor :raw_paths
84
-
85
- # @return [Hash<Symbol,String>] A hash containing the paths for all
86
- # snapshots. The keys correspond with the snapshot names, and the
87
- # values with the path.
88
- #
89
- # @api private
90
- attr_accessor :paths
91
-
92
- # @return [Hash<Symbol,String>] A hash containing the paths to the
93
- # temporary _files_ that filters write binary content to. This is only
94
- # used when the item representation is binary. The keys correspond
95
- # with the snapshot names, and the values with the filename. When
96
- # writing the item representation, the file corresponding with the
97
- # requested snapshot (usually `:last`) will be copied from
98
- # `filenames[snapshot]` to `raw_paths[snapshot]`.
99
- #
100
- # @api private
101
- attr_reader :temporary_filenames
102
-
103
- # @return [Hash<Symbol,String>] A hash containing the content at all
104
- # snapshots. The keys correspond with the snapshot names, and the
105
- # values with the content.
106
- #
107
- # @api private
108
- attr_accessor :content
109
-
110
- # Writes the item rep's compiled content to the rep's output file.
111
- #
112
- # This method will send two notifications: one before writing the item
113
- # representation, and one after. These notifications can be used for
114
- # generating diffs, for example.
115
- #
116
- # @api private
117
- #
118
- # @param [String, nil] raw_path The raw path to write the compiled rep
119
- # to. If nil, the default raw path will be used.
120
- #
121
- # @return [void]
122
- def write(snapshot=:last)
123
- # Get raw path
124
- raw_path = self.raw_path(:snapshot => snapshot)
125
- return if raw_path.nil?
126
-
127
- # Create parent directory
128
- FileUtils.mkdir_p(File.dirname(raw_path))
129
-
130
- # Check if file will be created
131
- is_created = !File.file?(raw_path)
132
-
133
- # Calculate characteristics of old content
134
- if File.file?(raw_path)
135
- hash_old = Pathname.new(raw_path).checksum
136
- size_old = File.size(raw_path)
137
- end
138
-
139
- # Notify
140
- Nanoc3::NotificationCenter.post(:will_write_rep, self, snapshot)
141
-
142
- if self.binary?
143
- # Calculate characteristics of new content
144
- size_new = File.size(temporary_filenames[:last])
145
- hash_new = Pathname.new(temporary_filenames[:last]).checksum if size_old == size_new
146
-
147
- # Check whether content was modified
148
- is_modified = (size_old != size_new || hash_old != hash_new)
149
-
150
- # Copy
151
- if is_modified
152
- FileUtils.cp(temporary_filenames[:last], raw_path)
153
- end
154
- else
155
- # Check whether content was modified
156
- is_modified = (!File.file?(raw_path) || File.read(raw_path) != @content[:last])
157
-
158
- # Write
159
- if is_modified
160
- File.open(raw_path, 'w') { |io| io.write(@content[:last]) }
161
- end
162
- end
163
-
164
- # Notify
165
- Nanoc3::NotificationCenter.post(:rep_written, self, raw_path, is_created, is_modified)
166
- end
167
-
168
- # Resets the compilation progress for this item representation. This is
169
- # necessary when an unmet dependency is detected during compilation.
170
- #
171
- # @api private
172
- #
173
- # @return [void]
174
- def forget_progress
175
- initialize_content
176
- end
177
-
178
- # Returns the type of this object. Will always return `:item_rep`,
179
- # because this is an item rep. For layouts, this method returns
180
- # `:layout`.
181
- #
182
- # @api private
183
- #
184
- # @return [Symbol] :item_rep
185
- def type
186
- :item_rep
187
- end
188
-
189
- end
190
-
191
- include Deprecated
192
- include Private
193
-
194
- # @return [Nanoc3::Item] The item to which this rep belongs
195
- attr_reader :item
196
-
197
- # @return [Symbol] The representation's unique name
198
- attr_reader :name
199
-
200
- # @return [Boolean] true if this rep is currently binary; false otherwise
201
- attr_reader :binary
202
- alias_method :binary?, :binary
203
-
204
- # Creates a new item representation for the given item.
205
- #
206
- # @param [Nanoc3::Item] item The item to which the new representation will
207
- # belong.
208
- #
209
- # @param [Symbol] name The unique name for the new item representation.
210
- def initialize(item, name)
211
- # Set primary attributes
212
- @item = item
213
- @name = name
214
-
215
- # Set binary
216
- @binary = @item.binary?
217
-
218
- # Set default attributes
219
- @raw_paths = {}
220
- @paths = {}
221
- @assigns = {}
222
- initialize_content
223
-
224
- # Reset flags
225
- @compiled = false
226
- end
227
-
228
- # Returns the compiled content from a given snapshot.
229
- #
230
- # @option params [String] :snapshot The name of the snapshot from which to
231
- # fetch the compiled content. By default, the returned compiled content
232
- # will be the content compiled right before the first layout call (if
233
- # any).
234
- #
235
- # @return [String] The compiled content at the given snapshot (or the
236
- # default snapshot if no snapshot is specified)
237
- def compiled_content(params={})
238
- # Notify
239
- Nanoc3::NotificationCenter.post(:visit_started, self.item)
240
- Nanoc3::NotificationCenter.post(:visit_ended, self.item)
241
-
242
- # Require compilation
243
- raise Nanoc3::Errors::UnmetDependency.new(self) if !compiled? && !params[:force]
244
-
245
- # Get name of last pre-layout snapshot
246
- snapshot_name = params[:snapshot]
247
- if @content[:pre]
248
- snapshot_name ||= :pre
249
- else
250
- snapshot_name ||= :last
251
- end
252
-
253
- # Check presence of snapshot
254
- if @content[snapshot_name].nil?
255
- warn(('-' * 78 + "\nWARNING: The “#{self.item.identifier}” item (rep “#{self.name}”) does not have the requested snapshot named #{snapshot_name.inspect}.\n\n* Make sure that you are requesting the correct snapshot.\n* It is not possible to request the compiled content of a binary item representation; if this item is marked as binary even though you believe it should be textual, you may need to add the extension of this item to the site configuration’s `text_extensions` array.\n" + '-' * 78).make_compatible_with_env)
256
- end
257
-
258
- # Get content
259
- @content[snapshot_name]
260
- end
261
-
262
- # Checks whether content exists at a given snapshot.
263
- #
264
- # @return [Boolean] True if content exists for the snapshot with the
265
- # given name, false otherwise
266
- #
267
- # @since 3.2.0
268
- def has_snapshot?(snapshot_name)
269
- !@content[snapshot_name].nil?
270
- end
271
-
272
- # Returns the item rep’s raw path. It includes the path to the output
273
- # directory and the full filename.
274
- #
275
- # @option params [Symbol] :snapshot (:last) The snapshot for which the
276
- # path should be returned
277
- #
278
- # @return [String] The item rep’s path
279
- def raw_path(params={})
280
- snapshot_name = params[:snapshot] || :last
281
- @raw_paths[snapshot_name]
282
- end
283
-
284
- # Returns the item rep’s path, as used when being linked to. It starts
285
- # with a slash and it is relative to the output directory. It does not
286
- # include the path to the output directory. It will not include the
287
- # filename if the filename is an index filename.
288
- #
289
- # @option params [Symbol] :snapshot (:last) The snapshot for which the
290
- # path should be returned
291
- #
292
- # @return [String] The item rep’s path
293
- def path(params={})
294
- snapshot_name = params[:snapshot] || :last
295
- @paths[snapshot_name]
296
- end
297
-
298
- # Runs the item content through the given filter with the given arguments.
299
- # This method will replace the content of the `:last` snapshot with the
300
- # filtered content of the last snapshot.
301
- #
302
- # This method is supposed to be called only in a compilation rule block
303
- # (see {Nanoc3::CompilerDSL#compile}).
304
- #
305
- # @see Nanoc3::ItemRepProxy#filter
306
- #
307
- # @param [Symbol] filter_name The name of the filter to run the item
308
- # representations' content through
309
- #
310
- # @param [Hash] filter_args The filter arguments that should be passed to
311
- # the filter's #run method
312
- #
313
- # @return [void]
314
- def filter(filter_name, filter_args={})
315
- # Get filter class
316
- klass = filter_named(filter_name)
317
- raise Nanoc3::Errors::UnknownFilter.new(filter_name) if klass.nil?
318
-
319
- # Check whether filter can be applied
320
- if klass.from_binary? && !self.binary?
321
- raise Nanoc3::Errors::CannotUseBinaryFilter.new(self, klass)
322
- elsif !klass.from_binary? && self.binary?
323
- raise Nanoc3::Errors::CannotUseTextualFilter.new(self, klass)
324
- end
325
-
326
- begin
327
- # Notify start
328
- Nanoc3::NotificationCenter.post(:filtering_started, self, filter_name)
329
-
330
- # Create filter
331
- filter = klass.new(assigns)
332
-
333
- # Run filter
334
- source = self.binary? ? temporary_filenames[:last] : @content[:last]
335
- result = filter.run(source, filter_args)
336
- if klass.to_binary?
337
- temporary_filenames[:last] = filter.output_filename
338
- else
339
- @content[:last] = result
340
- @content[:last].freeze
341
- end
342
- @binary = klass.to_binary?
343
-
344
- # Check whether file was written
345
- if self.binary? && !File.file?(filter.output_filename)
346
- raise RuntimeError,
347
- "The #{filter_name.inspect} filter did not write anything to the required output file, #{filter.output_filename}."
348
- end
349
-
350
- # Create snapshot
351
- snapshot(@content[:post] ? :post : :pre, :final => false) unless self.binary?
352
- ensure
353
- # Notify end
354
- Nanoc3::NotificationCenter.post(:filtering_ended, self, filter_name)
355
- end
356
- end
357
-
358
- # Lays out the item using the given layout. This method will replace the
359
- # content of the `:last` snapshot with the laid out content of the last
360
- # snapshot.
361
- #
362
- # This method is supposed to be called only in a compilation rule block
363
- # (see {Nanoc3::CompilerDSL#compile}).
364
- #
365
- # @see Nanoc3::ItemRepProxy#layout
366
- #
367
- # @param [Nanoc3::Layout] layout The layout to use
368
- #
369
- # @param [Symbol] filter_name The name of the filter to layout the item
370
- # representations' content with
371
- #
372
- # @param [Hash] filter_args The filter arguments that should be passed to
373
- # the filter's #run method
374
- #
375
- # @return [void]
376
- def layout(layout, filter_name, filter_args)
377
- # Check whether item can be laid out
378
- raise Nanoc3::Errors::CannotLayoutBinaryItem.new(self) if self.binary?
379
-
380
- # Create "pre" snapshot
381
- if @content[:post].nil?
382
- snapshot(:pre, :final => true)
383
- end
384
-
385
- # Create filter
386
- klass = filter_named(filter_name)
387
- raise Nanoc3::Errors::UnknownFilter.new(filter_name) if klass.nil?
388
- filter = klass.new(assigns.merge({ :layout => layout }))
389
-
390
- # Visit
391
- Nanoc3::NotificationCenter.post(:visit_started, layout)
392
- Nanoc3::NotificationCenter.post(:visit_ended, layout)
393
-
394
- begin
395
- # Notify start
396
- Nanoc3::NotificationCenter.post(:processing_started, layout)
397
- Nanoc3::NotificationCenter.post(:filtering_started, self, filter_name)
398
-
399
- # Layout
400
- @content[:last] = filter.run(layout.raw_content, filter_args)
401
-
402
- # Create "post" snapshot
403
- snapshot(:post, :final => false)
404
- ensure
405
- # Notify end
406
- Nanoc3::NotificationCenter.post(:filtering_ended, self, filter_name)
407
- Nanoc3::NotificationCenter.post(:processing_ended, layout)
408
- end
409
- end
410
-
411
- # Creates a snapshot of the current compiled item content.
412
- #
413
- # @param [Symbol] snapshot_name The name of the snapshot to create
414
- #
415
- # @option params [Boolean] :final (true) True if this is the final time
416
- # the snapshot will be updated; false if it is a non-final moving
417
- # snapshot (such as `:pre`, `:post` or `:last`)
418
- #
419
- # @return [void]
420
- def snapshot(snapshot_name, params={})
421
- # Parse params
422
- params[:final] = true if !params.has_key?(:final)
423
-
424
- # Create snapshot
425
- @content[snapshot_name] = @content[:last] unless self.binary?
426
-
427
- # Write
428
- write(snapshot_name) if params[:final]
429
- end
430
-
431
- # Returns a recording proxy that is used for determining whether the
432
- # compilation has changed, and thus whether the item rep needs to be
433
- # recompiled.
434
- #
435
- # @api private
436
- #
437
- # @return [Nanoc3::ItemRepRecorderProxy] The recording proxy
438
- def to_recording_proxy
439
- Nanoc3::ItemRepRecorderProxy.new(self)
440
- end
441
-
442
- # Returns false because this item is not yet a proxy, and therefore does
443
- # need to be wrapped in a proxy during compilation.
444
- #
445
- # @api private
446
- #
447
- # @return [false]
448
- #
449
- # @see Nanoc3::ItemRepRecorderProxy#is_proxy?
450
- # @see Nanoc3::ItemRepProxy#is_proxy?
451
- def is_proxy?
452
- false
453
- end
454
-
455
- # Returns an object that can be used for uniquely identifying objects.
456
- #
457
- # @api private
458
- #
459
- # @return [Object] An unique reference to this object
460
- def reference
461
- [ type, self.item.identifier, self.name ]
462
- end
463
-
464
- def inspect
465
- "<#{self.class}:0x#{self.object_id.to_s(16)} name=#{self.name} binary=#{self.binary?} raw_path=#{self.raw_path} item.identifier=#{self.item.identifier}>"
466
- end
467
-
468
- private
469
-
470
- def initialize_content
471
- # Initialize content and filenames
472
- if self.binary?
473
- @temporary_filenames = { :last => @item.raw_filename }
474
- @content = {}
475
- else
476
- @content = { :last => @item.raw_content }
477
- @content[:last].freeze
478
- @temporary_filenames = {}
479
- end
480
- end
481
-
482
- def filter_named(name)
483
- Nanoc3::Filter.named(name)
484
- end
485
-
486
- end
487
-
488
- end