nanoc3 3.2.0a3 → 3.2.0a4

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 (147) hide show
  1. data/.gemtest +0 -0
  2. data/LICENSE +1 -1
  3. data/NEWS.md +23 -4
  4. data/README.md +7 -0
  5. data/lib/nanoc3/base/compilation/checksum_store.rb +17 -90
  6. data/lib/nanoc3/base/compilation/compiled_content_cache.rb +5 -0
  7. data/lib/nanoc3/base/compilation/compiler.rb +112 -175
  8. data/lib/nanoc3/base/compilation/compiler_dsl.rb +54 -11
  9. data/lib/nanoc3/base/compilation/dependency_tracker.rb +32 -65
  10. data/lib/nanoc3/base/compilation/filter.rb +4 -3
  11. data/lib/nanoc3/base/compilation/item_rep_proxy.rb +19 -4
  12. data/lib/nanoc3/base/compilation/item_rep_recorder_proxy.rb +90 -0
  13. data/lib/nanoc3/base/compilation/outdatedness_checker.rb +152 -15
  14. data/lib/nanoc3/base/compilation/outdatedness_reasons.rb +12 -9
  15. data/lib/nanoc3/base/compilation/rule.rb +3 -1
  16. data/lib/nanoc3/base/compilation/rule_memory_calculator.rb +42 -0
  17. data/lib/nanoc3/base/compilation/rule_memory_store.rb +53 -0
  18. data/lib/nanoc3/base/compilation/rules_collection.rb +205 -0
  19. data/lib/nanoc3/base/core_ext/array.rb +20 -0
  20. data/lib/nanoc3/base/core_ext/hash.rb +30 -0
  21. data/lib/nanoc3/base/core_ext/pathname.rb +26 -0
  22. data/lib/nanoc3/base/core_ext/string.rb +12 -0
  23. data/lib/nanoc3/base/core_ext.rb +1 -0
  24. data/lib/nanoc3/base/directed_graph.rb +11 -3
  25. data/lib/nanoc3/base/errors.rb +0 -4
  26. data/lib/nanoc3/base/memoization.rb +72 -0
  27. data/lib/nanoc3/base/result_data/item_rep.rb +64 -25
  28. data/lib/nanoc3/base/source_data/code_snippet.rb +9 -0
  29. data/lib/nanoc3/base/source_data/configuration.rb +20 -0
  30. data/lib/nanoc3/base/source_data/item.rb +29 -4
  31. data/lib/nanoc3/base/source_data/layout.rb +20 -1
  32. data/lib/nanoc3/base/source_data/site.rb +49 -26
  33. data/lib/nanoc3/base/store.rb +10 -1
  34. data/lib/nanoc3/base.rb +6 -1
  35. data/lib/nanoc3/cli/base.rb +20 -7
  36. data/lib/nanoc3/cli/commands/compile.rb +0 -2
  37. data/lib/nanoc3/cli/commands/create_site.rb +16 -7
  38. data/lib/nanoc3/cli/commands/debug.rb +3 -3
  39. data/lib/nanoc3/cli/commands/view.rb +1 -0
  40. data/lib/nanoc3/cli/commands/watch.rb +2 -1
  41. data/lib/nanoc3/data_sources/deprecated/delicious.rb +0 -2
  42. data/lib/nanoc3/data_sources/deprecated/last_fm.rb +0 -2
  43. data/lib/nanoc3/data_sources/deprecated/twitter.rb +0 -2
  44. data/lib/nanoc3/data_sources/filesystem.rb +17 -3
  45. data/lib/nanoc3/data_sources/filesystem_unified.rb +17 -17
  46. data/lib/nanoc3/extra/auto_compiler.rb +5 -1
  47. data/lib/nanoc3/extra/core_ext/time.rb +1 -1
  48. data/lib/nanoc3/extra/file_proxy.rb +11 -1
  49. data/lib/nanoc3/extra/validators/links.rb +1 -1
  50. data/lib/nanoc3/filters/asciidoc.rb +3 -3
  51. data/lib/nanoc3/filters/colorize_syntax.rb +106 -27
  52. data/lib/nanoc3/filters/erb.rb +16 -6
  53. data/lib/nanoc3/filters/erubis.rb +5 -1
  54. data/lib/nanoc3/filters/haml.rb +2 -1
  55. data/lib/nanoc3/filters/less.rb +3 -6
  56. data/lib/nanoc3/filters/mustache.rb +3 -0
  57. data/lib/nanoc3/filters/redcarpet.rb +27 -0
  58. data/lib/nanoc3/filters/sass.rb +1 -5
  59. data/lib/nanoc3/filters/slim.rb +25 -0
  60. data/lib/nanoc3/filters/typogruby.rb +23 -0
  61. data/lib/nanoc3/filters.rb +6 -0
  62. data/lib/nanoc3/helpers/blogging.rb +22 -26
  63. data/lib/nanoc3/helpers/rendering.rb +1 -1
  64. data/lib/nanoc3/helpers/xml_sitemap.rb +11 -2
  65. data/lib/nanoc3.rb +24 -3
  66. data/nanoc3.gemspec +4 -3
  67. data/tasks/clean.rake +11 -0
  68. data/tasks/doc.rake +14 -0
  69. data/tasks/test.rake +38 -0
  70. data/test/base/core_ext/array_spec.rb +55 -0
  71. data/test/base/core_ext/hash_spec.rb +82 -0
  72. data/test/base/core_ext/pathname_spec.rb +29 -0
  73. data/test/base/core_ext/string_spec.rb +39 -0
  74. data/test/base/test_checksum_store.rb +37 -0
  75. data/test/base/test_code_snippet.rb +33 -0
  76. data/test/base/test_compiler.rb +303 -0
  77. data/test/base/test_compiler_dsl.rb +156 -0
  78. data/test/base/test_context.rb +33 -0
  79. data/test/base/test_data_source.rb +48 -0
  80. data/test/base/test_dependency_tracker.rb +264 -0
  81. data/test/base/test_directed_graph.rb +285 -0
  82. data/test/base/test_filter.rb +85 -0
  83. data/test/base/test_item.rb +164 -0
  84. data/test/base/test_item_rep.rb +555 -0
  85. data/test/base/test_layout.rb +44 -0
  86. data/test/base/test_memoization.rb +53 -0
  87. data/test/base/test_notification_center.rb +36 -0
  88. data/test/base/test_outdatedness_checker.rb +365 -0
  89. data/test/base/test_plugin.rb +32 -0
  90. data/test/base/test_rule.rb +21 -0
  91. data/test/base/test_rule_context.rb +67 -0
  92. data/test/base/test_site.rb +144 -0
  93. data/test/cli/commands/test_compile.rb +12 -0
  94. data/test/cli/commands/test_create_item.rb +12 -0
  95. data/test/cli/commands/test_create_layout.rb +28 -0
  96. data/test/cli/commands/test_create_site.rb +24 -0
  97. data/test/cli/commands/test_help.rb +12 -0
  98. data/test/cli/commands/test_info.rb +12 -0
  99. data/test/cli/commands/test_update.rb +12 -0
  100. data/test/cli/test_logger.rb +12 -0
  101. data/test/data_sources/test_filesystem.rb +420 -0
  102. data/test/data_sources/test_filesystem_unified.rb +562 -0
  103. data/test/data_sources/test_filesystem_verbose.rb +359 -0
  104. data/test/extra/core_ext/test_enumerable.rb +32 -0
  105. data/test/extra/core_ext/test_time.rb +17 -0
  106. data/test/extra/deployers/test_rsync.rb +234 -0
  107. data/test/extra/test_auto_compiler.rb +417 -0
  108. data/test/extra/test_file_proxy.rb +21 -0
  109. data/test/extra/test_vcs.rb +24 -0
  110. data/test/extra/validators/test_links.rb +53 -0
  111. data/test/extra/validators/test_w3c.rb +49 -0
  112. data/test/filters/test_asciidoc.rb +22 -0
  113. data/test/filters/test_bluecloth.rb +20 -0
  114. data/test/filters/test_coderay.rb +46 -0
  115. data/test/filters/test_colorize_syntax.rb +149 -0
  116. data/test/filters/test_erb.rb +101 -0
  117. data/test/filters/test_erubis.rb +72 -0
  118. data/test/filters/test_haml.rb +98 -0
  119. data/test/filters/test_kramdown.rb +20 -0
  120. data/test/filters/test_less.rb +59 -0
  121. data/test/filters/test_markaby.rb +26 -0
  122. data/test/filters/test_maruku.rb +20 -0
  123. data/test/filters/test_mustache.rb +27 -0
  124. data/test/filters/test_rainpress.rb +31 -0
  125. data/test/filters/test_rdiscount.rb +33 -0
  126. data/test/filters/test_rdoc.rb +18 -0
  127. data/test/filters/test_redcarpet.rb +63 -0
  128. data/test/filters/test_redcloth.rb +35 -0
  129. data/test/filters/test_relativize_paths.rb +231 -0
  130. data/test/filters/test_rubypants.rb +20 -0
  131. data/test/filters/test_sass.rb +103 -0
  132. data/test/filters/test_slim.rb +37 -0
  133. data/test/filters/test_typogruby.rb +23 -0
  134. data/test/helper.rb +161 -0
  135. data/test/helpers/test_blogging.rb +756 -0
  136. data/test/helpers/test_breadcrumbs.rb +83 -0
  137. data/test/helpers/test_capturing.rb +43 -0
  138. data/test/helpers/test_filtering.rb +108 -0
  139. data/test/helpers/test_html_escape.rb +34 -0
  140. data/test/helpers/test_link_to.rb +251 -0
  141. data/test/helpers/test_rendering.rb +90 -0
  142. data/test/helpers/test_tagging.rb +89 -0
  143. data/test/helpers/test_text.rb +26 -0
  144. data/test/helpers/test_xml_sitemap.rb +105 -0
  145. data/test/tasks/test_clean.rb +69 -0
  146. metadata +96 -27
  147. data/lib/nanoc3/base/compilation/checksummer.rb +0 -68
