nanoc 1.6.2 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +27 -0
- data/Rakefile +34 -27
- data/bin/nanoc +153 -49
- data/lib/nanoc.rb +15 -33
- data/lib/nanoc/base/auto_compiler.rb +124 -0
- data/lib/nanoc/base/compiler.rb +55 -0
- data/lib/nanoc/base/core_ext/hash.rb +34 -0
- data/lib/nanoc/base/data_source.rb +53 -0
- data/lib/nanoc/base/enhancements.rb +89 -0
- data/lib/nanoc/base/filter.rb +16 -0
- data/lib/nanoc/base/layout_processor.rb +33 -0
- data/lib/nanoc/base/page.rb +155 -0
- data/lib/nanoc/base/page_proxy.rb +31 -0
- data/lib/nanoc/base/plugin.rb +19 -0
- data/lib/nanoc/base/plugin_manager.rb +33 -0
- data/lib/nanoc/base/site.rb +143 -0
- data/lib/nanoc/data_sources/database.rb +259 -0
- data/lib/nanoc/data_sources/filesystem.rb +308 -0
- data/lib/nanoc/data_sources/trivial.rb +145 -0
- data/lib/nanoc/filters/erb.rb +34 -0
- data/lib/nanoc/filters/haml.rb +16 -0
- data/lib/nanoc/filters/markaby.rb +15 -0
- data/lib/nanoc/filters/markdown.rb +13 -0
- data/lib/nanoc/filters/rdoc.rb +14 -0
- data/lib/nanoc/filters/smartypants.rb +13 -0
- data/lib/nanoc/filters/textile.rb +13 -0
- data/lib/nanoc/layout_processors/erb.rb +35 -0
- data/lib/nanoc/layout_processors/haml.rb +18 -0
- data/lib/nanoc/layout_processors/markaby.rb +16 -0
- metadata +37 -30
- data/lib/nanoc/compiler.rb +0 -145
- data/lib/nanoc/core_ext.rb +0 -1
- data/lib/nanoc/core_ext/array.rb +0 -17
- data/lib/nanoc/core_ext/hash.rb +0 -43
- data/lib/nanoc/core_ext/string.rb +0 -13
- data/lib/nanoc/core_ext/yaml.rb +0 -10
- data/lib/nanoc/creator.rb +0 -180
- data/lib/nanoc/enhancements.rb +0 -101
- data/lib/nanoc/filters.rb +0 -7
- data/lib/nanoc/filters/eruby_filter.rb +0 -39
- data/lib/nanoc/filters/haml_filter.rb +0 -18
- data/lib/nanoc/filters/liquid_filter.rb +0 -47
- data/lib/nanoc/filters/markaby_filter.rb +0 -15
- data/lib/nanoc/filters/markdown_filter.rb +0 -13
- data/lib/nanoc/filters/rdoc_filter.rb +0 -15
- data/lib/nanoc/filters/sass_filter.rb +0 -13
- data/lib/nanoc/filters/smartypants_filter.rb +0 -13
- data/lib/nanoc/filters/textile_filter.rb +0 -13
- data/lib/nanoc/page.rb +0 -171
- data/lib/nanoc/page_drop.rb +0 -18
- data/lib/nanoc/page_proxy.rb +0 -30
data/lib/nanoc/core_ext/hash.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
class Hash
|
2
|
-
# Cleans up the hash and returns the result. It performs the following
|
3
|
-
# operations:
|
4
|
-
#
|
5
|
-
# * Values with keys ending in _at and _on are converted into Times and
|
6
|
-
# Dates, respectively
|
7
|
-
# * All keys are converted to symbols
|
8
|
-
# * Value strings 'true', 'false', and 'none' are converted into
|
9
|
-
# true, false, and nil, respectively
|
10
|
-
def clean
|
11
|
-
symbolize_keys.inject({}) do |hash, (key, value)|
|
12
|
-
if key.to_s =~ /_on$/
|
13
|
-
hash.merge(key => Date.parse(value))
|
14
|
-
elsif key.to_s =~ /_at$/
|
15
|
-
hash.merge(key => Time.parse(value))
|
16
|
-
elsif value == 'true'
|
17
|
-
hash.merge(key => true)
|
18
|
-
elsif value == 'false'
|
19
|
-
hash.merge(key => false)
|
20
|
-
elsif value == 'none'
|
21
|
-
hash.merge(key => nil)
|
22
|
-
else
|
23
|
-
hash.merge(key => value)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Converts all keys in the hash to symbols and returns the result
|
29
|
-
def symbolize_keys
|
30
|
-
inject({}) do |hash, (key, value)|
|
31
|
-
new_value = value.respond_to?(:symbolize_keys) ? value.symbolize_keys : value
|
32
|
-
hash.merge({ key.to_sym => new_value })
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Converts all keys in the hash to strings and returns the result
|
37
|
-
def stringify_keys
|
38
|
-
inject({}) do |hash, (key, value)|
|
39
|
-
new_value = value.respond_to?(:stringify_keys) ? value.stringify_keys : value
|
40
|
-
hash.merge({ key.to_s => new_value })
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/lib/nanoc/core_ext/yaml.rb
DELETED
data/lib/nanoc/creator.rb
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
module Nanoc
|
2
|
-
|
3
|
-
class Creator
|
4
|
-
|
5
|
-
def create_site(a_sitename)
|
6
|
-
ensure_nonexistant(a_sitename)
|
7
|
-
|
8
|
-
FileManager.create_dir a_sitename do
|
9
|
-
FileManager.create_dir 'output'
|
10
|
-
|
11
|
-
FileManager.create_file 'config.yaml' do
|
12
|
-
"output_dir: \"output\"\n"
|
13
|
-
end
|
14
|
-
|
15
|
-
FileManager.create_file 'meta.yaml' do
|
16
|
-
"# This file contains the default values for all metafiles.\n" +
|
17
|
-
"# Other metafiles can override the contents of this one.\n" +
|
18
|
-
"\n" +
|
19
|
-
"# Built-in\n" +
|
20
|
-
"layout: \"default\"\n" +
|
21
|
-
"filters: []\n" +
|
22
|
-
"filename: \"index\"\n" +
|
23
|
-
"extension: \"html\"\n" +
|
24
|
-
"\n" +
|
25
|
-
"# Custom\n"
|
26
|
-
end
|
27
|
-
|
28
|
-
FileManager.create_file 'Rakefile' do
|
29
|
-
"Dir['tasks/**/*.rake'].sort.each { |rakefile| load rakefile }\n" +
|
30
|
-
"\n" +
|
31
|
-
"task :default do\n" +
|
32
|
-
" puts 'This is an example rake task.'\n" +
|
33
|
-
"end\n"
|
34
|
-
end
|
35
|
-
|
36
|
-
FileManager.create_dir 'layouts' do
|
37
|
-
FileManager.create_file 'default.erb' do
|
38
|
-
"<html>\n" +
|
39
|
-
" <head>\n" +
|
40
|
-
" <title><%= @page.title %></title>\n" +
|
41
|
-
" </head>\n" +
|
42
|
-
" <body>\n" +
|
43
|
-
"<%= @page.content %>\n" +
|
44
|
-
" </body>\n" +
|
45
|
-
"</html>\n"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
FileManager.create_dir 'lib' do
|
50
|
-
FileManager.create_file 'default.rb' do
|
51
|
-
"\# All files in the 'lib' directory will be loaded\n" +
|
52
|
-
"\# before nanoc starts compiling.\n" +
|
53
|
-
"\n" +
|
54
|
-
"def html_escape(a_string)\n" +
|
55
|
-
" a_string.gsub('&', '&').gsub('<', '<').gsub('>', '>').gsub('\"', '"')\n" +
|
56
|
-
"end\n" +
|
57
|
-
"alias h html_escape\n"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
FileManager.create_dir 'tasks' do
|
62
|
-
FileManager.create_file 'default.rake' do
|
63
|
-
"task :example do\n" +
|
64
|
-
" puts 'This is an example rake task in tasks/default.rake.'\n" +
|
65
|
-
"end\n"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
FileManager.create_dir 'templates' do
|
70
|
-
FileManager.create_dir 'default' do
|
71
|
-
FileManager.create_file "default.txt" do
|
72
|
-
"This is a new page. Please edit me!\n"
|
73
|
-
end
|
74
|
-
FileManager.create_file 'meta.yaml' do
|
75
|
-
"# Built-in\n" +
|
76
|
-
"\n" +
|
77
|
-
"# Custom\n" +
|
78
|
-
"title: A New Page\n"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
FileManager.create_dir 'content' do
|
84
|
-
FileManager.create_file 'content.txt' do
|
85
|
-
"This is a sample root page. Please edit me!\n"
|
86
|
-
end
|
87
|
-
FileManager.create_file 'meta.yaml' do
|
88
|
-
"# Built-in\n" +
|
89
|
-
"\n" +
|
90
|
-
"# Custom\n" +
|
91
|
-
"title: My New Homepage\n"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def create_page(a_pagename, a_params={})
|
98
|
-
Nanoc.ensure_in_site
|
99
|
-
ensure_nonexistant(File.join(['content', a_pagename]))
|
100
|
-
|
101
|
-
# Sanitize page name
|
102
|
-
if a_pagename =~ /^[\/\.]+/
|
103
|
-
$stderr.puts 'ERROR: page name starts with dots and/or slashes, aborting' unless $quiet
|
104
|
-
return
|
105
|
-
end
|
106
|
-
|
107
|
-
# Read template
|
108
|
-
template = a_params[:template] || 'default'
|
109
|
-
begin
|
110
|
-
template_meta = File.read("templates/#{template}/meta.yaml")
|
111
|
-
|
112
|
-
# Find all files
|
113
|
-
template_content_filenames = Dir["templates/#{template}/#{template}.*"]
|
114
|
-
|
115
|
-
# Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
|
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)
|
125
|
-
template_content_filename = template_content_filenames[0]
|
126
|
-
|
127
|
-
template_index = File.read(template_content_filename)
|
128
|
-
rescue => e
|
129
|
-
puts e.inspect
|
130
|
-
$stderr.puts 'ERROR: no such template' unless $quiet
|
131
|
-
exit
|
132
|
-
end
|
133
|
-
template_meta = template_meta.eruby
|
134
|
-
template_index = template_index.eruby
|
135
|
-
|
136
|
-
# Create index and yaml file
|
137
|
-
FileManager.create_dir 'content' do
|
138
|
-
FileManager.create_dir a_pagename do
|
139
|
-
page_name = a_pagename.sub(/.*\/([^\/]+)/, '\1')
|
140
|
-
extension = File.extname(template_content_filename)
|
141
|
-
FileManager.create_file "#{page_name}#{extension}" do
|
142
|
-
template_index
|
143
|
-
end
|
144
|
-
FileManager.create_file 'meta.yaml' do
|
145
|
-
template_meta
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def create_template(a_templatename)
|
152
|
-
Nanoc.ensure_in_site
|
153
|
-
ensure_nonexistant(File.join(['templates', a_templatename]))
|
154
|
-
|
155
|
-
FileManager.create_dir 'templates' do
|
156
|
-
FileManager.create_dir a_templatename do
|
157
|
-
FileManager.create_file "#{a_templatename}.txt" do
|
158
|
-
"This is a new page. Please edit me!\n"
|
159
|
-
end
|
160
|
-
FileManager.create_file 'meta.yaml' do
|
161
|
-
"# Built-in\n" +
|
162
|
-
"\n" +
|
163
|
-
"# Custom\n" +
|
164
|
-
"title: A New Page\n"
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
private
|
171
|
-
|
172
|
-
def ensure_nonexistant(filename)
|
173
|
-
if File.exist?(filename)
|
174
|
-
$stderr.puts "ERROR: A file or directory named #{filename} already exists." unless $quiet
|
175
|
-
exit
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
end
|
180
|
-
end
|
data/lib/nanoc/enhancements.rb
DELETED
@@ -1,101 +0,0 @@
|
|
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'
|
14
|
-
|
15
|
-
require 'fileutils'
|
16
|
-
|
17
|
-
def handle_exception(exception, text)
|
18
|
-
unless $quiet or exception.class == SystemExit
|
19
|
-
$stderr.puts "ERROR: Exception occured while #{text}:\n"
|
20
|
-
$stderr.puts exception
|
21
|
-
$stderr.puts exception.backtrace.join("\n")
|
22
|
-
end
|
23
|
-
exit(1)
|
24
|
-
end
|
25
|
-
|
26
|
-
class FileLogger
|
27
|
-
COLORS = {
|
28
|
-
:reset => "\e[0m",
|
29
|
-
|
30
|
-
:bold => "\e[1m",
|
31
|
-
|
32
|
-
:black => "\e[30m",
|
33
|
-
:red => "\e[31m",
|
34
|
-
:green => "\e[32m",
|
35
|
-
:yellow => "\e[33m",
|
36
|
-
:blue => "\e[34m",
|
37
|
-
:magenta => "\e[35m",
|
38
|
-
:cyan => "\e[36m",
|
39
|
-
:white => "\e[37m"
|
40
|
-
}
|
41
|
-
|
42
|
-
ACTION_COLORS = {
|
43
|
-
:create => COLORS[:bold] + COLORS[:green],
|
44
|
-
:update => COLORS[:bold] + COLORS[:yellow],
|
45
|
-
:move => COLORS[:bold] + COLORS[:blue],
|
46
|
-
:identical => COLORS[:bold]
|
47
|
-
}
|
48
|
-
|
49
|
-
attr_reader :out
|
50
|
-
|
51
|
-
def initialize(a_out = $stdout)
|
52
|
-
@out = a_out
|
53
|
-
end
|
54
|
-
|
55
|
-
def log(a_action, a_path)
|
56
|
-
@out.puts('%s%12s%s %s' % [ACTION_COLORS[a_action.to_sym], a_action, COLORS[:reset], a_path]) unless $quiet
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def method_missing(a_method, *a_args)
|
62
|
-
log(a_method.to_s, a_args.first)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
class FileManager
|
67
|
-
@@stack = []
|
68
|
-
@@logger = FileLogger.new
|
69
|
-
|
70
|
-
def self.create_dir(a_name)
|
71
|
-
@@stack.pushing(a_name) do
|
72
|
-
path = File.join(@@stack)
|
73
|
-
unless File.directory?(path)
|
74
|
-
FileUtils.mkdir_p(path)
|
75
|
-
@@logger.create(path)
|
76
|
-
end
|
77
|
-
yield if block_given?
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.create_file(a_name)
|
82
|
-
path = File.join(@@stack + [ a_name ])
|
83
|
-
FileManager.create_dir(path.sub(/\/[^\/]+$/, '')) if @@stack.empty?
|
84
|
-
content = block_given? ? yield : nil
|
85
|
-
if File.exist?(path)
|
86
|
-
if block_given? and File.read(path) == content
|
87
|
-
@@logger.identical(path)
|
88
|
-
else
|
89
|
-
@@logger.update(path)
|
90
|
-
end
|
91
|
-
else
|
92
|
-
@@logger.create(path)
|
93
|
-
end
|
94
|
-
open(path, 'w') { |io| io.write(content) unless content.nil? }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def render(a_name, a_context={})
|
99
|
-
assigns = a_context.merge({ :page => @page, :pages => @pages })
|
100
|
-
File.read('layouts/' + a_name.to_s + '.erb').eruby(:assigns => assigns)
|
101
|
-
end
|
data/lib/nanoc/filters.rb
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
# Convenience function for registering filters
|
2
|
-
def register_filter(*names, &block)
|
3
|
-
names.each { |name| $nanoc_compiler.register_filter(name, &block) }
|
4
|
-
end
|
5
|
-
|
6
|
-
# Load all filters
|
7
|
-
Dir[File.join(File.dirname(__FILE__), 'filters', '*_filter.rb')].each { |f| require f }
|
@@ -1,39 +0,0 @@
|
|
1
|
-
class ERBContext
|
2
|
-
|
3
|
-
def initialize(hash)
|
4
|
-
hash.each_pair do |key, value|
|
5
|
-
instance_variable_set('@' + key.to_s, value)
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
def get_binding
|
10
|
-
binding
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
class String
|
16
|
-
|
17
|
-
# Converts the string using eRuby
|
18
|
-
def eruby(params={})
|
19
|
-
params[:eruby_engine] == :erubis ? erubis(params) : erb(params)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Converts the string using Erubis
|
23
|
-
def erubis(params={})
|
24
|
-
nanoc_require 'erubis'
|
25
|
-
Erubis::Eruby.new(self).evaluate(params[:assigns] || {})
|
26
|
-
end
|
27
|
-
|
28
|
-
# Converts the string using ERB
|
29
|
-
def erb(params={})
|
30
|
-
nanoc_require 'erb'
|
31
|
-
ERB.new(self).result(ERBContext.new(params[:assigns] || {}).get_binding)
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
register_filter 'eruby' do |page, pages, config|
|
37
|
-
assigns = { :page => page, :pages => pages }
|
38
|
-
page.content.eruby(:assigns => assigns, :eruby_engine => config[:eruby_engine])
|
39
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
class String
|
2
|
-
|
3
|
-
# Converts the string using Haml
|
4
|
-
def haml(params={})
|
5
|
-
nanoc_require 'haml'
|
6
|
-
|
7
|
-
options = (params[:haml_options] || {})
|
8
|
-
options[:locals] = params[:assigns] unless params[:assigns].nil?
|
9
|
-
|
10
|
-
Haml::Engine.new(self, options).to_html
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
register_filter 'haml' do |page, pages, config|
|
16
|
-
assigns = { :page => page, :pages => pages }
|
17
|
-
page.content.haml(:assigns => assigns, :haml_options => page[:haml_options])
|
18
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# Filter
|
2
|
-
|
3
|
-
class String
|
4
|
-
|
5
|
-
def liquid(params={})
|
6
|
-
nanoc_require 'liquid'
|
7
|
-
|
8
|
-
Liquid::Template.parse(self).render((params[:assigns] || {}).stringify_keys)
|
9
|
-
end
|
10
|
-
|
11
|
-
end
|
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
|
-
|
20
|
-
begin
|
21
|
-
class Nanoc::LiquidRenderTag < ::Liquid::Tag
|
22
|
-
Syntax = /(['"])([^'"]+)\1/
|
23
|
-
|
24
|
-
def initialize(markup, tokens)
|
25
|
-
if markup =~ Syntax
|
26
|
-
@layout_name = $2
|
27
|
-
else
|
28
|
-
raise SyntaxError.new("Error in tag 'render' - Valid syntax: render '[layout]'")
|
29
|
-
end
|
30
|
-
|
31
|
-
super
|
32
|
-
end
|
33
|
-
|
34
|
-
def parse(tokens)
|
35
|
-
end
|
36
|
-
|
37
|
-
def render(context)
|
38
|
-
source = File.read('layouts/' + @layout_name + '.liquid')
|
39
|
-
partial = Liquid::Template.parse(source)
|
40
|
-
|
41
|
-
partial.render(context)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
Liquid::Template.register_tag('render', Nanoc::LiquidRenderTag)
|
46
|
-
rescue NameError
|
47
|
-
end
|