nanoc 2.1.6 → 2.2
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 +3 -221
- data/Rakefile +9 -51
- data/bin/nanoc +5 -2
- data/lib/nanoc.rb +9 -31
- data/lib/nanoc/base.rb +26 -0
- data/lib/nanoc/base/core_ext.rb +2 -0
- data/lib/nanoc/base/filter.rb +11 -41
- data/lib/nanoc/base/layout.rb +1 -5
- data/lib/nanoc/base/page_rep.rb +1 -1
- data/lib/nanoc/base/proxies.rb +5 -0
- data/lib/nanoc/base/site.rb +4 -2
- data/lib/nanoc/binary_filters.rb +1 -0
- data/lib/nanoc/cli.rb +9 -1
- data/lib/nanoc/cli/base.rb +41 -129
- data/lib/nanoc/cli/commands.rb +10 -0
- data/lib/nanoc/cli/commands/autocompile.rb +1 -1
- data/lib/nanoc/cli/commands/compile.rb +51 -13
- data/lib/nanoc/cli/commands/create_layout.rb +1 -1
- data/lib/nanoc/cli/commands/create_page.rb +1 -1
- data/lib/nanoc/cli/commands/create_site.rb +1 -1
- data/lib/nanoc/cli/commands/create_template.rb +1 -1
- data/lib/nanoc/cli/commands/help.rb +1 -1
- data/lib/nanoc/cli/commands/info.rb +1 -1
- data/lib/nanoc/cli/commands/switch.rb +1 -1
- data/lib/nanoc/cli/commands/update.rb +1 -1
- data/lib/nanoc/cli/logger.rb +13 -7
- data/lib/nanoc/data_sources.rb +2 -0
- data/lib/nanoc/data_sources/filesystem.rb +3 -38
- data/lib/nanoc/extra.rb +6 -0
- data/lib/nanoc/extra/core_ext.rb +2 -0
- data/lib/nanoc/extra/vcses.rb +5 -0
- data/lib/nanoc/filters.rb +14 -0
- data/lib/nanoc/filters/erb.rb +3 -2
- data/lib/nanoc/filters/haml.rb +1 -1
- data/lib/nanoc/filters/markaby.rb +0 -1
- data/lib/nanoc/filters/rainpress.rb +13 -0
- data/lib/nanoc/filters/relativize_paths.rb +25 -0
- data/lib/nanoc/filters/sass.rb +1 -0
- data/lib/nanoc/helpers.rb +9 -0
- data/lib/nanoc/helpers/blogging.rb +55 -12
- data/lib/nanoc/helpers/filtering.rb +54 -0
- data/lib/nanoc/helpers/link_to.rb +40 -0
- data/lib/nanoc/helpers/text.rb +38 -0
- data/lib/nanoc/helpers/xml_sitemap.rb +3 -2
- data/lib/nanoc/routers.rb +3 -0
- data/vendor/cri/ChangeLog +0 -0
- data/vendor/cri/LICENSE +19 -0
- data/vendor/cri/NEWS +0 -0
- data/vendor/cri/README +4 -0
- data/vendor/cri/Rakefile +25 -0
- data/vendor/cri/lib/cri.rb +12 -0
- data/vendor/cri/lib/cri/base.rb +153 -0
- data/{lib/nanoc/cli → vendor/cri/lib/cri}/command.rb +5 -6
- data/vendor/cri/lib/cri/core_ext.rb +8 -0
- data/vendor/cri/lib/cri/core_ext/string.rb +41 -0
- data/{lib/nanoc/cli → vendor/cri/lib/cri}/option_parser.rb +35 -17
- data/vendor/cri/test/test_base.rb +6 -0
- data/vendor/cri/test/test_command.rb +6 -0
- data/vendor/cri/test/test_core_ext.rb +21 -0
- data/vendor/cri/test/test_option_parser.rb +279 -0
- data/vendor/mime-types/lib/mime/types.rb +1558 -0
- metadata +45 -9
- data/lib/nanoc/base/enhancements.rb +0 -14
- data/lib/nanoc/cli/cli.rb +0 -16
- data/lib/nanoc/cli/ext.rb +0 -37
data/lib/nanoc/cli/logger.rb
CHANGED
@@ -7,21 +7,27 @@ module Nanoc::CLI
|
|
7
7
|
class Logger
|
8
8
|
|
9
9
|
ACTION_COLORS = {
|
10
|
-
:create
|
11
|
-
:update
|
12
|
-
:identical
|
13
|
-
:skip
|
10
|
+
:create => "\e[1m" + "\e[32m", # bold + green
|
11
|
+
:update => "\e[1m" + "\e[33m", # bold + yellow
|
12
|
+
:identical => "\e[1m", # bold
|
13
|
+
:skip => "\e[1m", # bold
|
14
|
+
:'not written' => "\e[1m" # bold
|
14
15
|
}
|
15
16
|
|
16
17
|
include Singleton
|
17
18
|
|
18
|
-
# The log
|
19
|
+
# The log level, which can be :high, :low or :off (which will log all
|
19
20
|
# messages, only high-priority messages, or no messages at all,
|
20
21
|
# respectively).
|
21
22
|
attr_accessor :level
|
22
23
|
|
24
|
+
# Whether to use color in log messages or not
|
25
|
+
attr_accessor :color
|
26
|
+
alias_method :color?, :color
|
27
|
+
|
23
28
|
def initialize # :nodoc:
|
24
29
|
@level = :high
|
30
|
+
@color = true
|
25
31
|
end
|
26
32
|
|
27
33
|
# Logs a file-related action.
|
@@ -36,9 +42,9 @@ module Nanoc::CLI
|
|
36
42
|
log(
|
37
43
|
level,
|
38
44
|
'%s%12s%s %s%s' % [
|
39
|
-
ACTION_COLORS[action.to_sym],
|
45
|
+
color? ? ACTION_COLORS[action.to_sym] : '',
|
40
46
|
action,
|
41
|
-
"\e[0m",
|
47
|
+
color? ? "\e[0m" : '',
|
42
48
|
duration.nil? ? '' : "[%2.2fs] " % [ duration ],
|
43
49
|
path
|
44
50
|
]
|
@@ -120,7 +120,6 @@ module Nanoc::DataSources
|
|
120
120
|
def update # :nodoc:
|
121
121
|
update_page_defaults
|
122
122
|
update_pages
|
123
|
-
update_layouts
|
124
123
|
update_templates
|
125
124
|
end
|
126
125
|
|
@@ -368,8 +367,9 @@ module Nanoc::DataSources
|
|
368
367
|
if is_old_school
|
369
368
|
# Warn about deprecation
|
370
369
|
warn(
|
371
|
-
'nanoc 2.1 changes the way layouts are
|
372
|
-
'
|
370
|
+
'DEPRECATION WARNING: nanoc 2.1 changes the way layouts are ' +
|
371
|
+
'stored. Future versions will not support these outdated sites. ' +
|
372
|
+
'To update your site, issue \'nanoc update\'.'
|
373
373
|
)
|
374
374
|
|
375
375
|
Dir[File.join('layouts', '*')].reject { |f| f =~ /~$/ }.map do |filename|
|
@@ -679,41 +679,6 @@ module Nanoc::DataSources
|
|
679
679
|
end
|
680
680
|
end
|
681
681
|
|
682
|
-
# Updates outdated layouts.
|
683
|
-
def update_layouts
|
684
|
-
# layouts/abc.ext -> layouts/abc/abc.{html,yaml}
|
685
|
-
Dir[File.join('layouts', '*')].select { |f| File.file?(f) }.each do |filename|
|
686
|
-
# Get filter class
|
687
|
-
filter_class = Nanoc::Filter.with_extension(File.extname(filename))
|
688
|
-
|
689
|
-
# Get data
|
690
|
-
content = File.read(filename)
|
691
|
-
attributes = { :filter => filter_class.identifier.to_s }
|
692
|
-
path = File.basename(filename, File.extname(filename))
|
693
|
-
|
694
|
-
# Get layout
|
695
|
-
tmp_layout = Nanoc::Layout.new(content, attributes, path)
|
696
|
-
|
697
|
-
# Get filenames
|
698
|
-
last_component = tmp_layout.path.split('/')[-1]
|
699
|
-
dir_path = 'layouts' + tmp_layout.path
|
700
|
-
meta_filename = dir_path + last_component + '.yaml'
|
701
|
-
content_filename = dir_path + last_component + File.extname(filename)
|
702
|
-
|
703
|
-
# Create new files
|
704
|
-
FileUtils.mkdir_p(dir_path)
|
705
|
-
File.open(meta_filename, 'w') { |io| io.write(tmp_layout.attributes.to_split_yaml) }
|
706
|
-
File.open(content_filename, 'w') { |io| io.write(tmp_layout.content) }
|
707
|
-
|
708
|
-
# Add
|
709
|
-
vcs.add(meta_filename)
|
710
|
-
vcs.add(content_filename)
|
711
|
-
|
712
|
-
# Delete old files
|
713
|
-
vcs.remove(filename)
|
714
|
-
end
|
715
|
-
end
|
716
|
-
|
717
682
|
# Updates outdated templates (both content and meta file names).
|
718
683
|
def update_templates
|
719
684
|
# Update content files
|
data/lib/nanoc/extra.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'nanoc/filters/bluecloth'
|
2
|
+
require 'nanoc/filters/erb'
|
3
|
+
require 'nanoc/filters/erubis'
|
4
|
+
require 'nanoc/filters/haml'
|
5
|
+
require 'nanoc/filters/markaby'
|
6
|
+
require 'nanoc/filters/maruku'
|
7
|
+
require 'nanoc/filters/old'
|
8
|
+
require 'nanoc/filters/rainpress'
|
9
|
+
require 'nanoc/filters/rdiscount'
|
10
|
+
require 'nanoc/filters/rdoc'
|
11
|
+
require 'nanoc/filters/redcloth'
|
12
|
+
require 'nanoc/filters/relativize_paths'
|
13
|
+
require 'nanoc/filters/rubypants'
|
14
|
+
require 'nanoc/filters/sass'
|
data/lib/nanoc/filters/erb.rb
CHANGED
@@ -2,7 +2,6 @@ module Nanoc::Filters
|
|
2
2
|
class ERB < Nanoc::Filter
|
3
3
|
|
4
4
|
identifiers :erb
|
5
|
-
extensions '.erb', '.rhtml'
|
6
5
|
|
7
6
|
def run(content)
|
8
7
|
require 'erb'
|
@@ -11,7 +10,9 @@ module Nanoc::Filters
|
|
11
10
|
context = ::Nanoc::Extra::Context.new(assigns)
|
12
11
|
|
13
12
|
# Get result
|
14
|
-
::ERB.new(content)
|
13
|
+
erb = ::ERB.new(content)
|
14
|
+
erb.filename = filename
|
15
|
+
erb.result(context.get_binding)
|
15
16
|
end
|
16
17
|
|
17
18
|
end
|
data/lib/nanoc/filters/haml.rb
CHANGED
@@ -2,13 +2,13 @@ module Nanoc::Filters
|
|
2
2
|
class Haml < Nanoc::Filter
|
3
3
|
|
4
4
|
identifiers :haml
|
5
|
-
extensions '.haml'
|
6
5
|
|
7
6
|
def run(content)
|
8
7
|
require 'haml'
|
9
8
|
|
10
9
|
# Get options
|
11
10
|
options = @obj_rep.attribute_named(:haml_options) || {}
|
11
|
+
options[:filename] = filename
|
12
12
|
|
13
13
|
# Create context
|
14
14
|
context = ::Nanoc::Extra::Context.new(assigns)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Nanoc::Filters
|
2
|
+
class RelativizePaths < Nanoc::Filter
|
3
|
+
|
4
|
+
identifier :relativize_paths
|
5
|
+
|
6
|
+
require 'nanoc/helpers/link_to'
|
7
|
+
include Nanoc::Helpers::LinkTo
|
8
|
+
|
9
|
+
def run(content, params={})
|
10
|
+
type = params[:type] || :html
|
11
|
+
|
12
|
+
case type
|
13
|
+
when :html
|
14
|
+
content.gsub(/(src|href)=(['"]?)(\/.+?)\2([ >])/) do
|
15
|
+
$1 + '=' + $2 + relative_path_to($3) + $2 + $4
|
16
|
+
end
|
17
|
+
when :css
|
18
|
+
content.gsub(/url\((['"]?)(\/.+?)\1\)/) do
|
19
|
+
'url(' + $1 + relative_path_to($2) + $1 + ')'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/nanoc/filters/sass.rb
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'nanoc/helpers/blogging'
|
2
|
+
require 'nanoc/helpers/capturing'
|
3
|
+
require 'nanoc/helpers/filtering'
|
4
|
+
require 'nanoc/helpers/html_escape'
|
5
|
+
require 'nanoc/helpers/link_to'
|
6
|
+
require 'nanoc/helpers/render'
|
7
|
+
require 'nanoc/helpers/tagging'
|
8
|
+
require 'nanoc/helpers/text'
|
9
|
+
require 'nanoc/helpers/xml_sitemap'
|
@@ -21,14 +21,15 @@ module Nanoc::Helpers
|
|
21
21
|
# include Nanoc::Helpers::Blogging
|
22
22
|
module Blogging
|
23
23
|
|
24
|
-
# Returns
|
25
|
-
|
24
|
+
# Returns an unsorted list of articles.
|
25
|
+
def articles
|
26
|
+
@pages.select { |page| page.kind == 'article' }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns a list of articles, sorted by descending creation date (so newer
|
30
|
+
# articles appear first).
|
26
31
|
def sorted_articles
|
27
|
-
|
28
|
-
page.kind == 'article'
|
29
|
-
end.sort do |x,y|
|
30
|
-
y.created_at <=> x.created_at
|
31
|
-
end
|
32
|
+
articles.sort_by { |a| a.created_at }.reverse
|
32
33
|
end
|
33
34
|
|
34
35
|
# Returns a string representing the atom feed containing recent articles,
|
@@ -37,6 +38,19 @@ module Nanoc::Helpers
|
|
37
38
|
#
|
38
39
|
# +limit+:: The maximum number of articles to show. Defaults to 5.
|
39
40
|
#
|
41
|
+
# +articles+:: A list of articles to include in the feed. Defaults to the
|
42
|
+
# list of articles returned by the articles function.
|
43
|
+
#
|
44
|
+
# +content_proc+:: A proc that returns the content of the given article,
|
45
|
+
# passed as a parameter. By default, given the argument
|
46
|
+
# +article+, this proc will return +article.content+.
|
47
|
+
# This function may not return nil.
|
48
|
+
#
|
49
|
+
# +excerpt_proc+:: A proc that returns the excerpt of the given article,
|
50
|
+
# passed as a parameter. By default, given the argument
|
51
|
+
# +article+, this proc will return +article.excerpt+.
|
52
|
+
# This function may return nil.
|
53
|
+
#
|
40
54
|
# The following attributes must be set on blog articles:
|
41
55
|
#
|
42
56
|
# * 'title', containing the title of the blog post.
|
@@ -93,10 +107,38 @@ module Nanoc::Helpers
|
|
93
107
|
require 'builder'
|
94
108
|
|
95
109
|
# Extract parameters
|
96
|
-
limit
|
110
|
+
limit = params[:limit] || 5
|
111
|
+
relevant_articles = params[:articles] || articles || []
|
112
|
+
content_proc = params[:content_proc] || lambda { |a| a.content }
|
113
|
+
excerpt_proc = params[:excerpt_proc] || lambda { |a| a.excerpt }
|
114
|
+
|
115
|
+
# Check feed page attributes
|
116
|
+
if @page.base_url.nil?
|
117
|
+
raise RuntimeError.new('Cannot build Atom feed: feed page has no base_url')
|
118
|
+
end
|
119
|
+
if @page.title.nil?
|
120
|
+
raise RuntimeError.new('Cannot build Atom feed: feed page has no title')
|
121
|
+
end
|
122
|
+
if @page.author_name.nil?
|
123
|
+
raise RuntimeError.new('Cannot build Atom feed: feed page has no author_name')
|
124
|
+
end
|
125
|
+
if @page.author_uri.nil?
|
126
|
+
raise RuntimeError.new('Cannot build Atom feed: feed page has no author_uri')
|
127
|
+
end
|
128
|
+
|
129
|
+
# Check article attributes
|
130
|
+
if relevant_articles.empty?
|
131
|
+
raise RuntimeError.new('Cannot build Atom feed: no articles')
|
132
|
+
end
|
133
|
+
if relevant_articles.any? { |a| a.created_at.nil? }
|
134
|
+
raise RuntimeError.new('Cannot build Atom feed: one or more articles lack created_at')
|
135
|
+
end
|
136
|
+
|
137
|
+
# Get sorted relevant articles
|
138
|
+
sorted_relevant_articles = relevant_articles.sort_by { |a| a.created_at }.reverse.first(limit)
|
97
139
|
|
98
140
|
# Get most recent article
|
99
|
-
last_article =
|
141
|
+
last_article = sorted_relevant_articles.first
|
100
142
|
|
101
143
|
# Create builder
|
102
144
|
buffer = ''
|
@@ -123,7 +165,7 @@ module Nanoc::Helpers
|
|
123
165
|
end
|
124
166
|
|
125
167
|
# Add articles
|
126
|
-
|
168
|
+
sorted_relevant_articles.each do |a|
|
127
169
|
xml.entry do
|
128
170
|
# Add primary attributes
|
129
171
|
xml.id atom_tag_for(a)
|
@@ -137,8 +179,9 @@ module Nanoc::Helpers
|
|
137
179
|
xml.link(:rel => 'alternate', :href => url_for(a))
|
138
180
|
|
139
181
|
# Add content
|
140
|
-
|
141
|
-
xml.
|
182
|
+
summary = excerpt_proc.call(a)
|
183
|
+
xml.content content_proc.call(a), :type => 'html'
|
184
|
+
xml.summary summary, :type => 'html' unless summary.nil?
|
142
185
|
end
|
143
186
|
end
|
144
187
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Nanoc::Helpers
|
2
|
+
|
3
|
+
# Nanoc::Helpers::Filtering provides a filter method, which allows parts of
|
4
|
+
# a page to be filtered.
|
5
|
+
#
|
6
|
+
# For example, the following piece of code only runs the "rubypants" filter
|
7
|
+
# on the second paragraph:
|
8
|
+
#
|
9
|
+
# <p>Lorem ipsum dolor sit amet...</p>
|
10
|
+
# <% filter :rubypants do %>
|
11
|
+
# <p>Consectetur adipisicing elit...</p>
|
12
|
+
# <% end %>
|
13
|
+
#
|
14
|
+
# This helper likely only works with ERB (and perhaps Erubis).
|
15
|
+
#
|
16
|
+
# To activate this helper, +include+ it, like this:
|
17
|
+
#
|
18
|
+
# include Nanoc::Helpers::Filtering
|
19
|
+
module Filtering
|
20
|
+
|
21
|
+
# Filters the content in the given block and outputs it.
|
22
|
+
def filter(filter_name, &block)
|
23
|
+
# Capture block
|
24
|
+
data = capture(&block)
|
25
|
+
|
26
|
+
# Find filter
|
27
|
+
filter = Nanoc::Filter.named(filter_name).new(@_obj_rep)
|
28
|
+
|
29
|
+
# Filter captured data
|
30
|
+
filtered_data = filter.run(data)
|
31
|
+
|
32
|
+
# Append filtered data to buffer
|
33
|
+
buffer = eval('_erbout', block.binding)
|
34
|
+
buffer << filtered_data
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def capture(*args, &block)
|
40
|
+
buffer = eval('_erbout', block.binding)
|
41
|
+
|
42
|
+
pos = buffer.length
|
43
|
+
block.call(*args)
|
44
|
+
|
45
|
+
data = buffer[pos..-1]
|
46
|
+
|
47
|
+
buffer[pos..-1] = ''
|
48
|
+
|
49
|
+
data
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -7,6 +7,7 @@ module Nanoc::Helpers
|
|
7
7
|
# include Nanoc::Helpers::LinkTo
|
8
8
|
module LinkTo
|
9
9
|
|
10
|
+
require 'nanoc/helpers/html_escape'
|
10
11
|
include Nanoc::Helpers::HTMLEscape
|
11
12
|
|
12
13
|
# Creates a HTML link to the given path or page/asset representation, and
|
@@ -68,6 +69,45 @@ module Nanoc::Helpers
|
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
72
|
+
# Returns the relative path from the current page to the given path or
|
73
|
+
# page/asset representation.
|
74
|
+
#
|
75
|
+
# +path_or_rep+:: the URL or path (a String) to where the relative should
|
76
|
+
# point, or the page or asset representation to which the
|
77
|
+
# relative should point.
|
78
|
+
#
|
79
|
+
# Example:
|
80
|
+
#
|
81
|
+
# # if the current item's path is /foo/bar/
|
82
|
+
# relative_path('/foo/qux/')
|
83
|
+
# # => '../qux/'
|
84
|
+
def relative_path_to(path_or_rep)
|
85
|
+
require 'pathname'
|
86
|
+
|
87
|
+
# Find path
|
88
|
+
path = path_or_rep.is_a?(String) ? path_or_rep : path_or_rep.path
|
89
|
+
|
90
|
+
# Get source and destination paths
|
91
|
+
dst_path = Pathname.new(path)
|
92
|
+
src_path = Pathname.new(@item.path)
|
93
|
+
|
94
|
+
# Calculate elative path (method depends on whether destination is a
|
95
|
+
# directory or not).
|
96
|
+
if src_path.to_s[-1,1] != '/'
|
97
|
+
relative_path = dst_path.relative_path_from(src_path.dirname).to_s
|
98
|
+
else
|
99
|
+
relative_path = dst_path.relative_path_from(src_path).to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
# Add trailing slash if necessary
|
103
|
+
if dst_path.to_s[-1,1] == '/'
|
104
|
+
relative_path += '/'
|
105
|
+
end
|
106
|
+
|
107
|
+
# Done
|
108
|
+
relative_path
|
109
|
+
end
|
110
|
+
|
71
111
|
end
|
72
112
|
|
73
113
|
end
|