data/.gemtest ADDED
File without changes
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007-2010 Denis Defreyne and contributors
1
+ Copyright (c) 2007-2011 Denis Defreyne and contributors
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/NEWS.md CHANGED
@@ -2,22 +2,41 @@
2
2
 
3
3
  ## 3.2 (???)
4
4
 
5
+ Base:
6
+
5
7
  * Sped up nanoc quite a bit
6
- * Added AsciiDoc filter
7
8
  * Added progress indicator for long-running filters
8
9
  * Made all source data, such as item attributes, frozen during compilation
9
- * Exposed RedCloth parameters in the filter [Vincent Driessen]
10
10
  * Added --color option to force color on
11
11
  * Cleaned up internals, deprecating several parts and/or marking them as
12
12
  private in the progress
13
13
 
14
- ## 3.1.5 (???)
14
+ Extensions:
15
+
16
+ * Added AsciiDoc filter
17
+ * Added Redcarpet filter [Peter Aronoff]
18
+ * Added Typogruby filter
19
+ * Added Slim filter [Zaiste de Grengolada]
20
+ * Added :items parameter for the XML site map [Justin Hileman]
21
+ * Added support for params to ERB
22
+ * Allowed for passing arbitrary options to pygmentize [Matthias Vallentin]
23
+ * Exposed RedCloth parameters in the filter [Vincent Driessen]
24
+
25
+ ## 3.1.7 (2011-05-03)
26
+
27
+ * Restored compatibility with Sass 3.1
28
+
29
+ ## 3.1.6 (2010-11-21)
30
+
31
+ * Fixed issues with incompatible encodings
32
+
33
+ ## 3.1.5 (2010-08-24)
15
34
 
