jekyll 3.1.6 → 3.2.0.pre.beta1
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 +200 -74
- data/README.markdown +13 -13
- data/lib/jekyll.rb +12 -8
- data/lib/jekyll/cleaner.rb +11 -8
- data/lib/jekyll/collection.rb +3 -3
- data/lib/jekyll/commands/build.rb +15 -12
- data/lib/jekyll/commands/clean.rb +15 -16
- data/lib/jekyll/commands/doctor.rb +7 -7
- data/lib/jekyll/commands/help.rb +4 -3
- data/lib/jekyll/commands/new.rb +49 -14
- data/lib/jekyll/commands/new_theme.rb +33 -0
- data/lib/jekyll/commands/serve.rb +33 -27
- data/lib/jekyll/commands/serve/servlet.rb +2 -3
- data/lib/jekyll/configuration.rb +10 -34
- data/lib/jekyll/converter.rb +6 -2
- data/lib/jekyll/converters/markdown.rb +1 -1
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +1 -0
- data/lib/jekyll/convertible.rb +6 -9
- data/lib/jekyll/document.rb +5 -1
- data/lib/jekyll/drops/document_drop.rb +7 -33
- data/lib/jekyll/drops/drop.rb +2 -26
- data/lib/jekyll/drops/jekyll_drop.rb +0 -12
- data/lib/jekyll/drops/site_drop.rb +1 -1
- data/lib/jekyll/entry_filter.rb +61 -15
- data/lib/jekyll/errors.rb +6 -0
- data/lib/jekyll/excerpt.rb +5 -2
- data/lib/jekyll/filters.rb +49 -8
- data/lib/jekyll/frontmatter_defaults.rb +2 -2
- data/lib/jekyll/hooks.rb +1 -0
- data/lib/jekyll/layout.rb +16 -1
- data/lib/jekyll/page.rb +1 -0
- data/lib/jekyll/plugin.rb +1 -1
- data/lib/jekyll/plugin_manager.rb +5 -5
- data/lib/jekyll/publisher.rb +4 -4
- data/lib/jekyll/readers/data_reader.rb +3 -2
- data/lib/jekyll/readers/layout_reader.rb +19 -3
- data/lib/jekyll/readers/post_reader.rb +5 -1
- data/lib/jekyll/regenerator.rb +5 -3
- data/lib/jekyll/renderer.rb +4 -6
- data/lib/jekyll/site.rb +47 -18
- data/lib/jekyll/static_file.rb +5 -1
- data/lib/jekyll/tags/include.rb +33 -31
- data/lib/jekyll/tags/link.rb +26 -0
- data/lib/jekyll/tags/post_url.rb +18 -8
- data/lib/jekyll/theme.rb +56 -0
- data/lib/jekyll/theme_builder.rb +117 -0
- data/lib/jekyll/utils.rb +2 -14
- data/lib/jekyll/version.rb +1 -1
- data/lib/site_template/_config.yml +8 -2
- data/lib/site_template/_includes/footer.html +3 -3
- data/lib/site_template/_includes/head.html +2 -2
- data/lib/site_template/_includes/header.html +3 -3
- data/lib/site_template/_layouts/default.html +3 -3
- data/lib/site_template/_layouts/page.html +1 -1
- data/lib/site_template/_layouts/post.html +1 -1
- data/lib/site_template/_sass/_base.scss +11 -17
- data/lib/site_template/index.html +1 -1
- data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
- data/lib/theme_template/Gemfile +2 -0
- data/lib/theme_template/LICENSE.txt.erb +21 -0
- data/lib/theme_template/README.md.erb +46 -0
- data/lib/theme_template/Rakefile.erb +74 -0
- data/lib/theme_template/example/_config.yml.erb +1 -0
- data/lib/theme_template/example/_post.md +13 -0
- data/lib/theme_template/example/index.html +14 -0
- data/lib/theme_template/example/style.scss +7 -0
- data/lib/theme_template/theme.gemspec.erb +22 -0
- metadata +34 -7
- data/lib/jekyll/drops/excerpt_drop.rb +0 -15
@@ -7,7 +7,7 @@ module Jekyll
|
|
7
7
|
DEFAULTS = {
|
8
8
|
"Cache-Control" => "private, max-age=0, proxy-revalidate, " \
|
9
9
|
"no-store, no-cache, must-revalidate"
|
10
|
-
}
|
10
|
+
}.freeze
|
11
11
|
|
12
12
|
def initialize(server, root, callbacks)
|
13
13
|
# So we can access them easily.
|
@@ -25,8 +25,7 @@ module Jekyll
|
|
25
25
|
super || super(req, res, "#{basename}.html")
|
26
26
|
end
|
27
27
|
|
28
|
-
#
|
29
|
-
|
28
|
+
# rubocop:disable Style/MethodName
|
30
29
|
def do_GET(req, res)
|
31
30
|
rtn = super
|
32
31
|
validate_and_ensure_charset(req, res)
|
data/lib/jekyll/configuration.rb
CHANGED
@@ -44,6 +44,7 @@ module Jekyll
|
|
44
44
|
'port' => '4000',
|
45
45
|
'host' => '127.0.0.1',
|
46
46
|
'baseurl' => '',
|
47
|
+
'show_dir_listing' => false,
|
47
48
|
|
48
49
|
# Output Configuration
|
49
50
|
'permalink' => 'date',
|
@@ -71,24 +72,7 @@ module Jekyll
|
|
71
72
|
'hard_wrap' => false,
|
72
73
|
'footnote_nr' => 1
|
73
74
|
}
|
74
|
-
}
|
75
|
-
|
76
|
-
class << self
|
77
|
-
# Static: Produce a Configuration ready for use in a Site.
|
78
|
-
# It takes the input, fills in the defaults where values do not
|
79
|
-
# exist, and patches common issues including migrating options for
|
80
|
-
# backwards compatiblity. Except where a key or value is being fixed,
|
81
|
-
# the user configuration will override the defaults.
|
82
|
-
#
|
83
|
-
# user_config - a Hash or Configuration of overrides.
|
84
|
-
#
|
85
|
-
# Returns a Configuration filled with defaults and fixed for common
|
86
|
-
# problems and backwards-compatibility.
|
87
|
-
def from(user_config)
|
88
|
-
Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys).
|
89
|
-
fix_common_issues.add_default_collections
|
90
|
-
end
|
91
|
-
end
|
75
|
+
}]
|
92
76
|
|
93
77
|
# Public: Turn all keys into string
|
94
78
|
#
|
@@ -165,7 +149,7 @@ module Jekyll
|
|
165
149
|
Jekyll.logger.info "Configuration file:", file
|
166
150
|
next_config
|
167
151
|
rescue SystemCallError
|
168
|
-
if @default_config_file
|
152
|
+
if @default_config_file ||= nil
|
169
153
|
Jekyll.logger.warn "Configuration file:", "none"
|
170
154
|
{}
|
171
155
|
else
|
@@ -185,7 +169,6 @@ module Jekyll
|
|
185
169
|
|
186
170
|
begin
|
187
171
|
files.each do |config_file|
|
188
|
-
next if config_file.nil? or config_file.empty?
|
189
172
|
new_config = read_config_file(config_file)
|
190
173
|
configuration = Utils.deep_merge_hashes(configuration, new_config)
|
191
174
|
end
|
@@ -245,6 +228,7 @@ module Jekyll
|
|
245
228
|
end
|
246
229
|
|
247
230
|
%w(include exclude).each do |option|
|
231
|
+
config[option] ||= []
|
248
232
|
if config[option].is_a?(String)
|
249
233
|
Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" \
|
250
234
|
" must now be specified as an array, but you specified" \
|
@@ -252,7 +236,7 @@ module Jekyll
|
|
252
236
|
" as a list of comma-separated values."
|
253
237
|
config[option] = csv_to_array(config[option])
|
254
238
|
end
|
255
|
-
config[option].map!(&:to_s)
|
239
|
+
config[option].map!(&:to_s)
|
256
240
|
end
|
257
241
|
|
258
242
|
if (config['kramdown'] || {}).key?('use_coderay')
|
@@ -287,22 +271,14 @@ module Jekyll
|
|
287
271
|
def add_default_collections
|
288
272
|
config = clone
|
289
273
|
|
290
|
-
# It defaults to `{}`, so this is only if someone sets it to null manually.
|
291
274
|
return config if config['collections'].nil?
|
292
275
|
|
293
|
-
# Ensure we have a hash.
|
294
276
|
if config['collections'].is_a?(Array)
|
295
277
|
config['collections'] = Hash[config['collections'].map { |c| [c, {}] }]
|
296
278
|
end
|
297
|
-
|
298
|
-
config['collections'] =
|
299
|
-
|
300
|
-
).tap do |collections|
|
301
|
-
collections['posts']['output'] = true
|
302
|
-
if config['permalink']
|
303
|
-
collections['posts']['permalink'] ||= style_to_permalink(config['permalink'])
|
304
|
-
end
|
305
|
-
end
|
279
|
+
config['collections']['posts'] ||= {}
|
280
|
+
config['collections']['posts']['output'] = true
|
281
|
+
config['collections']['posts']['permalink'] = style_to_permalink(config['permalink'])
|
306
282
|
|
307
283
|
config
|
308
284
|
end
|
@@ -310,8 +286,8 @@ module Jekyll
|
|
310
286
|
def renamed_key(old, new, config, _ = nil)
|
311
287
|
if config.key?(old)
|
312
288
|
Jekyll::Deprecator.deprecation_message "The '#{old}' configuration" \
|
313
|
-
"option has been renamed to '#{new}'. Please update your config
|
314
|
-
"file accordingly."
|
289
|
+
" option has been renamed to '#{new}'. Please update your config" \
|
290
|
+
" file accordingly."
|
315
291
|
config[new] = config.delete(old)
|
316
292
|
end
|
317
293
|
end
|
data/lib/jekyll/converter.rb
CHANGED
@@ -8,7 +8,9 @@ module Jekyll
|
|
8
8
|
#
|
9
9
|
# Returns the String prefix.
|
10
10
|
def self.highlighter_prefix(highlighter_prefix = nil)
|
11
|
-
@highlighter_prefix
|
11
|
+
if !defined?(@highlighter_prefix) || !highlighter_prefix.nil?
|
12
|
+
@highlighter_prefix = highlighter_prefix
|
13
|
+
end
|
12
14
|
@highlighter_prefix
|
13
15
|
end
|
14
16
|
|
@@ -20,7 +22,9 @@ module Jekyll
|
|
20
22
|
#
|
21
23
|
# Returns the String suffix.
|
22
24
|
def self.highlighter_suffix(highlighter_suffix = nil)
|
23
|
-
@highlighter_suffix
|
25
|
+
if !defined?(@highlighter_suffix) || !highlighter_suffix.nil?
|
26
|
+
@highlighter_suffix = highlighter_suffix
|
27
|
+
end
|
24
28
|
@highlighter_suffix
|
25
29
|
end
|
26
30
|
|
@@ -6,7 +6,7 @@ module Jekyll
|
|
6
6
|
safe true
|
7
7
|
|
8
8
|
def setup
|
9
|
-
return if @setup
|
9
|
+
return if @setup ||= false
|
10
10
|
unless (@parser = get_processor)
|
11
11
|
Jekyll.logger.error "Invalid Markdown processor given:", @config["markdown"]
|
12
12
|
Jekyll.logger.info "", "Custom processors are not loaded in safe mode" if @config["safe"]
|
data/lib/jekyll/convertible.rb
CHANGED
@@ -39,9 +39,9 @@ module Jekyll
|
|
39
39
|
filename = File.join(base, name)
|
40
40
|
|
41
41
|
begin
|
42
|
-
self.content = File.read(site.in_source_dir(base, name),
|
42
|
+
self.content = File.read(@path || site.in_source_dir(base, name),
|
43
43
|
Utils.merged_file_read_opts(site, opts))
|
44
|
-
if content =~
|
44
|
+
if content =~ Document::YAML_FRONT_MATTER_REGEXP
|
45
45
|
self.content = $POSTMATCH
|
46
46
|
self.data = SafeYAML.load(Regexp.last_match(1))
|
47
47
|
end
|
@@ -209,18 +209,15 @@ module Jekyll
|
|
209
209
|
|
210
210
|
used = Set.new([layout])
|
211
211
|
|
212
|
-
# Reset the payload layout data to ensure it starts fresh for each page.
|
213
|
-
payload["layout"] = nil
|
214
|
-
|
215
212
|
while layout
|
216
213
|
Jekyll.logger.debug "Rendering Layout:", path
|
217
214
|
payload["content"] = output
|
218
|
-
payload["layout"] = Utils.deep_merge_hashes(
|
215
|
+
payload["layout"] = Utils.deep_merge_hashes(payload["layout"] || {}, layout.data)
|
219
216
|
|
220
217
|
self.output = render_liquid(layout.content,
|
221
|
-
|
222
|
-
|
223
|
-
|
218
|
+
payload,
|
219
|
+
info,
|
220
|
+
layout.relative_path)
|
224
221
|
|
225
222
|
# Add layout to dependency tree
|
226
223
|
site.regenerator.add_dependency(
|
data/lib/jekyll/document.rb
CHANGED
@@ -68,7 +68,11 @@ module Jekyll
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def date
|
71
|
-
data['date'] ||= site.time
|
71
|
+
data['date'] ||= (draft? ? source_file_mtime : site.time)
|
72
|
+
end
|
73
|
+
|
74
|
+
def source_file_mtime
|
75
|
+
@source_file_mtime ||= File.mtime(path)
|
72
76
|
end
|
73
77
|
|
74
78
|
# Returns whether the document is a draft. This is only the case if
|
@@ -5,12 +5,10 @@ module Jekyll
|
|
5
5
|
class DocumentDrop < Drop
|
6
6
|
extend Forwardable
|
7
7
|
|
8
|
-
NESTED_OBJECT_FIELD_BLACKLIST = %w{
|
9
|
-
content output excerpt next previous
|
10
|
-
}.freeze
|
11
|
-
|
12
8
|
mutable false
|
13
9
|
|
10
|
+
def_delegator :@obj, :next_doc, :next
|
11
|
+
def_delegator :@obj, :previous_doc, :previous
|
14
12
|
def_delegator :@obj, :relative_path, :path
|
15
13
|
def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
|
16
14
|
|
@@ -22,35 +20,11 @@ module Jekyll
|
|
22
20
|
fallback_data['excerpt'].to_s
|
23
21
|
end
|
24
22
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@obj.next_doc.to_liquid
|
31
|
-
end
|
32
|
-
|
33
|
-
# Generate a Hash for use in generating JSON.
|
34
|
-
# This is useful if fields need to be cleared before the JSON can generate.
|
35
|
-
#
|
36
|
-
# Returns a Hash ready for JSON generation.
|
37
|
-
def hash_for_json(state = nil)
|
38
|
-
to_h.tap do |hash|
|
39
|
-
if state && state.depth >= 2
|
40
|
-
hash["previous"] = collapse_document(hash["previous"]) if hash["previous"]
|
41
|
-
hash["next"] = collapse_document(hash["next"]) if hash["next"]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
# Generate a Hash which breaks the recursive chain.
|
47
|
-
# Certain fields which are normally available are omitted.
|
48
|
-
#
|
49
|
-
# Returns a Hash with only non-recursive fields present.
|
50
|
-
def collapse_document(doc)
|
51
|
-
doc.keys.each_with_object({}) do |(key, _), result|
|
52
|
-
result[key] = doc[key] unless NESTED_OBJECT_FIELD_BLACKLIST.include?(key)
|
53
|
-
end
|
23
|
+
def <=>(other)
|
24
|
+
return nil unless other.is_a? DocumentDrop
|
25
|
+
cmp = self['date'] <=> other['date']
|
26
|
+
cmp = self['path'] <=> other['path'] if cmp.nil? || cmp == 0
|
27
|
+
cmp
|
54
28
|
end
|
55
29
|
|
56
30
|
private
|
data/lib/jekyll/drops/drop.rb
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
module Jekyll
|
4
4
|
module Drops
|
5
5
|
class Drop < Liquid::Drop
|
6
|
-
|
7
|
-
|
8
|
-
NON_CONTENT_METHODS = [:fallback_data, :collapse_document].freeze
|
6
|
+
NON_CONTENT_METHODS = [:[], :[]=, :inspect, :to_h, :fallback_data].freeze
|
9
7
|
|
10
8
|
# Get or set whether the drop class is mutable.
|
11
9
|
# Mutability determines whether or not pre-defined fields may be
|
@@ -88,7 +86,7 @@ module Jekyll
|
|
88
86
|
# Returns an Array of strings which represent method-specific keys.
|
89
87
|
def content_methods
|
90
88
|
@content_methods ||= (
|
91
|
-
self.class.instance_methods -
|
89
|
+
self.class.instance_methods(false) - NON_CONTENT_METHODS
|
92
90
|
).map(&:to_s).reject do |method|
|
93
91
|
method.end_with?("=")
|
94
92
|
end
|
@@ -140,22 +138,6 @@ module Jekyll
|
|
140
138
|
JSON.pretty_generate to_h
|
141
139
|
end
|
142
140
|
|
143
|
-
# Generate a Hash for use in generating JSON.
|
144
|
-
# This is useful if fields need to be cleared before the JSON can generate.
|
145
|
-
#
|
146
|
-
# Returns a Hash ready for JSON generation.
|
147
|
-
def hash_for_json(state = nil)
|
148
|
-
to_h
|
149
|
-
end
|
150
|
-
|
151
|
-
# Generate a JSON representation of the Drop.
|
152
|
-
#
|
153
|
-
# Returns a JSON representation of the Drop in a String.
|
154
|
-
def to_json(state = nil)
|
155
|
-
require 'json'
|
156
|
-
JSON.generate(hash_for_json(state), state)
|
157
|
-
end
|
158
|
-
|
159
141
|
# Collects all the keys and passes each to the block in turn.
|
160
142
|
#
|
161
143
|
# block - a block which accepts one argument, the key
|
@@ -165,12 +147,6 @@ module Jekyll
|
|
165
147
|
keys.each(&block)
|
166
148
|
end
|
167
149
|
|
168
|
-
def each(&block)
|
169
|
-
each_key.each do |key|
|
170
|
-
yield key, self[key]
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
150
|
def merge(other, &block)
|
175
151
|
self.dup.tap do |me|
|
176
152
|
if block.nil?
|
@@ -16,18 +16,6 @@ module Jekyll
|
|
16
16
|
def environment
|
17
17
|
Jekyll.env
|
18
18
|
end
|
19
|
-
|
20
|
-
def to_h
|
21
|
-
@to_h ||= {
|
22
|
-
"version" => version,
|
23
|
-
"environment" => environment
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_json(state = nil)
|
28
|
-
require 'json'
|
29
|
-
JSON.generate(to_h, state)
|
30
|
-
end
|
31
19
|
end
|
32
20
|
end
|
33
21
|
end
|
data/lib/jekyll/entry_filter.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
module Jekyll
|
2
2
|
class EntryFilter
|
3
|
-
SPECIAL_LEADING_CHARACTERS = ['.', '_', '#'].freeze
|
4
|
-
|
5
3
|
attr_reader :site
|
4
|
+
SPECIAL_LEADING_CHARACTERS = [
|
5
|
+
'.', '_', '#', '~'
|
6
|
+
].freeze
|
6
7
|
|
7
8
|
def initialize(site, base_directory = nil)
|
8
9
|
@site = site
|
9
|
-
@base_directory = derive_base_directory(
|
10
|
+
@base_directory = derive_base_directory(
|
11
|
+
@site, base_directory.to_s.dup
|
12
|
+
)
|
10
13
|
end
|
11
14
|
|
12
15
|
def base_directory
|
@@ -14,14 +17,14 @@ module Jekyll
|
|
14
17
|
end
|
15
18
|
|
16
19
|
def derive_base_directory(site, base_dir)
|
17
|
-
if base_dir.start_with?(site.source)
|
18
|
-
base_dir[site.source] = ""
|
19
|
-
end
|
20
|
+
base_dir[site.source] = "" if base_dir.start_with?(site.source)
|
20
21
|
base_dir
|
21
22
|
end
|
22
23
|
|
23
24
|
def relative_to_source(entry)
|
24
|
-
File.join(
|
25
|
+
File.join(
|
26
|
+
base_directory, entry
|
27
|
+
)
|
25
28
|
end
|
26
29
|
|
27
30
|
def filter(entries)
|
@@ -33,7 +36,9 @@ module Jekyll
|
|
33
36
|
end
|
34
37
|
|
35
38
|
def included?(entry)
|
36
|
-
glob_include?(site.include,
|
39
|
+
glob_include?(site.include,
|
40
|
+
entry
|
41
|
+
)
|
37
42
|
end
|
38
43
|
|
39
44
|
def special?(entry)
|
@@ -51,21 +56,62 @@ module Jekyll
|
|
51
56
|
excluded
|
52
57
|
end
|
53
58
|
|
59
|
+
# --
|
60
|
+
# Check if a file is a symlink.
|
61
|
+
# NOTE: This can be converted to allowing even in safe,
|
62
|
+
# since we use Pathutil#in_path? now.
|
63
|
+
# --
|
54
64
|
def symlink?(entry)
|
55
|
-
File.symlink?(entry) &&
|
65
|
+
site.safe && File.symlink?(entry) && symlink_outside_site_source?(entry)
|
56
66
|
end
|
57
67
|
|
58
|
-
|
59
|
-
|
68
|
+
# --
|
69
|
+
# NOTE: Pathutil#in_path? gets the realpath.
|
70
|
+
# @param [<Anything>] entry the entry you want to validate.
|
71
|
+
# Check if a path is outside of our given root.
|
72
|
+
# --
|
73
|
+
def symlink_outside_site_source?(entry)
|
74
|
+
!Pathutil.new(entry).in_path?(
|
75
|
+
site.in_source_dir
|
76
|
+
)
|
60
77
|
end
|
61
78
|
|
79
|
+
# --
|
80
|
+
# Check if an entry matches a specific pattern and return true,false.
|
62
81
|
# Returns true if path matches against any glob pattern.
|
63
|
-
#
|
82
|
+
# --
|
64
83
|
def glob_include?(enum, e)
|
65
|
-
entry =
|
84
|
+
entry = Pathutil.new(site.in_source_dir).join(e)
|
66
85
|
enum.any? do |exp|
|
67
|
-
|
68
|
-
|
86
|
+
|
87
|
+
# Users who send a Regexp knows what they want to
|
88
|
+
# exclude, so let them send a Regexp to exclude files,
|
89
|
+
# we will not bother caring if it works or not, it's
|
90
|
+
# on them at this point.
|
91
|
+
|
92
|
+
if exp.is_a?(Regexp)
|
93
|
+
entry =~ exp
|
94
|
+
|
95
|
+
else
|
96
|
+
item = Pathutil.new(site.in_source_dir).join(exp)
|
97
|
+
|
98
|
+
# If it's a directory they want to exclude, AKA
|
99
|
+
# ends with a "/" then we will go on to check and
|
100
|
+
# see if the entry falls within that path and
|
101
|
+
# exclude it if that's the case.
|
102
|
+
|
103
|
+
if e.end_with?("/")
|
104
|
+
entry.in_path?(
|
105
|
+
item
|
106
|
+
)
|
107
|
+
|
108
|
+
else
|
109
|
+
File.fnmatch?(item, entry) ||
|
110
|
+
entry.to_path.start_with?(
|
111
|
+
item
|
112
|
+
)
|
113
|
+
end
|
114
|
+
end
|
69
115
|
end
|
70
116
|
end
|
71
117
|
end
|