nanoc3 3.0.9 → 3.1.0a1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/LICENSE +1 -1
  2. data/NEWS.md +360 -0
  3. data/README.md +85 -0
  4. data/Rakefile +2 -2
  5. data/bin/nanoc3 +0 -4
  6. data/lib/nanoc3/base/code_snippet.rb +14 -6
  7. data/lib/nanoc3/base/compiler.rb +68 -49
  8. data/lib/nanoc3/base/compiler_dsl.rb +70 -29
  9. data/lib/nanoc3/base/context.rb +47 -0
  10. data/lib/nanoc3/base/core_ext/array.rb +4 -0
  11. data/lib/nanoc3/base/core_ext/hash.rb +5 -1
  12. data/lib/nanoc3/base/core_ext/string.rb +2 -0
  13. data/lib/nanoc3/base/data_source.rb +132 -96
  14. data/lib/nanoc3/base/dependency_tracker.rb +160 -185
  15. data/lib/nanoc3/base/directed_graph.rb +252 -0
  16. data/lib/nanoc3/base/errors.rb +52 -4
  17. data/lib/nanoc3/base/filter.rb +43 -28
  18. data/lib/nanoc3/base/item.rb +93 -25
  19. data/lib/nanoc3/base/item_rep.rb +166 -55
  20. data/lib/nanoc3/base/layout.rb +16 -13
  21. data/lib/nanoc3/base/notification_center.rb +28 -12
  22. data/lib/nanoc3/base/plugin_registry.rb +158 -0
  23. data/lib/nanoc3/base/rule.rb +27 -8
  24. data/lib/nanoc3/base/rule_context.rb +59 -46
  25. data/lib/nanoc3/base/site.rb +124 -77
  26. data/lib/nanoc3/base.rb +7 -2
  27. data/lib/nanoc3/cli/base.rb +4 -1
  28. data/lib/nanoc3/cli/commands/autocompile.rb +5 -4
  29. data/lib/nanoc3/cli/commands/compile.rb +28 -7
  30. data/lib/nanoc3/cli/commands/create_item.rb +1 -1
  31. data/lib/nanoc3/cli/commands/create_layout.rb +1 -1
  32. data/lib/nanoc3/cli/commands/create_site.rb +46 -22
  33. data/lib/nanoc3/cli/commands/debug.rb +100 -0
  34. data/lib/nanoc3/cli/commands/help.rb +1 -1
  35. data/lib/nanoc3/cli/commands/info.rb +1 -1
  36. data/lib/nanoc3/cli/commands/view.rb +85 -0
  37. data/lib/nanoc3/cli/commands.rb +2 -0
  38. data/lib/nanoc3/cli/logger.rb +7 -0
  39. data/lib/nanoc3/cli.rb +0 -3
  40. data/lib/nanoc3/data_sources/{delicious.rb → deprecated/delicious.rb} +1 -24
  41. data/lib/nanoc3/data_sources/{last_fm.rb → deprecated/last_fm.rb} +1 -27
  42. data/lib/nanoc3/data_sources/{twitter.rb → deprecated/twitter.rb} +1 -14
  43. data/lib/nanoc3/data_sources/filesystem.rb +188 -176
  44. data/lib/nanoc3/data_sources/filesystem_unified.rb +107 -0
  45. data/lib/nanoc3/data_sources/filesystem_verbose.rb +80 -0
  46. data/lib/nanoc3/data_sources.rb +18 -9
  47. data/lib/nanoc3/extra/core_ext/enumerable.rb +39 -0
  48. data/lib/nanoc3/extra/core_ext/time.rb +2 -2
  49. data/lib/nanoc3/extra/core_ext.rb +1 -0
  50. data/lib/nanoc3/extra/deployers/rsync.rb +49 -3
  51. data/lib/nanoc3/extra/file_proxy.rb +7 -0
  52. data/lib/nanoc3/extra/vcs.rb +25 -24
  53. data/lib/nanoc3/extra/vcses/bazaar.rb +4 -0
  54. data/lib/nanoc3/extra/vcses/dummy.rb +4 -0
  55. data/lib/nanoc3/extra/vcses/git.rb +4 -0
  56. data/lib/nanoc3/extra/vcses/mercurial.rb +4 -0
  57. data/lib/nanoc3/extra/vcses/subversion.rb +4 -0
  58. data/lib/nanoc3/extra.rb +4 -1
  59. data/lib/nanoc3/filters/erb.rb +1 -1
  60. data/lib/nanoc3/filters/erubis.rb +1 -1
  61. data/lib/nanoc3/filters/haml.rb +1 -1
  62. data/lib/nanoc3/filters/kramdown.rb +14 -0
  63. data/lib/nanoc3/filters/maruku.rb +1 -1
  64. data/lib/nanoc3/filters/rainpress.rb +1 -1
  65. data/lib/nanoc3/filters/rdiscount.rb +3 -1
  66. data/lib/nanoc3/filters.rb +2 -0
  67. data/lib/nanoc3/helpers/blogging.rb +91 -75
  68. data/lib/nanoc3/helpers/breadcrumbs.rb +18 -10
  69. data/lib/nanoc3/helpers/capturing.rb +24 -29
  70. data/lib/nanoc3/helpers/filtering.rb +20 -17
  71. data/lib/nanoc3/helpers/html_escape.rb +7 -4
  72. data/lib/nanoc3/helpers/link_to.rb +51 -41
  73. data/lib/nanoc3/helpers/rendering.rb +15 -8
  74. data/lib/nanoc3/helpers/tagging.rb +27 -21
  75. data/lib/nanoc3/helpers/text.rb +12 -8
  76. data/lib/nanoc3/helpers/xml_sitemap.rb +13 -15
  77. data/lib/nanoc3/tasks/deploy/rsync.rake +4 -1
  78. data/lib/nanoc3/tasks.rb +2 -1
  79. data/lib/nanoc3.rb +24 -1
  80. metadata +43 -87
  81. data/NEWS.rdoc +0 -328
  82. data/README.rdoc +0 -83
  83. data/lib/nanoc3/base/plugin.rb +0 -88
  84. data/lib/nanoc3/base/preprocessor_context.rb +0 -37
  85. data/lib/nanoc3/data_sources/filesystem_combined.rb +0 -214
  86. data/lib/nanoc3/data_sources/filesystem_common.rb +0 -22
  87. data/lib/nanoc3/data_sources/filesystem_compact.rb +0 -256
  88. data/lib/nanoc3/extra/context.rb +0 -24
  89. data/lib/nanoc3/package.rb +0 -107
  90. data/vendor/cri/ChangeLog +0 -0
  91. data/vendor/cri/LICENSE +0 -19
  92. data/vendor/cri/NEWS +0 -0
  93. data/vendor/cri/README +0 -4
  94. data/vendor/cri/Rakefile +0 -25
  95. data/vendor/cri/lib/cri/base.rb +0 -153
  96. data/vendor/cri/lib/cri/command.rb +0 -105
  97. data/vendor/cri/lib/cri/core_ext/string.rb +0 -41
  98. data/vendor/cri/lib/cri/core_ext.rb +0 -8
  99. data/vendor/cri/lib/cri/option_parser.rb +0 -186
  100. data/vendor/cri/lib/cri.rb +0 -12
  101. data/vendor/cri/test/test_base.rb +0 -6
  102. data/vendor/cri/test/test_command.rb +0 -6
  103. data/vendor/cri/test/test_core_ext.rb +0 -21
  104. data/vendor/cri/test/test_option_parser.rb +0 -279