16
35
  * Improved `#render` documentation
17
36
  * Improved metadata section check so that e.g. raw diffs are handled properly
18
37
  * Deprecated using `Nanoc3::Site#initialize` with a non-`"."` argument
19
38
  * Added Ruby engine to version string
20
- * Allowed the `created_at` and `updated_at` attributes used in the`Blogging`
39
+ * Allowed the `created_at` and `updated_at` attributes used in the `Blogging`
21
40
  helper to be `Date` instances
22
41
 
23
42
  ## 3.1.4 (2010-07-25)
data/README.md CHANGED
@@ -74,11 +74,17 @@ may be interested in the development dependencies:
74
74
  * Dmitry Bilunov
75
75
  * Devon Luke Buchanan
76
76
  * Brian Candler
77
+ * Michal Cichra
78
+ * Zaiste de Grengolada
77
79
  * Vincent Driessen
78
80
  * Chris Eppstein
81
+ * Jeff Forcier
79
82
  * Felix Hanley
83
+ * Justin Hileman
80
84
  * Starr Horne
81
85
  * Tuomas Kareinen
86
+ * Nikhil Marathe
87
+ * Daniel Mendler
82
88
  * Ale Muñoz
83
89
  * Nicky Peeters
84
90
  * Christian Plessl
@@ -87,6 +93,7 @@ may be interested in the development dependencies:
87
93
  * “Soryu”
88
94
  * Eric Sunshine
89
95
  * Dennis Sutch
96
+ * Matthias Vallentin
90
97
 
91
98
  ## Contact
92
99
 
@@ -5,12 +5,6 @@ module Nanoc3
5
5
  # Stores checksums for objects in order to be able to detect whether a file
6
6
  # has changed since the last site compilation.
7
7
  #
8
- # Old checksums are checksums that were in effect during the previous site
9
- # compilation. New checksums are checksums that are in effect right now. If
10
- # an old checksum differs from a new checksum, the corresponding object was
11
- # modified and will need to be recompiled (along with the objects that
12
- # depend on that object).
13
- #
14
8
  # @api private
