jekyll 3.2.0.pre.beta1 → 3.2.0.pre.beta2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of jekyll might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -95
- data/README.markdown +6 -4
- data/{bin → exe}/jekyll +18 -14
- data/lib/jekyll.rb +79 -76
- data/lib/jekyll/collection.rb +32 -16
- data/lib/jekyll/command.rb +17 -13
- data/lib/jekyll/commands/build.rb +7 -2
- data/lib/jekyll/commands/doctor.rb +3 -1
- data/lib/jekyll/commands/new.rb +3 -0
- data/lib/jekyll/commands/new_theme.rb +7 -4
- data/lib/jekyll/commands/serve.rb +2 -0
- data/lib/jekyll/commands/serve/servlet.rb +2 -2
- data/lib/jekyll/configuration.rb +187 -125
- data/lib/jekyll/converters/markdown.rb +19 -9
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +12 -5
- data/lib/jekyll/converters/markdown/rdiscount_parser.rb +4 -4
- data/lib/jekyll/converters/markdown/redcarpet_parser.rb +90 -84
- data/lib/jekyll/convertible.rb +34 -21
- data/lib/jekyll/deprecator.rb +11 -6
- data/lib/jekyll/document.rb +52 -50
- data/lib/jekyll/drops/document_drop.rb +40 -5
- data/lib/jekyll/drops/drop.rb +49 -10
- data/lib/jekyll/drops/excerpt_drop.rb +15 -0
- data/lib/jekyll/drops/jekyll_drop.rb +12 -0
- data/lib/jekyll/drops/site_drop.rb +4 -2
- data/lib/jekyll/drops/url_drop.rb +4 -4
- data/lib/jekyll/entry_filter.rb +9 -6
- data/lib/jekyll/errors.rb +4 -3
- data/lib/jekyll/excerpt.rb +4 -6
- data/lib/jekyll/external.rb +4 -4
- data/lib/jekyll/filters.rb +67 -34
- data/lib/jekyll/frontmatter_defaults.rb +45 -38
- data/lib/jekyll/hooks.rb +21 -21
- data/lib/jekyll/layout.rb +3 -1
- data/lib/jekyll/liquid_renderer.rb +7 -3
- data/lib/jekyll/liquid_renderer/file.rb +1 -1
- data/lib/jekyll/liquid_renderer/table.rb +11 -11
- data/lib/jekyll/log_adapter.rb +2 -2
- data/lib/jekyll/page.rb +10 -10
- data/lib/jekyll/plugin.rb +5 -5
- data/lib/jekyll/plugin_manager.rb +12 -8
- data/lib/jekyll/publisher.rb +1 -1
- data/lib/jekyll/reader.rb +11 -7
- data/lib/jekyll/readers/data_reader.rb +9 -9
- data/lib/jekyll/readers/layout_reader.rb +7 -7
- data/lib/jekyll/readers/page_reader.rb +3 -1
- data/lib/jekyll/readers/post_reader.rb +9 -10
- data/lib/jekyll/readers/static_file_reader.rb +3 -1
- data/lib/jekyll/regenerator.rb +50 -28
- data/lib/jekyll/related_posts.rb +1 -1
- data/lib/jekyll/renderer.rb +29 -20
- data/lib/jekyll/site.rb +92 -50
- data/lib/jekyll/static_file.rb +33 -26
- data/lib/jekyll/stevenson.rb +6 -5
- data/lib/jekyll/tags/highlight.rb +50 -35
- data/lib/jekyll/tags/include.rb +42 -31
- data/lib/jekyll/tags/link.rb +11 -4
- data/lib/jekyll/tags/post_url.rb +8 -7
- data/lib/jekyll/theme.rb +4 -3
- data/lib/jekyll/theme_builder.rb +18 -6
- data/lib/jekyll/url.rb +21 -14
- data/lib/jekyll/utils.rb +57 -28
- data/lib/jekyll/utils/ansi.rb +9 -9
- data/lib/jekyll/utils/platforms.rb +2 -2
- data/lib/jekyll/version.rb +1 -1
- data/lib/site_template/_config.yml +2 -0
- data/lib/site_template/css/main.scss +3 -17
- data/lib/theme_template/_layouts/default.html +1 -0
- data/lib/theme_template/_layouts/page.html +5 -0
- data/lib/theme_template/_layouts/post.html +5 -0
- data/lib/theme_template/example/_post.md +1 -2
- data/lib/theme_template/example/index.html +2 -2
- data/lib/theme_template/gitignore.erb +4 -0
- data/lib/theme_template/theme.gemspec.erb +2 -6
- metadata +10 -18
- data/lib/site_template/_includes/footer.html +0 -38
- data/lib/site_template/_includes/head.html +0 -12
- data/lib/site_template/_includes/header.html +0 -27
- data/lib/site_template/_includes/icon-github.html +0 -1
- data/lib/site_template/_includes/icon-github.svg +0 -1
- data/lib/site_template/_includes/icon-twitter.html +0 -1
- data/lib/site_template/_includes/icon-twitter.svg +0 -1
- data/lib/site_template/_layouts/default.html +0 -20
- data/lib/site_template/_layouts/page.html +0 -14
- data/lib/site_template/_layouts/post.html +0 -15
- data/lib/site_template/_sass/_base.scss +0 -200
- data/lib/site_template/_sass/_layout.scss +0 -242
- data/lib/site_template/_sass/_syntax-highlighting.scss +0 -71
data/lib/jekyll/tags/link.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
module Jekyll
|
2
2
|
module Tags
|
3
3
|
class Link < Liquid::Tag
|
4
|
-
|
4
|
+
class << self
|
5
|
+
def tag_name
|
6
|
+
self.name.split("::").last.downcase
|
7
|
+
end
|
8
|
+
end
|
5
9
|
|
6
10
|
def initialize(tag_name, relative_path, tokens)
|
7
11
|
super
|
@@ -16,11 +20,14 @@ module Jekyll
|
|
16
20
|
return document.url if document.relative_path == @relative_path
|
17
21
|
end
|
18
22
|
|
19
|
-
raise ArgumentError,
|
20
|
-
|
23
|
+
raise ArgumentError, <<eos
|
24
|
+
Could not find document '#{@relative_path}' in tag '#{self.class.tag_name}'.
|
25
|
+
|
26
|
+
Make sure the document exists and the path is correct.
|
27
|
+
eos
|
21
28
|
end
|
22
29
|
end
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
26
|
-
Liquid::Template.register_tag(Jekyll::Tags::Link
|
33
|
+
Liquid::Template.register_tag(Jekyll::Tags::Link.tag_name, Jekyll::Tags::Link)
|
data/lib/jekyll/tags/post_url.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
module Jekyll
|
2
2
|
module Tags
|
3
3
|
class PostComparer
|
4
|
-
MATCHER =
|
4
|
+
MATCHER = %r!^(.+/)*(\d+-\d+-\d+)-(.*)$!
|
5
5
|
|
6
6
|
attr_reader :path, :date, :slug, :name
|
7
7
|
|
8
8
|
def initialize(name)
|
9
9
|
@name = name
|
10
10
|
|
11
|
-
all, @path, @date, @slug = *name.sub(
|
11
|
+
all, @path, @date, @slug = *name.sub(%r!^/!, "").match(MATCHER)
|
12
12
|
unless all
|
13
13
|
raise Jekyll::Errors::InvalidPostNameError,
|
14
14
|
"'#{name}' does not contain valid date and/or title."
|
15
15
|
end
|
16
16
|
|
17
|
-
@name_regex =
|
17
|
+
@name_regex = %r!^#{path}#{date}-#{slug}\.[^.]+!
|
18
18
|
end
|
19
19
|
|
20
20
|
def post_date
|
@@ -42,9 +42,9 @@ module Jekyll
|
|
42
42
|
def post_slug(other)
|
43
43
|
path = other.basename.split("/")[0...-1].join("/")
|
44
44
|
if path.nil? || path == ""
|
45
|
-
other.data[
|
45
|
+
other.data["slug"]
|
46
46
|
else
|
47
|
-
path +
|
47
|
+
path + "/" + other.data["slug"]
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -78,7 +78,8 @@ eos
|
|
78
78
|
|
79
79
|
site.posts.docs.each do |p|
|
80
80
|
next unless @post.deprecated_equality p
|
81
|
-
Jekyll::Deprecator.deprecation_message "A call to
|
81
|
+
Jekyll::Deprecator.deprecation_message "A call to "\
|
82
|
+
"'{{ post_url #{@post.name} }}' did not match " \
|
82
83
|
"a post using the new matching method of checking name " \
|
83
84
|
"(path-date-slug) equality. Please make sure that you " \
|
84
85
|
"change this tag to match the post's name exactly."
|
@@ -95,4 +96,4 @@ eos
|
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
98
|
-
Liquid::Template.register_tag(
|
99
|
+
Liquid::Template.register_tag("post_url", Jekyll::Tags::PostUrl)
|
data/lib/jekyll/theme.rb
CHANGED
@@ -27,7 +27,7 @@ module Jekyll
|
|
27
27
|
|
28
28
|
def configure_sass
|
29
29
|
return unless sass_path
|
30
|
-
require
|
30
|
+
require "sass"
|
31
31
|
Sass.load_paths << sass_path
|
32
32
|
end
|
33
33
|
|
@@ -38,7 +38,7 @@ module Jekyll
|
|
38
38
|
return unless resolved_dir
|
39
39
|
|
40
40
|
path = Jekyll.sanitized_path(root, resolved_dir)
|
41
|
-
path if
|
41
|
+
path if File.directory?(path)
|
42
42
|
end
|
43
43
|
|
44
44
|
def realpath_for(folder)
|
@@ -50,7 +50,8 @@ module Jekyll
|
|
50
50
|
def gemspec
|
51
51
|
@gemspec ||= Gem::Specification.find_by_name(name)
|
52
52
|
rescue Gem::LoadError
|
53
|
-
raise Jekyll::Errors::MissingDependencyException,
|
53
|
+
raise Jekyll::Errors::MissingDependencyException,
|
54
|
+
"The #{name} theme could not be found."
|
54
55
|
end
|
55
56
|
end
|
56
57
|
end
|
data/lib/jekyll/theme_builder.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
class Jekyll::ThemeBuilder
|
2
2
|
SCAFFOLD_DIRECTORIES = %w(
|
3
|
-
_layouts _includes _sass
|
3
|
+
_layouts _includes _sass
|
4
4
|
).freeze
|
5
5
|
|
6
|
-
attr_reader :name, :path
|
6
|
+
attr_reader :name, :path, :code_of_conduct
|
7
7
|
|
8
|
-
def initialize(theme_name)
|
9
|
-
@name = theme_name.to_s.tr(" ", "_").gsub(
|
8
|
+
def initialize(theme_name, opts)
|
9
|
+
@name = theme_name.to_s.tr(" ", "_").gsub(%r!_+!, "_")
|
10
10
|
@path = Pathname.new(File.expand_path(name, Dir.pwd))
|
11
|
+
@code_of_conduct = !!opts["code_of_conduct"]
|
11
12
|
end
|
12
13
|
|
13
14
|
def create!
|
14
15
|
create_directories
|
16
|
+
create_starter_files
|
15
17
|
create_gemspec
|
16
18
|
create_accessories
|
17
19
|
create_example_site
|
@@ -55,6 +57,13 @@ class Jekyll::ThemeBuilder
|
|
55
57
|
|
56
58
|
def create_directories
|
57
59
|
mkdir_p(SCAFFOLD_DIRECTORIES)
|
60
|
+
mkdir_p(%w(example example/_posts))
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_starter_files
|
64
|
+
%w(page post default).each do |layout|
|
65
|
+
write_file("_layouts/#{layout}.html", template("_layouts/#{layout}.html"))
|
66
|
+
end
|
58
67
|
end
|
59
68
|
|
60
69
|
def create_gemspec
|
@@ -63,7 +72,9 @@ class Jekyll::ThemeBuilder
|
|
63
72
|
end
|
64
73
|
|
65
74
|
def create_accessories
|
66
|
-
%w(README.md Rakefile
|
75
|
+
accessories = %w(README.md Rakefile LICENSE.txt)
|
76
|
+
accessories << "CODE_OF_CONDUCT.md" if code_of_conduct
|
77
|
+
accessories.each do |filename|
|
67
78
|
write_file(filename, template(filename))
|
68
79
|
end
|
69
80
|
end
|
@@ -81,6 +92,7 @@ class Jekyll::ThemeBuilder
|
|
81
92
|
def initialize_git_repo
|
82
93
|
Jekyll.logger.info "initialize", path.join(".git").to_s
|
83
94
|
Dir.chdir(path.to_s) { `git init` }
|
95
|
+
write_file(".gitignore", template("gitignore"))
|
84
96
|
end
|
85
97
|
|
86
98
|
def user_name
|
@@ -102,7 +114,7 @@ class Jekyll::ThemeBuilder
|
|
102
114
|
@theme_builder = theme_builder
|
103
115
|
end
|
104
116
|
|
105
|
-
def
|
117
|
+
def jekyll_version_with_minor
|
106
118
|
Jekyll::VERSION.split(".").take(2).join(".")
|
107
119
|
end
|
108
120
|
|
data/lib/jekyll/url.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "uri"
|
2
2
|
|
3
3
|
# Public: Methods that generate a URL for a resource such as a Post or a Page.
|
4
4
|
#
|
@@ -35,8 +35,15 @@ module Jekyll
|
|
35
35
|
# The generated relative URL of the resource
|
36
36
|
#
|
37
37
|
# Returns the String URL
|
38
|
+
# Raises a Jekyll::Errors::InvalidURLError if the relative URL contains a colon
|
38
39
|
def to_s
|
39
|
-
sanitize_url(generated_permalink || generated_url)
|
40
|
+
sanitized_url = sanitize_url(generated_permalink || generated_url)
|
41
|
+
if sanitized_url.include?(":")
|
42
|
+
raise Jekyll::Errors::InvalidURLError,
|
43
|
+
"The URL #{sanitized_url} is invalid because it contains a colon."
|
44
|
+
else
|
45
|
+
sanitized_url
|
46
|
+
end
|
40
47
|
end
|
41
48
|
|
42
49
|
# Generates a URL from the permalink
|
@@ -67,32 +74,32 @@ module Jekyll
|
|
67
74
|
|
68
75
|
def generate_url_from_hash(template)
|
69
76
|
@placeholders.inject(template) do |result, token|
|
70
|
-
break result if result.index(
|
77
|
+
break result if result.index(":").nil?
|
71
78
|
if token.last.nil?
|
72
|
-
# Remove leading
|
73
|
-
result.gsub(
|
79
|
+
# Remove leading "/" to avoid generating urls with `//`
|
80
|
+
result.gsub(%r!/:#{token.first}!, "")
|
74
81
|
else
|
75
|
-
result.gsub(
|
82
|
+
result.gsub(%r!:#{token.first}!, self.class.escape_path(token.last))
|
76
83
|
end
|
77
84
|
end
|
78
85
|
end
|
79
86
|
|
80
87
|
def generate_url_from_drop(template)
|
81
|
-
template.gsub(
|
82
|
-
replacement = @placeholders.public_send(match.sub(
|
88
|
+
template.gsub(%r!:([a-z_]+)!) do |match|
|
89
|
+
replacement = @placeholders.public_send(match.sub(":".freeze, "".freeze))
|
83
90
|
if replacement.nil?
|
84
|
-
|
91
|
+
"".freeze
|
85
92
|
else
|
86
93
|
self.class.escape_path(replacement)
|
87
94
|
end
|
88
|
-
end.gsub(
|
95
|
+
end.gsub(%r!//!, "/".freeze)
|
89
96
|
end
|
90
97
|
|
91
98
|
# Returns a sanitized String URL, stripping "../../" and multiples of "/",
|
92
99
|
# as well as the beginning "/" so we can enforce and ensure it.
|
93
100
|
|
94
101
|
def sanitize_url(str)
|
95
|
-
"/" + str.gsub(
|
102
|
+
"/" + str.gsub(%r!/{2,}!, "/").gsub(%r!\.+/|\A/+!, "")
|
96
103
|
end
|
97
104
|
|
98
105
|
# Escapes a path to be a valid URL path segment
|
@@ -106,7 +113,7 @@ module Jekyll
|
|
106
113
|
#
|
107
114
|
# Returns the escaped path.
|
108
115
|
def self.escape_path(path)
|
109
|
-
# Because URI.escape doesn't escape
|
116
|
+
# Because URI.escape doesn't escape "?", "[" and "]" by default,
|
110
117
|
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
111
118
|
#
|
112
119
|
# URI path segment is defined in RFC 3986 as follows:
|
@@ -116,7 +123,7 @@ module Jekyll
|
|
116
123
|
# pct-encoded = "%" HEXDIG HEXDIG
|
117
124
|
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
118
125
|
# / "*" / "+" / "," / ";" / "="
|
119
|
-
URI.escape(path,
|
126
|
+
URI.escape(path, %r{[^a-zA-Z\d\-._~!$&'()*+,;=:@\/]}).encode("utf-8")
|
120
127
|
end
|
121
128
|
|
122
129
|
# Unescapes a URL path segment
|
@@ -130,7 +137,7 @@ module Jekyll
|
|
130
137
|
#
|
131
138
|
# Returns the unescaped path.
|
132
139
|
def self.unescape_path(path)
|
133
|
-
URI.unescape(path.encode(
|
140
|
+
URI.unescape(path.encode("utf-8"))
|
134
141
|
end
|
135
142
|
end
|
136
143
|
end
|
data/lib/jekyll/utils.rb
CHANGED
@@ -2,27 +2,25 @@
|
|
2
2
|
module Jekyll
|
3
3
|
module Utils
|
4
4
|
extend self
|
5
|
-
autoload :Platforms,
|
5
|
+
autoload :Platforms, "jekyll/utils/platforms"
|
6
6
|
autoload :Ansi, "jekyll/utils/ansi"
|
7
7
|
|
8
8
|
# Constants for use in #slugify
|
9
|
-
SLUGIFY_MODES = %w(raw default pretty)
|
9
|
+
SLUGIFY_MODES = %w(raw default pretty).freeze
|
10
10
|
SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
|
11
|
-
SLUGIFY_DEFAULT_REGEXP = Regexp.new(
|
11
|
+
SLUGIFY_DEFAULT_REGEXP = Regexp.new("[^[:alnum:]]+").freeze
|
12
12
|
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^[:alnum:]._~!$&'()+,;=@]+").freeze
|
13
13
|
|
14
14
|
# Takes an indented string and removes the preceding spaces on each line
|
15
15
|
|
16
16
|
def strip_heredoc(str)
|
17
|
-
str.gsub(
|
17
|
+
str.gsub(%r!^[ \t]{#{(str.scan(%r!^[ \t]*(?=\S)!).min || "").size}}!, "")
|
18
18
|
end
|
19
19
|
|
20
20
|
# Takes a slug and turns it into a simple title.
|
21
21
|
|
22
22
|
def titleize_slug(slug)
|
23
|
-
slug.split("-").map!
|
24
|
-
val.capitalize
|
25
|
-
end.join(" ")
|
23
|
+
slug.split("-").map!(&:capitalize).join(" ")
|
26
24
|
end
|
27
25
|
|
28
26
|
# Non-destructive version of deep_merge_hashes! See that method.
|
@@ -42,17 +40,9 @@ module Jekyll
|
|
42
40
|
#
|
43
41
|
# Thanks to whoever made it.
|
44
42
|
def deep_merge_hashes!(target, overwrite)
|
45
|
-
target
|
46
|
-
|
47
|
-
|
48
|
-
else
|
49
|
-
mergable?(old_val) && mergable?(new_val) ? deep_merge_hashes(old_val, new_val) : new_val
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
if target.respond_to?(:default_proc) && overwrite.respond_to?(:default_proc) && target.default_proc.nil?
|
54
|
-
target.default_proc = overwrite.default_proc
|
55
|
-
end
|
43
|
+
merge_values(target, overwrite)
|
44
|
+
merge_default_proc(target, overwrite)
|
45
|
+
duplicate_frozen_values(target)
|
56
46
|
|
57
47
|
target
|
58
48
|
end
|
@@ -61,6 +51,15 @@ module Jekyll
|
|
61
51
|
value.is_a?(Hash) || value.is_a?(Drops::Drop)
|
62
52
|
end
|
63
53
|
|
54
|
+
def duplicable?(obj)
|
55
|
+
case obj
|
56
|
+
when nil, false, true, Symbol, Numeric
|
57
|
+
false
|
58
|
+
else
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
64
63
|
# Read array from the supplied hash favouring the singular key
|
65
64
|
# and then the plural key, and handling any nil entries.
|
66
65
|
#
|
@@ -71,7 +70,9 @@ module Jekyll
|
|
71
70
|
# Returns an array
|
72
71
|
def pluralized_array_from_hash(hash, singular_key, plural_key)
|
73
72
|
[].tap do |array|
|
74
|
-
|
73
|
+
value = value_from_singular_key(hash, singular_key)
|
74
|
+
value ||= value_from_plural_key(hash, plural_key)
|
75
|
+
array << value
|
75
76
|
end.flatten.compact
|
76
77
|
end
|
77
78
|
|
@@ -133,17 +134,19 @@ module Jekyll
|
|
133
134
|
# Determines whether a given file has
|
134
135
|
#
|
135
136
|
# Returns true if the YAML front matter is present.
|
137
|
+
# rubocop: disable PredicateName
|
136
138
|
def has_yaml_header?(file)
|
137
|
-
!!(File.open(file,
|
139
|
+
!!(File.open(file, "rb", &:readline) =~ %r!\A---\s*\r?\n!)
|
138
140
|
rescue EOFError
|
139
141
|
false
|
140
142
|
end
|
143
|
+
# rubocop: enable PredicateName
|
141
144
|
|
142
145
|
# Slugify a filename or title.
|
143
146
|
#
|
144
147
|
# string - the filename or title to slugify
|
145
148
|
# mode - how string is slugified
|
146
|
-
# cased - whether to replace all
|
149
|
+
# cased - whether to replace all uppercase letters with their
|
147
150
|
# lowercase counterparts
|
148
151
|
#
|
149
152
|
# When mode is "none", return the given string.
|
@@ -172,7 +175,7 @@ module Jekyll
|
|
172
175
|
#
|
173
176
|
# Returns the slugified string.
|
174
177
|
def slugify(string, mode: nil, cased: false)
|
175
|
-
mode ||=
|
178
|
+
mode ||= "default"
|
176
179
|
return nil if string.nil?
|
177
180
|
|
178
181
|
unless SLUGIFY_MODES.include?(mode)
|
@@ -182,21 +185,21 @@ module Jekyll
|
|
182
185
|
# Replace each character sequence with a hyphen
|
183
186
|
re =
|
184
187
|
case mode
|
185
|
-
when
|
188
|
+
when "raw"
|
186
189
|
SLUGIFY_RAW_REGEXP
|
187
|
-
when
|
190
|
+
when "default"
|
188
191
|
SLUGIFY_DEFAULT_REGEXP
|
189
|
-
when
|
192
|
+
when "pretty"
|
190
193
|
# "._~!$&'()+,;=@" is human readable (not URI-escaped) in URL
|
191
194
|
# and is allowed in both extN and NTFS.
|
192
195
|
SLUGIFY_PRETTY_REGEXP
|
193
196
|
end
|
194
197
|
|
195
198
|
# Strip according to the mode
|
196
|
-
slug = string.gsub(re,
|
199
|
+
slug = string.gsub(re, "-")
|
197
200
|
|
198
201
|
# Remove leading/trailing hyphen
|
199
|
-
slug.gsub!(
|
202
|
+
slug.gsub!(%r!^\-|\-$!i, "")
|
200
203
|
|
201
204
|
slug.downcase! unless cased
|
202
205
|
slug
|
@@ -267,7 +270,7 @@ module Jekyll
|
|
267
270
|
# Returns matched pathes
|
268
271
|
def safe_glob(dir, patterns, flags = 0)
|
269
272
|
return [] unless Dir.exist?(dir)
|
270
|
-
pattern = File.join(Array
|
273
|
+
pattern = File.join(Array(patterns))
|
271
274
|
return [dir] if pattern.empty?
|
272
275
|
Dir.chdir(dir) do
|
273
276
|
Dir.glob(pattern, flags).map { |f| File.join(dir, f) }
|
@@ -284,5 +287,31 @@ module Jekyll
|
|
284
287
|
merged
|
285
288
|
end
|
286
289
|
|
290
|
+
private
|
291
|
+
def merge_values(target, overwrite)
|
292
|
+
target.merge!(overwrite) do |_key, old_val, new_val|
|
293
|
+
if new_val.nil?
|
294
|
+
old_val
|
295
|
+
elsif mergable?(old_val) && mergable?(new_val)
|
296
|
+
deep_merge_hashes(old_val, new_val)
|
297
|
+
else
|
298
|
+
new_val
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
private
|
304
|
+
def merge_default_proc(target, overwrite)
|
305
|
+
if target.is_a?(Hash) && overwrite.is_a?(Hash) && target.default_proc.nil?
|
306
|
+
target.default_proc = overwrite.default_proc
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
private
|
311
|
+
def duplicate_frozen_values(target)
|
312
|
+
target.each do |key, val|
|
313
|
+
target[key] = val.dup if val.frozen? && duplicable?(val)
|
314
|
+
end
|
315
|
+
end
|
287
316
|
end
|
288
317
|
end
|
data/lib/jekyll/utils/ansi.rb
CHANGED
@@ -8,17 +8,17 @@ module Jekyll
|
|
8
8
|
extend self
|
9
9
|
|
10
10
|
ESCAPE = format("%c", 27)
|
11
|
-
MATCH =
|
11
|
+
MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix
|
12
12
|
COLORS = {
|
13
|
-
:red
|
14
|
-
:green
|
15
|
-
:black
|
13
|
+
:red => 31,
|
14
|
+
:green => 32,
|
15
|
+
:black => 30,
|
16
16
|
:magenta => 35,
|
17
|
-
:yellow
|
18
|
-
:white
|
19
|
-
:blue
|
20
|
-
:cyan
|
21
|
-
}
|
17
|
+
:yellow => 33,
|
18
|
+
:white => 37,
|
19
|
+
:blue => 34,
|
20
|
+
:cyan => 36
|
21
|
+
}.freeze
|
22
22
|
|
23
23
|
# Strip ANSI from the current string. It also strips cursor stuff,
|
24
24
|
# well some of it, and it also strips some other stuff that a lot of
|