@@ -1,64 +1,77 @@
1
1
  module Nanoc3
2
2
 
3
- # Nanoc3::RuleContext provides a context in which compilation and routing
4
- # rules can be executed. It provides access to the item representation that
5
- # is being compiled or routed.
6
- class RuleContext
3
+ # Provides a context in which compilation and routing rules can be executed.
4
+ # It provides access to the item representation that is being compiled or
5
+ # routed.
6
+ #
7
+ # The following variables will be available in this rules context:
8
+ #
9
+ # * `rep` ({Nanoc3::ItemRep}) - The current item rep
10
+ # * `item` ({Nanoc3::Item}) - The current item
11
+ # * `site` ({Nanoc3::Site}) - The site
12
+ # * `config` ({Hash}) - The site configuration
13
+ # * `items` ({Array}<{Nanoc3::Item}>) - A list of all items
14
+ # * `layouts` ({Array}<{Nanoc3::Layout}>) - A list of all layouts
15
+ class RuleContext < Context
7
16
 
8
- # Creates a new rule context for the given item representation.
17
+ # Creates a new rule context for the given iterm representation.
18
+ #
19
+ # @param [Nanoc3::ItemRep] rep The item representation for which to create
20
+ # a new rule context.
9
21
  def initialize(rep)
10
- @rep = rep
11
- end
12
-
13
- # The representation that is currently being processed in this context.
14
- def rep
15
- @rep
16
- end
17
-
18
- # The item of the representation that is currently being processed in this
19
- # context.
20
- def item
21
- rep.item
22
- end
23
-
24
- # The site of the item representation that is currently being processed in
25
- # this context.
26
- def site
27
- item.site
28
- end
22
+ item = rep.item
23
+ site = item.site
24
+ config = site.config
25
+ items = site.items
26
+ layouts = site.layouts
29
27
 