15
9
  class ChecksumStore < ::Nanoc3::Store
16
10
 
@@ -21,108 +15,41 @@ module Nanoc3
21
15
 
22
16
  @site = params[:site] if params.has_key?(:site)
23
17
 
24
- @new_checksums = {}
25
- @old_checksums = {}
26
- end
27
-
28
- # Returns the old checksum for the given object. The object must respond
29
- # to `#reference` (for example, {Nanoc3::Item#reference},
30
- # {Nanoc3::Layout#reference}, {Nanoc3::CodeSnippet#reference}, …).
31
- #
32
- # @param [#reference] obj The object for which to fetch the old checksum
33
- #
34
- # @return [String] The old checksum for the given object
35
- def old_checksum_for(obj)
36
- @old_checksums[obj.reference]
37
- end
38
-
39
- # Returns the new checksum for the given object. The object must respond
40
- # to `#reference` (for example, {Nanoc3::Item#reference},
41
- # {Nanoc3::Layout#reference}, {Nanoc3::CodeSnippet#reference}, …).
42
- #
43
- # @param [#reference] obj The object for which to calculate the new
44
- # checksum
45
- #
46
- # @return [String] The new checksum for the given object
47
- def new_checksum_for(obj)
48
- @new_checksums[obj.reference] ||= begin
49
- checksum_parts = []
50
-
51
- # Calculate content checksum
52
- checksum_parts << if obj.respond_to?(:binary?) && obj.binary?
53
- Nanoc3::Checksummer.checksum_for_file(obj.raw_filename)
54
- elsif obj.respond_to?(:raw_content)
55
- Nanoc3::Checksummer.checksum_for_string(obj.raw_content)
56
- elsif obj.respond_to?(:data)
57
- Nanoc3::Checksummer.checksum_for_string(obj.data)
58
- else
59
- raise RuntimeError, "Couldn’t figure out how to calculate the " \
60
- "content checksum for #{obj.inspect} (tried #raw_filename, " \
61
- "#raw_content and #data but none of these worked)"
62
- end
63
-
64
- # Calculate attributes checksum
65
- if obj.respond_to?(:attributes)
66
- attributes = obj.attributes.dup
67
- attributes.delete(:file)
68
- checksum_parts << Nanoc3::Checksummer.checksum_for_hash(attributes)
69
- end
70
-
71
- # Done
72
- checksum_parts.join('-')
73
- end
18
+ @checksums = {}
74
19
  end
75
20
 
76
- # Calculates the checksums for all objects in the site. This method should
77
- # be used to make the checksum store remember the new checksums for all
78
- # given objects; it is probably necessary to call this method before
79
- # calling {#store}, to make sure that all new checksums are calculated. It
80
- # is not necessary to call this method in order to use
81
- # {#new_checksum_for}.
21
+ # Returns the old checksum for the given object. This makes sense for
22
+ # items, layouts and code snippets.
82
23
  #
83
- # @return [void]
84
- def calculate_all_checksums
85
- @site.compiler.objects.each { |obj| new_checksum_for(obj) }
86
- end
87
-
88
- # @param [#reference] obj
24
+ # @param [#reference] obj The object for which to fetch the checksum
89
25
  #
90
- # @return [Boolean] false if either the new or the old checksum for the
91
- # given object is not available, true if both checksums are available
92
- def checksums_available?(obj)
93
- !!old_checksum_for(obj) && !!new_checksum_for(obj)
26
+ # @return [String] The checksum for the given object
27
+ def [](obj)
28
+ @checksums[obj.reference]
94
29
  end
95
30
 
96
- # @param [#reference] obj
31
+ # Sets the checksum for the given object.
97
32
  #
98
- # @return [Boolean] false if the old and new checksums for the given
99
- # object differ, true if they are identical
100
- def checksums_identical?(obj)
101
- old_checksum_for(obj) == new_checksum_for(obj)
102
- end
103
-
104
- # @param [#reference] obj
33
+ # @param [#reference] obj The object for which to set the checksum
105
34
  #
106
- # @return [Boolean] true if the old and new checksums for the given object
107
- # are available and identical, false otherwise
108
- def object_modified?(obj)
109
- !checksums_available?(obj) || !checksums_identical?(obj)
35
+ # @param [String] checksum The checksum
36
+ def []=(obj, checksum)
37
+ @checksums[obj.reference] = checksum
110
38
  end
111
39
 
112
- # @see Nanoc3::Store#store
113
- def store
114
- calculate_all_checksums
115
- super
40
+ # @see Nanoc3::Store#unload
41
+ def unload
42
+ @checksums = {}
116
43
  end
