nanoc 1.5 → 1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +33 -11
- data/lib/nanoc/compiler.rb +65 -113
- data/lib/nanoc/core_ext/hash.rb +3 -1
- data/lib/nanoc/core_ext/yaml.rb +2 -0
- data/lib/nanoc/creator.rb +18 -5
- data/lib/nanoc/enhancements.rb +14 -6
- data/lib/nanoc/filters/eruby_filter.rb +2 -7
- data/lib/nanoc/filters/haml_filter.rb +3 -9
- data/lib/nanoc/filters/liquid_filter.rb +10 -14
- data/lib/nanoc/filters/markaby_filter.rb +1 -11
- data/lib/nanoc/filters/markdown_filter.rb +2 -10
- data/lib/nanoc/filters/rdoc_filter.rb +3 -7
- data/lib/nanoc/filters/sass_filter.rb +1 -6
- data/lib/nanoc/filters/smartypants_filter.rb +1 -9
- data/lib/nanoc/filters/textile_filter.rb +1 -9
- data/lib/nanoc/page.rb +113 -84
- data/lib/nanoc/page_drop.rb +18 -0
- data/lib/nanoc/page_proxy.rb +26 -0
- data/lib/nanoc.rb +5 -2
- metadata +4 -2
data/ChangeLog
CHANGED
@@ -1,11 +1,25 @@
|
|
1
|
-
|
1
|
+
nanoc Release Notes
|
2
|
+
===================
|
3
|
+
|
4
|
+
1.6
|
5
|
+
---
|
6
|
+
|
7
|
+
* Added support for post-layout filters
|
8
|
+
* Added support for getting a File object for the page, so you can now e.g.
|
9
|
+
easily get the modification time for a given page (`@page.file.mtime`).
|
10
|
+
* Cleaned up the source code a lot
|
11
|
+
* Removed deprecated asset-copying functionality
|
12
|
+
|
13
|
+
1.5
|
14
|
+
---
|
2
15
|
|
3
16
|
* Added support for custom filters
|
4
17
|
* Improved Liquid support -- Liquid is now a first-class nanoc citizen
|
5
18
|
* Deprecated assets -- use something like rsync instead
|
6
19
|
* Added eruby_engine option, which can be 'erb' or 'erubis'
|
7
20
|
|
8
|
-
|
21
|
+
1.4
|
22
|
+
---
|
9
23
|
|
10
24
|
* nanoc now supports ERB (as well as Erubis); Erubis no longer is a dependency
|
11
25
|
* meta.yaml can now have haml_options property, which is passed to Haml
|
@@ -14,12 +28,14 @@
|
|
14
28
|
* Pages now know in what order they should be compiled, eliminating the need
|
15
29
|
for custom page ordering [Dennis Sutch]
|
16
30
|
|
17
|
-
|
31
|
+
1.3.1
|
32
|
+
-----
|
18
33
|
|
19
34
|
* The contents of the 'assets' directory are now copied into the output
|
20
35
|
directory specified in 'config.yaml'
|
21
36
|
|
22
|
-
|
37
|
+
1.3
|
38
|
+
---
|
23
39
|
|
24
40
|
* The @pages array now also contains uncompiled pages
|
25
41
|
* Pages with 'skip_output' set to true will not be outputted
|
@@ -29,9 +45,10 @@
|
|
29
45
|
* nanoc now warns before overwriting in create_site, create_page and
|
30
46
|
create_template (but not in compile)
|
31
47
|
|
32
|
-
|
48
|
+
1.2
|
49
|
+
---
|
33
50
|
|
34
|
-
* Sites now have an 'assets' directory, whose contents are copied to the
|
51
|
+
* Sites now have an 'assets' directory, whose contents are copied to the
|
35
52
|
'output' directory when compiling [Soryu]
|
36
53
|
* Added support for non-eRuby layouts (Markaby, Haml, Liquid, ...)
|
37
54
|
* Added more filters (Markaby, Haml, Liquid, RDoc [Dmitry Bilunov])
|
@@ -41,16 +58,19 @@
|
|
41
58
|
* Page attributes can now be accessed using dot notation, i.e. @page.title as
|
42
59
|
well as @page[:title]
|
43
60
|
|
44
|
-
|
61
|
+
1.1.3
|
62
|
+
-----
|
45
63
|
|
46
64
|
* Fixed bug which would cause layoutless pages to be outputted incorrectly
|
47
65
|
|
48
|
-
|
66
|
+
1.1.2
|
67
|
+
-----
|
49
68
|
|
50
69
|
* Backup files (files ending with a “~”) are now ignored
|
51
70
|
* Fixed bug which would cause subpages not to be generated correctly
|
52
71
|
|
53
|
-
|
72
|
+
1.1
|
73
|
+
---
|
54
74
|
|
55
75
|
* Added support for nested layouts
|
56
76
|
* Added coloured logging
|
@@ -59,12 +79,14 @@
|
|
59
79
|
directory they are in [Colin Barrett]
|
60
80
|
* It is now possible to access @page in the page’s content file
|
61
81
|
|
62
|
-
|
82
|
+
1.0.1
|
83
|
+
-----
|
63
84
|
|
64
85
|
* Fixed a bug which would cause a “no such template” error to be displayed
|
65
86
|
when the template existed but compiling it would raise an exception
|
66
87
|
* Fixed bug which would cause pages not to be sorted by order before compiling
|
67
88
|
|
68
|
-
|
89
|
+
1.0
|
90
|
+
---
|
69
91
|
|
70
92
|
* Initial release
|
data/lib/nanoc/compiler.rb
CHANGED
@@ -23,6 +23,8 @@ module Nanoc
|
|
23
23
|
:layout => 'default'
|
24
24
|
}
|
25
25
|
|
26
|
+
attr_reader :config, :stack, :pages
|
27
|
+
|
26
28
|
def initialize
|
27
29
|
@filters = {}
|
28
30
|
end
|
@@ -38,17 +40,23 @@ module Nanoc
|
|
38
40
|
# Require all Ruby source files in lib/
|
39
41
|
Dir['lib/*.rb'].each { |f| require f }
|
40
42
|
|
41
|
-
# Create output
|
43
|
+
# Create output directory if necessary
|
42
44
|
FileUtils.mkdir_p(@config[:output_dir])
|
43
45
|
|
44
|
-
#
|
45
|
-
|
46
|
+
# Get all pages
|
47
|
+
@pages = find_uncompiled_pages
|
48
|
+
|
49
|
+
# Filter, layout, and filter again
|
50
|
+
filter(:pre)
|
51
|
+
layout
|
52
|
+
filter(:post)
|
46
53
|
|
47
|
-
#
|
48
|
-
|
49
|
-
pages = layout(compile(pages))
|
54
|
+
# Save pages
|
55
|
+
save_pages
|
50
56
|
end
|
51
57
|
|
58
|
+
# Filter management
|
59
|
+
|
52
60
|
def register_filter(name, &block)
|
53
61
|
@filters[name.to_sym] = block
|
54
62
|
end
|
@@ -57,137 +65,81 @@ module Nanoc
|
|
57
65
|
@filters[name.to_sym]
|
58
66
|
end
|
59
67
|
|
60
|
-
def config
|
61
|
-
@config
|
62
|
-
end
|
63
|
-
|
64
68
|
private
|
65
69
|
|
66
|
-
#
|
67
|
-
def path_for_page(page)
|
68
|
-
if page.attributes[:custom_path].nil?
|
69
|
-
@config[:output_dir] + page.attributes[:path] +
|
70
|
-
page.attributes[:filename] + '.' + page.attributes[:extension]
|
71
|
-
else
|
72
|
-
@config[:output_dir] + page.attributes[:custom_path]
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Returns the layout for the given page
|
77
|
-
def layout_for_page(page)
|
78
|
-
if page.attributes[:layout].nil?
|
79
|
-
{ :type => :eruby, :content => "<%= @page.content %>" }
|
80
|
-
else
|
81
|
-
filenames = Dir["layouts/#{page.attributes[:layout]}.*"]
|
82
|
-
filenames.ensure_single('layout files', page.attributes[:layout])
|
83
|
-
filename = filenames[0]
|
84
|
-
|
85
|
-
{ :type => FILE_TYPES[File.extname(filename)], :content => File.read(filename) }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def copy_assets
|
90
|
-
# Check for assets
|
91
|
-
if Dir['assets/*'].size > 0
|
92
|
-
deprecate 'Asset-copying functionality is deprecated as of nanoc 1.5,' +
|
93
|
-
'and will be removed in nanoc 1.6. Please use a Rake task that' +
|
94
|
-
'copies assets using something like rsync instead.'
|
95
|
-
end
|
96
|
-
|
97
|
-
# Remove existing assets
|
98
|
-
Dir['assets/*'].each do |f|
|
99
|
-
FileUtils.remove_entry_secure(f.sub('assets/', @config[:output_dir] + '/'), true)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Copy assets
|
103
|
-
if File.directory?('assets') and !Dir['assets/*'].empty?
|
104
|
-
FileUtils.cp_r(Dir['assets/*'], @config[:output_dir])
|
105
|
-
end
|
106
|
-
end
|
70
|
+
# Main methods
|
107
71
|
|
108
72
|
def find_uncompiled_pages
|
109
73
|
# Read all meta files
|
110
|
-
|
74
|
+
Dir['content/**/meta.yaml'].inject([]) do |pages, filename|
|
111
75
|
# Read the meta file
|
112
|
-
|
76
|
+
hash = @global_page.merge(YAML.load_file_and_clean(filename))
|
113
77
|
|
114
78
|
# Fix the path
|
115
|
-
|
79
|
+
hash[:path] = filename.sub(/^content/, '').sub('meta.yaml', '')
|
80
|
+
|
81
|
+
# Convert to a Page instance
|
82
|
+
page = Page.new(hash, self)
|
116
83
|
|
117
84
|
# Get the content filename
|
118
|
-
|
119
|
-
content_filenames.reject! { |f| f =~ /~$/ }
|
120
|
-
content_filenames += Dir["#{File.dirname(filename)}/index.*"] # fallback for nanoc 1.0
|
121
|
-
content_filenames.ensure_single('content files', File.dirname(filename))
|
122
|
-
page[:_content_filename] = content_filenames[0]
|
85
|
+
page.content_filename = content_filename_for_meta_filename(filename)
|
123
86
|
|
124
|
-
|
87
|
+
# Skip drafts
|
88
|
+
hash[:is_draft] ? pages : pages + [ page ]
|
125
89
|
end
|
126
|
-
|
127
|
-
# Ignore drafts
|
128
|
-
pages.reject! { |page| page[:is_draft] }
|
129
|
-
|
130
|
-
pages
|
131
90
|
end
|
132
91
|
|
133
|
-
def
|
134
|
-
#
|
135
|
-
|
136
|
-
pages.each { |page| given_pages << Page.new(page) }
|
92
|
+
def filter(stage)
|
93
|
+
# Reset filter stack
|
94
|
+
@stack = []
|
137
95
|
|
138
|
-
#
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
end
|
143
|
-
|
144
|
-
def layouted_page(page, pages)
|
145
|
-
# Find layout
|
146
|
-
layout = layout_for_page(page)
|
147
|
-
|
148
|
-
# Build params
|
149
|
-
if layout[:type] == :liquid
|
150
|
-
public_page = page.to_liquid
|
151
|
-
public_pages = pages.map { |p| p.to_liquid }
|
152
|
-
else
|
153
|
-
public_page = page.to_proxy
|
154
|
-
public_pages = pages.map { |p| p.to_proxy }
|
155
|
-
end
|
156
|
-
params = { :assigns => { :page => public_page, :pages => public_pages } }
|
157
|
-
params[:haml_options] = (page.attributes[:haml_options] || {}).symbolize_keys
|
158
|
-
|
159
|
-
# Layout
|
160
|
-
case layout[:type]
|
161
|
-
when :eruby
|
162
|
-
content = layout[:content].eruby(params)
|
163
|
-
when :haml
|
164
|
-
content = layout[:content].haml(params)
|
165
|
-
when :markaby
|
166
|
-
content = layout[:content].markaby(params)
|
167
|
-
when :liquid
|
168
|
-
content = layout[:content].liquid(params)
|
169
|
-
else
|
170
|
-
content = nil
|
96
|
+
# Prepare pages
|
97
|
+
@pages.each do |page|
|
98
|
+
page.stage = stage
|
99
|
+
page.is_filtered = false
|
171
100
|
end
|
172
101
|
|
173
|
-
|
102
|
+
# Filter pages
|
103
|
+
@pages.each { |page| page.filter! }
|
174
104
|
end
|
175
105
|
|
176
|
-
def layout
|
177
|
-
|
106
|
+
def layout
|
107
|
+
# For each page (ignoring drafts)
|
108
|
+
@pages.reject { |page| page.attributes[:skip_output] }.each do |page|
|
178
109
|
begin
|
179
|
-
#
|
180
|
-
|
181
|
-
|
182
|
-
# Write page with layout
|
183
|
-
FileManager.create_file(path_for_page(page)) { content }
|
110
|
+
# Layout the page
|
111
|
+
page.layout!
|
184
112
|
rescue => exception
|
185
|
-
|
186
|
-
l = page.attributes[:layout]
|
187
|
-
handle_exception(exception, "layouting page '#{p}' in layout '#{l}'")
|
113
|
+
handle_exception(exception, "layouting page '#{page.content_filename}' in layout '#{page.attributes[:layout]}'")
|
188
114
|
end
|
189
115
|
end
|
190
116
|
end
|
191
117
|
|
118
|
+
def save_pages
|
119
|
+
@pages.reject { |page| page.attributes[:skip_output] }.each do |page|
|
120
|
+
# Write page with layout
|
121
|
+
FileManager.create_file(page.path) { page.content }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Helper methods
|
126
|
+
|
127
|
+
def content_filename_for_meta_filename(filename)
|
128
|
+
# Find all files with base name of parent directory
|
129
|
+
content_filenames = Dir[filename.sub('meta.yaml', File.basename(File.dirname(filename)) + '.*')]
|
130
|
+
|
131
|
+
# Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
|
132
|
+
content_filenames += Dir["#{File.dirname(filename)}/index.*"]
|
133
|
+
|
134
|
+
# Reject backups
|
135
|
+
content_filenames.reject! { |f| f =~ /~$/ }
|
136
|
+
|
137
|
+
# Make sure there is only one content file
|
138
|
+
content_filenames.ensure_single('content files', File.dirname(filename))
|
139
|
+
|
140
|
+
# Return the first (and only one)
|
141
|
+
content_filenames[0]
|
142
|
+
end
|
143
|
+
|
192
144
|
end
|
193
145
|
end
|
data/lib/nanoc/core_ext/hash.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class Hash
|
2
|
-
# Cleans up the hash
|
2
|
+
# Cleans up the hash and returns the result. It performs the following
|
3
|
+
# operations:
|
4
|
+
#
|
3
5
|
# * Values with keys ending in _at and _on are converted into Times and
|
4
6
|
# Dates, respectively
|
5
7
|
# * All keys are converted to symbols
|
data/lib/nanoc/core_ext/yaml.rb
CHANGED
data/lib/nanoc/creator.rb
CHANGED
@@ -6,7 +6,6 @@ module Nanoc
|
|
6
6
|
ensure_nonexistant(a_sitename)
|
7
7
|
|
8
8
|
FileManager.create_dir a_sitename do
|
9
|
-
FileManager.create_dir 'assets'
|
10
9
|
FileManager.create_dir 'output'
|
11
10
|
|
12
11
|
FileManager.create_file 'config.yaml' do
|
@@ -20,7 +19,7 @@ module Nanoc
|
|
20
19
|
"# Built-in\n" +
|
21
20
|
"layout: \"default\"\n" +
|
22
21
|
"filters: []\n" +
|
23
|
-
"filename: \"index\"\n" +
|
22
|
+
"filename: \"index\"\n" +
|
24
23
|
"extension: \"html\"\n" +
|
25
24
|
"\n" +
|
26
25
|
"# Custom\n"
|
@@ -101,7 +100,7 @@ module Nanoc
|
|
101
100
|
|
102
101
|
# Sanitize page name
|
103
102
|
if a_pagename =~ /^[\/\.]+/
|
104
|
-
$stderr.puts 'ERROR: page name starts with dots and/or slashes, aborting' unless $quiet
|
103
|
+
$stderr.puts 'ERROR: page name starts with dots and/or slashes, aborting' unless $quiet
|
105
104
|
return
|
106
105
|
end
|
107
106
|
|
@@ -109,12 +108,26 @@ module Nanoc
|
|
109
108
|
template = a_params[:template] || 'default'
|
110
109
|
begin
|
111
110
|
template_meta = File.read("templates/#{template}/meta.yaml")
|
111
|
+
|
112
|
+
# Find all files
|
112
113
|
template_content_filenames = Dir["templates/#{template}/#{template}.*"]
|
114
|
+
|
115
|
+
# Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
|
113
116
|
template_content_filenames += Dir["templates/#{template}/index.*"]
|
117
|
+
|
118
|
+
# Reject backups
|
119
|
+
template_content_filenames.reject! { |f| f =~ /~$/ }
|
120
|
+
|
121
|
+
# Make sure there is only one content file
|
122
|
+
template_content_filenames.ensure_single('template files', template)
|
123
|
+
|
124
|
+
# Get the first (and only one)
|
114
125
|
template_content_filename = template_content_filenames[0]
|
126
|
+
|
115
127
|
template_index = File.read(template_content_filename)
|
116
|
-
rescue
|
117
|
-
|
128
|
+
rescue => e
|
129
|
+
puts e.inspect
|
130
|
+
$stderr.puts 'ERROR: no such template' unless $quiet
|
118
131
|
exit
|
119
132
|
end
|
120
133
|
template_meta = template_meta.eruby
|
data/lib/nanoc/enhancements.rb
CHANGED
@@ -1,4 +1,16 @@
|
|
1
|
-
def try_require(s)
|
1
|
+
def try_require(s)
|
2
|
+
require s
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
|
6
|
+
def nanoc_require(s)
|
7
|
+
require s
|
8
|
+
rescue LoadError
|
9
|
+
$stderr.puts "ERROR: You need '#{s}' to compile this site." unless $quiet
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
try_require 'rubygems'
|
2
14
|
|
3
15
|
require 'fileutils'
|
4
16
|
|
@@ -8,11 +20,7 @@ def handle_exception(exception, text)
|
|
8
20
|
$stderr.puts exception
|
9
21
|
$stderr.puts exception.backtrace.join("\n")
|
10
22
|
end
|
11
|
-
exit
|
12
|
-
end
|
13
|
-
|
14
|
-
def deprecate(str)
|
15
|
-
$stderr.puts 'DEPRECATION WARNING: ' + str unless $quiet
|
23
|
+
exit(1)
|
16
24
|
end
|
17
25
|
|
18
26
|
class FileLogger
|
@@ -1,10 +1,3 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
require 'erb'
|
6
|
-
try_require 'erubis'
|
7
|
-
|
8
1
|
class ERBContext
|
9
2
|
|
10
3
|
def initialize(hash)
|
@@ -28,11 +21,13 @@ class String
|
|
28
21
|
|
29
22
|
# Converts the string using Erubis
|
30
23
|
def erubis(params={})
|
24
|
+
nanoc_require 'erubis'
|
31
25
|
Erubis::Eruby.new(self).evaluate(params[:assigns] || {})
|
32
26
|
end
|
33
27
|
|
34
28
|
# Converts the string using ERB
|
35
29
|
def erb(params={})
|
30
|
+
nanoc_require 'erb'
|
36
31
|
ERB.new(self).result(ERBContext.new(params[:assigns] || {}).get_binding)
|
37
32
|
end
|
38
33
|
|
@@ -1,19 +1,13 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
try_require 'haml'
|
6
|
-
|
7
1
|
class String
|
8
2
|
|
9
3
|
# Converts the string using Haml
|
10
4
|
def haml(params={})
|
5
|
+
nanoc_require 'haml'
|
6
|
+
|
11
7
|
options = (params[:haml_options] || {})
|
12
8
|
options[:locals] = params[:assigns] unless params[:assigns].nil?
|
9
|
+
|
13
10
|
Haml::Engine.new(self, options).to_html
|
14
|
-
rescue NameError
|
15
|
-
$stderr.puts 'ERROR: String#haml failed (Haml not installed?)' unless $quiet
|
16
|
-
exit
|
17
11
|
end
|
18
12
|
|
19
13
|
end
|
@@ -1,21 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
try_require 'liquid'
|
1
|
+
# Filter
|
6
2
|
|
7
3
|
class String
|
8
4
|
|
9
|
-
# Converts the string using Liquid
|
10
5
|
def liquid(params={})
|
6
|
+
nanoc_require 'liquid'
|
7
|
+
|
11
8
|
Liquid::Template.parse(self).render((params[:assigns] || {}).stringify_keys)
|
12
|
-
rescue NameError
|
13
|
-
$stderr.puts 'ERROR: String#liquid failed (Liquid not installed?)' unless $quiet
|
14
|
-
exit
|
15
9
|
end
|
16
10
|
|
17
11
|
end
|
18
12
|
|
13
|
+
register_filter 'liquid' do |page, pages, config|
|
14
|
+
assigns = { :page => page, :pages => pages }
|
15
|
+
page.content.liquid(:assigns => assigns)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Render tag
|
19
|
+
|
19
20
|
begin
|
20
21
|
class Nanoc::LiquidRenderTag < ::Liquid::Tag
|
21
22
|
Syntax = /(['"])([^'"]+)\1/
|
@@ -44,8 +45,3 @@ begin
|
|
44
45
|
Liquid::Template.register_tag('render', Nanoc::LiquidRenderTag)
|
45
46
|
rescue NameError
|
46
47
|
end
|
47
|
-
|
48
|
-
register_filter 'liquid' do |page, pages, config|
|
49
|
-
assigns = { :page => page, :pages => pages }
|
50
|
-
page.content.liquid(:assigns => assigns)
|
51
|
-
end
|
@@ -1,20 +1,10 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
require 'erb'
|
6
|
-
|
7
|
-
try_require 'markaby'
|
8
|
-
|
9
1
|
class String
|
10
2
|
|
11
3
|
# Converts the string using Markaby
|
12
4
|
# TODO perhaps add support for helpers
|
13
5
|
def markaby(params={})
|
6
|
+
nanoc_require 'markaby'
|
14
7
|
Markaby::Builder.new((params[:assigns] || {})).instance_eval(self).to_s
|
15
|
-
rescue NameError
|
16
|
-
$stderr.puts 'ERROR: String#markaby failed (Markaby not installed?)' unless $quiet
|
17
|
-
exit
|
18
8
|
end
|
19
9
|
|
20
10
|
end
|
@@ -1,17 +1,9 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
try_require 'bluecloth'
|
6
|
-
|
7
1
|
class String
|
8
2
|
|
9
|
-
# Converts the string
|
3
|
+
# Converts the string using Markdown
|
10
4
|
def markdown
|
5
|
+
nanoc_require 'bluecloth'
|
11
6
|
BlueCloth.new(self).to_html
|
12
|
-
rescue NameError
|
13
|
-
$stderr.puts 'ERROR: String#markdown failed: BlueCloth not installed' unless $quiet
|
14
|
-
exit
|
15
7
|
end
|
16
8
|
|
17
9
|
end
|
@@ -1,14 +1,10 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
try_require 'rdoc/markup/simple_markup'
|
6
|
-
try_require 'rdoc/markup/simple_markup/to_html'
|
7
|
-
|
8
1
|
class String
|
9
2
|
|
10
3
|
# Converts the string using RDoc
|
11
4
|
def rdoc
|
5
|
+
nanoc_require 'rdoc/markup/simple_markup'
|
6
|
+
nanoc_require 'rdoc/markup/simple_markup/to_html'
|
7
|
+
|
12
8
|
SM::SimpleMarkup.new.convert(self, SM::ToHtml.new)
|
13
9
|
end
|
14
10
|
|
@@ -1,17 +1,9 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
try_require 'rubypants'
|
6
|
-
|
7
1
|
class String
|
8
2
|
|
9
3
|
# Converts the string using RubyPants/SmartyPants
|
10
4
|
def smartypants
|
5
|
+
nanoc_require 'rubypants'
|
11
6
|
RubyPants.new(self).to_html
|
12
|
-
rescue NameError
|
13
|
-
$stderr.puts 'ERROR: String#smartypants failed (RubyPants not installed?)' unless $quiet
|
14
|
-
exit
|
15
7
|
end
|
16
8
|
|
17
9
|
end
|
@@ -1,17 +1,9 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
|
5
|
-
try_require 'redcloth'
|
6
|
-
|
7
1
|
class String
|
8
2
|
|
9
3
|
# Converts the string using RedCloth/Textile
|
10
4
|
def textile
|
5
|
+
nanoc_require 'redcloth'
|
11
6
|
RedCloth.new(self).to_html
|
12
|
-
rescue NameError
|
13
|
-
$stderr.puts 'ERROR: String#textile failed (RedCloth not installed?)' unless $quiet
|
14
|
-
exit
|
15
7
|
end
|
16
8
|
|
17
9
|
end
|
data/lib/nanoc/page.rb
CHANGED
@@ -1,64 +1,13 @@
|
|
1
|
-
def try_require(s) ; begin ; require s ; rescue LoadError ; end ; end
|
2
|
-
|
3
|
-
try_require 'rubygems'
|
4
|
-
try_require 'liquid'
|
5
|
-
|
6
1
|
module Nanoc
|
7
2
|
|
8
|
-
# Page drop
|
9
|
-
|
10
|
-
begin
|
11
|
-
class PageDrop < ::Liquid::Drop
|
12
|
-
def initialize(page)
|
13
|
-
@page = page
|
14
|
-
end
|
15
|
-
|
16
|
-
def before_method(name)
|
17
|
-
name == 'content' ? @page.content : @page.attributes[name.to_sym]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
rescue NameError
|
21
|
-
class PageDrop
|
22
|
-
def initialize(*args)
|
23
|
-
$stderr.puts 'ERROR: Liquid not installed; cannot use Liquid in layouts.'
|
24
|
-
exit
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Page proxy
|
30
|
-
|
31
|
-
class PageProxy
|
32
|
-
def initialize(page, params={})
|
33
|
-
@page = page
|
34
|
-
@do_compile = (params[:compile] != false)
|
35
|
-
end
|
36
|
-
|
37
|
-
def [](key)
|
38
|
-
if key.to_sym == :content and @do_compile
|
39
|
-
@page.content
|
40
|
-
else
|
41
|
-
if key.to_s.starts_with?('_')
|
42
|
-
nil
|
43
|
-
elsif key.to_s.ends_with?('?')
|
44
|
-
@page.attributes[key.to_s[0..-2].to_sym]
|
45
|
-
else
|
46
|
-
@page.attributes[key]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def method_missing(method, *args)
|
52
|
-
self[method]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Page
|
57
|
-
|
58
3
|
class Page
|
59
4
|
|
60
|
-
|
5
|
+
attr_accessor :stage, :is_filtered, :content_filename
|
6
|
+
|
7
|
+
def initialize(hash, compiler)
|
61
8
|
@attributes = hash
|
9
|
+
@compiler = compiler
|
10
|
+
@stage = nil
|
62
11
|
end
|
63
12
|
|
64
13
|
def attributes
|
@@ -66,79 +15,159 @@ module Nanoc
|
|
66
15
|
end
|
67
16
|
|
68
17
|
def content
|
69
|
-
|
18
|
+
filter!
|
70
19
|
@attributes[:content]
|
71
20
|
end
|
72
21
|
|
22
|
+
def stage=(s) ; @stage = s ; puts 'NEW STAGE = ' + s.to_s ; end
|
23
|
+
|
73
24
|
# Proxy/Liquid support
|
74
25
|
|
75
26
|
def to_proxy(params={})
|
76
|
-
PageProxy.new(self, :
|
27
|
+
PageProxy.new(self, :filter => params[:filter])
|
77
28
|
end
|
78
29
|
|
79
30
|
def to_liquid
|
31
|
+
nanoc_require 'liquid'
|
80
32
|
PageDrop.new(self)
|
81
33
|
end
|
82
34
|
|
83
|
-
#
|
35
|
+
# Helper methods
|
84
36
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
37
|
+
def path
|
38
|
+
if @attributes[:custom_path].nil?
|
39
|
+
@compiler.config[:output_dir] + @attributes[:path] +
|
40
|
+
@attributes[:filename] + '.' + @attributes[:extension]
|
41
|
+
else
|
42
|
+
@compiler.config[:output_dir] + @attributes[:custom_path]
|
43
|
+
end
|
44
|
+
end
|
88
45
|
|
89
|
-
|
90
|
-
|
46
|
+
def file
|
47
|
+
File.new(@content_filename)
|
91
48
|
end
|
92
49
|
|
93
|
-
def
|
50
|
+
def find_layout
|
51
|
+
if @attributes[:layout].nil?
|
52
|
+
{ :type => :eruby, :content => "<%= @page.content %>" }
|
53
|
+
else
|
54
|
+
# Find all layouts
|
55
|
+
filenames = Dir["layouts/#{@attributes[:layout]}.*"]
|
56
|
+
|
57
|
+
# Reject backups
|
58
|
+
filenames.reject! { |f| f =~ /~$/ }
|
59
|
+
|
60
|
+
# Make sure there is only one content file
|
61
|
+
filenames.ensure_single('layout files', @attributes[:layout])
|
62
|
+
|
63
|
+
# Get the first (and only one)
|
64
|
+
filename = filenames[0]
|
65
|
+
|
66
|
+
{ :type => Nanoc::Compiler::FILE_TYPES[File.extname(filename)], :content => File.read(filename) }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Filtering
|
71
|
+
|
72
|
+
def filter!
|
73
|
+
# Get stack and list of other pages
|
74
|
+
stack = @compiler.stack
|
75
|
+
other_pages = @compiler.pages
|
76
|
+
|
94
77
|
# Check for recursive call
|
95
|
-
if
|
96
|
-
# Print
|
78
|
+
if stack.include?(self)
|
79
|
+
# Print stack
|
97
80
|
unless $quiet
|
98
81
|
$stderr.puts 'ERROR: Recursive call to page content.'
|
99
|
-
|
82
|
+
print_stack
|
100
83
|
end
|
101
84
|
|
102
85
|
exit
|
103
|
-
|
104
|
-
|
105
|
-
|
86
|
+
end
|
87
|
+
|
88
|
+
# Get filters
|
89
|
+
if @stage == :pre
|
90
|
+
filters = @attributes[:filters_pre] || @attributes[:filters] || []
|
91
|
+
elsif @stage == :post
|
92
|
+
filters = @attributes[:filters_post] || []
|
93
|
+
else
|
94
|
+
puts '?????!!!!!!!!'
|
95
|
+
puts `pwd`
|
96
|
+
end
|
97
|
+
|
98
|
+
# Filter if not yet filtered
|
99
|
+
unless @is_filtered
|
100
|
+
stack.pushing(self) do
|
106
101
|
# Read page
|
107
|
-
content = File.read(@
|
102
|
+
content = @attributes[:content] || File.read(@content_filename)
|
108
103
|
|
109
104
|
begin
|
110
105
|
# Get params
|
111
|
-
page = self.to_proxy(:
|
112
|
-
pages =
|
106
|
+
page = self.to_proxy(:filter => false)
|
107
|
+
pages = other_pages.map { |p| p.to_proxy }
|
113
108
|
config = $nanoc_compiler.config
|
114
109
|
|
115
110
|
# Filter page
|
116
111
|
@attributes[:content] = content
|
117
|
-
|
112
|
+
filters.each do |filter_name|
|
118
113
|
filter = $nanoc_compiler.filter_named(filter_name)
|
119
114
|
if filter.nil?
|
120
115
|
$stderr.puts 'WARNING: Unknown filter: ' + filter_name unless $quiet
|
121
116
|
else
|
122
117
|
@attributes[:content] = filter.call(page, pages, config)
|
118
|
+
@is_filtered = true
|
123
119
|
end
|
124
120
|
end
|
125
121
|
rescue Exception => exception
|
126
|
-
handle_exception(exception, "
|
122
|
+
handle_exception(exception, "filter page '#{@content_filename}'")
|
127
123
|
end
|
128
124
|
end
|
129
125
|
end
|
130
126
|
end
|
131
127
|
|
132
|
-
def
|
133
|
-
#
|
134
|
-
|
135
|
-
|
136
|
-
|
128
|
+
def layout!
|
129
|
+
# Get list of other pages
|
130
|
+
other_pages = @compiler.pages
|
131
|
+
|
132
|
+
# Find layout
|
133
|
+
layout = self.find_layout
|
134
|
+
|
135
|
+
# Build params
|
136
|
+
if layout[:type] == :liquid
|
137
|
+
public_page = self.to_liquid
|
138
|
+
public_pages = other_pages.map { |p| p.to_liquid }
|
139
|
+
else
|
140
|
+
public_page = self.to_proxy
|
141
|
+
public_pages = other_pages.map { |p| p.to_proxy }
|
142
|
+
end
|
143
|
+
params = { :assigns => { :page => public_page, :pages => public_pages } }
|
144
|
+
params[:haml_options] = (@attributes[:haml_options] || {}).symbolize_keys
|
145
|
+
|
146
|
+
# Layout
|
147
|
+
case layout[:type]
|
148
|
+
when :eruby
|
149
|
+
@attributes[:content] = layout[:content].eruby(params)
|
150
|
+
when :haml
|
151
|
+
@attributes[:content] = layout[:content].haml(params)
|
152
|
+
when :markaby
|
153
|
+
@attributes[:content] = layout[:content].markaby(params)
|
154
|
+
when :liquid
|
155
|
+
@attributes[:content] = layout[:content].liquid(params)
|
156
|
+
else
|
157
|
+
@attributes[:content] = nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def print_stack
|
162
|
+
# Determine relevant part of stack
|
163
|
+
stack_begin = @compiler.stack.index(self)
|
164
|
+
stack_end = @compiler.stack.size
|
165
|
+
relevant_stack_part = @compiler.stack.last(stack_end - stack_begin)
|
137
166
|
|
138
|
-
# Print relevant part of
|
139
|
-
$stderr.puts 'Page
|
167
|
+
# Print relevant part of stack
|
168
|
+
$stderr.puts 'Page filter stack:'
|
140
169
|
relevant_stack_part.each_with_index do |page, i|
|
141
|
-
$stderr.puts "#{i} #{page.
|
170
|
+
$stderr.puts "#{i} #{page.content_filename}"
|
142
171
|
end
|
143
172
|
end
|
144
173
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
try_require 'liquid'
|
2
|
+
|
3
|
+
module Nanoc
|
4
|
+
|
5
|
+
begin
|
6
|
+
class PageDrop < ::Liquid::Drop
|
7
|
+
def initialize(page)
|
8
|
+
@page = page
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_method(name)
|
12
|
+
name == 'content' ? @page.content : @page.attributes[name.to_sym]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
rescue NameError
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Nanoc
|
2
|
+
class PageProxy
|
3
|
+
|
4
|
+
def initialize(page, params={})
|
5
|
+
@page = page
|
6
|
+
@do_filter = (params[:filter] != false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](key)
|
10
|
+
if key.to_sym == :content and @do_filter
|
11
|
+
@page.content
|
12
|
+
elsif key.to_sym == :file
|
13
|
+
@page.file
|
14
|
+
elsif key.to_s.ends_with?('?')
|
15
|
+
@page.attributes[key.to_s[0..-2].to_sym]
|
16
|
+
else
|
17
|
+
@page.attributes[key]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def method_missing(method, *args)
|
22
|
+
self[method]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/lib/nanoc.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Nanoc
|
2
2
|
|
3
|
-
VERSION = '1.
|
3
|
+
VERSION = '1.6'
|
4
4
|
|
5
5
|
def self.ensure_in_site
|
6
6
|
unless in_site?
|
@@ -27,6 +27,8 @@ module Nanoc
|
|
27
27
|
|
28
28
|
end
|
29
29
|
|
30
|
+
require File.dirname(__FILE__) + '/nanoc/enhancements.rb'
|
31
|
+
|
30
32
|
require File.dirname(__FILE__) + '/nanoc/creator.rb'
|
31
33
|
require File.dirname(__FILE__) + '/nanoc/compiler.rb'
|
32
34
|
|
@@ -34,6 +36,7 @@ $nanoc_creator = Nanoc::Creator.new
|
|
34
36
|
$nanoc_compiler = Nanoc::Compiler.new
|
35
37
|
|
36
38
|
require File.dirname(__FILE__) + '/nanoc/core_ext.rb'
|
37
|
-
require File.dirname(__FILE__) + '/nanoc/enhancements.rb'
|
38
39
|
require File.dirname(__FILE__) + '/nanoc/filters.rb'
|
39
40
|
require File.dirname(__FILE__) + '/nanoc/page.rb'
|
41
|
+
require File.dirname(__FILE__) + '/nanoc/page_drop.rb'
|
42
|
+
require File.dirname(__FILE__) + '/nanoc/page_proxy.rb'
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: nanoc
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "1.
|
7
|
-
date: 2007-
|
6
|
+
version: "1.6"
|
7
|
+
date: 2007-10-13 00:00:00 +02:00
|
8
8
|
summary: a CMS that doesn't run on your server
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -56,6 +56,8 @@ files:
|
|
56
56
|
- lib/nanoc/filters/textile_filter.rb
|
57
57
|
- lib/nanoc/filters.rb
|
58
58
|
- lib/nanoc/page.rb
|
59
|
+
- lib/nanoc/page_drop.rb
|
60
|
+
- lib/nanoc/page_proxy.rb
|
59
61
|
- lib/nanoc.rb
|
60
62
|
test_files: []
|
61
63
|
|