30
- # The configuration of the site of the item representation that is
31
- # currently being processed in this context.
32
- def config
33
- site.config
28
+ super({
29
+ :rep => rep,
30
+ :item => item,
31
+ :site => site,
32
+ :config => config,
33
+ :items => items,
34
+ :layouts => layouts
35
+ })
34
36
  end
35
37
 
36
- # The items in the site of the item representation that is currently being
37
- # processed in this context.
38
- def items
39
- site.items
40
- end
41
-
42
- # The layouts in the site of the item representation that is currently
43
- # being processed in this context.
44
- def layouts
45
- site.layouts
46
- end
47
-
48
- # Filters the current representation (calls #filter with the given
49
- # arguments on the rep).
38
+ # Filters the current representation (calls {Nanoc3::ItemRep#filter} with
39
+ # the given arguments on the rep).
40
+ #
41
+ # @see Nanoc3::ItemRep#filter
42
+ #
43
+ # @param [Symbol] filter_name The name of the filter to run the item
44
+ # representations' content through
45
+ #
46
+ # @param [Hash] filter_args The filter arguments that should be passed to
47
+ # the filter's #run method
48
+ #
49
+ # @return [void]
50
50
  def filter(filter_name, filter_args={})
51
51
  rep.filter(filter_name, filter_args)
52
52
  end
53
53
 
54
- # Layouts the current representation (calls #layout with the given
55
- # arguments on the rep).
54
+ # Layouts the current representation (calls {Nanoc3::ItemRep#layout} with
55
+ # the given arguments on the rep).
56
+ #
57
+ # @see Nanoc3::ItemRep#layout
58
+ #
59
+ # @param [String] layout_identifier The identifier of the layout the ite
60
+ # should be laid out with
61
+ #
62
+ # @return [void]
56
63
  def layout(layout_identifier)
57
64
  rep.layout(layout_identifier)
58
65
  end
59
66
 
60
- # Creates a snapshot of the current representation (calls #snapshot with
61
- # the given arguments on the rep).
67
+ # Creates a snapshot of the current compiled item content. Calls
68
+ # {Nanoc3::ItemRep#snapshot} with the given arguments on the rep.
69
+ #
70
+ # @see Nanoc3::ItemRep#snapshot
71
+ #
72
+ # @param [Symbol] snapshot_name The name of the snapshot to create
73
+ #
74
+ # @return [void]
62
75
  def snapshot(snapshot_name)
63
76
  rep.snapshot(snapshot_name)
64
77
  end
@@ -2,59 +2,26 @@
2
2
 
3
3
  module Nanoc3
4
4
 
5
- # A Nanoc3::Site is the in-memory representation of a nanoc site. It holds
6
- # references to the following site data:
5
+ # The in-memory representation of a nanoc site. It holds references to the
6
+ # following site data:
7
7
  #
8
- # * +items+ is a list of Nanoc3::Item instances representing items
9
- # * +layouts+ is a list of Nanoc3::Layout instances representing layouts
10
- # * +code_snippets+ is list of Nanoc3::CodeSnippet instance representing
11
- # custom site code
8
+ # * {#items} - the list of items ({Nanoc3::Item})
9
+ # * {#layouts} - the list of layouts ({Nanoc3::Layout})
10
+ # * {#code_snippets} - the list of code snippets ({Nanoc3::CodeSnippet})
12
11
  #