117
44
 
118
45
  protected
119
46
 
120
47
  def data
121
- @new_checksums
48
+ @checksums
122
49
  end
123
50
 
124
51
  def data=(new_data)
125
- @old_checksums = new_data
52
+ @checksums = new_data
126
53
  end
127
54
 
128
55
  end
@@ -42,6 +42,11 @@ module Nanoc3
42
42
  @cache[rep.item.identifier][rep.name] = content
43
43
  end
44
44
 
45
+ # @see Nanoc3::Store#unload
46
+ def unload
47
+ @cache = {}
48
+ end
49
+
45
50
  protected
46
51
 
47
52
  def data
@@ -40,6 +40,8 @@ module Nanoc3
40
40
  # the specified object.
41
41
  class Compiler
42
42
 
43
+ extend Nanoc3::Memoization
44
+
43
45
  # @group Accessors
44
46
 
45
47
  # @return [Nanoc3::Site] The site this compiler belongs to
@@ -52,24 +54,6 @@ module Nanoc3
52
54
  # @return [Array] The compilation stack
53
55
  attr_reader :stack
54
56
 
55
- # @return [Array<Nanoc3::Rule>] The list of item compilation rules that
56
- # will be used to compile items.
57
- attr_reader :item_compilation_rules
58
-
59
- # @return [Array<Nanoc3::Rule>] The list of routing rules that will be
60
- # used to give all items a path.
61
- attr_reader :item_routing_rules
62
-
63
- # The hash containing layout-to-filter mapping rules. This hash is
64
- # ordered: iterating over the hash will happen in insertion order.
65
- #
66
- # @return [Hash] The layout-to-filter mapping rules
67
- attr_reader :layout_filter_mapping
68
-
69
- # @return [Proc] The code block that will be executed after all data is
70
- # loaded but before the site is compiled
71
- attr_accessor :preprocessor
72
-
73
57
  # @group Public instance methods
74
58
 
75
59
  # Creates a new compiler fo the given site
@@ -79,10 +63,6 @@ module Nanoc3
79
63
  @site = site
80
64
 
81
65
  @stack = []
82
-
83
- @item_compilation_rules = []
84
- @item_routing_rules = []
85
- @layout_filter_mapping = OrderedHash.new
86
66
  end
87
67
 
88
68
  # Compiles the site and writes out the compiled item representations.
@@ -112,20 +92,27 @@ module Nanoc3
112
92
 
113
93
  # @group Private instance methods
114
94
 
95
+ # @return [Nanoc3::RulesCollection] The collection of rules to be used
96
+ # for compiling this site
97
+ def rules_collection
98
+ Nanoc3::RulesCollection.new(self)
99
+ end
100
+ memoize :rules_collection
101
+
115
102
  # Load the helper data that is used for compiling the site.
116
103
  #
117
104
  # @api private
118
105
  #
119
106
  # @return [void]
120
107
  def load
121
- return if @loaded
122
- @loaded = true
108
+ return if @loaded || @loading
109
+ @loading = true
123
110
 
124
111
  # Load site if necessary
125
- @site.load
112
+ site.load
126
113
 
127
114
  # Preprocess
128
- load_rules
115
+ rules_collection.load
129
116
  preprocess
130
117
  site.setup_child_parent_links
131
118
  build_reps
@@ -135,140 +122,78 @@ module Nanoc3
135
122
  stores.each { |s| s.load }
136
123
 
137
124
  # Determine which reps need to be recompiled
138
- dependency_tracker.propagate_outdatedness
139
125
  forget_dependencies_if_outdated(items)
126
+
127
+ @loaded = true
128
+ rescue => e
129
+ unload
130
+ raise e
131
+ ensure
132
+ @loading = false
140
133
  end
141
134
 
142
- # Store the modified helper data used for compiling the site.
135
+ # Undoes the effects of {#load}. Used when {#load} raises an exception.
143
136
  #
144
137
  # @api private
145
138
  #
146
139
  # @return [void]
147
- def store
148
- stores.each { |s| s.store }
149
- end
140
+ def unload
141
+ return if @unloading
142
+ @unloading = true
150
143
 
151
- # Returns the dependency tracker for this site, creating it first if it
152
- # does not yet exist.
153
- #
154
- # @api private
155
- #
156
- # @return [Nanoc3::DependencyTracker] The dependency tracker for this site
157
- def dependency_tracker
158
- @dependency_tracker ||= begin
159
- dt = Nanoc3::DependencyTracker.new(@site.items + @site.layouts)
160
- dt.compiler = self
161
- dt
162
- end
163
- end
144
+ stores.each { |s| s.unload }
164
145
 
