nanoc3 3.0.0

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