13
- # In addition, each site has a +config+ hash which stores the site
14
- # configuration. This configuration hash can have the following keys:
15
- #
16
- # +output_dir+:: The directory to which compiled items will be written. This
17
- # path is relative to the current working directory, but can
18
- # also be an absolute path.
19
- #
20
- # +data_sources+:: A list of data sources for this site. See below for
21
- # documentation on the structure of this list. By default,
22
- # there is only one data source of the filesystem type
23
- # mounted at /.
24
- #
25
- # +index_filenames+:: A list of filenames that will be stripped off full
26
- # item paths to create cleaner URLs (for example,
27
- # '/about/' will be used instead of
28
- # '/about/index.html'). The default value should be okay
29
- # in most cases.
30
- #
31
- # The list of data sources consists of hashes with the following keys:
32
- #
33
- # +:type+:: The type of data source, i.e. its identifier.
34
- #
35
- # +:items_root+:: The prefix that should be given to all items returned by
36
- # the #items method (comparable to mount points for
37
- # filesystems in Unix-ish OSes).
38
- #
39
- # +:layouts_root+:: The prefix that should be given to all layouts returned
40
- # by the #layouts method (comparable to mount points for
41
- # filesystems in Unix-ish OSes).
42
- #
43
- # +:config+:: A hash containing the configuration for this data source. This
44
- # is especially useful for online data sources; for example, a
45
- # Twitter data source would need the username of the account
46
- # from which to fetch tweets.
12
+ # In addition, each site has a {#config} hash which stores the site
13
+ # configuration.
47
14
  #
48
15
  # A site also has several helper classes:
49
16
  #
50
- # * +data_source+ is a Nanoc3::DataSource subclass instance used for loading
51
- # site data.
52
- # * +compiler+ is a Nanoc3::Compiler instance that compiles item
53
- # representations.
17
+ # * {#data_sources} (array of {Nanoc3::DataSource}) - A list of data sources
18
+ # that are used for loading site data
19
+ # * {#compiler} ({Nanoc3::Compiler}) - The compiler that is used for
20
+ # compiling items and their representations
54
21
  #
55
- # The physical representation of a Nanoc3::Site is usually a directory that
56
- # contains a configuration file, site data, a rakefile, a rules file, etc.
57
- # The way site data is stored depends on the data source.
22
+ # The physical representation of a {Nanoc3::Site} is usually a directory
23
+ # that contains a configuration file, site data, a rakefile, a rules file,
24
+ # etc. The way site data is stored depends on the data source.
58
25
  class Site
59
26
 
60
27
  # The default configuration for a data source. A data source's
@@ -67,34 +34,67 @@ module Nanoc3
67
34
  }
68
35
 
69
36
  # The default configuration for a site. A site's configuration overrides
70
- # these options: when a Nanoc3::Site is created with a configuration that
71
- # lacks some options, the default value will be taken from
72
- # +DEFAULT_CONFIG+.
37
+ # these options: when a {Nanoc3::Site} is created with a configuration
38
+ # that lacks some options, the default value will be taken from
39
+ # `DEFAULT_CONFIG`.
73
40
  DEFAULT_CONFIG = {
74
41
  :output_dir => 'output',
75
42
  :data_sources => [ {} ],
76
43
  :index_filenames => [ 'index.html' ]
77
44
  }
78
45
 
79
- # The site configuration.
46
+ # The site configuration. The configuration has the following keys:
47
+ #
48
+ # * `output_dir` ({String}) - The directory to which compiled items will
49
+ # be written. This path is relative to the current working directory,
50
+ # but can also be an absolute path.
51
+ #
52
+ # * `data_sources` ({Array<Hash>}) - A list of data sources for this site.
53
+ # See below for documentation on the structure of this list. By
54
+ # default, there is only one data source of the filesystem type
55
+ # mounted at `/`.
56
+ #
57
+ # * `index_filenames` ({Array<String>}) - A list of filenames that will be
58
+ # stripped off full item paths to create cleaner URLs. For example,
59
+ # `/about/` will be used instead of `/about/index.html`). The default
60
+ # value should be okay in most cases.
61
+ #
62
+ # The list of data sources consists of hashes with the following keys:
63
+ #
64
+ # * `:type` ({String}) - The type of data source, i.e. its identifier.
65
+ #
66
+ # * `:items_root` ({String}) - The prefix that should be given to all
67
+ # items returned by the {#items} method (comparable to mount points
68
+ # for filesystems in Unix-ish OSes).
69
+ #
70
+ # * `:layouts_root` ({String}) - The prefix that should be given to all
71
+ # layouts returned by the {#layouts} method (comparable to mount
72
+ # points for filesystems in Unix-ish OSes).
73
+ #
74
+ # * `:config` ({Hash}) - A hash containing the configuration for this data
75
+ # source. nanoc itself does not use this hash. This is especially
76
+ # useful for online data sources; for example, a Twitter data source
77
+ # would need the username of the account from which to fetch tweets.
78
+ #
79
+ # @return [Hash] The site configuration
80
80
  attr_reader :config