165
- # Finds the first matching compilation rule for the given item
166
- # representation.
167
- #
168
- # @api private
169
- #
170
- # @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
171
- #
172
- # @return [Nanoc3::Rule, nil] The compilation rule for the given item rep,
173
- # or nil if no rules have been found
174
- def compilation_rule_for(rep)
175
- @item_compilation_rules.find do |rule|
176
- rule.applicable_to?(rep.item) && rule.rep_name == rep.name
177
- end
178
- end
146
+ @stack = []
179
147
 
180
- # Finds the first matching routing rule for the given item representation.
181
- #
182
- # @api private
183
- #
184
- # @param [Nanoc3::ItemRep] rep The item rep for which to fetch the rule
185
- #
186
- # @return [Nanoc3::Rule, nil] The routing rule for the given item rep, or
187
- # nil if no rules have been found
188
- def routing_rule_for(rep)
189
- @item_routing_rules.find do |rule|
190
- rule.applicable_to?(rep.item) && rule.rep_name == rep.name
191
- end
192
- end
148
+ items.each { |item| item.reps.clear }
149
+ site.teardown_child_parent_links
150
+ rules_collection.unload
193
151
 
194
- # Returns the list of routing rules that can be applied to the given item
195
- # representation. For each snapshot, the first matching rule will be
196
- # returned. The result is a hash containing the corresponding rule for
197
- # each snapshot.
198
- #
199
- # @api private
200
- #
201
- # @return [Hash<Symbol, Nanoc3::Rule>] The routing rules for the given rep
202
- def routing_rules_for(rep)
203
- rules = {}
204
- @item_routing_rules.each do |rule|
205
- next if !rule.applicable_to?(rep.item)
206
- next if rule.rep_name != rep.name
207
- next if rules.has_key?(rule.snapshot_name)
208
-
209
- rules[rule.snapshot_name] = rule
210
- end
211
- rules
152
+ site.unload
153
+
154
+ @loaded = false
155
+ @unloading = false
212
156
  end
213
157
 
214
- # Finds the filter name and arguments to use for the given layout.
158
+ # Store the modified helper data used for compiling the site.
215
159
  #
216
160
  # @api private
217
161
  #
218
- # @param [Nanoc3::Layout] layout The layout for which to fetch the filter.
219
- #
220
- # @return [Array, nil] A tuple containing the filter name and the filter
221
- # arguments for the given layout.
222
- def filter_for_layout(layout)
223
- @layout_filter_mapping.each_pair do |layout_identifier, filter_name_and_args|
224
- return filter_name_and_args if layout.identifier =~ layout_identifier
162
+ # @return [void]
163
+ def store
164
+ # Calculate rule memory
165
+ (reps + layouts).each do |obj|
166
+ rule_memory_store[obj] = rule_memory_calculator[obj]
225
167
  end
226
- nil
227
- end
228
168
 
229
- # @api private
230
- #
231
- # @return [Boolean] true if the object is outdated, false otherwise
232
- def outdated?(obj)
233
- outdatedness_checker.outdated?(obj)
234
- end
169
+ # Calculate checksums
170
+ self.objects.each do |obj|
171
+ checksum_store[obj] = obj.checksum
172
+ end
235
173
 
236
- # Returns the reason why the given object is outdated.
237
- #
238
- # @see Nanoc3::OutdatednessChecker#outdatedness_reason_for
239
- #
240
- # @api private
241
- def outdatedness_reason_for(obj)
242
- outdatedness_checker.outdatedness_reason_for(obj)
174
+ # Store
175
+ stores.each { |s| s.store }
243
176
  end
244
177
 
245
- # Returns the Nanoc3::CompilerDSL that should be used for this site.
178
+ # Returns the dependency tracker for this site, creating it first if it
179
+ # does not yet exist.
246
180
  #
247
181
  # @api private
248
- def dsl
249
- @dsl ||= Nanoc3::CompilerDSL.new(self)
250
- end
251
-
252
- # Loads this site’s rules.
253
182
  #
254
- # @api private
255
- def load_rules
256
- # Find rules file
257
- rules_filename = [ 'Rules', 'rules', 'Rules.rb', 'rules.rb' ].find { |f| File.file?(f) }
258
- raise Nanoc3::Errors::NoRulesFileFound.new if rules_filename.nil?
259
-
260
- # Get rule data
261
- @rules = File.read(rules_filename)
262
-
263
- # Load DSL
264
- dsl.instance_eval(@rules, "./#{rules_filename}")
183
+ # @return [Nanoc3::DependencyTracker] The dependency tracker for this site
184
+ def dependency_tracker
185
+ dt = Nanoc3::DependencyTracker.new(@site.items + @site.layouts)
186
+ dt.compiler = self
187
+ dt
265
188
  end
