jekyll 4.0.0.pre.alpha1 → 4.0.0.pre.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -3
- data/lib/jekyll.rb +1 -0
- data/lib/jekyll/cache.rb +71 -64
- data/lib/jekyll/cleaner.rb +3 -3
- data/lib/jekyll/collection.rb +4 -2
- data/lib/jekyll/commands/serve/servlet.rb +13 -14
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/configuration.rb +33 -124
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +0 -8
- data/lib/jekyll/convertible.rb +1 -1
- data/lib/jekyll/document.rb +39 -28
- data/lib/jekyll/drops/drop.rb +14 -8
- data/lib/jekyll/drops/site_drop.rb +11 -1
- data/lib/jekyll/drops/url_drop.rb +43 -0
- data/lib/jekyll/entry_filter.rb +19 -36
- data/lib/jekyll/excerpt.rb +2 -2
- data/lib/jekyll/filters.rb +37 -6
- data/lib/jekyll/frontmatter_defaults.rb +5 -5
- data/lib/jekyll/liquid_renderer/table.rb +22 -2
- data/lib/jekyll/mime.types +53 -11
- data/lib/jekyll/page.rb +1 -1
- data/lib/jekyll/path_manager.rb +31 -0
- data/lib/jekyll/reader.rb +4 -1
- data/lib/jekyll/readers/page_reader.rb +4 -5
- data/lib/jekyll/readers/post_reader.rb +1 -1
- data/lib/jekyll/readers/static_file_reader.rb +2 -3
- data/lib/jekyll/site.rb +4 -4
- data/lib/jekyll/tags/highlight.rb +2 -4
- data/lib/jekyll/tags/include.rb +5 -4
- data/lib/jekyll/tags/post_url.rb +8 -5
- data/lib/jekyll/theme.rb +13 -2
- data/lib/jekyll/url.rb +7 -3
- data/lib/jekyll/utils.rb +9 -13
- data/lib/jekyll/utils/platforms.rb +1 -1
- data/lib/jekyll/version.rb +1 -1
- metadata +13 -11
@@ -34,7 +34,6 @@ module Jekyll
|
|
34
34
|
@config["syntax_highlighter_opts"]["guess_lang"] = @config["guess_lang"]
|
35
35
|
@config["coderay"] ||= {} # XXX: Legacy.
|
36
36
|
modernize_coderay_config
|
37
|
-
make_accessible
|
38
37
|
end
|
39
38
|
|
40
39
|
def convert(content)
|
@@ -64,13 +63,6 @@ module Jekyll
|
|
64
63
|
end
|
65
64
|
end
|
66
65
|
|
67
|
-
def make_accessible(hash = @config)
|
68
|
-
hash.keys.each do |key|
|
69
|
-
hash[key.to_sym] = hash[key]
|
70
|
-
make_accessible(hash[key]) if hash[key].is_a?(Hash)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
66
|
# config[kramdown][syntax_higlighter] >
|
75
67
|
# config[kramdown][enable_coderay] >
|
76
68
|
# config[highlighter]
|
data/lib/jekyll/convertible.rb
CHANGED
@@ -146,7 +146,7 @@ module Jekyll
|
|
146
146
|
#
|
147
147
|
# Returns true if extname == .sass or .scss, false otherwise.
|
148
148
|
def sass_file?
|
149
|
-
|
149
|
+
Jekyll::Document::SASS_FILE_EXTS.include?(ext)
|
150
150
|
end
|
151
151
|
|
152
152
|
# Determine whether the document is a CoffeeScript file.
|
data/lib/jekyll/document.rb
CHANGED
@@ -5,7 +5,7 @@ module Jekyll
|
|
5
5
|
include Comparable
|
6
6
|
extend Forwardable
|
7
7
|
|
8
|
-
attr_reader :path, :site, :extname, :collection
|
8
|
+
attr_reader :path, :site, :extname, :collection, :type
|
9
9
|
attr_accessor :content, :output
|
10
10
|
|
11
11
|
def_delegator :self, :read_post_data, :post_read
|
@@ -14,6 +14,23 @@ module Jekyll
|
|
14
14
|
DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!.freeze
|
15
15
|
DATE_FILENAME_MATCHER = %r!^(?>.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.]+)$!.freeze
|
16
16
|
|
17
|
+
SASS_FILE_EXTS = %w(.sass .scss).freeze
|
18
|
+
YAML_FILE_EXTS = %w(.yaml .yml).freeze
|
19
|
+
|
20
|
+
#
|
21
|
+
|
22
|
+
# Class-wide cache to stash and retrieve regexp to detect "super-directories"
|
23
|
+
# of a particular Jekyll::Document object.
|
24
|
+
#
|
25
|
+
# dirname - The *special directory* for the Document.
|
26
|
+
# e.g. "_posts" or "_drafts" for Documents from the `site.posts` collection.
|
27
|
+
def self.superdirs_regex(dirname)
|
28
|
+
@superdirs_regex ||= {}
|
29
|
+
@superdirs_regex[dirname] ||= %r!#{dirname}.*!
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
|
17
34
|
# Create a new Document.
|
18
35
|
#
|
19
36
|
# path - the path to the file
|
@@ -27,6 +44,8 @@ module Jekyll
|
|
27
44
|
@path = path
|
28
45
|
@extname = File.extname(path)
|
29
46
|
@collection = relations[:collection]
|
47
|
+
@type = @collection.label.to_sym
|
48
|
+
|
30
49
|
@has_yaml_header = nil
|
31
50
|
|
32
51
|
if draft?
|
@@ -36,7 +55,7 @@ module Jekyll
|
|
36
55
|
end
|
37
56
|
|
38
57
|
data.default_proc = proc do |_, key|
|
39
|
-
site.frontmatter_defaults.find(relative_path,
|
58
|
+
site.frontmatter_defaults.find(relative_path, type, key)
|
40
59
|
end
|
41
60
|
|
42
61
|
trigger_hooks(:post_init)
|
@@ -138,7 +157,7 @@ module Jekyll
|
|
138
157
|
#
|
139
158
|
# Returns true if the extname is either .yml or .yaml, false otherwise.
|
140
159
|
def yaml_file?
|
141
|
-
|
160
|
+
YAML_FILE_EXTS.include?(extname)
|
142
161
|
end
|
143
162
|
|
144
163
|
# Determine whether the document is an asset file.
|
@@ -154,7 +173,7 @@ module Jekyll
|
|
154
173
|
#
|
155
174
|
# Returns true if extname == .sass or .scss, false otherwise.
|
156
175
|
def sass_file?
|
157
|
-
|
176
|
+
SASS_FILE_EXTS.include?(extname)
|
158
177
|
end
|
159
178
|
|
160
179
|
# Determine whether the document is a CoffeeScript file.
|
@@ -373,12 +392,6 @@ module Jekyll
|
|
373
392
|
@related_posts ||= Jekyll::RelatedPosts.new(self).build
|
374
393
|
end
|
375
394
|
|
376
|
-
# Override of normal respond_to? to match method_missing's logic for
|
377
|
-
# looking in @data.
|
378
|
-
def respond_to?(method, include_private = false)
|
379
|
-
data.key?(method.to_s) || super
|
380
|
-
end
|
381
|
-
|
382
395
|
# Override of method_missing to check in @data for the key.
|
383
396
|
def method_missing(method, *args, &blck)
|
384
397
|
if data.key?(method.to_s)
|
@@ -401,28 +414,29 @@ module Jekyll
|
|
401
414
|
#
|
402
415
|
# Returns nothing.
|
403
416
|
def categories_from_path(special_dir)
|
404
|
-
superdirs = relative_path.sub(
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
end
|
417
|
+
superdirs = relative_path.sub(Document.superdirs_regex(special_dir), "")
|
418
|
+
superdirs = superdirs.split(File::SEPARATOR)
|
419
|
+
superdirs.reject! { |c| c.empty? || c == special_dir || c == basename }
|
420
|
+
|
409
421
|
merge_data!({ "categories" => superdirs }, :source => "file path")
|
410
422
|
end
|
411
423
|
|
412
424
|
def populate_categories
|
413
|
-
|
414
|
-
"categories"
|
415
|
-
Array(data["categories"]) + Utils.pluralized_array_from_hash(
|
416
|
-
data, "category", "categories"
|
417
|
-
)
|
418
|
-
).map(&:to_s).flatten.uniq
|
425
|
+
categories = Array(data["categories"]) + Utils.pluralized_array_from_hash(
|
426
|
+
data, "category", "categories"
|
419
427
|
)
|
428
|
+
categories.map!(&:to_s)
|
429
|
+
categories.flatten!
|
430
|
+
categories.uniq!
|
431
|
+
|
432
|
+
merge_data!("categories" => categories)
|
420
433
|
end
|
421
434
|
|
422
435
|
def populate_tags
|
423
|
-
|
424
|
-
|
425
|
-
|
436
|
+
tags = Utils.pluralized_array_from_hash(data, "tag", "tags")
|
437
|
+
tags.flatten!
|
438
|
+
|
439
|
+
merge_data!("tags" => tags)
|
426
440
|
end
|
427
441
|
|
428
442
|
private
|
@@ -444,10 +458,7 @@ module Jekyll
|
|
444
458
|
end
|
445
459
|
|
446
460
|
def merge_defaults
|
447
|
-
defaults = @site.frontmatter_defaults.all(
|
448
|
-
relative_path,
|
449
|
-
collection.label.to_sym
|
450
|
-
)
|
461
|
+
defaults = @site.frontmatter_defaults.all(relative_path, type)
|
451
462
|
merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
|
452
463
|
end
|
453
464
|
|
data/lib/jekyll/drops/drop.rb
CHANGED
@@ -30,7 +30,6 @@ module Jekyll
|
|
30
30
|
# Returns nothing
|
31
31
|
def initialize(obj)
|
32
32
|
@obj = obj
|
33
|
-
@mutations = {} # only if mutable: true
|
34
33
|
end
|
35
34
|
|
36
35
|
# Access a method in the Drop or a field in the underlying hash data.
|
@@ -42,8 +41,8 @@ module Jekyll
|
|
42
41
|
#
|
43
42
|
# Returns the value for the given key, or nil if none exists
|
44
43
|
def [](key)
|
45
|
-
if self.class.mutable? &&
|
46
|
-
|
44
|
+
if self.class.mutable? && mutations.key?(key)
|
45
|
+
mutations[key]
|
47
46
|
elsif self.class.invokable? key
|
48
47
|
public_send key
|
49
48
|
else
|
@@ -66,11 +65,12 @@ module Jekyll
|
|
66
65
|
# and the key matches a method in which case it raises a
|
67
66
|
# DropMutationException.
|
68
67
|
def []=(key, val)
|
69
|
-
|
70
|
-
|
68
|
+
setter = "#{key}="
|
69
|
+
if respond_to?(setter)
|
70
|
+
public_send(setter, val)
|
71
71
|
elsif respond_to?(key.to_s)
|
72
72
|
if self.class.mutable?
|
73
|
-
|
73
|
+
mutations[key] = val
|
74
74
|
else
|
75
75
|
raise Errors::DropMutationException, "Key #{key} cannot be set in the drop."
|
76
76
|
end
|
@@ -100,7 +100,7 @@ module Jekyll
|
|
100
100
|
# Returns true if the given key is present
|
101
101
|
def key?(key)
|
102
102
|
return false if key.nil?
|
103
|
-
return true if self.class.mutable? &&
|
103
|
+
return true if self.class.mutable? && mutations.key?(key)
|
104
104
|
|
105
105
|
respond_to?(key) || fallback_data.key?(key)
|
106
106
|
end
|
@@ -113,7 +113,7 @@ module Jekyll
|
|
113
113
|
# Returns an Array of unique keys for content for the Drop.
|
114
114
|
def keys
|
115
115
|
(content_methods |
|
116
|
-
|
116
|
+
mutations.keys |
|
117
117
|
fallback_data.keys).flatten
|
118
118
|
end
|
119
119
|
|
@@ -204,6 +204,12 @@ module Jekyll
|
|
204
204
|
return yield(key) unless block.nil?
|
205
205
|
return default unless default.nil?
|
206
206
|
end
|
207
|
+
|
208
|
+
private
|
209
|
+
|
210
|
+
def mutations
|
211
|
+
@mutations ||= {}
|
212
|
+
end
|
207
213
|
end
|
208
214
|
end
|
209
215
|
end
|
@@ -8,7 +8,7 @@ module Jekyll
|
|
8
8
|
mutable false
|
9
9
|
|
10
10
|
def_delegator :@obj, :site_data, :data
|
11
|
-
def_delegators :@obj, :time, :pages, :static_files, :
|
11
|
+
def_delegators :@obj, :time, :pages, :static_files, :tags, :categories
|
12
12
|
|
13
13
|
private def_delegator :@obj, :config, :fallback_data
|
14
14
|
|
@@ -38,6 +38,16 @@ module Jekyll
|
|
38
38
|
@site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
|
39
39
|
end
|
40
40
|
|
41
|
+
# `Site#documents` cannot be memoized so that `Site#docs_to_write` can access the
|
42
|
+
# latest state of the attribute.
|
43
|
+
#
|
44
|
+
# Since this method will be called after `Site#pre_render` hook, the `Site#documents`
|
45
|
+
# array shouldn't thereafter change and can therefore be safely memoized to prevent
|
46
|
+
# additional computation of `Site#documents`.
|
47
|
+
def documents
|
48
|
+
@documents ||= @obj.documents
|
49
|
+
end
|
50
|
+
|
41
51
|
# `{{ site.related_posts }}` is how posts can get posts related to
|
42
52
|
# them, either through LSI if it's enabled, or through the most
|
43
53
|
# recent posts.
|
@@ -35,46 +35,89 @@ module Jekyll
|
|
35
35
|
category_set.to_a.join("/")
|
36
36
|
end
|
37
37
|
|
38
|
+
# CCYY
|
38
39
|
def year
|
39
40
|
@obj.date.strftime("%Y")
|
40
41
|
end
|
41
42
|
|
43
|
+
# MM: 01..12
|
42
44
|
def month
|
43
45
|
@obj.date.strftime("%m")
|
44
46
|
end
|
45
47
|
|
48
|
+
# DD: 01..31
|
46
49
|
def day
|
47
50
|
@obj.date.strftime("%d")
|
48
51
|
end
|
49
52
|
|
53
|
+
# hh: 00..23
|
50
54
|
def hour
|
51
55
|
@obj.date.strftime("%H")
|
52
56
|
end
|
53
57
|
|
58
|
+
# mm: 00..59
|
54
59
|
def minute
|
55
60
|
@obj.date.strftime("%M")
|
56
61
|
end
|
57
62
|
|
63
|
+
# ss: 00..59
|
58
64
|
def second
|
59
65
|
@obj.date.strftime("%S")
|
60
66
|
end
|
61
67
|
|
68
|
+
# D: 1..31
|
62
69
|
def i_day
|
63
70
|
@obj.date.strftime("%-d")
|
64
71
|
end
|
65
72
|
|
73
|
+
# M: 1..12
|
66
74
|
def i_month
|
67
75
|
@obj.date.strftime("%-m")
|
68
76
|
end
|
69
77
|
|
78
|
+
# MMM: Jan..Dec
|
70
79
|
def short_month
|
71
80
|
@obj.date.strftime("%b")
|
72
81
|
end
|
73
82
|
|
83
|
+
# MMMM: January..December
|
84
|
+
def long_month
|
85
|
+
@obj.date.strftime("%B")
|
86
|
+
end
|
87
|
+
|
88
|
+
# YY: 00..99
|
74
89
|
def short_year
|
75
90
|
@obj.date.strftime("%y")
|
76
91
|
end
|
77
92
|
|
93
|
+
# CCYYw, ISO week year
|
94
|
+
# may differ from CCYY for the first days of January and last days of December
|
95
|
+
def w_year
|
96
|
+
@obj.date.strftime("%G")
|
97
|
+
end
|
98
|
+
|
99
|
+
# WW: 01..53
|
100
|
+
# %W and %U do not comply with ISO 8601-1
|
101
|
+
def week
|
102
|
+
@obj.date.strftime("%V")
|
103
|
+
end
|
104
|
+
|
105
|
+
# d: 1..7 (Monday..Sunday)
|
106
|
+
def w_day
|
107
|
+
@obj.date.strftime("%u")
|
108
|
+
end
|
109
|
+
|
110
|
+
# dd: Mon..Sun
|
111
|
+
def short_day
|
112
|
+
@obj.date.strftime("%a")
|
113
|
+
end
|
114
|
+
|
115
|
+
# ddd: Monday..Sunday
|
116
|
+
def long_day
|
117
|
+
@obj.date.strftime("%A")
|
118
|
+
end
|
119
|
+
|
120
|
+
# DDD: 001..366
|
78
121
|
def y_day
|
79
122
|
@obj.date.strftime("%j")
|
80
123
|
end
|
data/lib/jekyll/entry_filter.rb
CHANGED
@@ -3,9 +3,7 @@
|
|
3
3
|
module Jekyll
|
4
4
|
class EntryFilter
|
5
5
|
attr_reader :site
|
6
|
-
|
7
|
-
".", "_", "#", "~",
|
8
|
-
].freeze
|
6
|
+
SPECIAL_LEADING_CHAR_REGEX = %r!\A#{Regexp.union([".", "_", "#", "~"])}!o.freeze
|
9
7
|
|
10
8
|
def initialize(site, base_directory = nil)
|
11
9
|
@site = site
|
@@ -31,6 +29,9 @@ module Jekyll
|
|
31
29
|
|
32
30
|
def filter(entries)
|
33
31
|
entries.reject do |e|
|
32
|
+
# Reject this entry if it is just a "dot" representation.
|
33
|
+
# e.g.: '.', '..', '_movies/.', 'music/..', etc
|
34
|
+
next true if e.end_with?(".")
|
34
35
|
# Reject this entry if it is a symlink.
|
35
36
|
next true if symlink?(e)
|
36
37
|
# Do not reject this entry if it is included.
|
@@ -47,8 +48,8 @@ module Jekyll
|
|
47
48
|
end
|
48
49
|
|
49
50
|
def special?(entry)
|
50
|
-
|
51
|
-
|
51
|
+
SPECIAL_LEADING_CHAR_REGEX.match?(entry) ||
|
52
|
+
SPECIAL_LEADING_CHAR_REGEX.match?(File.basename(entry))
|
52
53
|
end
|
53
54
|
|
54
55
|
def backup?(entry)
|
@@ -86,40 +87,22 @@ module Jekyll
|
|
86
87
|
)
|
87
88
|
end
|
88
89
|
|
89
|
-
#
|
90
|
-
#
|
91
|
-
|
92
|
-
|
93
|
-
def glob_include?(enum, entry)
|
94
|
-
entry_path = Pathutil.new(site.in_source_dir).join(entry)
|
95
|
-
enum.any? do |exp|
|
96
|
-
# Users who send a Regexp knows what they want to
|
97
|
-
# exclude, so let them send a Regexp to exclude files,
|
98
|
-
# we will not bother caring if it works or not, it's
|
99
|
-
# on them at this point.
|
90
|
+
# Check if an entry matches a specific pattern.
|
91
|
+
# Returns true if path matches against any glob pattern, else false.
|
92
|
+
def glob_include?(enumerator, entry)
|
93
|
+
entry_with_source = PathManager.join(site.source, entry)
|
100
94
|
|
101
|
-
|
102
|
-
|
95
|
+
enumerator.any? do |pattern|
|
96
|
+
case pattern
|
97
|
+
when String
|
98
|
+
pattern_with_source = PathManager.join(site.source, pattern)
|
103
99
|
|
100
|
+
File.fnmatch?(pattern_with_source, entry_with_source) ||
|
101
|
+
entry_with_source.start_with?(pattern_with_source)
|
102
|
+
when Regexp
|
103
|
+
pattern.match?(entry_with_source)
|
104
104
|
else
|
105
|
-
|
106
|
-
|
107
|
-
# If it's a directory they want to exclude, AKA
|
108
|
-
# ends with a "/" then we will go on to check and
|
109
|
-
# see if the entry falls within that path and
|
110
|
-
# exclude it if that's the case.
|
111
|
-
|
112
|
-
if entry.end_with?("/")
|
113
|
-
entry_path.in_path?(
|
114
|
-
item
|
115
|
-
)
|
116
|
-
|
117
|
-
else
|
118
|
-
File.fnmatch?(item, entry_path) ||
|
119
|
-
entry_path.to_path.start_with?(
|
120
|
-
item
|
121
|
-
)
|
122
|
-
end
|
105
|
+
false
|
123
106
|
end
|
124
107
|
end
|
125
108
|
end
|
data/lib/jekyll/excerpt.rb
CHANGED
@@ -10,7 +10,7 @@ module Jekyll
|
|
10
10
|
|
11
11
|
def_delegators :@doc,
|
12
12
|
:site, :name, :ext, :extname,
|
13
|
-
:collection, :related_posts,
|
13
|
+
:collection, :related_posts, :type,
|
14
14
|
:coffeescript_file?, :yaml_file?,
|
15
15
|
:url, :next_doc, :previous_doc
|
16
16
|
|
@@ -155,7 +155,7 @@ module Jekyll
|
|
155
155
|
tag_names.flatten!
|
156
156
|
tag_names.reverse_each do |tag_name|
|
157
157
|
next unless liquid_block?(tag_name)
|
158
|
-
next if
|
158
|
+
next if endtag_regex_stash(tag_name).match?(head)
|
159
159
|
|
160
160
|
modified = true
|
161
161
|
head << "\n{% end#{tag_name} %}"
|