81
81
 
82
- # The timestamp when the site configuration was last modified.
82
+ # @return [Time] The timestamp when the site configuration was last
83
+ # modified
83
84
  attr_reader :config_mtime
84
85
 
85
- # The timestamp when the rules were last modified.
86
+ # @return [Time] The timestamp when the rules were last modified
86
87
  attr_reader :rules_mtime
87
88
 
88
- # The code block that will be executed after all data is loaded but before
89
- # the site is compiled.
89
+ # @return [Proc] The code block that will be executed after all data is
90
+ # loaded but before the site is compiled
90
91
  attr_accessor :preprocessor
91
92
 
92
- # Creates a Nanoc3::Site object for the site specified by the given
93
- # +dir_or_config_hash+ argument.
93
+ # Creates a site object for the site specified by the given
94
+ # `dir_or_config_hash` argument.
94
95
  #
95
- # +dir_or_config_hash+:: If a string, contains the path to the site
96
- # directory; if a hash, contains the site
97
- # configuration.
96
+ # @param [Hash, String] dir_or_config_hash If a string, contains the path
97
+ # to the site directory; if a hash, contains the site configuration.
98
98
  def initialize(dir_or_config_hash)
99
99
  build_config(dir_or_config_hash)
100
100
 
@@ -105,13 +105,20 @@ module Nanoc3
105
105
 
106
106
  # Returns the compiler for this site. Will create a new compiler if none
107
107
  # exists yet.
108
+ #
109
+ # @return [Nanoc3::Compiler] The compiler for this site
108
110
  def compiler
109
111
  @compiler ||= Compiler.new(self)
110
112
  end
111
113
 
112
114
  # Returns the data sources for this site. Will create a new data source if
113
- # none exists yet. Raises Nanoc3::Errors::UnknownDataSource if the site
114
- # configuration specifies an unknown data source.
115
+ # none exists yet.
116
+ #
117
+ # @return [Array<Nanoc3::DataSource>] The list of data sources for this
118
+ # site
119
+ #
120
+ # @raise [Nanoc3::Errors::UnknownDataSource] if the site configuration
121
+ # specifies an unknown data source
115
122
  def data_sources
116
123
  @data_sources ||= begin
117
124
  @config[:data_sources].map do |data_source_hash|
@@ -119,6 +126,12 @@ module Nanoc3
119
126
  data_source_class = Nanoc3::DataSource.named(data_source_hash[:type])
120
127
  raise Nanoc3::Errors::UnknownDataSource.new(data_source_hash[:type]) if data_source_class.nil?
121
128
 
129
+ # Warn about deprecated data sources
130
+ # TODO [in nanoc 4.0] remove me
131
+ if data_source_hash[:type] == 'filesystem'
132
+ warn "Warning: the 'filesystem' data source has been renamed to 'filesystem_verbose'. Using 'filesystem' will work in nanoc 3.1.x, but it will likely not work anymore in a future release of nanoc. Please update your data source configuration and replace 'filesystem' with 'filesystem_verbose'."
133
+ end
134
+
122
135
  # Create data source