189
+ memoize :dependency_tracker
266
190
 
267
191
  # Runs the preprocessor.
268
192
  #
269
193
  # @api private
270
194
  def preprocess
271
- preprocessor_context.instance_eval(&preprocessor) if preprocessor
195
+ return if rules_collection.preprocessor.nil?
196
+ preprocessor_context.instance_eval(&rules_collection.preprocessor)
272
197
  end
273
198
 
274
199
  # Returns all objects managed by the site (items, layouts, code snippets,
@@ -276,23 +201,8 @@ module Nanoc3
276
201
  #
277
202
  # @api private
278
203
  def objects
279
- # FIXME remove reference to rules
280
- site.items + site.layouts + site.code_snippets + [ site.config, self.rules_with_reference ]
281
- end
282
-
283
- # Returns the rules along with an unique reference (`:rules`) so that the
284
- # outdatedness checker can use them.
285
- #
286
- # @api private
287
- def rules_with_reference
288
- rules = @rules
289
- @rules_pseudo ||= begin
290
- pseudo = Object.new
291
- pseudo.instance_eval { @data = rules }
292
- def pseudo.reference ; :rules ; end
293
- def pseudo.data ; @data.inspect ; end
294
- pseudo
295
- end
204
+ site.items + site.layouts + site.code_snippets +
205
+ [ site.config, rules_collection ]
296
206
  end
297
207
 
298
208
  # Creates the representations of all items as defined by the compilation
@@ -300,9 +210,9 @@ module Nanoc3
300
210
  #
301
211
  # @api private
302
212
  def build_reps
303
- @site.items.each do |item|
213
+ items.each do |item|
304
214
  # Find matching rules
305
- matching_rules = item_compilation_rules.select { |r| r.applicable_to?(item) }
215
+ matching_rules = rules_collection.item_compilation_rules_for(item)
306
216
  raise Nanoc3::Errors::NoMatchingCompilationRuleFound.new(item) if matching_rules.empty?
307
217
 
308
218
  # Create reps
@@ -317,10 +227,9 @@ module Nanoc3
317
227
  #
318
228
  # @api private
319
229
  def route_reps
320
- reps = @site.items.map { |i| i.reps }.flatten
321
230
  reps.each do |rep|
322
231
  # Find matching rules
323
- rules = routing_rules_for(rep)
232
+ rules = rules_collection.routing_rules_for(rep)
324
233
  raise Nanoc3::Errors::NoMatchingRoutingRuleFound.new(rep) if rules[:last].nil?
325
234
 
326
235
  rules.each_pair do |snapshot, rule|
@@ -371,15 +280,34 @@ module Nanoc3
371
280
  })
372
281
  end
373
282
 
283
+ # @return [Nanoc3::OutdatednessChecker] The outdatedness checker
284
+ def outdatedness_checker
285
+ Nanoc3::OutdatednessChecker.new(
286
+ :site => @site,
287
+ :checksum_store => checksum_store,
288
+ :dependency_tracker => dependency_tracker)
289
+ end
290
+ memoize :outdatedness_checker
291
+
374
292
  private
375
293
 
294
+ # @return [Array<Nanoc3::Item>] The site’s items
376
295
  def items
377
- @items ||= @site.items
296
+ @site.items
378
297
  end
298
+ memoize :items
379
299
 
300
+ # @return [Array<Nanoc3::ItemRep>] The site’s item representations
380
301
  def reps
381
- @reps ||= items.map { |i| i.reps }.flatten
302
+ items.map { |i| i.reps }.flatten
382
303
  end
304
+ memoize :reps
305
+
306
+ # @return [Array<Nanoc3::Layout>] The site’s layouts
307
+ def layouts
308
+ @site.layouts
309
+ end
310
+ memoize :layouts
383
311
 
384
312
  # Compiles the given representations.
385
313
  #
@@ -387,17 +315,7 @@ module Nanoc3
387
315
  #
388
316
  # @return [void]
389
317
  def compile_reps(reps)
390
- require 'set'
391
-
392
- # Partition in outdated and non-outdated
393
- outdated_reps = Set.new
394
- skipped_reps = Set.new
395
- reps.each do |rep|
396
- target = (outdated?(rep) || dependency_tracker.outdated_due_to_dependencies?(rep.item)) ? outdated_reps : skipped_reps
397
- target.add(rep)
398
- end
399
-
400
- # Build graph for outdated reps
318
+ outdated_reps = Set.new(reps.select { |rep| outdatedness_checker.outdated?(rep) })
401
319
  content_dependency_graph = Nanoc3::DirectedGraph.new(outdated_reps)
