nanoc 1.6.2 → 2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|