nanoc3 3.0.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 (116) hide show
  1. data/ChangeLog +3 -0
  2. data/LICENSE +19 -0
  3. data/NEWS.rdoc +262 -0
  4. data/README.rdoc +80 -0
  5. data/Rakefile +11 -0
  6. data/bin/nanoc3 +16 -0
  7. data/lib/nanoc3/base/code_snippet.rb +42 -0
  8. data/lib/nanoc3/base/compiler.rb +225 -0
  9. data/lib/nanoc3/base/compiler_dsl.rb +110 -0
  10. data/lib/nanoc3/base/core_ext/array.rb +21 -0
  11. data/lib/nanoc3/base/core_ext/hash.rb +23 -0
  12. data/lib/nanoc3/base/core_ext/string.rb +14 -0
  13. data/lib/nanoc3/base/core_ext.rb +5 -0
  14. data/lib/nanoc3/base/data_source.rb +197 -0
  15. data/lib/nanoc3/base/dependency_tracker.rb +291 -0
  16. data/lib/nanoc3/base/errors.rb +95 -0
  17. data/lib/nanoc3/base/filter.rb +60 -0
  18. data/lib/nanoc3/base/item.rb +87 -0
  19. data/lib/nanoc3/base/item_rep.rb +236 -0
  20. data/lib/nanoc3/base/layout.rb +53 -0
  21. data/lib/nanoc3/base/notification_center.rb +68 -0
  22. data/lib/nanoc3/base/plugin.rb +88 -0
  23. data/lib/nanoc3/base/preprocessor_context.rb +37 -0
  24. data/lib/nanoc3/base/rule.rb +37 -0
  25. data/lib/nanoc3/base/rule_context.rb +68 -0
  26. data/lib/nanoc3/base/site.rb +334 -0
  27. data/lib/nanoc3/base.rb +25 -0
  28. data/lib/nanoc3/cli/base.rb +151 -0
  29. data/lib/nanoc3/cli/commands/autocompile.rb +89 -0
  30. data/lib/nanoc3/cli/commands/compile.rb +279 -0
  31. data/lib/nanoc3/cli/commands/create_item.rb +79 -0
  32. data/lib/nanoc3/cli/commands/create_layout.rb +94 -0
  33. data/lib/nanoc3/cli/commands/create_site.rb +320 -0
  34. data/lib/nanoc3/cli/commands/help.rb +71 -0
  35. data/lib/nanoc3/cli/commands/info.rb +114 -0
  36. data/lib/nanoc3/cli/commands/update.rb +96 -0
  37. data/lib/nanoc3/cli/commands.rb +13 -0
  38. data/lib/nanoc3/cli/logger.rb +73 -0
  39. data/lib/nanoc3/cli.rb +16 -0
  40. data/lib/nanoc3/data_sources/delicious.rb +66 -0
  41. data/lib/nanoc3/data_sources/filesystem.rb +231 -0
  42. data/lib/nanoc3/data_sources/filesystem_combined.rb +202 -0
  43. data/lib/nanoc3/data_sources/filesystem_common.rb +22 -0
  44. data/lib/nanoc3/data_sources/filesystem_compact.rb +232 -0
  45. data/lib/nanoc3/data_sources/last_fm.rb +103 -0
  46. data/lib/nanoc3/data_sources/twitter.rb +53 -0
  47. data/lib/nanoc3/data_sources.rb +20 -0
  48. data/lib/nanoc3/extra/auto_compiler.rb +97 -0
  49. data/lib/nanoc3/extra/chick.rb +119 -0
  50. data/lib/nanoc3/extra/context.rb +24 -0
  51. data/lib/nanoc3/extra/core_ext/time.rb +19 -0
  52. data/lib/nanoc3/extra/core_ext.rb +3 -0
  53. data/lib/nanoc3/extra/deployers/rsync.rb +64 -0
  54. data/lib/nanoc3/extra/deployers.rb +12 -0
  55. data/lib/nanoc3/extra/file_proxy.rb +31 -0
  56. data/lib/nanoc3/extra/validators/links.rb +0 -0
  57. data/lib/nanoc3/extra/validators/w3c.rb +71 -0
  58. data/lib/nanoc3/extra/validators.rb +12 -0
  59. data/lib/nanoc3/extra/vcs.rb +65 -0
  60. data/lib/nanoc3/extra/vcses/bazaar.rb +21 -0
  61. data/lib/nanoc3/extra/vcses/dummy.rb +20 -0
  62. data/lib/nanoc3/extra/vcses/git.rb +21 -0
  63. data/lib/nanoc3/extra/vcses/mercurial.rb +21 -0
  64. data/lib/nanoc3/extra/vcses/subversion.rb +21 -0
  65. data/lib/nanoc3/extra/vcses.rb +17 -0
  66. data/lib/nanoc3/extra.rb +16 -0
  67. data/lib/nanoc3/filters/bluecloth.rb +13 -0
  68. data/lib/nanoc3/filters/coderay.rb +17 -0
  69. data/lib/nanoc3/filters/erb.rb +19 -0
  70. data/lib/nanoc3/filters/erubis.rb +17 -0
  71. data/lib/nanoc3/filters/haml.rb +20 -0
  72. data/lib/nanoc3/filters/less.rb +13 -0
  73. data/lib/nanoc3/filters/markaby.rb +14 -0
  74. data/lib/nanoc3/filters/maruku.rb +14 -0
  75. data/lib/nanoc3/filters/rainpress.rb +13 -0
  76. data/lib/nanoc3/filters/rdiscount.rb +13 -0
  77. data/lib/nanoc3/filters/rdoc.rb +23 -0
  78. data/lib/nanoc3/filters/redcloth.rb +14 -0
  79. data/lib/nanoc3/filters/relativize_paths.rb +32 -0
  80. data/lib/nanoc3/filters/rubypants.rb +14 -0
  81. data/lib/nanoc3/filters/sass.rb +17 -0
  82. data/lib/nanoc3/filters.rb +37 -0
  83. data/lib/nanoc3/helpers/blogging.rb +226 -0
  84. data/lib/nanoc3/helpers/breadcrumbs.rb +25 -0
  85. data/lib/nanoc3/helpers/capturing.rb +71 -0
  86. data/lib/nanoc3/helpers/filtering.rb +46 -0
  87. data/lib/nanoc3/helpers/html_escape.rb +22 -0
  88. data/lib/nanoc3/helpers/link_to.rb +120 -0
  89. data/lib/nanoc3/helpers/rendering.rb +76 -0
  90. data/lib/nanoc3/helpers/tagging.rb +58 -0
  91. data/lib/nanoc3/helpers/text.rb +40 -0
  92. data/lib/nanoc3/helpers/xml_sitemap.rb +69 -0
  93. data/lib/nanoc3/helpers.rb +16 -0
  94. data/lib/nanoc3/package.rb +106 -0
  95. data/lib/nanoc3/tasks/clean.rake +16 -0
  96. data/lib/nanoc3/tasks/clean.rb +33 -0
  97. data/lib/nanoc3/tasks/deploy/rsync.rake +11 -0
  98. data/lib/nanoc3/tasks/validate.rake +35 -0
  99. data/lib/nanoc3/tasks.rb +9 -0
  100. data/lib/nanoc3.rb +19 -0
  101. data/vendor/cri/ChangeLog +0 -0
  102. data/vendor/cri/LICENSE +19 -0
  103. data/vendor/cri/NEWS +0 -0
  104. data/vendor/cri/README +4 -0
  105. data/vendor/cri/Rakefile +25 -0
  106. data/vendor/cri/lib/cri/base.rb +153 -0
  107. data/vendor/cri/lib/cri/command.rb +105 -0
  108. data/vendor/cri/lib/cri/core_ext/string.rb +41 -0
  109. data/vendor/cri/lib/cri/core_ext.rb +8 -0
  110. data/vendor/cri/lib/cri/option_parser.rb +186 -0
  111. data/vendor/cri/lib/cri.rb +12 -0
  112. data/vendor/cri/test/test_base.rb +6 -0
  113. data/vendor/cri/test/test_command.rb +6 -0
  114. data/vendor/cri/test/test_core_ext.rb +21 -0
  115. data/vendor/cri/test/test_option_parser.rb +279 -0
  116. metadata +225 -0
