nanoc 1.6.2 → 2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/ChangeLog +27 -0
  2. data/Rakefile +34 -27
  3. data/bin/nanoc +153 -49
  4. data/lib/nanoc.rb +15 -33
  5. data/lib/nanoc/base/auto_compiler.rb +124 -0
  6. data/lib/nanoc/base/compiler.rb +55 -0
  7. data/lib/nanoc/base/core_ext/hash.rb +34 -0
  8. data/lib/nanoc/base/data_source.rb +53 -0
  9. data/lib/nanoc/base/enhancements.rb +89 -0
  10. data/lib/nanoc/base/filter.rb +16 -0
  11. data/lib/nanoc/base/layout_processor.rb +33 -0
  12. data/lib/nanoc/base/page.rb +155 -0
  13. data/lib/nanoc/base/page_proxy.rb +31 -0
  14. data/lib/nanoc/base/plugin.rb +19 -0
  15. data/lib/nanoc/base/plugin_manager.rb +33 -0
  16. data/lib/nanoc/base/site.rb +143 -0
  17. data/lib/nanoc/data_sources/database.rb +259 -0
  18. data/lib/nanoc/data_sources/filesystem.rb +308 -0
  19. data/lib/nanoc/data_sources/trivial.rb +145 -0
  20. data/lib/nanoc/filters/erb.rb +34 -0
  21. data/lib/nanoc/filters/haml.rb +16 -0
  22. data/lib/nanoc/filters/markaby.rb +15 -0
  23. data/lib/nanoc/filters/markdown.rb +13 -0
  24. data/lib/nanoc/filters/rdoc.rb +14 -0
  25. data/lib/nanoc/filters/smartypants.rb +13 -0
  26. data/lib/nanoc/filters/textile.rb +13 -0
  27. data/lib/nanoc/layout_processors/erb.rb +35 -0
  28. data/lib/nanoc/layout_processors/haml.rb +18 -0
  29. data/lib/nanoc/layout_processors/markaby.rb +16 -0
  30. metadata +37 -30
  31. data/lib/nanoc/compiler.rb +0 -145
  32. data/lib/nanoc/core_ext.rb +0 -1
  33. data/lib/nanoc/core_ext/array.rb +0 -17
  34. data/lib/nanoc/core_ext/hash.rb +0 -43
  35. data/lib/nanoc/core_ext/string.rb +0 -13
  36. data/lib/nanoc/core_ext/yaml.rb +0 -10
  37. data/lib/nanoc/creator.rb +0 -180
  38. data/lib/nanoc/enhancements.rb +0 -101
  39. data/lib/nanoc/filters.rb +0 -7
  40. data/lib/nanoc/filters/eruby_filter.rb +0 -39
  41. data/lib/nanoc/filters/haml_filter.rb +0 -18
  42. data/lib/nanoc/filters/liquid_filter.rb +0 -47
  43. data/lib/nanoc/filters/markaby_filter.rb +0 -15
  44. data/lib/nanoc/filters/markdown_filter.rb +0 -13
  45. data/lib/nanoc/filters/rdoc_filter.rb +0 -15
  46. data/lib/nanoc/filters/sass_filter.rb +0 -13
  47. data/lib/nanoc/filters/smartypants_filter.rb +0 -13
  48. data/lib/nanoc/filters/textile_filter.rb +0 -13
  49. data/lib/nanoc/page.rb +0 -171
  50. data/lib/nanoc/page_drop.rb +0 -18
  51. data/lib/nanoc/page_proxy.rb +0 -30
@@ -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
@@ -1,13 +0,0 @@
1
- class String
2
-
3
- # Returns true if the string starts with str
4
- def starts_with?(str)
5
- str == self[0, str.length]
6
- end
7
-
8
- # Returns true if the string ends with str
9
- def ends_with?(str)
10
- str == self[-str.length, str.length]
11
- end
12
-
13
- end
@@ -1,10 +0,0 @@
1
- require 'yaml'
2
-
3
- module YAML
4
-
5
- # Loads a YAML file, cleans it using Hash#clean, and returns the result
6
- def self.load_file_and_clean(a_filename)
7
- (YAML.load_file(a_filename) || {}).clean
8
- end
9
-
10
- end
@@ -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('&', '&amp;').gsub('<', '&lt;').gsub('>', '&gt;').gsub('\"', '&quot;')\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
@@ -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
@@ -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