nanoc 4.0.0rc1 → 4.0.0rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -1
- data/Gemfile.lock +21 -27
- data/NEWS.md +17 -1
- data/README.md +6 -6
- data/bin/nanoc +1 -1
- data/lib/nanoc.rb +3 -3
- data/lib/nanoc/base/compilation/compiler.rb +17 -2
- data/lib/nanoc/base/entities/content.rb +1 -1
- data/lib/nanoc/base/error.rb +1 -1
- data/lib/nanoc/base/errors.rb +3 -3
- data/lib/nanoc/base/source_data/code_snippet.rb +2 -2
- data/lib/nanoc/cli.rb +2 -2
- data/lib/nanoc/cli/command_runner.rb +3 -3
- data/lib/nanoc/cli/commands/create-site.rb +12 -12
- data/lib/nanoc/cli/commands/nanoc.rb +2 -2
- data/lib/nanoc/cli/commands/prune.rb +4 -4
- data/lib/nanoc/cli/commands/shell.rb +2 -2
- data/lib/nanoc/cli/commands/show-plugins.rb +1 -1
- data/lib/nanoc/cli/commands/view.rb +0 -1
- data/lib/nanoc/cli/error_handler.rb +1 -1
- data/lib/nanoc/data_sources/filesystem.rb +14 -0
- data/lib/nanoc/data_sources/filesystem_unified.rb +1 -1
- data/lib/nanoc/extra/checking/runner.rb +1 -1
- data/lib/nanoc/extra/jruby_nokogiri_warner.rb +3 -3
- data/lib/nanoc/extra/pruner.rb +2 -2
- data/lib/nanoc/filters/erubis.rb +1 -1
- data/lib/nanoc/filters/slim.rb +2 -2
- data/lib/nanoc/helpers/capturing.rb +1 -1
- data/lib/nanoc/version.rb +2 -2
- data/nanoc.gemspec +1 -1
- data/test/base/test_compiler.rb +29 -2
- data/test/data_sources/test_filesystem.rb +27 -0
- metadata +4 -5
- data/TODO.md +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce4a238700e7502d74064d9e013beb617db329ec
|
4
|
+
data.tar.gz: 89e4fd37145ee9fad99eb7f3675cc2bba2205d81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d62477b536a1ebee8555c3e025eeed536a355bd11c2caa1b1fd7865696f899f0857c10eb2c12224f884541e3a16bb67e75e4d87f96f272ec68f18b2f1a6ae0b
|
7
|
+
data.tar.gz: 2d5e7a0dd2238702dd44df29e66fc5c81abed4a48f752066a55f03e300fecc702a877c4a4cbeb47e1bf59b0150a278842ce0cc617826237f8098f8749d311eaa
|
data/CONTRIBUTING.md
CHANGED
@@ -4,7 +4,7 @@ Contributing
|
|
4
4
|
Reporting bugs
|
5
5
|
--------------
|
6
6
|
|
7
|
-
If you find a bug in
|
7
|
+
If you find a bug in Nanoc, you should report it! Some information that you should include in your bug report is the Nanoc version (`nanoc --version`) and, if relevant, the crash log (`crash.log`).
|
8
8
|
|
9
9
|
For details, check the [*bug reporting* section of the development guide](http://nanoc.ws/development/#reporting-bugs).
|
10
10
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nanoc (4.0.
|
4
|
+
nanoc (4.0.0rc2)
|
5
5
|
cri (~> 2.3)
|
6
6
|
|
7
7
|
GEM
|
@@ -17,8 +17,6 @@ GEM
|
|
17
17
|
parser (>= 2.2.0.pre.3, < 3.0)
|
18
18
|
bluecloth (2.2.0)
|
19
19
|
builder (3.2.2)
|
20
|
-
celluloid (0.16.0)
|
21
|
-
timers (~> 4.0.0)
|
22
20
|
chunky_png (1.3.4)
|
23
21
|
coderay (1.1.0)
|
24
22
|
coffee-script (2.4.1)
|
@@ -31,7 +29,7 @@ GEM
|
|
31
29
|
chunky_png (~> 1.2)
|
32
30
|
fssm (>= 0.2.7)
|
33
31
|
sass (~> 3.2.19)
|
34
|
-
coveralls (0.8.
|
32
|
+
coveralls (0.8.2)
|
35
33
|
json (~> 1.8)
|
36
34
|
rest-client (>= 1.6.8, < 2)
|
37
35
|
simplecov (~> 0.10.0)
|
@@ -48,15 +46,15 @@ GEM
|
|
48
46
|
erubis (2.7.0)
|
49
47
|
excon (0.45.3)
|
50
48
|
execjs (2.5.2)
|
51
|
-
ffi (1.9.
|
49
|
+
ffi (1.9.10)
|
52
50
|
fission (0.5.0)
|
53
51
|
CFPropertyList (~> 2.2)
|
54
|
-
fog (1.
|
52
|
+
fog (1.32.0)
|
55
53
|
fog-atmos
|
56
|
-
fog-aws (
|
54
|
+
fog-aws (>= 0.6.0)
|
57
55
|
fog-brightbox (~> 0.4)
|
58
|
-
fog-core (~> 1.
|
59
|
-
fog-ecloud
|
56
|
+
fog-core (~> 1.32)
|
57
|
+
fog-ecloud (= 0.1.1)
|
60
58
|
fog-google (>= 0.0.2)
|
61
59
|
fog-json
|
62
60
|
fog-local
|
@@ -77,26 +75,26 @@ GEM
|
|
77
75
|
fog-atmos (0.1.0)
|
78
76
|
fog-core
|
79
77
|
fog-xml
|
80
|
-
fog-aws (0.
|
78
|
+
fog-aws (0.6.0)
|
81
79
|
fog-core (~> 1.27)
|
82
80
|
fog-json (~> 1.0)
|
83
81
|
fog-xml (~> 0.1)
|
84
82
|
ipaddress (~> 0.8)
|
85
|
-
fog-brightbox (0.7.
|
83
|
+
fog-brightbox (0.7.2)
|
86
84
|
fog-core (~> 1.22)
|
87
85
|
fog-json
|
88
86
|
inflecto (~> 0.0.2)
|
89
|
-
fog-core (1.
|
87
|
+
fog-core (1.32.0)
|
90
88
|
builder
|
91
89
|
excon (~> 0.45)
|
92
90
|
formatador (~> 0.2)
|
93
91
|
mime-types
|
94
92
|
net-scp (~> 1.1)
|
95
93
|
net-ssh (>= 2.1.3)
|
96
|
-
fog-ecloud (0.1.
|
94
|
+
fog-ecloud (0.1.1)
|
97
95
|
fog-core
|
98
96
|
fog-xml
|
99
|
-
fog-google (0.0.
|
97
|
+
fog-google (0.0.6)
|
100
98
|
fog-core
|
101
99
|
fog-json
|
102
100
|
fog-xml
|
@@ -127,7 +125,7 @@ GEM
|
|
127
125
|
fog-serverlove (0.1.2)
|
128
126
|
fog-core
|
129
127
|
fog-json
|
130
|
-
fog-softlayer (0.4.
|
128
|
+
fog-softlayer (0.4.7)
|
131
129
|
fog-core
|
132
130
|
fog-json
|
133
131
|
fog-storm_on_demand (0.1.1)
|
@@ -153,7 +151,6 @@ GEM
|
|
153
151
|
handlebars-source (~> 3.0.0)
|
154
152
|
therubyracer (~> 0.12.1)
|
155
153
|
handlebars-source (3.0.3)
|
156
|
-
hitimes (1.2.2)
|
157
154
|
http-cookie (1.0.2)
|
158
155
|
domain_name (~> 0.5)
|
159
156
|
inflecto (0.0.2)
|
@@ -162,9 +159,8 @@ GEM
|
|
162
159
|
kramdown (1.7.0)
|
163
160
|
less (2.6.0)
|
164
161
|
commonjs (~> 0.2.7)
|
165
|
-
libv8 (3.16.14.
|
166
|
-
listen (
|
167
|
-
celluloid (~> 0.16.0)
|
162
|
+
libv8 (3.16.14.11)
|
163
|
+
listen (3.0.1)
|
168
164
|
rb-fsevent (>= 0.9.3)
|
169
165
|
rb-inotify (>= 0.9)
|
170
166
|
markaby (0.8.0)
|
@@ -178,7 +174,7 @@ GEM
|
|
178
174
|
mocha (1.1.0)
|
179
175
|
metaclass (~> 0.0.1)
|
180
176
|
multi_json (1.11.1)
|
181
|
-
mustache (1.0.
|
177
|
+
mustache (1.0.2)
|
182
178
|
net-scp (1.2.1)
|
183
179
|
net-ssh (>= 2.6.5)
|
184
180
|
net-ssh (2.9.2)
|
@@ -186,7 +182,7 @@ GEM
|
|
186
182
|
nokogiri (1.6.6.2)
|
187
183
|
mini_portile (~> 0.6.0)
|
188
184
|
pandoc-ruby (1.0.0)
|
189
|
-
parser (2.2.2.
|
185
|
+
parser (2.2.2.6)
|
190
186
|
ast (>= 1.1, < 3.0)
|
191
187
|
posix-spawn (0.3.11)
|
192
188
|
powerpack (0.1.1)
|
@@ -206,7 +202,7 @@ GEM
|
|
206
202
|
ffi (>= 0.5.0)
|
207
203
|
rdiscount (2.1.8)
|
208
204
|
rdoc (4.2.0)
|
209
|
-
redcarpet (3.3.
|
205
|
+
redcarpet (3.3.2)
|
210
206
|
ref (1.0.5)
|
211
207
|
rest-client (1.8.0)
|
212
208
|
http-cookie (>= 1.0.2, < 2.0)
|
@@ -246,16 +242,14 @@ GEM
|
|
246
242
|
tilt (>= 1.3.3, < 2.1)
|
247
243
|
slop (3.6.0)
|
248
244
|
temple (0.7.6)
|
249
|
-
term-ansicolor (1.3.
|
245
|
+
term-ansicolor (1.3.2)
|
250
246
|
tins (~> 1.0)
|
251
247
|
therubyracer (0.12.2)
|
252
248
|
libv8 (~> 3.16.14.0)
|
253
249
|
ref
|
254
250
|
thor (0.19.1)
|
255
251
|
tilt (2.0.1)
|
256
|
-
|
257
|
-
hitimes
|
258
|
-
tins (1.5.2)
|
252
|
+
tins (1.5.4)
|
259
253
|
typogruby (1.0.18)
|
260
254
|
rubypants
|
261
255
|
uglifier (2.7.1)
|
@@ -328,4 +322,4 @@ DEPENDENCIES
|
|
328
322
|
yuicompressor
|
329
323
|
|
330
324
|
BUNDLED WITH
|
331
|
-
1.10.
|
325
|
+
1.10.5
|
data/NEWS.md
CHANGED
@@ -1,4 +1,20 @@
|
|
1
|
-
#
|
1
|
+
# Nanoc news
|
2
|
+
|
3
|
+
## 4.0.0rc2 (2015-07-11)
|
4
|
+
|
5
|
+
Fixes:
|
6
|
+
|
7
|
+
* Fixed broken `shell` command (#672) [Jim Mendenhall]
|
8
|
+
* Fixed absolute path check on Windows (#656)
|
9
|
+
|
10
|
+
Enhancements:
|
11
|
+
|
12
|
+
* Made Nanoc error when multiple items have the same output path (#665, #669)
|
13
|
+
* Improved error message for non-hash frontmatter (#670, #673)
|
14
|
+
|
15
|
+
Changes:
|
16
|
+
|
17
|
+
* nanoc is now called Nanoc
|
2
18
|
|
3
19
|
## 4.0.0rc1 (2015-06-21)
|
4
20
|
|
data/README.md
CHANGED
@@ -3,13 +3,13 @@
|
|
3
3
|
[![Code Climate](http://img.shields.io/codeclimate/github/nanoc/nanoc.svg)](https://codeclimate.com/github/nanoc/nanoc)
|
4
4
|
[![Code Coverage](http://img.shields.io/coveralls/nanoc/nanoc.svg)](https://coveralls.io/r/nanoc/nanoc)
|
5
5
|
|
6
|
-
![
|
6
|
+
![Nanoc logo](https://avatars1.githubusercontent.com/u/3260163?s=140)
|
7
7
|
|
8
|
-
#
|
8
|
+
# Nanoc
|
9
9
|
|
10
|
-
|
10
|
+
Nanoc is a flexible static-site generator written in Ruby. See the [Nanoc web site](http://nanoc.ws) for more information.
|
11
11
|
|
12
|
-
**Please take a moment and [donate](http://pledgie.com/campaigns/9282) to
|
12
|
+
**Please take a moment and [donate](http://pledgie.com/campaigns/9282) to Nanoc. A lot of time has gone into developing Nanoc, and I would like to keep it going. Your support will ensure that Nanoc will continue to improve.**
|
13
13
|
|
14
14
|
## Contributing
|
15
15
|
|
@@ -17,6 +17,6 @@ Contributions are greatly appreciated! Consult the [Development guidelines](http
|
|
17
17
|
|
18
18
|
### Contributors
|
19
19
|
|
20
|
-
Many thanks to everyone who has contributed to
|
20
|
+
Many thanks to everyone who has contributed to Nanoc in one way or another:
|
21
21
|
|
22
|
-
Ale Muñoz, Alexander Mankuta, Arnau Siches, Ben Armston, Bil Bas, Brian Candler, Bruno Dufour, Chris Eppstein, Christian Plessl, Colin Barrett, Damien Pollet, Dan Callahan, Daniel Hofstetter, Daniel Mendler, Daniel Wollschlaeger, David Alexander, David Everitt, Dennis Sutch, Devon Luke Buchanan, Dmitry Bilunov, Eric Sunshine, Erik Hollensbe, Fabian Buch, Felix Hanley, Go Maeda, Gregory Pakosz, Grégory Karékinian, Guilherme Garnier, Jack Chu, Jake Benilov, Jasper Van der Jeugt, Jeff Forcier, John Nishinaga, Justin Clift, Justin Hileman, Kevin Lynagh, Louis T., Mathias Bynens, Matt Keveney, Matthew Frazier, Matthias Beyer, Matthias Reitinger, Matthias Vallentin, Michal Cichra, Nelson Chen, Nicky Peeters, Nikhil Marathe, Oliver Byford, Peter Aronoff, Raphael von der Grün, Remko Tronçon, Riley Goodside, Ruben Verborgh, Scott Vokes, Simon South, Spencer Whitt, Stanley Rost, Starr Horne, Stefan Bühler, Stuart Montgomery, Takashi Uchibe, Toon Willems, Tuomas Kareinen, Ursula Kallio, Vincent Driessen, Xavier Shay, Zaiste de Grengolada, Šime Ramov
|
22
|
+
Ale Muñoz, Alexander Mankuta, Arnau Siches, Ben Armston, Bil Bas, Brian Candler, Bruno Dufour, Chris Eppstein, Christian Plessl, Colin Barrett, Damien Pollet, Dan Callahan, Daniel Hofstetter, Daniel Mendler, Daniel Wollschlaeger, David Alexander, David Everitt, Dennis Sutch, Devon Luke Buchanan, Dmitry Bilunov, Eric Sunshine, Erik Hollensbe, Fabian Buch, Felix Hanley, Go Maeda, Gregory Pakosz, Grégory Karékinian, Guilherme Garnier, Jack Chu, Jake Benilov, Jasper Van der Jeugt, Jeff Forcier, Jim Mendenhall, John Nishinaga, Justin Clift, Justin Hileman, Kevin Lynagh, Louis T., Mathias Bynens, Matt Keveney, Matthew Frazier, Matthias Beyer, Matthias Reitinger, Matthias Vallentin, Michal Cichra, Nelson Chen, Nicky Peeters, Nikhil Marathe, Oliver Byford, Peter Aronoff, Raphael von der Grün, Remko Tronçon, Riley Goodside, Ruben Verborgh, Scott Vokes, Simon South, Spencer Whitt, Stanley Rost, Starr Horne, Stefan Bühler, Stuart Montgomery, Takashi Uchibe, Toon Willems, Tuomas Kareinen, Ursula Kallio, Vincent Driessen, Xavier Shay, Zaiste de Grengolada, Šime Ramov
|
data/bin/nanoc
CHANGED
@@ -3,7 +3,7 @@ require 'nanoc'
|
|
3
3
|
require 'nanoc/cli'
|
4
4
|
|
5
5
|
if File.file?('Gemfile') && !defined?(Bundler)
|
6
|
-
warn 'A Gemfile was detected, but Bundler is not loaded. This is probably not what you want. To run
|
6
|
+
warn 'A Gemfile was detected, but Bundler is not loaded. This is probably not what you want. To run Nanoc with Bundler, use `bundle exec nanoc`.'
|
7
7
|
end
|
8
8
|
|
9
9
|
Nanoc::CLI.run(ARGV)
|
data/lib/nanoc.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Nanoc
|
2
|
-
# @return [String] A string containing information about this
|
2
|
+
# @return [String] A string containing information about this Nanoc version
|
3
3
|
# and its environment (Ruby engine and version, Rubygems version if any).
|
4
4
|
#
|
5
5
|
# @api private
|
@@ -7,7 +7,7 @@ module Nanoc
|
|
7
7
|
gem_info = defined?(Gem) ? "with RubyGems #{Gem::VERSION}" : 'without RubyGems'
|
8
8
|
engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
9
9
|
res = ''
|
10
|
-
res << "
|
10
|
+
res << "Nanoc #{Nanoc::VERSION} © 2007-2015 Denis Defreyne.\n"
|
11
11
|
res << "Running #{engine} #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) on #{RUBY_PLATFORM} #{gem_info}.\n"
|
12
12
|
res
|
13
13
|
end
|
@@ -34,7 +34,7 @@ require 'time'
|
|
34
34
|
require 'yaml'
|
35
35
|
require 'English'
|
36
36
|
|
37
|
-
# Load
|
37
|
+
# Load Nanoc
|
38
38
|
require 'nanoc/version'
|
39
39
|
require 'nanoc/base'
|
40
40
|
require 'nanoc/extra'
|
@@ -40,6 +40,12 @@ module Nanoc::Int
|
|
40
40
|
class Compiler
|
41
41
|
extend Nanoc::Int::Memoization
|
42
42
|
|
43
|
+
class IdenticalRoutesError < ::Nanoc::Error
|
44
|
+
def initialize(output_path, rep_a, rep_b)
|
45
|
+
super("The item representations #{rep_a.inspect} and #{rep_b.inspect} are both routed to #{output_path}.")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
43
49
|
# @group Accessors
|
44
50
|
|
45
51
|
# @return [Nanoc::Int::Site] The site this compiler belongs to
|
@@ -65,9 +71,9 @@ module Nanoc::Int
|
|
65
71
|
|
66
72
|
# Compiles the site and writes out the compiled item representations.
|
67
73
|
#
|
68
|
-
# Previous versions of
|
74
|
+
# Previous versions of Nanoc (< 3.2) allowed passing items to compile, and
|
69
75
|
# had a “force” option to make the compiler recompile all pages, even
|
70
|
-
# when not outdated. These arguments and options are, as of
|
76
|
+
# when not outdated. These arguments and options are, as of Nanoc 3.2, no
|
71
77
|
# longer used, and will simply be ignored when passed to {#run}.
|
72
78
|
#
|
73
79
|
# @overload run
|
@@ -215,6 +221,8 @@ module Nanoc::Int
|
|
215
221
|
#
|
216
222
|
# @api private
|
217
223
|
def route_reps
|
224
|
+
paths_to_reps = {}
|
225
|
+
|
218
226
|
reps.each do |rep|
|
219
227
|
# Find matching rules
|
220
228
|
rules = rules_collection.routing_rules_for(rep)
|
@@ -228,6 +236,13 @@ module Nanoc::Int
|
|
228
236
|
raise "The path returned for the #{rep.inspect} item representation, “#{basic_path}”, does not start with a slash. Please ensure that all routing rules return a path that starts with a slash."
|
229
237
|
end
|
230
238
|
|
239
|
+
# Check for duplicate paths
|
240
|
+
if paths_to_reps.key?(basic_path)
|
241
|
+
raise IdenticalRoutesError.new(basic_path, paths_to_reps[basic_path], rep)
|
242
|
+
else
|
243
|
+
paths_to_reps[basic_path] = rep
|
244
|
+
end
|
245
|
+
|
231
246
|
# Get raw path by prepending output directory
|
232
247
|
rep.raw_paths[snapshot] = @site.config[:output_dir] + basic_path
|
233
248
|
|
data/lib/nanoc/base/error.rb
CHANGED
data/lib/nanoc/base/errors.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module Nanoc::Int
|
2
|
-
# Module that contains all
|
2
|
+
# Module that contains all Nanoc-specific errors.
|
3
3
|
#
|
4
4
|
# @api private
|
5
5
|
module Errors
|
6
6
|
Generic = ::Nanoc::Error
|
7
7
|
|
8
|
-
# Generic trivial error. Superclass for all
|
8
|
+
# Generic trivial error. Superclass for all Nanoc-specific errors that are
|
9
9
|
# considered "trivial", i.e. errors that do not require a full crash report.
|
10
10
|
class GenericTrivial < Generic
|
11
11
|
end
|
@@ -66,7 +66,7 @@ module Nanoc::Int
|
|
66
66
|
# working directory.
|
67
67
|
class NoRulesFileFound < Generic
|
68
68
|
def initialize
|
69
|
-
super('This site does not have a rules file, which is required for
|
69
|
+
super('This site does not have a rules file, which is required for Nanoc sites.')
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Nanoc::Int
|
2
|
-
# Nanoc::Int::CodeSnippet represent a piece of custom code of a
|
2
|
+
# Nanoc::Int::CodeSnippet represent a piece of custom code of a Nanoc site.
|
3
3
|
#
|
4
4
|
# @api private
|
5
5
|
class CodeSnippet
|
@@ -20,7 +20,7 @@ module Nanoc::Int
|
|
20
20
|
#
|
21
21
|
# @param [String] filename The filename corresponding to this code snippet
|
22
22
|
#
|
23
|
-
# @param [Time, Hash] _params Extra parameters. Ignored by
|
23
|
+
# @param [Time, Hash] _params Extra parameters. Ignored by Nanoc; it is
|
24
24
|
# only included for backwards compatibility.
|
25
25
|
def initialize(data, filename, _params = nil)
|
26
26
|
@data = data
|
data/lib/nanoc/cli.rb
CHANGED
@@ -2,7 +2,7 @@ begin
|
|
2
2
|
require 'cri'
|
3
3
|
rescue LoadError => e
|
4
4
|
$stderr.puts e
|
5
|
-
$stderr.puts "If you are using a Gemfile, make sure that the Gemfile contains
|
5
|
+
$stderr.puts "If you are using a Gemfile, make sure that the Gemfile contains Nanoc ('gem \"nanoc\"')."
|
6
6
|
exit 1
|
7
7
|
end
|
8
8
|
|
@@ -42,7 +42,7 @@ module Nanoc::CLI
|
|
42
42
|
@debug = boolean
|
43
43
|
end
|
44
44
|
|
45
|
-
# Invokes the
|
45
|
+
# Invokes the Nanoc command-line tool with the given arguments.
|
46
46
|
#
|
47
47
|
# @param [Array<String>] args An array of command-line arguments
|
48
48
|
#
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Nanoc::CLI
|
2
|
-
# A command runner subclass for
|
2
|
+
# A command runner subclass for Nanoc commands that adds Nanoc-specific
|
3
3
|
# convenience methods and error handling.
|
4
4
|
#
|
5
5
|
# @api private
|
@@ -34,7 +34,7 @@ module Nanoc::CLI
|
|
34
34
|
@site = new_site
|
35
35
|
end
|
36
36
|
|
37
|
-
# @return [Boolean] true if the current working directory is a
|
37
|
+
# @return [Boolean] true if the current working directory is a Nanoc site
|
38
38
|
# directory, false otherwise
|
39
39
|
def in_site_dir?
|
40
40
|
Nanoc::Int::SiteLoader.cwd_is_nanoc_site?
|
@@ -48,7 +48,7 @@ module Nanoc::CLI
|
|
48
48
|
# @return [void]
|
49
49
|
def require_site
|
50
50
|
if site.nil?
|
51
|
-
raise ::Nanoc::Int::Errors::GenericTrivial, 'The current working directory does not seem to be a
|
51
|
+
raise ::Nanoc::Int::Errors::GenericTrivial, 'The current working directory does not seem to be a Nanoc site.'
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -18,10 +18,10 @@ module Nanoc::CLI::Commands
|
|
18
18
|
DEFAULT_CONFIG = <<EOS unless defined? DEFAULT_CONFIG
|
19
19
|
# The syntax to use for patterns in the Rules file. Can be either `"glob"`
|
20
20
|
# (default) or `"legacy"`. The former will enable glob patterns, which behave
|
21
|
-
# like Ruby’s File.fnmatch. The latter will enable
|
21
|
+
# like Ruby’s File.fnmatch. The latter will enable Nanoc 3.x-style patterns.
|
22
22
|
string_pattern_type: glob
|
23
23
|
|
24
|
-
# A list of file extensions that
|
24
|
+
# A list of file extensions that Nanoc will consider to be textual rather than
|
25
25
|
# binary. If an item with an extension not in this list is found, the file
|
26
26
|
# will be considered as binary.
|
27
27
|
text_extensions: #{array_to_yaml(Nanoc::Int::Configuration::DEFAULT_CONFIG[:text_extensions])}
|
@@ -34,7 +34,7 @@ output_dir: #{Nanoc::Int::Configuration::DEFAULT_CONFIG[:output_dir]}
|
|
34
34
|
# A list of index filenames, i.e. names of files that will be served by a web
|
35
35
|
# server when a directory is requested. Usually, index files are named
|
36
36
|
# “index.html”, but depending on the web server, this may be something else,
|
37
|
-
# such as “default.htm”. This list is used by
|
37
|
+
# such as “default.htm”. This list is used by Nanoc to generate pretty URLs.
|
38
38
|
index_filenames: #{array_to_yaml(Nanoc::Int::Configuration::DEFAULT_CONFIG[:index_filenames])}
|
39
39
|
|
40
40
|
# Whether or not to generate a diff of the compiled content when compiling a
|
@@ -43,7 +43,7 @@ index_filenames: #{array_to_yaml(Nanoc::Int::Configuration::DEFAULT_CONFIG[:inde
|
|
43
43
|
enable_output_diff: false
|
44
44
|
|
45
45
|
prune:
|
46
|
-
# Whether to automatically remove files not managed by
|
46
|
+
# Whether to automatically remove files not managed by Nanoc from the output
|
47
47
|
# directory.
|
48
48
|
auto_prune: true
|
49
49
|
|
@@ -52,7 +52,7 @@ prune:
|
|
52
52
|
# .git, .svn etc.
|
53
53
|
exclude: [ '.git', '.hg', '.svn', 'CVS' ]
|
54
54
|
|
55
|
-
# The data sources where
|
55
|
+
# The data sources where Nanoc loads its data from. This is an array of
|
56
56
|
# hashes; each array element represents a single data source. By default,
|
57
57
|
# there is only a single data source that reads data from the “content/” and
|
58
58
|
# “layout/” directories in the site directory.
|
@@ -78,7 +78,7 @@ data_sources:
|
|
78
78
|
|
79
79
|
# The kind of identifier to use for items and layouts. The default is
|
80
80
|
# “full”, meaning that identifiers include file extensions. This can also
|
81
|
-
# be “legacy”, primarily used by older
|
81
|
+
# be “legacy”, primarily used by older Nanoc sites.
|
82
82
|
identifier_type: full
|
83
83
|
|
84
84
|
# Configuration for the “check” command, which run unit tests on the site.
|
@@ -102,7 +102,7 @@ end
|
|
102
102
|
|
103
103
|
# This is an example rule that matches Markdown (.md) files, and filters them
|
104
104
|
# using the :kramdown filter. It is commented out by default, because kramdown
|
105
|
-
# is not bundled with
|
105
|
+
# is not bundled with Nanoc or Ruby.
|
106
106
|
#
|
107
107
|
#compile '/**/*.md' do
|
108
108
|
# filter :kramdown
|
@@ -132,16 +132,16 @@ EOS
|
|
132
132
|
title: Home
|
133
133
|
---
|
134
134
|
|
135
|
-
<h1>A Brand New
|
135
|
+
<h1>A Brand New Nanoc Site</h1>
|
136
136
|
|
137
|
-
<p>You’ve just created a new
|
137
|
+
<p>You’ve just created a new Nanoc site. The page you are looking at right now is the home page for your site. To get started, consider replacing this default homepage with your own customized homepage. Some pointers on how to do so:</p>
|
138
138
|
|
139
139
|
<ul>
|
140
140
|
<li><p><strong>Change this page’s content</strong> by editing the “index.html” file in the “content” directory. This is the actual page content, and therefore doesn’t include the header, sidebar or style information (those are part of the layout).</p></li>
|
141
141
|
<li><p><strong>Change the layout</strong>, which is the “default.html” file in the “layouts” directory, and create something unique (and hopefully less bland).</p></li>
|
142
142
|
</ul>
|
143
143
|
|
144
|
-
<p>If you need any help with customizing your
|
144
|
+
<p>If you need any help with customizing your Nanoc web site, be sure to check out the documentation (see sidebar), and be sure to subscribe to the discussion group (also see sidebar). Enjoy!</p>
|
145
145
|
EOS
|
146
146
|
|
147
147
|
DEFAULT_STYLESHEET = <<EOS unless defined? DEFAULT_STYLESHEET
|
@@ -253,11 +253,11 @@ EOS
|
|
253
253
|
<html lang="en">
|
254
254
|
<head>
|
255
255
|
<meta charset="utf-8">
|
256
|
-
<title>A Brand New
|
256
|
+
<title>A Brand New Nanoc Site - <%= @item[:title] %></title>
|
257
257
|
<link rel="stylesheet" href="<%= @items['/stylesheet.*'].path %>">
|
258
258
|
|
259
259
|
<!-- you don't need to keep this, but it's cool for stats! -->
|
260
|
-
<meta name="generator" content="
|
260
|
+
<meta name="generator" content="Nanoc <%= Nanoc::VERSION %>">
|
261
261
|
</head>
|
262
262
|
<body>
|
263
263
|
<div id="main">
|
@@ -1,5 +1,5 @@
|
|
1
1
|
usage 'nanoc command [options] [arguments]'
|
2
|
-
summary '
|
2
|
+
summary 'Nanoc, a static site compiler written in Ruby'
|
3
3
|
|
4
4
|
opt :l, :color, 'enable color' do
|
5
5
|
$stdout.remove_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors)
|
@@ -20,7 +20,7 @@ opt :C, :'no-color', 'disable color' do
|
|
20
20
|
$stderr.add_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors)
|
21
21
|
end
|
22
22
|
|
23
|
-
opt :V, :verbose, 'make
|
23
|
+
opt :V, :verbose, 'make output more detailed' do
|
24
24
|
Nanoc::CLI::Logger.instance.level = :low
|
25
25
|
end
|
26
26
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
usage 'prune'
|
2
|
-
summary 'remove files not managed by
|
2
|
+
summary 'remove files not managed by Nanoc from the output directory'
|
3
3
|
description <<-EOS
|
4
4
|
Find all files in the output directory that do not correspond to an item
|
5
|
-
managed by
|
5
|
+
managed by Nanoc and remove them. Since this is a hazardous operation, an
|
6
6
|
additional `--yes` flag is needed as confirmation.
|
7
7
|
|
8
8
|
Also see the `auto_prune` configuration option in `nanoc.yaml` (`config.yaml`
|
9
|
-
for older
|
9
|
+
for older Nanoc sites), which will automatically prune after compilation.
|
10
10
|
EOS
|
11
11
|
|
12
12
|
flag :y, :yes, 'confirm deletion'
|
@@ -25,7 +25,7 @@ module Nanoc::CLI::Commands
|
|
25
25
|
else
|
26
26
|
$stderr.puts 'WARNING: Since the prune command is a destructive command, it requires an additional --yes flag in order to work.'
|
27
27
|
$stderr.puts
|
28
|
-
$stderr.puts 'Please ensure that the output directory does not contain any files (such as images or stylesheets) that are necessary but are not managed by
|
28
|
+
$stderr.puts 'Please ensure that the output directory does not contain any files (such as images or stylesheets) that are necessary but are not managed by Nanoc. If you want to get a list of all files that would be removed, pass --dry-run.'
|
29
29
|
exit 1
|
30
30
|
end
|
31
31
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
usage 'shell'
|
2
|
-
summary 'open a shell on the
|
2
|
+
summary 'open a shell on the Nanoc environment'
|
3
3
|
aliases 'console'
|
4
4
|
description "
|
5
5
|
Open an IRB shell on a context that contains @items, @layouts, and @config.
|
@@ -21,7 +21,7 @@ module Nanoc::CLI::Commands
|
|
21
21
|
self.class.env_for_site(site)
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.
|
24
|
+
def self.env_for_site(site)
|
25
25
|
{
|
26
26
|
items: Nanoc::ItemCollectionView.new(site.items),
|
27
27
|
layouts: Nanoc::LayoutCollectionView.new(site.layouts),
|
@@ -3,7 +3,7 @@ aliases :info
|
|
3
3
|
usage 'show-plugins [options]'
|
4
4
|
description <<-EOS
|
5
5
|
Show a list of available plugins, including filters and data sources.
|
6
|
-
If the current directory contains a
|
6
|
+
If the current directory contains a Nanoc web site, the plugins defined in this site will be shown as well.
|
7
7
|
EOS
|
8
8
|
|
9
9
|
module Nanoc::CLI::Commands
|
@@ -297,7 +297,7 @@ module Nanoc::CLI
|
|
297
297
|
|
298
298
|
def write_issue_link(stream, _params = {})
|
299
299
|
stream.puts
|
300
|
-
stream.puts 'If you believe this is a bug in
|
300
|
+
stream.puts 'If you believe this is a bug in Nanoc, please do report it at'
|
301
301
|
stream.puts '-> https://github.com/nanoc/nanoc/issues/new <-'
|
302
302
|
stream.puts
|
303
303
|
stream.puts 'A detailed crash log has been written to ./crash.log.'
|
@@ -219,6 +219,7 @@ module Nanoc::DataSources
|
|
219
219
|
rescue Exception => e
|
220
220
|
raise "Could not parse YAML for #{meta_filename}: #{e.message}"
|
221
221
|
end
|
222
|
+
verify_meta(meta, meta_filename)
|
222
223
|
return [meta, content]
|
223
224
|
end
|
224
225
|
|
@@ -244,12 +245,25 @@ module Nanoc::DataSources
|
|
244
245
|
rescue Exception => e
|
245
246
|
raise "Could not parse YAML for #{content_filename}: #{e.message}"
|
246
247
|
end
|
248
|
+
verify_meta(meta, content_filename)
|
247
249
|
content = pieces[4]
|
248
250
|
|
249
251
|
# Done
|
250
252
|
[meta, content]
|
251
253
|
end
|
252
254
|
|
255
|
+
class InvalidMetadataError < Nanoc::Error
|
256
|
+
def initialize(filename, klass)
|
257
|
+
super("The file #{filename} has invalid metadata (expected key-value pairs, found #{klass} instead)")
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def verify_meta(meta, filename)
|
262
|
+
return if meta.is_a?(Hash)
|
263
|
+
|
264
|
+
raise InvalidMetadataError.new(filename, meta.class)
|
265
|
+
end
|
266
|
+
|
253
267
|
# Reads the content of the file with the given name and returns a string
|
254
268
|
# in UTF-8 encoding. The original encoding of the string is derived from
|
255
269
|
# the default external encoding, but this can be overridden by the
|
@@ -44,7 +44,7 @@ module Nanoc::DataSources
|
|
44
44
|
# (`allow_periods_in_identifiers` set to false)
|
45
45
|
# foo.html.erb → /foo/
|
46
46
|
#
|
47
|
-
# Note that each item must have an unique identifier.
|
47
|
+
# Note that each item must have an unique identifier. Nanoc will display an
|
48
48
|
# error if two items with the same identifier are found.
|
49
49
|
#
|
50
50
|
# Some more examples:
|
@@ -5,7 +5,7 @@ module Nanoc::Extra::Checking
|
|
5
5
|
class Runner
|
6
6
|
CHECKS_FILENAMES = ['Checks', 'Checks.rb', 'checks', 'checks.rb']
|
7
7
|
|
8
|
-
# @param [Nanoc::Int::Site] site The
|
8
|
+
# @param [Nanoc::Int::Site] site The Nanoc site this runner is for
|
9
9
|
def initialize(site)
|
10
10
|
@site = site
|
11
11
|
end
|
@@ -12,12 +12,12 @@ Note:
|
|
12
12
|
The behavior of Pure Java Nokogiri differs from the Nokogiri used on the
|
13
13
|
standard Ruby interpreter (MRI) due to differences in underlying libraries.
|
14
14
|
|
15
|
-
These sometimes problematic behavioral differences can cause
|
15
|
+
These sometimes problematic behavioral differences can cause Nanoc filters not
|
16
16
|
to function properly, if at all. If you need reliable (X)HTML and XML handling
|
17
17
|
functionality, consider not using Nokogiri on JRuby for the time being.
|
18
18
|
|
19
|
-
These issues are being worked on both from the Nokogiri and the
|
20
|
-
your Nokogiri and
|
19
|
+
These issues are being worked on both from the Nokogiri and the Nanoc side. Keep
|
20
|
+
your Nokogiri and Nanoc versions up to date!
|
21
21
|
|
22
22
|
For details, see https://github.com/nanoc/nanoc/pull/422.
|
23
23
|
--------------------------------------------------------------------------------
|
data/lib/nanoc/extra/pruner.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Nanoc::Extra
|
2
2
|
# Responsible for finding and deleting files in the site’s output directory
|
3
|
-
# that are not managed by
|
3
|
+
# that are not managed by Nanoc.
|
4
4
|
#
|
5
5
|
# @api private
|
6
6
|
class Pruner
|
@@ -18,7 +18,7 @@ module Nanoc::Extra
|
|
18
18
|
@exclude = params.fetch(:exclude) { [] }
|
19
19
|
end
|
20
20
|
|
21
|
-
# Prunes all output files not managed by
|
21
|
+
# Prunes all output files not managed by Nanoc.
|
22
22
|
#
|
23
23
|
# @return [void]
|
24
24
|
def run
|
data/lib/nanoc/filters/erubis.rb
CHANGED
@@ -4,7 +4,7 @@ module Nanoc::Filters
|
|
4
4
|
requires 'erubis'
|
5
5
|
|
6
6
|
# The same as `::Erubis::Eruby` but adds `_erbout` as an alias for the
|
7
|
-
# `_buf` variable, making it compatible with
|
7
|
+
# `_buf` variable, making it compatible with Nanoc’s helpers that rely
|
8
8
|
# on `_erbout`, such as {Nanoc::Helpers::Capturing}.
|
9
9
|
class ErubisWithErbout < ::Erubis::Eruby
|
10
10
|
include ::Erubis::ErboutEnhancer
|
data/lib/nanoc/filters/slim.rb
CHANGED
@@ -13,8 +13,8 @@ module Nanoc::Filters
|
|
13
13
|
# @return [String] The filtered content
|
14
14
|
def run(content, params = {})
|
15
15
|
params = {
|
16
|
-
disable_capture: true, # Capture managed by
|
17
|
-
buffer: '_erbout', # Force slim to output to the buffer used by
|
16
|
+
disable_capture: true, # Capture managed by Nanoc
|
17
|
+
buffer: '_erbout', # Force slim to output to the buffer used by Nanoc
|
18
18
|
}.merge params
|
19
19
|
|
20
20
|
# Create context
|
@@ -15,7 +15,7 @@ module Nanoc::Helpers
|
|
15
15
|
# @example Capturing content for a summary
|
16
16
|
#
|
17
17
|
# <% content_for :summary do %>
|
18
|
-
# <p>On this item,
|
18
|
+
# <p>On this item, Nanoc is introduced, blah blah.</p>
|
19
19
|
# <% end %>
|
20
20
|
#
|
21
21
|
# @example Showing captured content in a sidebar
|
data/lib/nanoc/version.rb
CHANGED
data/nanoc.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.version = Nanoc::VERSION
|
6
6
|
s.homepage = 'http://nanoc.ws/'
|
7
7
|
s.summary = 'A static-site generator with a focus on flexibility.'
|
8
|
-
s.description = '
|
8
|
+
s.description = 'Nanoc is a static-site generator focused on flexibility. It transforms content from a format such as Markdown or AsciiDoc into another format, usually HTML, and lays out pages consistently to retain the site’s look and feel throughout. Static sites built with Nanoc can be deployed to any web server.'
|
9
9
|
|
10
10
|
s.author = 'Denis Defreyne'
|
11
11
|
s.email = 'denis.defreyne@stoneship.org'
|
data/test/base/test_compiler.rb
CHANGED
@@ -278,6 +278,33 @@ class Nanoc::Int::CompilerTest < Nanoc::TestCase
|
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
|
+
def test_disallow_duplicate_routes
|
282
|
+
# Create site
|
283
|
+
Nanoc::CLI.run %w( create_site bar)
|
284
|
+
|
285
|
+
FileUtils.cd('bar') do
|
286
|
+
# Create routes
|
287
|
+
File.open('Rules', 'w') do |io|
|
288
|
+
io.write "compile '/**/*' do\n"
|
289
|
+
io.write "end\n"
|
290
|
+
io.write "\n"
|
291
|
+
io.write "route '/**/*' do\n"
|
292
|
+
io.write " '/index.html'\n"
|
293
|
+
io.write "end\n"
|
294
|
+
end
|
295
|
+
|
296
|
+
# Create files
|
297
|
+
File.write('content/foo.html', 'asdf')
|
298
|
+
File.write('content/bar.html', 'asdf')
|
299
|
+
|
300
|
+
# Create site
|
301
|
+
site = Nanoc::Int::SiteLoader.new.new_from_cwd
|
302
|
+
assert_raises(Nanoc::Int::Compiler::IdenticalRoutesError) do
|
303
|
+
site.compile
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
281
308
|
def test_load_should_be_idempotent
|
282
309
|
# Create site
|
283
310
|
Nanoc::CLI.run %w( create_site bar)
|
@@ -325,7 +352,7 @@ class Nanoc::Int::CompilerTest < Nanoc::TestCase
|
|
325
352
|
io.write "end\n"
|
326
353
|
io.write "\n"
|
327
354
|
io.write "route '/**/*' do\n"
|
328
|
-
io.write "
|
355
|
+
io.write " item.identifier.to_s\n"
|
329
356
|
io.write "end\n"
|
330
357
|
io.write "\n"
|
331
358
|
io.write "layout '/**/*', :erb\n"
|
@@ -601,7 +628,7 @@ class Nanoc::Int::CompilerTest < Nanoc::TestCase
|
|
601
628
|
io.write "end\n"
|
602
629
|
io.write "\n"
|
603
630
|
io.write "route '/**/*' do\n"
|
604
|
-
io.write "
|
631
|
+
io.write " item.identifier.to_s\n"
|
605
632
|
io.write "end\n"
|
606
633
|
io.write "\n"
|
607
634
|
io.write "layout '/**/*', :erb\n"
|
@@ -451,4 +451,31 @@ class Nanoc::DataSources::FilesystemTest < Nanoc::TestCase
|
|
451
451
|
assert_equal({ 'foo' => 'bar' }, result[0])
|
452
452
|
assert_equal('blah blah', result[1])
|
453
453
|
end
|
454
|
+
|
455
|
+
def test_parse_internal_bad_metadata
|
456
|
+
content = \
|
457
|
+
"---\n" \
|
458
|
+
"Hello world!\n" \
|
459
|
+
"---\n" \
|
460
|
+
"blah blah\n"
|
461
|
+
|
462
|
+
File.open('test.html', 'w') { |io| io.write(content) }
|
463
|
+
|
464
|
+
data_source = Nanoc::DataSources::FilesystemUnified.new(nil, nil, nil, nil)
|
465
|
+
|
466
|
+
assert_raises(Nanoc::DataSources::Filesystem::InvalidMetadataError) do
|
467
|
+
data_source.instance_eval { parse('test.html', nil, 'foobar') }
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
def test_parse_external_bad_metadata
|
472
|
+
File.open('test.html', 'w') { |io| io.write('blah blah') }
|
473
|
+
File.open('test.yaml', 'w') { |io| io.write('Hello world!') }
|
474
|
+
|
475
|
+
data_source = Nanoc::DataSources::FilesystemUnified.new(nil, nil, nil, nil)
|
476
|
+
|
477
|
+
assert_raises(Nanoc::DataSources::Filesystem::InvalidMetadataError) do
|
478
|
+
data_source.instance_eval { parse('test.html', 'test.yaml', 'foobar') }
|
479
|
+
end
|
480
|
+
end
|
454
481
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nanoc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.0rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cri
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '2.0'
|
47
|
-
description:
|
47
|
+
description: Nanoc is a static-site generator focused on flexibility. It transforms
|
48
48
|
content from a format such as Markdown or AsciiDoc into another format, usually
|
49
49
|
HTML, and lays out pages consistently to retain the site’s look and feel throughout.
|
50
|
-
Static sites built with
|
50
|
+
Static sites built with Nanoc can be deployed to any web server.
|
51
51
|
email: denis.defreyne@stoneship.org
|
52
52
|
executables:
|
53
53
|
- nanoc
|
@@ -66,7 +66,6 @@ files:
|
|
66
66
|
- NEWS.md
|
67
67
|
- README.md
|
68
68
|
- Rakefile
|
69
|
-
- TODO.md
|
70
69
|
- bin/nanoc
|
71
70
|
- doc/yardoc_handlers/identifier.rb
|
72
71
|
- doc/yardoc_templates/default/layout/html/footer.erb
|
data/TODO.md
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# To do
|
2
|
-
|
3
|
-
## Ideas
|
4
|
-
|
5
|
-
* binary snapshots could be possible
|
6
|
-
* binary layotus could be possible
|
7
|
-
|
8
|
-
## Removing `forget_progress`
|
9
|
-
|
10
|
-
This means not storing compiled content inside item reps anymore.
|
11
|
-
|
12
|
-
Compiler could store it, and `snapshot` could move temporary compiled content (like `:last`) and crystallize it in a more permanent store (even in-memory).
|
13
|
-
|
14
|
-
CompiledContent class, which is basically snapshot -> Content.
|