402
320
 
403
321
  # Listen to processing start/stop
@@ -417,7 +335,6 @@ module Nanoc3
417
335
  rescue Nanoc3::Errors::UnmetDependency => e
418
336
  content_dependency_graph.add_edge(e.rep, rep)
419
337
  unless content_dependency_graph.vertices.include?(e.rep)
420
- skipped_reps.delete(e.rep)
421
338
  content_dependency_graph.add_vertex(e.rep)
422
339
  end
423
340
  end
@@ -446,13 +363,18 @@ module Nanoc3
446
363
  Nanoc3::NotificationCenter.post(:processing_started, rep)
447
364
  Nanoc3::NotificationCenter.post(:visit_started, rep.item)
448
365
 
449
- if !outdated?(rep) && !dependency_tracker.outdated_due_to_dependencies?(rep.item) && compiled_content_cache[rep]
366
+ # Calculate rule memory if we haven’t yet done do
367
+ rules_collection.new_rule_memory_for_rep(rep)
368
+
369
+ if !outdatedness_checker.outdated?(rep) && compiled_content_cache[rep]
370
+ # Reuse content
450
371
  Nanoc3::NotificationCenter.post(:cached_content_used, rep)
451
372
  rep.content = compiled_content_cache[rep]
452
373
  else
374
+ # Recalculate content
453
375
  rep.snapshot(:raw)
454
376
  rep.snapshot(:pre, :final => false)
455
- compilation_rule_for(rep).apply_to(rep, :compiler => self)
377
+ rules_collection.compilation_rule_for(rep).apply_to(rep, :compiler => self)
456
378
  rep.snapshot(:post) if rep.has_snapshot?(:post)
457
379
  rep.snapshot(:last)
458
380
  end
@@ -477,7 +399,7 @@ module Nanoc3
477
399
  # @return [void]
478
400
  def forget_dependencies_if_outdated(items)
479
401
  items.each do |i|
480
- if i.reps.any? { |r| outdated?(r) } || dependency_tracker.outdated_due_to_dependencies?(i)
402
+ if i.reps.any? { |r| outdatedness_checker.outdated?(r) }
481
403
  dependency_tracker.forget_dependencies_for(i)
482
404
  end
483
405
  end
@@ -485,33 +407,48 @@ module Nanoc3
485
407
 
486
408
  # Returns a preprocessor context, creating one if none exists yet.
487
409
  def preprocessor_context
488
- @preprocessor_context ||= Nanoc3::Context.new({
410
+ Nanoc3::Context.new({
489
411
  :site => @site,
490
412
  :config => @site.config,
491
413
  :items => @site.items,
492
414
  :layouts => @site.layouts
493
415
  })
494
416
  end
417
+ memoize :preprocessor_context
495
418
 
496
419
  # @return [CompiledContentCache] The compiled content cache
497
420
  def compiled_content_cache
498
- @compiled_content_cache ||= Nanoc3::CompiledContentCache.new
421
+ Nanoc3::CompiledContentCache.new
499
422
  end
423
+ memoize :compiled_content_cache
500
424
 
501
425
  # @return [ChecksumStore] The checksum store
502
426
  def checksum_store
503
- @checksum_store ||= Nanoc3::ChecksumStore.new(:site => @site)
427
+ Nanoc3::ChecksumStore.new(:site => @site)
504
428
  end
429
+ memoize :checksum_store
505
430
 
506
- # @return [Nanoc3::OutdatednessChecker] The outdatedness checker
507
- def outdatedness_checker
508
- @outdatedness_checker ||= Nanoc3::OutdatednessChecker.new(:site => @site, :checksum_store => checksum_store)
431
+ # @return [RuleMemoryStore] The rule memory store
432
+ def rule_memory_store
433
+ Nanoc3::RuleMemoryStore.new(:site => @site)
434
+ end
435
+ memoize :rule_memory_store
436
+
437
+ # @return [RuleMemoryCalculator] The rule memory calculator
438
+ def rule_memory_calculator
439
+ Nanoc3::RuleMemoryCalculator.new(:rules_collection => rules_collection)
509
440
  end
441
+ memoize :rule_memory_calculator
510
442
 
511
443
  # Returns all stores that can load/store data that can be used for
512
444
  # compilation.
513
445
  def stores
514
- [ compiled_content_cache, checksum_store, dependency_tracker ]
446
+ [
447
+ checksum_store,
448
+ compiled_content_cache,
449
+ dependency_tracker,
450
+ rule_memory_store
451
+ ]
515
452
  end
516
453
 
517
454
  end