jekyll 4.0.0.pre.alpha1 → 4.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +58 -17
- data/lib/jekyll.rb +5 -1
- data/lib/jekyll/cache.rb +71 -64
- data/lib/jekyll/cleaner.rb +5 -5
- data/lib/jekyll/collection.rb +6 -4
- data/lib/jekyll/command.rb +4 -2
- data/lib/jekyll/commands/new.rb +4 -4
- data/lib/jekyll/commands/serve.rb +9 -1
- data/lib/jekyll/commands/serve/servlet.rb +13 -14
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/configuration.rb +40 -129
- data/lib/jekyll/converters/identity.rb +2 -2
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +70 -9
- data/lib/jekyll/convertible.rb +21 -20
- data/lib/jekyll/document.rb +56 -31
- data/lib/jekyll/drops/document_drop.rb +12 -0
- data/lib/jekyll/drops/drop.rb +14 -8
- data/lib/jekyll/drops/site_drop.rb +11 -1
- data/lib/jekyll/drops/url_drop.rb +52 -1
- data/lib/jekyll/entry_filter.rb +38 -44
- data/lib/jekyll/excerpt.rb +3 -3
- data/lib/jekyll/filters.rb +140 -22
- data/lib/jekyll/filters/url_filters.rb +41 -14
- data/lib/jekyll/frontmatter_defaults.rb +15 -20
- data/lib/jekyll/hooks.rb +2 -5
- data/lib/jekyll/inclusion.rb +32 -0
- data/lib/jekyll/liquid_renderer.rb +18 -15
- data/lib/jekyll/liquid_renderer/file.rb +10 -0
- data/lib/jekyll/liquid_renderer/table.rb +18 -61
- data/lib/jekyll/mime.types +53 -11
- data/lib/jekyll/page.rb +26 -2
- data/lib/jekyll/page_excerpt.rb +25 -0
- data/lib/jekyll/path_manager.rb +31 -0
- data/lib/jekyll/profiler.rb +58 -0
- data/lib/jekyll/reader.rb +4 -1
- data/lib/jekyll/readers/collection_reader.rb +1 -0
- data/lib/jekyll/readers/data_reader.rb +1 -0
- data/lib/jekyll/readers/layout_reader.rb +1 -0
- data/lib/jekyll/readers/page_reader.rb +5 -5
- data/lib/jekyll/readers/post_reader.rb +2 -1
- data/lib/jekyll/readers/static_file_reader.rb +3 -3
- data/lib/jekyll/readers/theme_assets_reader.rb +1 -0
- data/lib/jekyll/renderer.rb +9 -15
- data/lib/jekyll/site.rb +21 -12
- data/lib/jekyll/static_file.rb +15 -10
- data/lib/jekyll/tags/highlight.rb +2 -4
- data/lib/jekyll/tags/include.rb +67 -11
- data/lib/jekyll/tags/post_url.rb +8 -5
- data/lib/jekyll/theme.rb +19 -10
- data/lib/jekyll/url.rb +7 -3
- data/lib/jekyll/utils.rb +14 -18
- data/lib/jekyll/utils/platforms.rb +1 -1
- data/lib/jekyll/utils/win_tz.rb +1 -1
- data/lib/jekyll/version.rb +1 -1
- data/lib/theme_template/theme.gemspec.erb +1 -4
- metadata +33 -36
data/lib/jekyll/static_file.rb
CHANGED
@@ -4,7 +4,7 @@ module Jekyll
|
|
4
4
|
class StaticFile
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
attr_reader :relative_path, :extname, :name
|
7
|
+
attr_reader :relative_path, :extname, :name
|
8
8
|
|
9
9
|
def_delegator :to_liquid, :to_json, :to_json
|
10
10
|
|
@@ -25,7 +25,7 @@ module Jekyll
|
|
25
25
|
# base - The String path to the <source>.
|
26
26
|
# dir - The String path between <source> and the file.
|
27
27
|
# name - The String filename of the file.
|
28
|
-
# rubocop: disable ParameterLists
|
28
|
+
# rubocop: disable Metrics/ParameterLists
|
29
29
|
def initialize(site, base, dir, name, collection = nil)
|
30
30
|
@site = site
|
31
31
|
@base = base
|
@@ -34,17 +34,18 @@ module Jekyll
|
|
34
34
|
@collection = collection
|
35
35
|
@relative_path = File.join(*[@dir, @name].compact)
|
36
36
|
@extname = File.extname(@name)
|
37
|
-
@data = @site.frontmatter_defaults.all(relative_path, type)
|
38
37
|
end
|
39
|
-
# rubocop: enable ParameterLists
|
38
|
+
# rubocop: enable Metrics/ParameterLists
|
40
39
|
|
41
40
|
# Returns source file path.
|
42
41
|
def path
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
@path ||= begin
|
43
|
+
# Static file is from a collection inside custom collections directory
|
44
|
+
if !@collection.nil? && !@site.config["collections_dir"].empty?
|
45
|
+
File.join(*[@base, @site.config["collections_dir"], @dir, @name].compact)
|
46
|
+
else
|
47
|
+
File.join(*[@base, @dir, @name].compact)
|
48
|
+
end
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
@@ -111,6 +112,10 @@ module Jekyll
|
|
111
112
|
true
|
112
113
|
end
|
113
114
|
|
115
|
+
def data
|
116
|
+
@data ||= @site.frontmatter_defaults.all(relative_path, type)
|
117
|
+
end
|
118
|
+
|
114
119
|
def to_liquid
|
115
120
|
@to_liquid ||= Drops::StaticFileDrop.new(self)
|
116
121
|
end
|
@@ -126,7 +131,7 @@ module Jekyll
|
|
126
131
|
:collection => @collection.label,
|
127
132
|
:path => cleaned_relative_path,
|
128
133
|
:output_ext => "",
|
129
|
-
:name =>
|
134
|
+
:name => basename,
|
130
135
|
:title => "",
|
131
136
|
}
|
132
137
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Jekyll
|
4
4
|
module Tags
|
5
|
-
class HighlightBlock < Liquid::
|
5
|
+
class HighlightBlock < Liquid::Block
|
6
6
|
include Liquid::StandardFilters
|
7
7
|
|
8
8
|
# The regular expression syntax checker. Start with the language specifier.
|
@@ -33,7 +33,7 @@ module Jekyll
|
|
33
33
|
def render(context)
|
34
34
|
prefix = context["highlighter_prefix"] || ""
|
35
35
|
suffix = context["highlighter_suffix"] || ""
|
36
|
-
code
|
36
|
+
code = super.to_s.gsub(LEADING_OR_TRAILING_LINE_TERMINATORS, "")
|
37
37
|
|
38
38
|
output =
|
39
39
|
case context.registers[:site].highlighter
|
@@ -103,8 +103,6 @@ module Jekyll
|
|
103
103
|
"<figure class=\"highlight\"><pre><code #{code_attributes}>"\
|
104
104
|
"#{code.chomp}</code></pre></figure>"
|
105
105
|
end
|
106
|
-
|
107
|
-
def ensure_valid_markup(tag_name, markup, parse_context); end
|
108
106
|
end
|
109
107
|
end
|
110
108
|
end
|
data/lib/jekyll/tags/include.rb
CHANGED
@@ -5,25 +5,26 @@ module Jekyll
|
|
5
5
|
class IncludeTag < Liquid::Tag
|
6
6
|
VALID_SYNTAX = %r!
|
7
7
|
([\w-]+)\s*=\s*
|
8
|
-
(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w
|
8
|
+
(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w.-]+))
|
9
9
|
!x.freeze
|
10
10
|
VARIABLE_SYNTAX = %r!
|
11
|
-
(?<variable>[^{]*(\{\{\s*[\w
|
11
|
+
(?<variable>[^{]*(\{\{\s*[\w\-.]+\s*(\|.*)?\}\}[^\s{}]*)+)
|
12
12
|
(?<params>.*)
|
13
13
|
!mx.freeze
|
14
14
|
|
15
15
|
FULL_VALID_SYNTAX = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!.freeze
|
16
|
-
VALID_FILENAME_CHARS = %r!^[\w
|
16
|
+
VALID_FILENAME_CHARS = %r!^[\w/.-]+$!.freeze
|
17
17
|
INVALID_SEQUENCES = %r![./]{2,}!.freeze
|
18
18
|
|
19
19
|
def initialize(tag_name, markup, tokens)
|
20
20
|
super
|
21
|
-
|
21
|
+
markup = markup.strip
|
22
|
+
matched = markup.match(VARIABLE_SYNTAX)
|
22
23
|
if matched
|
23
24
|
@file = matched["variable"].strip
|
24
25
|
@params = matched["params"].strip
|
25
26
|
else
|
26
|
-
@file, @params = markup.
|
27
|
+
@file, @params = markup.split(%r!\s+!, 2)
|
27
28
|
end
|
28
29
|
validate_params if @params
|
29
30
|
@tag_name = tag_name
|
@@ -54,7 +55,7 @@ module Jekyll
|
|
54
55
|
end
|
55
56
|
|
56
57
|
def validate_file_name(file)
|
57
|
-
if file
|
58
|
+
if INVALID_SEQUENCES.match?(file) || !VALID_FILENAME_CHARS.match?(file)
|
58
59
|
raise ArgumentError, <<~MSG
|
59
60
|
Invalid syntax for include tag. File contains invalid characters or sequences:
|
60
61
|
|
@@ -69,7 +70,7 @@ module Jekyll
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def validate_params
|
72
|
-
unless @params
|
73
|
+
unless FULL_VALID_SYNTAX.match?(@params)
|
73
74
|
raise ArgumentError, <<~MSG
|
74
75
|
Invalid syntax for include tag:
|
75
76
|
|
@@ -90,7 +91,7 @@ module Jekyll
|
|
90
91
|
|
91
92
|
# Render the variable if required
|
92
93
|
def render_variable(context)
|
93
|
-
Liquid::Template.parse(@file).render(context) if @file
|
94
|
+
Liquid::Template.parse(@file).render(context) if VARIABLE_SYNTAX.match?(@file)
|
94
95
|
end
|
95
96
|
|
96
97
|
def tag_includes_dirs(context)
|
@@ -100,7 +101,7 @@ module Jekyll
|
|
100
101
|
def locate_include_file(context, file, safe)
|
101
102
|
includes_dirs = tag_includes_dirs(context)
|
102
103
|
includes_dirs.each do |dir|
|
103
|
-
path =
|
104
|
+
path = PathManager.join(dir, file)
|
104
105
|
return path if valid_include_file?(path, dir.to_s, safe)
|
105
106
|
end
|
106
107
|
raise IOError, could_not_locate_message(file, includes_dirs, safe)
|
@@ -176,7 +177,7 @@ module Jekyll
|
|
176
177
|
|
177
178
|
# This method allows to modify the file content by inheriting from the class.
|
178
179
|
def read_file(file, context)
|
179
|
-
File.read(file, file_read_opts(context))
|
180
|
+
File.read(file, **file_read_opts(context))
|
180
181
|
end
|
181
182
|
|
182
183
|
private
|
@@ -192,6 +193,60 @@ module Jekyll
|
|
192
193
|
end
|
193
194
|
end
|
194
195
|
|
196
|
+
# Do not inherit from this class.
|
197
|
+
# TODO: Merge into the `Jekyll::Tags::IncludeTag` in v5.0
|
198
|
+
class OptimizedIncludeTag < IncludeTag
|
199
|
+
def render(context)
|
200
|
+
@site ||= context.registers[:site]
|
201
|
+
|
202
|
+
file = render_variable(context) || @file
|
203
|
+
validate_file_name(file)
|
204
|
+
|
205
|
+
@site.inclusions[file] ||= locate_include_file(file)
|
206
|
+
inclusion = @site.inclusions[file]
|
207
|
+
|
208
|
+
add_include_to_dependency(inclusion, context) if @site.incremental?
|
209
|
+
|
210
|
+
context.stack do
|
211
|
+
context["include"] = parse_params(context) if @params
|
212
|
+
inclusion.render(context)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
218
|
+
def locate_include_file(file)
|
219
|
+
@site.includes_load_paths.each do |dir|
|
220
|
+
path = PathManager.join(dir, file)
|
221
|
+
return Inclusion.new(@site, dir, file) if valid_include_file?(path, dir)
|
222
|
+
end
|
223
|
+
raise IOError, could_not_locate_message(file, @site.includes_load_paths, @site.safe)
|
224
|
+
end
|
225
|
+
|
226
|
+
def valid_include_file?(path, dir)
|
227
|
+
File.file?(path) && !outside_scope?(path, dir)
|
228
|
+
end
|
229
|
+
|
230
|
+
def outside_scope?(path, dir)
|
231
|
+
@site.safe && !realpath_prefixed_with?(path, dir)
|
232
|
+
end
|
233
|
+
|
234
|
+
def realpath_prefixed_with?(path, dir)
|
235
|
+
File.realpath(path).start_with?(dir)
|
236
|
+
rescue StandardError
|
237
|
+
false
|
238
|
+
end
|
239
|
+
|
240
|
+
def add_include_to_dependency(inclusion, context)
|
241
|
+
return unless context.registers[:page]&.key?("path")
|
242
|
+
|
243
|
+
@site.regenerator.add_dependency(
|
244
|
+
@site.in_source_dir(context.registers[:page]["path"]),
|
245
|
+
inclusion.path
|
246
|
+
)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
195
250
|
class IncludeRelativeTag < IncludeTag
|
196
251
|
def tag_includes_dirs(context)
|
197
252
|
Array(page_path(context)).freeze
|
@@ -209,6 +264,7 @@ module Jekyll
|
|
209
264
|
else
|
210
265
|
File.join(site.config["collections_dir"], page_payload["path"])
|
211
266
|
end
|
267
|
+
resource_path.sub!(%r!/#excerpt\z!, "")
|
212
268
|
site.in_source_dir File.dirname(resource_path)
|
213
269
|
end
|
214
270
|
end
|
@@ -216,5 +272,5 @@ module Jekyll
|
|
216
272
|
end
|
217
273
|
end
|
218
274
|
|
219
|
-
Liquid::Template.register_tag("include", Jekyll::Tags::
|
275
|
+
Liquid::Template.register_tag("include", Jekyll::Tags::OptimizedIncludeTag)
|
220
276
|
Liquid::Template.register_tag("include_relative", Jekyll::Tags::IncludeRelativeTag)
|
data/lib/jekyll/tags/post_url.rb
CHANGED
@@ -57,6 +57,8 @@ module Jekyll
|
|
57
57
|
end
|
58
58
|
|
59
59
|
class PostUrl < Liquid::Tag
|
60
|
+
include Jekyll::Filters::URLFilters
|
61
|
+
|
60
62
|
def initialize(tag_name, post, tokens)
|
61
63
|
super
|
62
64
|
@orig_post = post.strip
|
@@ -72,24 +74,25 @@ module Jekyll
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def render(context)
|
77
|
+
@context = context
|
75
78
|
site = context.registers[:site]
|
76
79
|
|
77
|
-
site.posts.docs.each do |
|
78
|
-
return
|
80
|
+
site.posts.docs.each do |document|
|
81
|
+
return relative_url(document) if @post == document
|
79
82
|
end
|
80
83
|
|
81
84
|
# New matching method did not match, fall back to old method
|
82
85
|
# with deprecation warning if this matches
|
83
86
|
|
84
|
-
site.posts.docs.each do |
|
85
|
-
next unless @post.deprecated_equality
|
87
|
+
site.posts.docs.each do |document|
|
88
|
+
next unless @post.deprecated_equality document
|
86
89
|
|
87
90
|
Jekyll::Deprecator.deprecation_message "A call to "\
|
88
91
|
"'{% post_url #{@post.name} %}' did not match " \
|
89
92
|
"a post using the new matching method of checking name " \
|
90
93
|
"(path-date-slug) equality. Please make sure that you " \
|
91
94
|
"change this tag to match the post's name exactly."
|
92
|
-
return
|
95
|
+
return relative_url(document)
|
93
96
|
end
|
94
97
|
|
95
98
|
raise Jekyll::Errors::PostURLError, <<~MSG
|
data/lib/jekyll/theme.rb
CHANGED
@@ -4,13 +4,13 @@ module Jekyll
|
|
4
4
|
class Theme
|
5
5
|
extend Forwardable
|
6
6
|
attr_reader :name
|
7
|
+
|
7
8
|
def_delegator :gemspec, :version, :version
|
8
9
|
|
9
10
|
def initialize(name)
|
10
11
|
@name = name.downcase.strip
|
11
12
|
Jekyll.logger.debug "Theme:", name
|
12
13
|
Jekyll.logger.debug "Theme source:", root
|
13
|
-
configure_sass
|
14
14
|
end
|
15
15
|
|
16
16
|
def root
|
@@ -22,6 +22,11 @@ module Jekyll
|
|
22
22
|
"or includes a symbolic link loop"
|
23
23
|
end
|
24
24
|
|
25
|
+
# The name of theme directory
|
26
|
+
def basename
|
27
|
+
@basename ||= File.basename(root)
|
28
|
+
end
|
29
|
+
|
25
30
|
def includes_path
|
26
31
|
@includes_path ||= path_for "_includes"
|
27
32
|
end
|
@@ -38,13 +43,6 @@ module Jekyll
|
|
38
43
|
@assets_path ||= path_for "assets"
|
39
44
|
end
|
40
45
|
|
41
|
-
def configure_sass
|
42
|
-
return unless sass_path
|
43
|
-
|
44
|
-
External.require_with_graceful_fail("sass") unless defined?(Sass)
|
45
|
-
Sass.load_paths << sass_path
|
46
|
-
end
|
47
|
-
|
48
46
|
def runtime_dependencies
|
49
47
|
gemspec.runtime_dependencies
|
50
48
|
end
|
@@ -62,11 +60,22 @@ module Jekyll
|
|
62
60
|
# escape the theme root.
|
63
61
|
# However, symlinks are allowed to point to other directories within the theme.
|
64
62
|
Jekyll.sanitized_path(root, File.realpath(Jekyll.sanitized_path(root, folder.to_s)))
|
65
|
-
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
|
66
|
-
|
63
|
+
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP => e
|
64
|
+
log_realpath_exception(e, folder)
|
67
65
|
nil
|
68
66
|
end
|
69
67
|
|
68
|
+
def log_realpath_exception(err, folder)
|
69
|
+
return if err.is_a?(Errno::ENOENT)
|
70
|
+
|
71
|
+
case err
|
72
|
+
when Errno::EACCES
|
73
|
+
Jekyll.logger.error "Theme error:", "Directory '#{folder}' is not accessible."
|
74
|
+
when Errno::ELOOP
|
75
|
+
Jekyll.logger.error "Theme error:", "Directory '#{folder}' includes a symbolic link loop."
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
70
79
|
def gemspec
|
71
80
|
@gemspec ||= Gem::Specification.find_by_name(name)
|
72
81
|
rescue Gem::LoadError
|
data/lib/jekyll/url.rb
CHANGED
@@ -129,6 +129,8 @@ module Jekyll
|
|
129
129
|
#
|
130
130
|
# Returns the escaped path.
|
131
131
|
def self.escape_path(path)
|
132
|
+
return path if path.empty? || %r!^[a-zA-Z0-9./-]+$!.match?(path)
|
133
|
+
|
132
134
|
# Because URI.escape doesn't escape "?", "[" and "]" by default,
|
133
135
|
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
134
136
|
#
|
@@ -139,8 +141,7 @@ module Jekyll
|
|
139
141
|
# pct-encoded = "%" HEXDIG HEXDIG
|
140
142
|
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
141
143
|
# / "*" / "+" / "," / ";" / "="
|
142
|
-
|
143
|
-
path.encode("utf-8").sub("#", "%23")
|
144
|
+
Addressable::URI.encode(path).encode("utf-8").sub("#", "%23")
|
144
145
|
end
|
145
146
|
|
146
147
|
# Unescapes a URL path segment
|
@@ -154,7 +155,10 @@ module Jekyll
|
|
154
155
|
#
|
155
156
|
# Returns the unescaped path.
|
156
157
|
def self.unescape_path(path)
|
157
|
-
|
158
|
+
path = path.encode("utf-8")
|
159
|
+
return path unless path.include?("%")
|
160
|
+
|
161
|
+
Addressable::URI.unencode(path)
|
158
162
|
end
|
159
163
|
end
|
160
164
|
end
|
data/lib/jekyll/utils.rb
CHANGED
@@ -13,18 +13,11 @@ module Jekyll
|
|
13
13
|
# Constants for use in #slugify
|
14
14
|
SLUGIFY_MODES = %w(raw default pretty ascii latin).freeze
|
15
15
|
SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
|
16
|
-
SLUGIFY_DEFAULT_REGEXP = Regexp.new("[
|
17
|
-
SLUGIFY_PRETTY_REGEXP = Regexp.new("[
|
16
|
+
SLUGIFY_DEFAULT_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}]+").freeze
|
17
|
+
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}._~!$&'()+,;=@]+").freeze
|
18
18
|
SLUGIFY_ASCII_REGEXP = Regexp.new("[^[A-Za-z0-9]]+").freeze
|
19
19
|
|
20
|
-
# Takes an indented string and removes the preceding spaces on each line
|
21
|
-
|
22
|
-
def strip_heredoc(str)
|
23
|
-
str.gsub(%r!^[ \t]{#{(str.scan(%r!^[ \t]*(?=\S)!).min || "").size}}!, "")
|
24
|
-
end
|
25
|
-
|
26
20
|
# Takes a slug and turns it into a simple title.
|
27
|
-
|
28
21
|
def titleize_slug(slug)
|
29
22
|
slug.split("-").map!(&:capitalize).join(" ")
|
30
23
|
end
|
@@ -75,11 +68,14 @@ module Jekyll
|
|
75
68
|
#
|
76
69
|
# Returns an array
|
77
70
|
def pluralized_array_from_hash(hash, singular_key, plural_key)
|
78
|
-
[]
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
71
|
+
array = []
|
72
|
+
value = value_from_singular_key(hash, singular_key)
|
73
|
+
value ||= value_from_plural_key(hash, plural_key)
|
74
|
+
|
75
|
+
array << value
|
76
|
+
array.flatten!
|
77
|
+
array.compact!
|
78
|
+
array
|
83
79
|
end
|
84
80
|
|
85
81
|
def value_from_singular_key(hash, key)
|
@@ -140,9 +136,9 @@ module Jekyll
|
|
140
136
|
# Determines whether a given file has
|
141
137
|
#
|
142
138
|
# Returns true if the YAML front matter is present.
|
143
|
-
# rubocop: disable PredicateName
|
139
|
+
# rubocop: disable Naming/PredicateName
|
144
140
|
def has_yaml_header?(file)
|
145
|
-
|
141
|
+
File.open(file, "rb", &:readline).match? %r!\A---\s*\r?\n!
|
146
142
|
rescue EOFError
|
147
143
|
false
|
148
144
|
end
|
@@ -155,7 +151,7 @@ module Jekyll
|
|
155
151
|
|
156
152
|
content.include?("{%") || content.include?("{{")
|
157
153
|
end
|
158
|
-
# rubocop: enable PredicateName
|
154
|
+
# rubocop: enable Naming/PredicateName
|
159
155
|
|
160
156
|
# Slugify a filename or title.
|
161
157
|
#
|
@@ -219,7 +215,7 @@ module Jekyll
|
|
219
215
|
slug = replace_character_sequence_with_hyphen(string, :mode => mode)
|
220
216
|
|
221
217
|
# Remove leading/trailing hyphen
|
222
|
-
slug.gsub!(%r
|
218
|
+
slug.gsub!(%r!^-|-$!i, "")
|
223
219
|
|
224
220
|
slug.downcase! unless cased
|
225
221
|
Jekyll.logger.warn("Warning:", "Empty `slug` generated for '#{string}'.") if slug.empty?
|