123
136
  data_source_class.new(
124
137
  self,
@@ -130,13 +143,15 @@ module Nanoc3
130
143
  end
131
144
  end
132
145
 
133
- # Loads the site data. This will query the Nanoc3::DataSource associated
146
+ # Loads the site data. This will query the {Nanoc3::DataSource} associated
134
147
  # with the site and fetch all site data. The site data is cached, so
135
148
  # calling this method will not have any effect the second time, unless
136
- # +force+ is true.
149
+ # the `force` parameter is true.
137
150
  #
138
- # +force+:: If true, will force load the site data even if it has been
139
- # loaded before, to circumvent caching issues.
151
+ # @param [Boolean] force If true, will force load the site data even if it
152
+ # has been loaded before, to circumvent caching issues
153
+ #
154
+ # @return [void]
140
155
  def load_data(force=false)
141
156
  # Don't load data twice
142
157
  return if instance_variable_defined?(:@data_loaded) && @data_loaded && !force
@@ -151,7 +166,7 @@ module Nanoc3
151
166
 
152
167
  # Preprocess
153
168
  setup_child_parent_links
154
- Nanoc3::PreprocessorContext.new(self).instance_eval(&preprocessor) unless preprocessor.nil?
169
+ preprocessor_context.instance_eval(&preprocessor) unless preprocessor.nil?
155
170
  link_everything_to_site
156
171
  setup_child_parent_links
157
172
  build_reps
@@ -161,19 +176,35 @@ module Nanoc3
161
176
  @data_loaded = true
162
177
  end
163
178
 
164
- # Returns this site's code snippets. Raises an exception if data hasn't been loaded yet.
179
+ # Returns this sites code snippets.
180
+ #
181
+ # @return [Array<Nanoc3::CodeSnippet>] The list of code snippets in this
182
+ # site
183
+ #
184
+ # @raise [Nanoc3::Errors::DataNotYetAvailable] if the site data hasn’t
185
+ # been loaded yet (call {#load_data} to load the site data)
165
186
  def code_snippets
166
187
  raise Nanoc3::Errors::DataNotYetAvailable.new('Code snippets', false) unless @code_snippets_loaded
167
188
  @code_snippets
168
189
  end
169
190
 
170
- # Returns this site's items. Raises an exception if data hasn't been loaded yet.
191
+ # Returns this sites items.
192
+ #
193
+ # @return [Array<Nanoc3::Item>] The list of items in this site
194
+ #
195
+ # @raise [Nanoc3::Errors::DataNotYetAvailable] if the site data hasn’t
196
+ # been loaded yet (call {#load_data} to load the site data)
171
197
  def items
172
198
  raise Nanoc3::Errors::DataNotYetAvailable.new('Items', true) unless @items_loaded
173
199
  @items
174
200
  end
175
201
 
176
- # Returns this site's layouts. Raises an exception if data hasn't been loaded yet.
202
+ # Returns this sites layouts.
203
+ #
204
+ # @return [Array<Nanoc3::Layouts>] The list of layout in this site
205
+ #
206
+ # @raise [Nanoc3::Errors::DataNotYetAvailable] if the site data hasn’t
207
+ # been loaded yet (call {#load_data} to load the site data)
177
208
  def layouts
178
209
  raise Nanoc3::Errors::DataNotYetAvailable.new('Layouts', true) unless @layouts_loaded
179
210
  @layouts
@@ -186,13 +217,19 @@ module Nanoc3
186
217
  @dsl ||= Nanoc3::CompilerDSL.new(self)
187
218
  end
188
219
 
189
- # Loads this site's code and executes it.
220
+ # Loads this sites code and executes it.
190
221
  def load_code_snippets(force=false)
191
222
  # Don't load code snippets twice
192
223
  return if @code_snippets_loaded and !force
193
224
 
194
225
  # Get code snippets
195
- @code_snippets = data_sources.map { |ds| ds.code_snippets }.flatten
226
+ @code_snippets = Dir['lib/**/*.rb'].sort.map do |filename|
227
+ Nanoc3::CodeSnippet.new(
228
+ File.read(filename),
229
+ filename.sub(/^lib\//, ''),
230
+ File.stat(filename).mtime
231
+ )
232
+ end
196
233
 
197
234
  # Execute code snippets
198
235
  @code_snippets.each { |cs| cs.load }
@@ -200,7 +237,7 @@ module Nanoc3
200
237
  @code_snippets_loaded = true
201
238
  end
202
239
 
203
- # Loads this site's rules.
240
+ # Loads this sites rules.
204
241
  def load_rules
205
242
  # Find rules file
206
243
  rules_filename = [ 'Rules', 'rules', 'Rules.rb', 'rules.rb' ].find { |f| File.file?(f) }
@@ -214,26 +251,26 @@ module Nanoc3
214
251
  dsl.instance_eval(@rules)
215
252
  end
216
253
 
217
- # Loads this site's items, sets up item child-parent relationships and
254
+ # Loads this sites items, sets up item child-parent relationships and
218
255
  # builds each item's list of item representations.
219
256
  def load_items
220
257
  @items = []
221
258
  data_sources.each do |ds|
222
259
  items_in_ds = ds.items
223
260
  items_in_ds.each { |i| i.identifier = File.join(ds.items_root, i.identifier) }
224
- @items += items_in_ds
261
+ @items.concat(items_in_ds)
225
262
  end
226
263
 
227
264
  @items_loaded = true
228
265
  end
229
266
 
230
- # Loads this site's layouts.
267
+ # Loads this sites layouts.
231
268
  def load_layouts
232
269
  @layouts = []
233
270
  data_sources.each do |ds|
234
271
  layouts_in_ds = ds.layouts
235
272
  layouts_in_ds.each { |i| i.identifier = File.join(ds.layouts_root, i.identifier) }
236
- @layouts += layouts_in_ds
273
+ @layouts.concat(layouts_in_ds)
237
274
  end
238
275
 
239
276
  @layouts_loaded = true
@@ -329,6 +366,16 @@ module Nanoc3
329
366
  @config[:data_sources].map! { |ds| DEFAULT_DATA_SOURCE_CONFIG.merge(ds) }
330
367
  end
331
368
 
369
+ # Returns a preprocessor context, creating one if none exists yet.
370
+ def preprocessor_context
371
+ @preprocessor_context ||= Nanoc3::Context.new({
372
+ :site => self,
373
+ :config => self.config,
374
+ :items => self.items,
375
+ :layouts => self.layouts
376
+ })
377
+ end
378
+
332
379
  end
333
380
 
334
381
  end
data/lib/nanoc3/base.rb CHANGED
@@ -9,18 +9,23 @@ module Nanoc3
9
9
  autoload 'Compiler', 'nanoc3/base/compiler'
10
10
  autoload 'CompilerDSL', 'nanoc3/base/compiler_dsl'
11
11
  autoload 'Config', 'nanoc3/base/config'
12
+ autoload 'Context', 'nanoc3/base/context'
12
13
  autoload 'DataSource', 'nanoc3/base/data_source'
13
14
  autoload 'DependencyTracker', 'nanoc3/base/dependency_tracker'
15
+ autoload 'DirectedGraph', 'nanoc3/base/directed_graph'
14
16
  autoload 'Errors', 'nanoc3/base/errors'
15
17
  autoload 'Filter', 'nanoc3/base/filter'
16
18
  autoload 'Item', 'nanoc3/base/item'
17
19
  autoload 'ItemRep', 'nanoc3/base/item_rep'
18
20
  autoload 'Layout', 'nanoc3/base/layout'
19
21
  autoload 'NotificationCenter', 'nanoc3/base/notification_center'
20
- autoload 'Plugin', 'nanoc3/base/plugin'
21
- autoload 'PreprocessorContext', 'nanoc3/base/preprocessor_context'
22
+ autoload 'PluginRegistry', 'nanoc3/base/plugin_registry'
22
23
  autoload 'Rule', 'nanoc3/base/rule'
23
24
  autoload 'RuleContext', 'nanoc3/base/rule_context'
24
25
  autoload 'Site', 'nanoc3/base/site'
25
26
 
27
+ # Deprecated; use PluginRepository instead
28
+ # TODO [in nanoc 4.0] remove me
29
+ autoload 'Plugin', 'nanoc3/base/plugin_registry'
30
+
26
31
  end
@@ -17,8 +17,10 @@ module Nanoc3::CLI
17
17
  add_command(Nanoc3::CLI::Commands::CreateLayout.new)
18
18
  add_command(Nanoc3::CLI::Commands::CreateItem.new)
19
19
  add_command(Nanoc3::CLI::Commands::CreateSite.new)
20
+ add_command(Nanoc3::CLI::Commands::Debug.new)
20
21
  add_command(Nanoc3::CLI::Commands::Info.new)
21
22
  add_command(Nanoc3::CLI::Commands::Update.new)
23
+ add_command(Nanoc3::CLI::Commands::View.new)
22
24
  end
23
25
 
24
26
  def self.shared_base
@@ -110,6 +112,7 @@ module Nanoc3::CLI
110
112
  def resolution_for(error)
111
113
  # FIXME this should probably go somewhere else so that 3rd-party code can add other gem names too
112
114
  gem_names = {
115
+ 'adsf' => 'adsf',
113
116
  'bluecloth' => 'bluecloth',
114
117
  'builder' => 'builder',
115
118
  'coderay' => 'coderay',
@@ -200,7 +203,7 @@ module Nanoc3::CLI
200
203
  def handle_option(option)
201
204
  case option
202
205
  when :version
203
- puts "nanoc #{Nanoc3::VERSION} (c) 2007-2010 Denis Defreyne."
206
+ puts "nanoc #{Nanoc3::VERSION} (c) 2007-2009 Denis Defreyne."
204
207
  puts "Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) running on #{RUBY_PLATFORM}"
205
208
  exit 0
206
209
  when :verbose
@@ -28,10 +28,10 @@ module Nanoc3::CLI::Commands
28
28
 
29
29
  def option_definitions
30
30
  [
31
- # --server
31
+ # --handler
32
32
  {
33
- :long => 'server', :short => 's', :argument => :required,
34
- :desc => 'specify the server to use (webrick/mongrel)'
33
+ :long => 'handler', :short => 'H', :argument => :required,
34
+ :desc => 'specify the handler to use (webrick/mongrel/...)'
35
35
  },
36
36
  # --host
37
37
  {
@@ -59,7 +59,7 @@ module Nanoc3::CLI::Commands
59
59
  }
60
60
 
61
61
  # Guess which handler we should use
62
- unless handler = Rack::Handler.get(options[:server])
62
+ unless handler = Rack::Handler.get(options[:handler])
63
63
  begin
64
64
  handler = Rack::Handler::Mongrel
65
65
  rescue LoadError => e
@@ -76,6 +76,7 @@ module Nanoc3::CLI::Commands
76
76
  end.to_app
77
77
 
78
78
  # Run autocompiler
79
+ puts "Running on http://#{options_for_rack[:Host]}:#{options_for_rack[:Port]}/"
79
80
  handler.run(app, options_for_rack)
80
81
  end
81
82
 
@@ -93,9 +93,12 @@ module Nanoc3::CLI::Commands
93
93
  reps.select { |r| !r.compiled? }.each do |rep|
94
94
  next if rep.raw_path.nil?
95
95
  duration = @rep_times[rep.raw_path]
96
- Nanoc3::CLI::Logger.instance.file(:low, :skip, rep.raw_path, duration)
96
+ Nanoc3::CLI::Logger.instance.file(:high, :skip, rep.raw_path, duration)
97
97
  end
98
98
 
99
+ # Show diff
100
+ write_diff_for(reps)
101
+
99
102
  # Give general feedback
100
103
  puts
101
104
  puts "No items were modified." unless reps.any? { |r| r.modified? }
@@ -124,6 +127,24 @@ module Nanoc3::CLI::Commands
124
127
  end
125
128
  end
126
129
 
130
+ def write_diff_for(reps)
131
+ full_diff = ''
132
+ reps.each do |rep|
133
+ diff = rep.diff
134
+ next if diff.nil?
135
+
136
+ # Fix header
137
+ diff.sub!(/^--- .*/, '--- ' + rep.raw_path)
138
+ diff.sub!(/^\+\+\+ .*/, '+++ ' + rep.raw_path)
139
+
140
+ # Add
141
+ full_diff << diff
142
+ end
143
+
144
+ # Write
145
+ File.open('output.diff', 'w') { |io| io.write(full_diff) }
146
+ end
147
+
127
148
  def print_state_feedback(reps)
128
149
  # Categorise reps
129
150
  rest = reps
@@ -198,20 +219,20 @@ module Nanoc3::CLI::Commands
198
219
  return unless rep.written?
199
220
 
200
221
  # Get action and level
201
- action, level = *if rep.created?
202
- [ :create, :high ]
222
+ action = if rep.created?
223
+ :create
203
224
  elsif rep.modified?
204
- [ :update, :high ]
225
+ :update
205
226
  elsif !rep.compiled?
206
- [ nil, nil ]
227
+ nil
207
228
  else
208
- [ :identical, :low ]
229
+ :identical
209
230
  end
210
231
 
211
232
  # Log
212
233
  unless action.nil?
213
234
  duration = @rep_times[rep.raw_path]
214
- Nanoc3::CLI::Logger.instance.file(level, action, rep.raw_path, duration)
235
+ Nanoc3::CLI::Logger.instance.file(:high, action, rep.raw_path, duration)
215
236
  end
216
237
  end
217
238
 
@@ -21,7 +21,7 @@ module Nanoc3::CLI::Commands
21
21
  end
22
22
 
23
23
  def usage
24
- "nanoc3 create_item [options] [identifier]"
24
+ "nanoc3 create_item [options] identifier"
25
25
  end
26
26
 
27
27
  def option_definitions
@@ -21,7 +21,7 @@ module Nanoc3::CLI::Commands
21
21
  end
22
22
 
23
23
  def usage
24
- "nanoc3 create_layout [identifier]"
24
+ "nanoc3 create_layout [options] identifier"
25
25
  end
26
26
 
27
27
  def option_definitions