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/deprecator.rb
CHANGED
@@ -9,20 +9,24 @@ module Jekyll
|
|
9
9
|
'serve' subcommand."
|
10
10
|
arg_is_present? args, "--no-server", "To build Jekyll without launching a server, \
|
11
11
|
use the 'build' subcommand."
|
12
|
-
arg_is_present? args, "--auto", "The switch '--auto' has been replaced with
|
12
|
+
arg_is_present? args, "--auto", "The switch '--auto' has been replaced with \
|
13
|
+
'--watch'."
|
13
14
|
arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
|
14
15
|
the '--watch' switch."
|
15
16
|
arg_is_present? args, "--pygments", "The 'pygments'settings has been removed in \
|
16
17
|
favour of 'highlighter'."
|
17
|
-
arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in
|
18
|
+
arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in \
|
19
|
+
your config files."
|
20
|
+
arg_is_present? args, "--url", "The 'url' setting can only be set in your \
|
18
21
|
config files."
|
19
|
-
arg_is_present? args, "--url", "The 'url' setting can only be set in your config files."
|
20
22
|
no_subcommand(args)
|
21
23
|
end
|
22
24
|
|
23
25
|
def no_subcommand(args)
|
24
|
-
|
25
|
-
|
26
|
+
unless args.empty? ||
|
27
|
+
args.first !~ %r(!/^--/!) || %w(--help --version).include?(args.first)
|
28
|
+
deprecation_message "Jekyll now uses subcommands instead of just switches. \
|
29
|
+
Run `jekyll help` to find out more."
|
26
30
|
abort
|
27
31
|
end
|
28
32
|
end
|
@@ -39,7 +43,8 @@ module Jekyll
|
|
39
43
|
|
40
44
|
def defaults_deprecate_type(old, current)
|
41
45
|
Jekyll.logger.warn "Defaults:", "The '#{old}' type has become '#{current}'."
|
42
|
-
Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use
|
46
|
+
Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use \
|
47
|
+
'type: #{current}'."
|
43
48
|
end
|
44
49
|
|
45
50
|
end
|
data/lib/jekyll/document.rb
CHANGED
@@ -7,9 +7,9 @@ module Jekyll
|
|
7
7
|
attr_reader :path, :site, :extname, :collection
|
8
8
|
attr_accessor :content, :output
|
9
9
|
|
10
|
-
YAML_FRONT_MATTER_REGEXP =
|
11
|
-
DATELESS_FILENAME_MATCHER =
|
12
|
-
DATE_FILENAME_MATCHER =
|
10
|
+
YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m
|
11
|
+
DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!
|
12
|
+
DATE_FILENAME_MATCHER = %r!^(?:.+/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$!
|
13
13
|
|
14
14
|
# Create a new Document.
|
15
15
|
#
|
@@ -51,16 +51,16 @@ module Jekyll
|
|
51
51
|
#
|
52
52
|
# Returns the merged data.
|
53
53
|
def merge_data!(other, source: "YAML front matter")
|
54
|
-
if other.key?(
|
55
|
-
if other[
|
56
|
-
other[
|
54
|
+
if other.key?("categories") && !other["categories"].nil?
|
55
|
+
if other["categories"].is_a?(String)
|
56
|
+
other["categories"] = other["categories"].split(" ").map(&:strip)
|
57
57
|
end
|
58
|
-
other[
|
58
|
+
other["categories"] = (data["categories"] || []) | other["categories"]
|
59
59
|
end
|
60
60
|
Utils.deep_merge_hashes!(data, other)
|
61
|
-
if data.key?(
|
62
|
-
data[
|
63
|
-
data[
|
61
|
+
if data.key?("date") && !data["date"].is_a?(Time)
|
62
|
+
data["date"] = Utils.parse_date(
|
63
|
+
data["date"].to_s,
|
64
64
|
"Document '#{relative_path}' does not have a valid date in the #{source}."
|
65
65
|
)
|
66
66
|
end
|
@@ -68,7 +68,7 @@ module Jekyll
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def date
|
71
|
-
data[
|
71
|
+
data["date"] ||= (draft? ? source_file_mtime : site.time)
|
72
72
|
end
|
73
73
|
|
74
74
|
def source_file_mtime
|
@@ -81,7 +81,8 @@ module Jekyll
|
|
81
81
|
#
|
82
82
|
# Returns whether the document is a draft.
|
83
83
|
def draft?
|
84
|
-
data[
|
84
|
+
data["draft"] ||= relative_path.index(collection.relative_directory).nil? &&
|
85
|
+
collection.label == "posts"
|
85
86
|
end
|
86
87
|
|
87
88
|
# The path to the document, relative to the site source.
|
@@ -89,7 +90,8 @@ module Jekyll
|
|
89
90
|
# Returns a String path which represents the relative path
|
90
91
|
# from the site source to this document
|
91
92
|
def relative_path
|
92
|
-
@relative_path ||= Pathname.new(path)
|
93
|
+
@relative_path ||= Pathname.new(path)
|
94
|
+
.relative_path_from(Pathname.new(site.source)).to_s
|
93
95
|
end
|
94
96
|
|
95
97
|
# The output extension of the document.
|
@@ -103,7 +105,7 @@ module Jekyll
|
|
103
105
|
#
|
104
106
|
# Returns the basename without the file extname.
|
105
107
|
def basename_without_ext
|
106
|
-
@basename_without_ext ||= File.basename(path,
|
108
|
+
@basename_without_ext ||= File.basename(path, ".*")
|
107
109
|
end
|
108
110
|
|
109
111
|
# The base filename of the document.
|
@@ -156,7 +158,7 @@ module Jekyll
|
|
156
158
|
#
|
157
159
|
# Returns true if extname == .coffee, false otherwise.
|
158
160
|
def coffeescript_file?
|
159
|
-
|
161
|
+
".coffee" == extname
|
160
162
|
end
|
161
163
|
|
162
164
|
# Determine whether the file should be rendered with Liquid.
|
@@ -195,7 +197,7 @@ module Jekyll
|
|
195
197
|
#
|
196
198
|
# Returns the permalink or nil if no permalink was set in the data.
|
197
199
|
def permalink
|
198
|
-
data && data.is_a?(Hash) && data[
|
200
|
+
data && data.is_a?(Hash) && data["permalink"]
|
199
201
|
end
|
200
202
|
|
201
203
|
# The computed URL for the document. See `Jekyll::URL#to_s` for more details.
|
@@ -203,9 +205,9 @@ module Jekyll
|
|
203
205
|
# Returns the computed URL for the document.
|
204
206
|
def url
|
205
207
|
@url = URL.new({
|
206
|
-
:template
|
208
|
+
:template => url_template,
|
207
209
|
:placeholders => url_placeholders,
|
208
|
-
:permalink
|
210
|
+
:permalink => permalink
|
209
211
|
}).to_s
|
210
212
|
end
|
211
213
|
|
@@ -237,18 +239,17 @@ module Jekyll
|
|
237
239
|
def write(dest)
|
238
240
|
path = destination(dest)
|
239
241
|
FileUtils.mkdir_p(File.dirname(path))
|
240
|
-
File.
|
241
|
-
f.write(output)
|
242
|
-
end
|
242
|
+
File.write(path, output, :mode => "wb")
|
243
243
|
|
244
244
|
trigger_hooks(:post_write)
|
245
245
|
end
|
246
246
|
|
247
247
|
# Whether the file is published or not, as indicated in YAML front-matter
|
248
248
|
#
|
249
|
-
# Returns
|
249
|
+
# Returns 'false' if the 'published' key is specified in the
|
250
|
+
# YAML front-matter and is 'false'. Otherwise returns 'true'.
|
250
251
|
def published?
|
251
|
-
!(data.key?(
|
252
|
+
!(data.key?("published") && data["published"] == false)
|
252
253
|
end
|
253
254
|
|
254
255
|
# Read in the file and assign the content and data based on the file contents.
|
@@ -263,23 +264,24 @@ module Jekyll
|
|
263
264
|
@data = SafeYAML.load_file(path)
|
264
265
|
else
|
265
266
|
begin
|
266
|
-
defaults = @site.frontmatter_defaults.all(
|
267
|
-
|
267
|
+
defaults = @site.frontmatter_defaults.all(
|
268
|
+
relative_path,
|
269
|
+
collection.label.to_sym
|
270
|
+
)
|
271
|
+
merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
|
268
272
|
|
269
273
|
self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
|
270
274
|
if content =~ YAML_FRONT_MATTER_REGEXP
|
271
275
|
self.content = $POSTMATCH
|
272
276
|
data_file = SafeYAML.load(Regexp.last_match(1))
|
273
|
-
merge_data!(data_file, source
|
277
|
+
merge_data!(data_file, :source => "YAML front matter") if data_file
|
274
278
|
end
|
275
279
|
|
276
280
|
post_read
|
277
281
|
rescue SyntaxError => e
|
278
282
|
Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{e.message}"
|
279
|
-
rescue
|
280
|
-
if e.is_a? Jekyll::Errors::FatalException
|
281
|
-
raise e
|
282
|
-
end
|
283
|
+
rescue => e
|
284
|
+
raise e if e.is_a? Jekyll::Errors::FatalException
|
283
285
|
Jekyll.logger.error "Error:", "could not read file #{path}: #{e.message}"
|
284
286
|
end
|
285
287
|
end
|
@@ -287,19 +289,19 @@ module Jekyll
|
|
287
289
|
|
288
290
|
def post_read
|
289
291
|
if relative_path =~ DATE_FILENAME_MATCHER
|
290
|
-
date, slug, ext =
|
291
|
-
if !data[
|
292
|
-
merge_data!({"date" => date}, source
|
292
|
+
date, slug, ext = Regexp.last_match.captures
|
293
|
+
if !data["date"] || data["date"].to_i == site.time.to_i
|
294
|
+
merge_data!({ "date" => date }, :source => "filename")
|
293
295
|
end
|
294
296
|
elsif relative_path =~ DATELESS_FILENAME_MATCHER
|
295
|
-
slug, ext =
|
297
|
+
slug, ext = Regexp.last_match.captures
|
296
298
|
end
|
297
299
|
|
298
300
|
# Try to ensure the user gets a title.
|
299
301
|
data["title"] ||= Utils.titleize_slug(slug)
|
300
302
|
# Only overwrite slug & ext if they aren't specified.
|
301
|
-
data[
|
302
|
-
data[
|
303
|
+
data["slug"] ||= slug
|
304
|
+
data["ext"] ||= ext
|
303
305
|
|
304
306
|
populate_categories
|
305
307
|
populate_tags
|
@@ -312,16 +314,19 @@ module Jekyll
|
|
312
314
|
#
|
313
315
|
# Returns nothing.
|
314
316
|
def categories_from_path(special_dir)
|
315
|
-
superdirs = relative_path.sub(
|
317
|
+
superdirs = relative_path.sub(%r!#{special_dir}(.*)!, "")
|
318
|
+
.split(File::SEPARATOR)
|
319
|
+
.reject do |c|
|
316
320
|
c.empty? || c.eql?(special_dir) || c.eql?(basename)
|
317
321
|
end
|
318
|
-
merge_data!({
|
322
|
+
merge_data!({ "categories" => superdirs }, :source => "file path")
|
319
323
|
end
|
320
324
|
|
321
325
|
def populate_categories
|
322
326
|
merge_data!({
|
323
|
-
|
324
|
-
Array(data[
|
327
|
+
"categories" => (
|
328
|
+
Array(data["categories"]) +
|
329
|
+
Utils.pluralized_array_from_hash(data, "category", "categories")
|
325
330
|
).map(&:to_s).flatten.uniq
|
326
331
|
})
|
327
332
|
end
|
@@ -351,7 +356,7 @@ module Jekyll
|
|
351
356
|
#
|
352
357
|
# Returns the content of the document
|
353
358
|
def to_s
|
354
|
-
output || content ||
|
359
|
+
output || content || "NO CONTENT"
|
355
360
|
end
|
356
361
|
|
357
362
|
# Compare this document against another document.
|
@@ -361,7 +366,7 @@ module Jekyll
|
|
361
366
|
# equal or greater than the other doc's path. See String#<=> for more details.
|
362
367
|
def <=>(other)
|
363
368
|
return nil unless other.respond_to?(:data)
|
364
|
-
cmp = data[
|
369
|
+
cmp = data["date"] <=> other.data["date"]
|
365
370
|
cmp = path <=> other.path if cmp.nil? || cmp == 0
|
366
371
|
cmp
|
367
372
|
end
|
@@ -380,7 +385,7 @@ module Jekyll
|
|
380
385
|
#
|
381
386
|
# Returns the document excerpt_separator
|
382
387
|
def excerpt_separator
|
383
|
-
(data[
|
388
|
+
(data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
|
384
389
|
end
|
385
390
|
|
386
391
|
# Whether to generate an excerpt
|
@@ -394,8 +399,6 @@ module Jekyll
|
|
394
399
|
pos = collection.docs.index { |post| post.equal?(self) }
|
395
400
|
if pos && pos < collection.docs.length - 1
|
396
401
|
collection.docs[pos + 1]
|
397
|
-
else
|
398
|
-
nil
|
399
402
|
end
|
400
403
|
end
|
401
404
|
|
@@ -403,8 +406,6 @@ module Jekyll
|
|
403
406
|
pos = collection.docs.index { |post| post.equal?(self) }
|
404
407
|
if pos && pos > 0
|
405
408
|
collection.docs[pos - 1]
|
406
|
-
else
|
407
|
-
nil
|
408
409
|
end
|
409
410
|
end
|
410
411
|
|
@@ -414,7 +415,7 @@ module Jekyll
|
|
414
415
|
end
|
415
416
|
|
416
417
|
def id
|
417
|
-
@id ||= File.join(File.dirname(url), (data[
|
418
|
+
@id ||= File.join(File.dirname(url), (data["slug"] || basename_without_ext).to_s)
|
418
419
|
end
|
419
420
|
|
420
421
|
# Calculate related posts.
|
@@ -433,8 +434,9 @@ module Jekyll
|
|
433
434
|
# Override of method_missing to check in @data for the key.
|
434
435
|
def method_missing(method, *args, &blck)
|
435
436
|
if data.key?(method.to_s)
|
436
|
-
Jekyll.
|
437
|
-
|
437
|
+
Jekyll::Deprecator.deprecation_message "Document##{method} is now a key "\
|
438
|
+
"in the #data hash."
|
439
|
+
Jekyll::Deprecator.deprecation_message "Called by #{caller.first}."
|
438
440
|
data[method.to_s]
|
439
441
|
else
|
440
442
|
super
|
@@ -5,10 +5,12 @@ 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
|
+
|
8
12
|
mutable false
|
9
13
|
|
10
|
-
def_delegator :@obj, :next_doc, :next
|
11
|
-
def_delegator :@obj, :previous_doc, :previous
|
12
14
|
def_delegator :@obj, :relative_path, :path
|
13
15
|
def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
|
14
16
|
|
@@ -17,16 +19,49 @@ module Jekyll
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def excerpt
|
20
|
-
fallback_data[
|
22
|
+
fallback_data["excerpt"].to_s
|
21
23
|
end
|
22
24
|
|
23
25
|
def <=>(other)
|
24
26
|
return nil unless other.is_a? DocumentDrop
|
25
|
-
cmp = self[
|
26
|
-
cmp = self[
|
27
|
+
cmp = self["date"] <=> other["date"]
|
28
|
+
cmp = self["path"] <=> other["path"] if cmp.nil? || cmp == 0
|
27
29
|
cmp
|
28
30
|
end
|
29
31
|
|
32
|
+
def previous
|
33
|
+
@obj.previous_doc.to_liquid
|
34
|
+
end
|
35
|
+
|
36
|
+
def next
|
37
|
+
@obj.next_doc.to_liquid
|
38
|
+
end
|
39
|
+
|
40
|
+
# Generate a Hash for use in generating JSON.
|
41
|
+
# This is useful if fields need to be cleared before the JSON can generate.
|
42
|
+
#
|
43
|
+
# state - the JSON::State object which determines the state of current processing.
|
44
|
+
#
|
45
|
+
# Returns a Hash ready for JSON generation.
|
46
|
+
def hash_for_json(state = nil)
|
47
|
+
to_h.tap do |hash|
|
48
|
+
if state && state.depth >= 2
|
49
|
+
hash["previous"] = collapse_document(hash["previous"]) if hash["previous"]
|
50
|
+
hash["next"] = collapse_document(hash["next"]) if hash["next"]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Generate a Hash which breaks the recursive chain.
|
56
|
+
# Certain fields which are normally available are omitted.
|
57
|
+
#
|
58
|
+
# Returns a Hash with only non-recursive fields present.
|
59
|
+
def collapse_document(doc)
|
60
|
+
doc.keys.each_with_object({}) do |(key, _), result|
|
61
|
+
result[key] = doc[key] unless NESTED_OBJECT_FIELD_BLACKLIST.include?(key)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
30
65
|
private
|
31
66
|
def_delegator :@obj, :data, :fallback_data
|
32
67
|
end
|
data/lib/jekyll/drops/drop.rb
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
module Jekyll
|
4
4
|
module Drops
|
5
5
|
class Drop < Liquid::Drop
|
6
|
-
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
NON_CONTENT_METHODS = [:fallback_data, :collapse_document].freeze
|
7
9
|
|
8
10
|
# Get or set whether the drop class is mutable.
|
9
11
|
# Mutability determines whether or not pre-defined fields may be
|
@@ -13,11 +15,11 @@ module Jekyll
|
|
13
15
|
#
|
14
16
|
# Returns the mutability of the class
|
15
17
|
def self.mutable(is_mutable = nil)
|
16
|
-
if is_mutable
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
@is_mutable = if is_mutable
|
19
|
+
is_mutable
|
20
|
+
else
|
21
|
+
false
|
22
|
+
end
|
21
23
|
end
|
22
24
|
|
23
25
|
def self.mutable?
|
@@ -86,7 +88,9 @@ module Jekyll
|
|
86
88
|
# Returns an Array of strings which represent method-specific keys.
|
87
89
|
def content_methods
|
88
90
|
@content_methods ||= (
|
89
|
-
self.class.instance_methods
|
91
|
+
self.class.instance_methods \
|
92
|
+
- Jekyll::Drops::Drop.instance_methods \
|
93
|
+
- NON_CONTENT_METHODS
|
90
94
|
).map(&:to_s).reject do |method|
|
91
95
|
method.end_with?("=")
|
92
96
|
end
|
@@ -98,8 +102,8 @@ module Jekyll
|
|
98
102
|
#
|
99
103
|
# Returns true if the given key is present
|
100
104
|
def key?(key)
|
101
|
-
if self.class.mutable
|
102
|
-
|
105
|
+
if self.class.mutable
|
106
|
+
@mutations.key?(key)
|
103
107
|
else
|
104
108
|
respond_to?(key) || fallback_data.key?(key)
|
105
109
|
end
|
@@ -134,10 +138,28 @@ module Jekyll
|
|
134
138
|
#
|
135
139
|
# Returns a pretty generation of the hash representation of the Drop.
|
136
140
|
def inspect
|
137
|
-
require
|
141
|
+
require "json"
|
138
142
|
JSON.pretty_generate to_h
|
139
143
|
end
|
140
144
|
|
145
|
+
# Generate a Hash for use in generating JSON.
|
146
|
+
# This is useful if fields need to be cleared before the JSON can generate.
|
147
|
+
#
|
148
|
+
# Returns a Hash ready for JSON generation.
|
149
|
+
def hash_for_json(*)
|
150
|
+
to_h
|
151
|
+
end
|
152
|
+
|
153
|
+
# Generate a JSON representation of the Drop.
|
154
|
+
#
|
155
|
+
# state - the JSON::State object which determines the state of current processing.
|
156
|
+
#
|
157
|
+
# Returns a JSON representation of the Drop in a String.
|
158
|
+
def to_json(state = nil)
|
159
|
+
require "json"
|
160
|
+
JSON.generate(hash_for_json(state), state)
|
161
|
+
end
|
162
|
+
|
141
163
|
# Collects all the keys and passes each to the block in turn.
|
142
164
|
#
|
143
165
|
# block - a block which accepts one argument, the key
|
@@ -147,6 +169,12 @@ module Jekyll
|
|
147
169
|
keys.each(&block)
|
148
170
|
end
|
149
171
|
|
172
|
+
def each
|
173
|
+
each_key.each do |key|
|
174
|
+
yield key, self[key]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
150
178
|
def merge(other, &block)
|
151
179
|
self.dup.tap do |me|
|
152
180
|
if block.nil?
|
@@ -171,6 +199,17 @@ module Jekyll
|
|
171
199
|
end
|
172
200
|
end
|
173
201
|
end
|
202
|
+
|
203
|
+
# Imitate Hash.fetch method in Drop
|
204
|
+
#
|
205
|
+
# Returns value if key is present in Drop, otherwise returns default value
|
206
|
+
# KeyError is raised if key is not present and no default value given
|
207
|
+
def fetch(key, default = nil, &block)
|
208
|
+
return self[key] if key?(key)
|
209
|
+
raise KeyError, %(key not found: "#{key}") if default.nil? && block.nil?
|
210
|
+
return yield(key) unless block.nil?
|
211
|
+
return default unless default.nil?
|
212
|
+
end
|
174
213
|
end
|
175
214
|
end
|
176
215
|
end
|