data/ChangeLog ADDED
@@ -0,0 +1,3 @@
1
+ For a list of all changes, please see the changelog on the project repository
2
+ instead (http://projects.stoneship.org/hg/nanoc/shortlog). For release notes,
3
+ please see the NEWS file.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2007-2009 Denis Defreyne and contributors
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/NEWS.rdoc ADDED
@@ -0,0 +1,262 @@
1
+ = nanoc News
2
+
3
+ == 3.0
4
+
5
+ New:
6
+
7
+ * Multiple data sources
8
+ * Dependency tracking between items
9
+ * Filters can now optionally take arguments
10
+ * create_page and create_layout methods in data sources
11
+ * A new way to specify compilation/routing rules using a Rules file
12
+ * Coderay filter
13
+ * A filesystem_compact data source which uses less directories
14
+
15
+ Changed:
16
+
17
+ * Pages and textual assets are now known as "items"
18
+
19
+ Removed:
20
+
21
+ * Support for drafts
22
+ * Support for binary assets
23
+ * Support for templates
24
+ * Everything that was deprecated in nanoc 2.x
25
+ * save_*, move_* and delete_* methods in data sources
26
+ * Processing instructions in metadata
27
+
28
+ == 2.2.2
29
+
30
+ * Removed relativize_paths filter; use relativize_paths_in_html or
31
+ relativize_paths_in_css instead
32
+ * Fixed bug which could cause nanoc to eat massive amounts of memory when an
33
+ exception occurs
34
+ * Fixed bug which would cause nanoc to complain about the open file limit
35
+ being reached when using a large amount of assets
36
+
37
+ == 2.2.1
38
+
39
+ * Fixed bug which prevented relative_path_to from working
40
+ * Split relativize_paths filter into two filter: relativize_paths_in_html
41
+ and relativize_paths_in_css
42
+ * Removed bundled mime-types library
43
+
44
+ == 2.2
45
+
46
+ New:
47
+
48
+ * --pages and --assets compiler options
49
+ * --no-color commandline option
50
+ * Filtering helper
51
+ * relative_path_to function in LinkTo helper
52
+ * Rainpress filter
53
+ * RelativizePaths filter
54
+ * The current layout is now accessible through the @layout variable
55
+ * Much more informative stack traces when something goes wrong
56
+
57
+ Changed:
58
+
59
+ * The commandline option parser is now a lot more reliable
60
+ * atom_feed now takes optional :content_proc, :excerpt_proc and :articles
61
+ parameters
62
+ * The compile command show non-written items (those with skip_output: true)
63
+ * The compile command compiles everything by default
64
+ * Added --only-outdated option to compile only outdated pages
65
+
66
+ Removed:
67
+
68
+ * deprecated extension-based code
69
+
70
+ == 2.1.6
71
+
72
+ * The FilesystemCombined data source now supports empty metadata sections
73
+ * The RDoc filter now works for both RDoc 1.x and 2.x
74
+ * The autocompiler now serves a 500 when an exception occurs outside
75
+ compilation
76
+ * The autocompiler no longer serves index files when the request path does not
77
+ end with a slash
78
+ * The autocompiler now always serves asset content correctly
79
+
80
+ == 2.1.5
81
+
82
+ * Added Ruby 1.9 compatibility
83
+ * The Filesystem and FilesystemCombined data sources now preserve custom
84
+ extensions
85
+
86
+ == 2.1.4
87
+
88
+ * Fixed an issue where the autocompiler in Windows would serve broken assets
89
+
90
+ == 2.1.3
91
+
92
+ * The Haml and Sass filters now correctly take their options from assets
93
+ * Autocompiler now serves index files instead of 404s
94
+ * Layouts named "index" are now handled correctly
95
+ * filesystem_combined now properly handles assets
96
+
97
+ == 2.1.2
98
+
99
+ * Autocompiler now compiles assets as well
100
+ * Sass filter now takes options (just like the Haml filter)
101
+ * Haml/Sass options are now taken from the page *rep* instead of the page
102
+
103
+ == 2.1.1
104
+
105
+ * Fixed issue which would cause files not to be required in the right order
106
+
107
+ == 2.1
108
+
109
+ This is only a short summary of all changes in 2.1. For details, see the nanoc
110
+ web site at <http://nanoc.stoneship.org/> -- especially the blog and the
111
+ updated manual will be useful.
112
+
113
+ New:
114
+
115
+ * New filters: RDiscount, Maruku, Erubis
116
+ * A better commandline frontend
117
+ * A new filesystem data source named "filesystem_combined"
118
+ * Routers, which decide where compiled pages should be written to
119
+ * Page/layout mtimes can now be retrieved through page.mtime/layout.mtime
120
+
121
+ Changed:
122
+
123
+ * Already compiled pages will no longer be re-compiled unless outdated
124
+ * Layout processors and filters have been merged
125
+ * Layouts no longer rely on file extensions to determine the layout processor
126
+ * Greatly improved source code documentation
127
+ * Greatly improved unit test suite
128
+
129
+ Removed:
130
+
131
+ * Several filters have been removed and replaced by newer filters:
132
+ * `eruby`: use `erb` or `erubis` instead
133
+ * `markdown`: use `bluecloth`, `rdiscount` or `maruku` instead
134
+ * `textile`: use `redcloth` instead
135
+
136
+ == 2.0.4
137
+
138
+ * Fixed default.rb's `html_escape`
139
+ * Updated Haml filter and layout processor so that @page, @pages and @config
140
+ are now available as instance variables instead of local variables
141
+
142
+ == 2.0.3
143
+
144
+ * The autocompiler now honors custom paths
145
+ * The autocompiler now attempts to serve pages with the most appropriate MIME
146
+ type, instead of always serving everything as "text/html"
147
+
148
+ == 2.0.2
149
+
150
+ * nanoc now requires Ruby 1.8.5 instead of 1.8.6
151
+
152
+ == 2.0.1
153
+
154
+ * Fixed a "too many open files" error that could appear during (auto)compiling
155
+
156
+ == 2.0
157
+
158
+ New:
159
+
160
+ * Support for custom layout processors
161
+ * Support for custom data sources
162
+ * Database data source
163
+ * Auto-compiler
164
+ * Pages have `parent` and `children`
165
+
166
+ Changed:
167
+
168
+ * The source has been restructured and cleaned up a great deal
169
+ * Filters are defined in a different way now
170
+ * The 'eruby' filter now uses ERB instead of Erubis
171
+
172
+ Removed:
173
+
174
+ * The `filters` property; use `filters_pre` instead
175
+ * Support for Liquid
176
+
177
+ == 1.6.2
178
+
179
+ * Fixed an issue which prevented the content capturing plugin from working
180
+
181
+ == 1.6.1
182
+
183
+ * Removed a stray debug message
184
+
185
+ == 1.6
186
+
187
+ * Added support for post-layout filters
188
+ * Added support for getting a File object for the page, so you can now e.g.
189
+ easily get the modification time for a given page (`@page.file.mtime`)
190
+ * Cleaned up the source code a lot
191
+ * Removed deprecated asset-copying functionality
192
+
193
+ == 1.5
194
+
195
+ * Added support for custom filters
196
+ * Improved Liquid support -- Liquid is now a first-class nanoc citizen
197
+ * Deprecated assets -- use something like rsync instead
198
+ * Added eruby_engine option, which can be 'erb' or 'erubis'
199
+
200
+ == 1.4
201
+
202
+ * nanoc now supports ERB (as well as Erubis); Erubis no longer is a dependency
203
+ * meta.yaml can now have haml_options property, which is passed to Haml
204
+ * Pages can now have a 'filename' property, which defaults to 'index' [Dennis
205
+ Sutch]
206
+ * Pages now know in what order they should be compiled, eliminating the need
207
+ for custom page ordering [Dennis Sutch]
208
+
209
+ == 1.3.1
210
+
211
+ * The contents of the 'assets' directory are now copied into the output
212
+ directory specified in 'config.yaml'
213
+
214
+ == 1.3
215
+
216
+ * The @pages array now also contains uncompiled pages
217
+ * Pages with 'skip_output' set to true will not be outputted
218
+ * Added new filters
219
+ * Textile/RedCloth
220
+ * Sass
221
+ * nanoc now warns before overwriting in create_site, create_page and
222
+ create_template (but not in compile)
223
+
224
+ == 1.2
225
+
226
+ * Sites now have an 'assets' directory, whose contents are copied to the
227
+ 'output' directory when compiling [Soryu]
228
+ * Added support for non-eRuby layouts (Markaby, Haml, Liquid, ...)
229
+ * Added more filters (Markaby, Haml, Liquid, RDoc [Dmitry Bilunov])
230
+ * Improved error reporting
231
+ * Accessing page attributes using instance variables, and not through @page,
232
+ is no longer possible
233
+ * Page attributes can now be accessed using dot notation, i.e. @page.title as
234
+ well as @page[:title]
235
+
236
+ == 1.1.3
237
+
238
+ * Fixed bug which would cause layoutless pages to be outputted incorrectly
239
+
240
+ == 1.1.2
241
+
242
+ * Backup files (files ending with a “~”) are now ignored
243
+ * Fixed bug which would cause subpages not to be generated correctly
244
+
245
+ == 1.1
246
+
247
+ * Added support for nested layouts
248
+ * Added coloured logging
249
+ * @page now hold the page that is currently being processed
250
+ * Index files are now called “content” files and are now named after the
251
+ directory they are in [Colin Barrett]
252
+ * It is now possible to access @page in the page’s content file
253
+
254
+ == 1.0.1
255
+
256
+ * Fixed a bug which would cause a “no such template” error to be displayed
257
+ when the template existed but compiling it would raise an exception
258
+ * Fixed bug which would cause pages not to be sorted by order before compiling
259
+
260
+ == 1.0
261
+
262
+ * Initial release
data/README.rdoc ADDED
@@ -0,0 +1,80 @@
1
+ = nanoc 3
2
+
3
+ nanoc is a simple but very flexible static site generator written in Ruby.
4
+ It operates on local files, and therefore does not run on the server. nanoc
5
+ "compiles" the local source files into HTML (usually), by evaluating eRuby,
6
+ Markdown, etc.
7
+
8
+ == Documentation
9
+
10
+ nanoc3's web site, which can be found at http://nanoc.stoneship.org, contains a
11
+ few useful resources to help you get started with nanoc:
12
+
13
+ * The tutorial at http://nanoc.stoneship.org/help/tutorial
14
+ * The manual at http://nanoc.stoneship.org/help/manual
15
+
16
+ It is probably also worth checking out and perhaps subscribing to the
17
+ discussion groups:
18
+
19
+ * The discussion group in English at http://groups.google.com/group/nanoc
20
+ * The discussion group in Spanish at http://groups.google.com/group/nanoc-es
21
+
22
+ === Source Code Documentation
23
+
24
+ The source code is structured in a few directories:
25
+
26
+ * *bin* contains the commandline tool aptly named +nanoc+
27
+ * *lib*
28
+ * *nanoc*
29
+ * *base* contains the bare essentials necessary for nanoc to function
30
+ * *cli* contains the commandline interface
31
+ * *data_sources* contains the standard data sources (Nanoc3::DataSource
32
+ subclasses), such as the filesystem data source
33
+ * *helpers* contains helpers, which provide functionality some sites
34
+ may find useful, such as the blogging and tagging helpers
35
+ * *extra* contains stuff that is not needed by nanoc itself, but which may
36
+ be used by helpers, data sources, filters or VCSes.
37
+ * *filters* contains the standard filters (Nanoc3::Filter subclasses) such
38
+ as ERB, Markdown, Haml, ...
39
+ * *test* contains testing code, structured in the same way as lib/nanoc
40
+
41
+ The namespaces (modules) are organised like this:
42
+
43
+ * *Nanoc* is the namespace for everything nanoc-related (obviously). The
44
+ classes in 'lib/nanoc3/base' are part of this module (not Nanoc3::Base which
45
+ does not exist)
46
+ * *CLI* containing everything related to the commandline tool.
47
+ * *DataSources* contains the data sources
48
+ * *Helpers* contains the helpers
49
+ * *Extra* contains useful stuff not needed by nanoc itself
50
+ * *Filters* contains the (textual) filters
51
+
52
+ The central class in nanoc is Nanoc3::Site, so you should start there if you
53
+ want to explore nanoc from a technical perspective.
54
+
55
+ == Dependencies
56
+
57
+ nanoc itself can be used without installing any dependencies. Some components, however, do have dependencies:
58
+
59
+ autocompiler:: +mime-types+, +rack+
60
+ documentation generation:: +rdoc+ (2.4 or newer), +yardoc+
61
+ packaging:: +rubygems+ (1.3 or newer)
62
+
63
+ You may need to manually install the rdoc gem and update the rubygems installation.
64
+
65
+ == Contributors
66
+
67
+ (In alphabetical order)
68
+
69
+ * Christian Plessl
70
+ * Colin Barrett
71
+ * Dmitry Bilunov
72
+ * Šime Ramov
73
+ * "Soryu"
74
+ * Dennis Sutch
75
+
76
+ Special thanks to Ale Muñoz.
77
+
78
+ == Contact
79
+
80
+ You can reach me at <denis.defreyne@stoneship.org>.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ # Load nanoc
4
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/lib'))
5
+ require 'nanoc3'
6
+
7
+ # Load tasks
8
+ Dir.glob('tasks/**/*.rake').each { |r| Rake.application.add_import r }
9
+
10
+ # Set default talk
11
+ task :default => [ :fetch_dependencies, :test ]
data/bin/nanoc3 ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ # Add lib to load path
5
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
6
+
7
+ # Load nanoc
8
+ require 'nanoc3'
9
+ require 'nanoc3/cli'
10
+
11
+ # Load custom code that can't be load later
12
+ Dir['lib/commands/*.rb'].sort.each { |f| require f }
13
+ Dir['lib/data_sources/*.rb'].sort.each { |f| require f }
14
+
15
+ # Run base
16
+ Nanoc3::CLI::Base.shared_base.run(ARGV)
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc3
4
+
5
+ # Nanoc3::CodeSnippet represent a piece of custom code of a nanoc site. It
6
+ # contains the textual source code as well as a mtime, which is used to
7
+ # speed up site compilation.
8
+ class CodeSnippet
9
+
10
+ # The Nanoc3::Site this code snippet belongs to.
11
+ attr_accessor :site
12
+
13
+ # A string containing the actual code in this code snippet.
14
+ attr_reader :data
15
+
16
+ # The filename corresponding to this code snippet.
17
+ attr_reader :filename
18
+
19
+ # The time where this code snippet was last modified.
20
+ attr_reader :mtime
21
+
22
+ # Creates a new code snippet.
23
+ #
24
+ # +data+:: The raw source code which will be executed before compilation.
25
+ #
26
+ # +filename+:: The filename corresponding to this code snippet.
27
+ #
28
+ # +mtime+:: The time when the code was last modified (can be nil).
29
+ def initialize(data, filename, mtime=nil)
30
+ @data = data
31
+ @filename = filename
32
+ @mtime = mtime
33
+ end
34
+
35
+ # Loads the code by executing it.
36
+ def load
37
+ eval(@data, TOPLEVEL_BINDING, @filename)
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,225 @@
1
+ # encoding: utf-8
2
+
3
+ module Nanoc3
4
+
5
+ # Nanoc3::Compiler is responsible for compiling a site's item
6
+ # representations.
7
+ class Compiler
8
+
9
+ # The compilation stack. When the compiler begins compiling a rep or a
10
+ # layout, it will be placed on the stack; when it is done compiling the
11
+ # rep or layout, it will be removed from the stack.
12
+ attr_reader :stack
13
+
14
+ # The list of compilation rules that will be used to compile items. This
15
+ # array will be filled by Nanoc3::Site#load_data.
16
+ attr_reader :item_compilation_rules
17
+
18
+ # The list of routing rules that will be used to give all items a path.
19
+ # This array will be filled by Nanoc3::Site#load_data.
20
+ attr_reader :item_routing_rules
21
+
22
+ # The hash containing layout-to-filter mapping rules.
23
+ attr_reader :layout_filter_mapping
24
+
25
+ # Creates a new compiler for the given site.
26
+ def initialize(site)
27
+ @site = site
28
+
29
+ @stack = []
30
+
31
+ @item_compilation_rules = []
32
+ @item_routing_rules = []
33
+ @layout_filter_mapping = {}
34
+ end
35
+
36
+ # Compiles (part of) the site and writes out the compiled item
37
+ # representations.
38
+ #
39
+ # +items+:: The items that should be compiled, along with their
40
+ # dependencies. Pass +nil+ if the entire site should be
41
+ # compiled.
42
+ #
43
+ # This method also accepts a few optional parameters:
44
+ #
45
+ # +:force+:: true if the rep should be compiled even if it is not
46
+ # outdated, false if not. Defaults to false.
47
+ def run(item=nil, params={})
48
+ # Create output directory if necessary
49
+ FileUtils.mkdir_p(@site.config[:output_dir])
50
+
51
+ # Load dependencies
52
+ dependency_tracker.load_graph
53
+ print_dependency_graph if $DEBUG
54
+
55
+ # Get items and reps to compile
56
+ if item
57
+ items = [ item ] + dependency_tracker.all_inverse_dependencies_for(item)
58
+ items.uniq!
59
+ else
60
+ items = @site.items
61
+ end
62
+ reps = items.map { |i| i.reps }.flatten
63
+
64
+ # Prepare dependencies
65
+ mark_outdated_items(reps, params.has_key?(:force) && params[:force])
66
+ forget_dependencies_if_outdated(items)
67
+
68
+ # Compile reps
69
+ dependency_tracker.start
70
+ compile_reps(reps)
71
+ dependency_tracker.stop
72
+
73
+ # Store dependencies
74
+ dependency_tracker.store_graph
75
+ end
76
+
77
+ # Returns the first matching compilation rule for the given rep.
78
+ def compilation_rule_for(rep)
79
+ @item_compilation_rules.find do |rule|
80
+ rule.applicable_to?(rep.item) && rule.rep_name == rep.name
81
+ end
82
+ end
83
+
84
+ # Returns the first matching routing rule for the given rep.
85
+ def routing_rule_for(rep)
86
+ @item_routing_rules.find do |rule|
87
+ rule.applicable_to?(rep.item) && rule.rep_name == rep.name
88
+ end
89
+ end
90
+
91
+ # Returns a tuple containing the filter name and the filter arguments for
92
+ # the given layout.
93
+ def filter_for_layout(layout)
94
+ @layout_filter_mapping.each_pair do |layout_identifier, filter_name_and_args|
95
+ return filter_name_and_args if layout.identifier =~ layout_identifier
96
+ end
97
+ nil
98
+ end
99
+
100
+ private
101
+
102
+ # Compiles all item representations in the site.
103
+ def compile_reps(reps)
104
+ active_reps, skipped_reps = reps.partition { |rep| rep.outdated? || rep.item.dependencies_outdated? }
105
+ inactive_reps = []
106
+ compiled_reps = []
107
+
108
+ # Repeat as long as something is successfully compiled...
109
+ changed = true
110
+ until !changed
111
+ changed = false
112
+
113
+ # Attempt to compile all active reps
114
+ until active_reps.empty?
115
+ @stack.clear
116
+ begin
117
+ rep = active_reps.shift
118
+ puts "*** Attempting to compile #{rep.inspect}" if $DEBUG
119
+
120
+ @stack.push(rep)
121
+ compile_rep(rep)
122
+ rescue Nanoc3::Errors::UnmetDependency => e
123
+ puts "*** Attempt failed due to unmet dependency on #{e.rep.inspect}" if $DEBUG
124
+
125
+ # Save rep to compile it later
126
+ inactive_reps << rep
127
+
128
+ # Add dependency to list of items to compile
129
+ unless active_reps.include?(e.rep) || inactive_reps.include?(e.rep)
130
+ changed = true
131
+ skipped_reps.delete(e.rep)
132
+ inactive_reps.unshift(e.rep)
133
+ end
134
+ else
135
+ puts "*** Attempt succeeded" if $DEBUG
136
+
137
+ changed = true
138
+ compiled_reps << rep
139
+ end
140
+ puts if $DEBUG
141
+ end
142
+
143
+ # Retry
144
+ puts "*** No active reps left; activating all (#{inactive_reps.size}) inactive reps" if $DEBUG
145
+ puts if $DEBUG
146
+ active_reps = inactive_reps
147
+ inactive_reps = []
148
+ end
149
+
150
+ # Notify skipped reps
151
+ skipped_reps.each do |rep|
152
+ Nanoc3::NotificationCenter.post(:compilation_started, rep)
153
+ Nanoc3::NotificationCenter.post(:compilation_ended, rep)
154
+ end
155
+
156
+ # Raise error if some active but non-compileable reps are left
157
+ if !active_reps.empty?
158
+ raise Nanoc3::Errors::RecursiveCompilation.new(active_reps)
159
+ end
160
+ end
161
+
162
+ # Compiles the given item representation.
163
+ #
164
+ # This method should not be called directly; please use
165
+ # Nanoc3::Compiler#run instead, and pass this item representation's item as
166
+ # its first argument.
167
+ #
168
+ # +rep+:: The rep that is to be compiled.
169
+ def compile_rep(rep)
170
+ # Start
171
+ Nanoc3::NotificationCenter.post(:compilation_started, rep)
172
+ Nanoc3::NotificationCenter.post(:visit_started, rep.item)
173
+
174
+ # Apply matching rule
175
+ compilation_rule_for(rep).apply_to(rep)
176
+ rep.compiled = true
177
+
178
+ # Write if rep is routed
179
+ rep.write unless rep.raw_path.nil?
180
+
181
+ # Stop
182
+ Nanoc3::NotificationCenter.post(:visit_ended, rep.item)
183
+ Nanoc3::NotificationCenter.post(:compilation_ended, rep)
184
+ end
185
+
186
+ # Returns the dependency tracker for this site.
187
+ def dependency_tracker
188
+ @dependency_tracker ||= Nanoc3::DependencyTracker.new(@site.items)
189
+ end
190
+
191
+ # Marks the necessary items as outdated.
192
+ def mark_outdated_items(reps, force)
193
+ if force
194
+ reps.each { |r| r.force_outdated = true }
195
+ else
196
+ dependency_tracker.mark_outdated_items
197
+ end
198
+ end
199
+
200
+ # Clears the list of dependencies for items that will be recompiled.
201
+ def forget_dependencies_if_outdated(items)
202
+ items.each do |i|
203
+ if i.outdated? || i.dependencies_outdated?
204
+ dependency_tracker.forget_dependencies_for(i)
205
+ end
206
+ end
207
+ end
208
+
209
+ # Prints the dependency graph.
210
+ def print_dependency_graph
211
+ graph = dependency_tracker.instance_eval { @graph }
212
+ puts "DEPENDENCY GRAPH:"
213
+ graph.each_pair do |key, values|
214
+ puts "#{key.inspect} depends on:"
215
+ values.each do |value|
216
+ puts " #{value.inspect}"
217
+ end
218
+ puts " (nothing!)" if values.empty?
219
+ puts
220
+ end
221
+ end
222
+
223
+ end
224
+
225
+ end