nanoc3 3.2.0a3 → 3.2.0a4

Sign up to get free protection for your applications and to get access to all the features.
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