jekyll 3.8.7 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +71 -62
- data/LICENSE +1 -1
- data/README.markdown +46 -17
- data/lib/blank_template/_config.yml +3 -0
- data/lib/blank_template/_layouts/default.html +12 -0
- data/lib/blank_template/_sass/main.scss +9 -0
- data/lib/blank_template/assets/css/main.scss +4 -0
- data/lib/blank_template/index.md +8 -0
- data/lib/jekyll.rb +10 -1
- data/lib/jekyll/cache.rb +190 -0
- data/lib/jekyll/cleaner.rb +5 -4
- data/lib/jekyll/collection.rb +82 -10
- data/lib/jekyll/command.rb +33 -6
- data/lib/jekyll/commands/build.rb +11 -20
- data/lib/jekyll/commands/clean.rb +2 -0
- data/lib/jekyll/commands/doctor.rb +15 -8
- data/lib/jekyll/commands/help.rb +1 -1
- data/lib/jekyll/commands/new.rb +37 -35
- data/lib/jekyll/commands/new_theme.rb +30 -28
- data/lib/jekyll/commands/serve.rb +55 -81
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
- data/lib/jekyll/commands/serve/servlet.rb +22 -25
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/configuration.rb +61 -149
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +84 -11
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +30 -31
- data/lib/jekyll/deprecator.rb +1 -3
- data/lib/jekyll/document.rb +89 -61
- data/lib/jekyll/drops/collection_drop.rb +2 -3
- data/lib/jekyll/drops/document_drop.rb +14 -1
- data/lib/jekyll/drops/drop.rb +17 -14
- data/lib/jekyll/drops/excerpt_drop.rb +4 -0
- data/lib/jekyll/drops/page_drop.rb +18 -0
- data/lib/jekyll/drops/site_drop.rb +6 -5
- data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
- data/lib/jekyll/drops/url_drop.rb +53 -1
- data/lib/jekyll/entry_filter.rb +42 -45
- data/lib/jekyll/excerpt.rb +45 -34
- data/lib/jekyll/external.rb +10 -5
- data/lib/jekyll/filters.rb +200 -40
- data/lib/jekyll/filters/date_filters.rb +6 -3
- data/lib/jekyll/filters/grouping_filters.rb +1 -2
- data/lib/jekyll/filters/url_filters.rb +46 -14
- data/lib/jekyll/frontmatter_defaults.rb +46 -35
- data/lib/jekyll/hooks.rb +4 -8
- data/lib/jekyll/inclusion.rb +32 -0
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer.rb +31 -16
- data/lib/jekyll/liquid_renderer/file.rb +24 -3
- data/lib/jekyll/liquid_renderer/table.rb +36 -77
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/mime.types +53 -11
- data/lib/jekyll/page.rb +54 -12
- data/lib/jekyll/page_excerpt.rb +26 -0
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/path_manager.rb +31 -0
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +2 -0
- data/lib/jekyll/profiler.rb +58 -0
- data/lib/jekyll/reader.rb +42 -9
- data/lib/jekyll/readers/collection_reader.rb +1 -0
- data/lib/jekyll/readers/data_reader.rb +8 -9
- data/lib/jekyll/readers/layout_reader.rb +3 -12
- data/lib/jekyll/readers/page_reader.rb +5 -5
- data/lib/jekyll/readers/post_reader.rb +31 -18
- data/lib/jekyll/readers/static_file_reader.rb +4 -4
- data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
- data/lib/jekyll/regenerator.rb +4 -12
- data/lib/jekyll/renderer.rb +23 -40
- data/lib/jekyll/site.rb +91 -38
- data/lib/jekyll/static_file.rb +62 -21
- data/lib/jekyll/stevenson.rb +2 -3
- data/lib/jekyll/tags/highlight.rb +19 -51
- data/lib/jekyll/tags/include.rb +82 -42
- data/lib/jekyll/tags/link.rb +11 -7
- data/lib/jekyll/tags/post_url.rb +25 -21
- data/lib/jekyll/theme.rb +16 -18
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +10 -5
- data/lib/jekyll/utils.rb +18 -21
- data/lib/jekyll/utils/ansi.rb +1 -1
- data/lib/jekyll/utils/exec.rb +0 -1
- data/lib/jekyll/utils/internet.rb +2 -4
- data/lib/jekyll/utils/platforms.rb +8 -8
- data/lib/jekyll/utils/thread_event.rb +1 -5
- data/lib/jekyll/utils/win_tz.rb +2 -2
- data/lib/jekyll/version.rb +1 -1
- data/lib/site_template/.gitignore +2 -0
- data/lib/site_template/404.html +1 -0
- data/lib/site_template/_config.yml +17 -5
- data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
- data/lib/site_template/{about.md → about.markdown} +0 -0
- data/lib/site_template/{index.md → index.markdown} +0 -0
- data/lib/theme_template/gitignore.erb +1 -0
- data/lib/theme_template/theme.gemspec.erb +1 -4
- data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -0
- metadata +69 -31
- data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
- data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
- data/lib/jekyll/utils/rouge.rb +0 -22
|
@@ -10,13 +10,17 @@ module Jekyll
|
|
|
10
10
|
# Returns the absolute URL as a String.
|
|
11
11
|
def absolute_url(input)
|
|
12
12
|
return if input.nil?
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
)
|
|
13
|
+
|
|
14
|
+
cache = if input.is_a?(String)
|
|
15
|
+
(@context.registers[:site].filter_cache[:absolute_url] ||= {})
|
|
16
|
+
else
|
|
17
|
+
(@context.registers[:cached_absolute_url] ||= {})
|
|
18
|
+
end
|
|
19
|
+
cache[input] ||= compute_absolute_url(input)
|
|
20
|
+
|
|
21
|
+
# Duplicate cached string so that the cached value is never mutated by
|
|
22
|
+
# a subsequent filter.
|
|
23
|
+
cache[input].dup
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
# Produces a URL relative to the domain root based on site.baseurl
|
|
@@ -27,13 +31,17 @@ module Jekyll
|
|
|
27
31
|
# Returns a URL relative to the domain root as a String.
|
|
28
32
|
def relative_url(input)
|
|
29
33
|
return if input.nil?
|
|
30
|
-
input = input.url if input.respond_to?(:url)
|
|
31
|
-
return input if Addressable::URI.parse(input.to_s).absolute?
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
cache = if input.is_a?(String)
|
|
36
|
+
(@context.registers[:site].filter_cache[:relative_url] ||= {})
|
|
37
|
+
else
|
|
38
|
+
(@context.registers[:cached_relative_url] ||= {})
|
|
39
|
+
end
|
|
40
|
+
cache[input] ||= compute_relative_url(input)
|
|
41
|
+
|
|
42
|
+
# Duplicate cached string so that the cached value is never mutated by
|
|
43
|
+
# a subsequent filter.
|
|
44
|
+
cache[input].dup
|
|
37
45
|
end
|
|
38
46
|
|
|
39
47
|
# Strips trailing `/index.html` from URLs to create pretty permalinks
|
|
@@ -43,11 +51,35 @@ module Jekyll
|
|
|
43
51
|
# Returns a URL with the trailing `/index.html` removed
|
|
44
52
|
def strip_index(input)
|
|
45
53
|
return if input.nil? || input.to_s.empty?
|
|
54
|
+
|
|
46
55
|
input.sub(%r!/index\.html?$!, "/")
|
|
47
56
|
end
|
|
48
57
|
|
|
49
58
|
private
|
|
50
59
|
|
|
60
|
+
def compute_absolute_url(input)
|
|
61
|
+
input = input.url if input.respond_to?(:url)
|
|
62
|
+
return input if Addressable::URI.parse(input.to_s).absolute?
|
|
63
|
+
|
|
64
|
+
site = @context.registers[:site]
|
|
65
|
+
site_url = site.config["url"]
|
|
66
|
+
return relative_url(input) if site_url.nil? || site_url == ""
|
|
67
|
+
|
|
68
|
+
Addressable::URI.parse(
|
|
69
|
+
site_url.to_s + relative_url(input)
|
|
70
|
+
).normalize.to_s
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def compute_relative_url(input)
|
|
74
|
+
input = input.url if input.respond_to?(:url)
|
|
75
|
+
return input if Addressable::URI.parse(input.to_s).absolute?
|
|
76
|
+
|
|
77
|
+
parts = [sanitized_baseurl, input]
|
|
78
|
+
Addressable::URI.parse(
|
|
79
|
+
parts.compact.map { |part| ensure_leading_slash(part.to_s) }.join
|
|
80
|
+
).normalize.to_s
|
|
81
|
+
end
|
|
82
|
+
|
|
51
83
|
def sanitized_baseurl
|
|
52
84
|
site = @context.registers[:site]
|
|
53
85
|
site.config["baseurl"].to_s.chomp("/")
|
|
@@ -55,9 +87,9 @@ module Jekyll
|
|
|
55
87
|
|
|
56
88
|
def ensure_leading_slash(input)
|
|
57
89
|
return input if input.nil? || input.empty? || input.start_with?("/")
|
|
90
|
+
|
|
58
91
|
"/#{input}"
|
|
59
92
|
end
|
|
60
|
-
|
|
61
93
|
end
|
|
62
94
|
end
|
|
63
95
|
end
|
|
@@ -12,6 +12,10 @@ module Jekyll
|
|
|
12
12
|
@site = site
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def reset
|
|
16
|
+
@glob_cache = {} if @glob_cache
|
|
17
|
+
end
|
|
18
|
+
|
|
15
19
|
def update_deprecated_types(set)
|
|
16
20
|
return set unless set.key?("scope") && set["scope"].key?("type")
|
|
17
21
|
|
|
@@ -36,6 +40,7 @@ module Jekyll
|
|
|
36
40
|
def ensure_time!(set)
|
|
37
41
|
return set unless set.key?("values") && set["values"].key?("date")
|
|
38
42
|
return set if set["values"]["date"].is_a?(Time)
|
|
43
|
+
|
|
39
44
|
set["values"]["date"] = Utils.parse_date(
|
|
40
45
|
set["values"]["date"],
|
|
41
46
|
"An invalid date format was found in a front-matter default set: #{set}"
|
|
@@ -92,48 +97,51 @@ module Jekyll
|
|
|
92
97
|
# path - the path to check for
|
|
93
98
|
# type - the type (:post, :page or :draft) to check for
|
|
94
99
|
#
|
|
95
|
-
# Returns true if the scope applies to the given
|
|
100
|
+
# Returns true if the scope applies to the given type and path
|
|
96
101
|
def applies?(scope, path, type)
|
|
97
|
-
|
|
102
|
+
applies_type?(scope, type) && applies_path?(scope, path)
|
|
98
103
|
end
|
|
99
104
|
|
|
100
|
-
# rubocop:disable Metrics/AbcSize
|
|
101
105
|
def applies_path?(scope, path)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if scope["path"].to_s.include?("*")
|
|
110
|
-
Dir.glob(abs_scope_path).each do |scope_path|
|
|
111
|
-
scope_path = Pathname.new(scope_path).relative_path_from(site_path)
|
|
112
|
-
scope_path = strip_collections_dir(scope_path)
|
|
113
|
-
Jekyll.logger.debug "Globbed Scope Path:", scope_path
|
|
114
|
-
return true if path_is_subpath?(sanitized_path, scope_path)
|
|
115
|
-
end
|
|
116
|
-
false
|
|
106
|
+
rel_scope_path = scope["path"]
|
|
107
|
+
return true if !rel_scope_path.is_a?(String) || rel_scope_path.empty?
|
|
108
|
+
|
|
109
|
+
sanitized_path = sanitize_path(path)
|
|
110
|
+
|
|
111
|
+
if rel_scope_path.include?("*")
|
|
112
|
+
glob_scope(sanitized_path, rel_scope_path)
|
|
117
113
|
else
|
|
118
114
|
path_is_subpath?(sanitized_path, strip_collections_dir(rel_scope_path))
|
|
119
115
|
end
|
|
120
116
|
end
|
|
121
|
-
# rubocop:enable Metrics/AbcSize
|
|
122
117
|
|
|
123
|
-
def
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return true
|
|
127
|
-
end
|
|
128
|
-
end
|
|
118
|
+
def glob_scope(sanitized_path, rel_scope_path)
|
|
119
|
+
site_source = Pathname.new(@site.source)
|
|
120
|
+
abs_scope_path = site_source.join(rel_scope_path).to_s
|
|
129
121
|
|
|
122
|
+
glob_cache(abs_scope_path).each do |scope_path|
|
|
123
|
+
scope_path = Pathname.new(scope_path).relative_path_from(site_source).to_s
|
|
124
|
+
scope_path = strip_collections_dir(scope_path)
|
|
125
|
+
Jekyll.logger.debug "Globbed Scope Path:", scope_path
|
|
126
|
+
return true if path_is_subpath?(sanitized_path, scope_path)
|
|
127
|
+
end
|
|
130
128
|
false
|
|
131
129
|
end
|
|
132
130
|
|
|
131
|
+
def glob_cache(path)
|
|
132
|
+
@glob_cache ||= {}
|
|
133
|
+
@glob_cache[path] ||= Dir.glob(path)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def path_is_subpath?(path, parent_path)
|
|
137
|
+
path.start_with?(parent_path)
|
|
138
|
+
end
|
|
139
|
+
|
|
133
140
|
def strip_collections_dir(path)
|
|
134
141
|
collections_dir = @site.config["collections_dir"]
|
|
135
|
-
slashed_coll_dir = "#{collections_dir}/"
|
|
142
|
+
slashed_coll_dir = collections_dir.empty? ? "/" : "#{collections_dir}/"
|
|
136
143
|
return path if collections_dir.empty? || !path.to_s.start_with?(slashed_coll_dir)
|
|
144
|
+
|
|
137
145
|
path.sub(slashed_coll_dir, "")
|
|
138
146
|
end
|
|
139
147
|
|
|
@@ -167,7 +175,7 @@ module Jekyll
|
|
|
167
175
|
# new_scope - the new scope hash
|
|
168
176
|
#
|
|
169
177
|
# Returns true if the new scope has precedence over the older
|
|
170
|
-
# rubocop: disable PredicateName
|
|
178
|
+
# rubocop: disable Naming/PredicateName
|
|
171
179
|
def has_precedence?(old_scope, new_scope)
|
|
172
180
|
return true if old_scope.nil?
|
|
173
181
|
|
|
@@ -182,14 +190,18 @@ module Jekyll
|
|
|
182
190
|
!old_scope.key? "type"
|
|
183
191
|
end
|
|
184
192
|
end
|
|
185
|
-
# rubocop: enable PredicateName
|
|
193
|
+
# rubocop: enable Naming/PredicateName
|
|
186
194
|
|
|
187
195
|
# Collects a list of sets that match the given path and type
|
|
188
196
|
#
|
|
189
197
|
# Returns an array of hashes
|
|
190
198
|
def matching_sets(path, type)
|
|
191
|
-
|
|
192
|
-
|
|
199
|
+
@matched_set_cache ||= {}
|
|
200
|
+
@matched_set_cache[path] ||= {}
|
|
201
|
+
@matched_set_cache[path][type] ||= begin
|
|
202
|
+
valid_sets.select do |set|
|
|
203
|
+
!set.key?("scope") || applies?(set["scope"], path, type)
|
|
204
|
+
end
|
|
193
205
|
end
|
|
194
206
|
end
|
|
195
207
|
|
|
@@ -214,15 +226,14 @@ module Jekyll
|
|
|
214
226
|
end.compact
|
|
215
227
|
end
|
|
216
228
|
|
|
217
|
-
# Sanitizes the given path by removing a leading
|
|
218
|
-
|
|
219
|
-
SANITIZATION_REGEX = %r!\A/|(?<=[^/])\z!
|
|
220
|
-
|
|
229
|
+
# Sanitizes the given path by removing a leading slash
|
|
221
230
|
def sanitize_path(path)
|
|
222
231
|
if path.nil? || path.empty?
|
|
223
232
|
""
|
|
233
|
+
elsif path.start_with?("/")
|
|
234
|
+
path.gsub(%r!\A/|(?<=[^/])\z!, "")
|
|
224
235
|
else
|
|
225
|
-
path
|
|
236
|
+
path
|
|
226
237
|
end
|
|
227
238
|
end
|
|
228
239
|
end
|
data/lib/jekyll/hooks.rb
CHANGED
|
@@ -60,6 +60,7 @@ module Jekyll
|
|
|
60
60
|
# Ensure the priority is a Fixnum
|
|
61
61
|
def self.priority_value(priority)
|
|
62
62
|
return priority if priority.is_a?(Integer)
|
|
63
|
+
|
|
63
64
|
PRIORITY_MAP[priority] || DEFAULT_PRIORITY
|
|
64
65
|
end
|
|
65
66
|
|
|
@@ -77,9 +78,7 @@ module Jekyll
|
|
|
77
78
|
"following hooks #{@registry[owner].keys.inspect}"
|
|
78
79
|
end
|
|
79
80
|
|
|
80
|
-
unless block.respond_to? :call
|
|
81
|
-
raise Uncallable, "Hooks must respond to :call"
|
|
82
|
-
end
|
|
81
|
+
raise Uncallable, "Hooks must respond to :call" unless block.respond_to? :call
|
|
83
82
|
|
|
84
83
|
insert_hook owner, event, priority, &block
|
|
85
84
|
end
|
|
@@ -92,11 +91,8 @@ module Jekyll
|
|
|
92
91
|
# interface for Jekyll core components to trigger hooks
|
|
93
92
|
def self.trigger(owner, event, *args)
|
|
94
93
|
# proceed only if there are hooks to call
|
|
95
|
-
|
|
96
|
-
return
|
|
97
|
-
|
|
98
|
-
# hooks to call for this owner and event
|
|
99
|
-
hooks = @registry[owner][event]
|
|
94
|
+
hooks = @registry.dig(owner, event)
|
|
95
|
+
return if hooks.nil? || hooks.empty?
|
|
100
96
|
|
|
101
97
|
# sort and call hooks according to priority and load order
|
|
102
98
|
hooks.sort_by { |h| @hook_priority[h] }.each do |hook|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class Inclusion
|
|
5
|
+
attr_reader :site, :name, :path
|
|
6
|
+
private :site
|
|
7
|
+
|
|
8
|
+
def initialize(site, base, name)
|
|
9
|
+
@site = site
|
|
10
|
+
@name = name
|
|
11
|
+
@path = PathManager.join(base, name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def render(context)
|
|
15
|
+
@template ||= site.liquid_renderer.file(path).parse(content)
|
|
16
|
+
@template.render!(context)
|
|
17
|
+
rescue Liquid::Error => e
|
|
18
|
+
e.template_name = path
|
|
19
|
+
e.markup_context = "included " if e.markup_context.nil?
|
|
20
|
+
raise e
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def content
|
|
24
|
+
@content ||= File.read(path, **site.file_read_opts)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inspect
|
|
28
|
+
"#{self.class} #{path.inspect}"
|
|
29
|
+
end
|
|
30
|
+
alias_method :to_s, :inspect
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -5,11 +5,6 @@ require_relative "liquid_renderer/table"
|
|
|
5
5
|
|
|
6
6
|
module Jekyll
|
|
7
7
|
class LiquidRenderer
|
|
8
|
-
extend Forwardable
|
|
9
|
-
|
|
10
|
-
private def_delegator :@site, :in_source_dir, :source_dir
|
|
11
|
-
private def_delegator :@site, :in_theme_dir, :theme_dir
|
|
12
|
-
|
|
13
8
|
def initialize(site)
|
|
14
9
|
@site = site
|
|
15
10
|
Liquid::Template.error_mode = @site.config["liquid"]["error_mode"].to_sym
|
|
@@ -18,19 +13,13 @@ module Jekyll
|
|
|
18
13
|
|
|
19
14
|
def reset
|
|
20
15
|
@stats = {}
|
|
16
|
+
@cache = {}
|
|
21
17
|
end
|
|
22
18
|
|
|
23
19
|
def file(filename)
|
|
24
|
-
filename
|
|
25
|
-
filename =
|
|
26
|
-
if Regexp.last_match(1) == theme_dir("")
|
|
27
|
-
::File.join(::File.basename(Regexp.last_match(1)), Regexp.last_match(2))
|
|
28
|
-
else
|
|
29
|
-
Regexp.last_match(2)
|
|
30
|
-
end
|
|
20
|
+
filename = normalize_path(filename)
|
|
31
21
|
LiquidRenderer::File.new(self, filename).tap do
|
|
32
22
|
@stats[filename] ||= new_profile_hash
|
|
33
|
-
@stats[filename][:count] += 1
|
|
34
23
|
end
|
|
35
24
|
end
|
|
36
25
|
|
|
@@ -42,6 +31,10 @@ module Jekyll
|
|
|
42
31
|
@stats[filename][:time] += time
|
|
43
32
|
end
|
|
44
33
|
|
|
34
|
+
def increment_count(filename)
|
|
35
|
+
@stats[filename][:count] += 1
|
|
36
|
+
end
|
|
37
|
+
|
|
45
38
|
def stats_table(num_of_rows = 50)
|
|
46
39
|
LiquidRenderer::Table.new(@stats).to_s(num_of_rows)
|
|
47
40
|
end
|
|
@@ -50,11 +43,33 @@ module Jekyll
|
|
|
50
43
|
"#{error.message} in #{path}"
|
|
51
44
|
end
|
|
52
45
|
|
|
46
|
+
# A persistent cache to store and retrieve parsed templates based on the filename
|
|
47
|
+
# via `LiquidRenderer::File#parse`
|
|
48
|
+
#
|
|
49
|
+
# It is emptied when `self.reset` is called.
|
|
50
|
+
def cache
|
|
51
|
+
@cache ||= {}
|
|
52
|
+
end
|
|
53
|
+
|
|
53
54
|
private
|
|
54
55
|
|
|
55
|
-
def
|
|
56
|
-
@
|
|
57
|
-
|
|
56
|
+
def normalize_path(filename)
|
|
57
|
+
@normalize_path ||= {}
|
|
58
|
+
@normalize_path[filename] ||= begin
|
|
59
|
+
theme_dir = @site.theme&.root
|
|
60
|
+
case filename
|
|
61
|
+
when %r!\A(#{Regexp.escape(@site.source)}/)(?<rest>.*)!io
|
|
62
|
+
Regexp.last_match(:rest)
|
|
63
|
+
when %r!(/gems/.*)*/gems/(?<dirname>[^/]+)(?<rest>.*)!,
|
|
64
|
+
%r!(?<dirname>[^/]+/lib)(?<rest>.*)!
|
|
65
|
+
"#{Regexp.last_match(:dirname)}#{Regexp.last_match(:rest)}"
|
|
66
|
+
when theme_dir && %r!\A#{Regexp.escape(theme_dir)}/(?<rest>.*)!io
|
|
67
|
+
PathManager.join(@site.theme.basename, Regexp.last_match(:rest))
|
|
68
|
+
when %r!\A/(.*)!
|
|
69
|
+
Regexp.last_match(1)
|
|
70
|
+
else
|
|
71
|
+
filename
|
|
72
|
+
end
|
|
58
73
|
end
|
|
59
74
|
end
|
|
60
75
|
|
|
@@ -10,24 +10,34 @@ module Jekyll
|
|
|
10
10
|
|
|
11
11
|
def parse(content)
|
|
12
12
|
measure_time do
|
|
13
|
-
@
|
|
13
|
+
@renderer.cache[@filename] ||= Liquid::Template.parse(content, :line_numbers => true)
|
|
14
14
|
end
|
|
15
|
+
@template = @renderer.cache[@filename]
|
|
15
16
|
|
|
16
17
|
self
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
def render(*args)
|
|
21
|
+
reset_template_assigns
|
|
22
|
+
|
|
20
23
|
measure_time do
|
|
21
24
|
measure_bytes do
|
|
22
|
-
|
|
25
|
+
measure_counts do
|
|
26
|
+
@template.render(*args)
|
|
27
|
+
end
|
|
23
28
|
end
|
|
24
29
|
end
|
|
25
30
|
end
|
|
26
31
|
|
|
32
|
+
# This method simply 'rethrows any error' before attempting to render the template.
|
|
27
33
|
def render!(*args)
|
|
34
|
+
reset_template_assigns
|
|
35
|
+
|
|
28
36
|
measure_time do
|
|
29
37
|
measure_bytes do
|
|
30
|
-
|
|
38
|
+
measure_counts do
|
|
39
|
+
@template.render!(*args)
|
|
40
|
+
end
|
|
31
41
|
end
|
|
32
42
|
end
|
|
33
43
|
end
|
|
@@ -38,6 +48,17 @@ module Jekyll
|
|
|
38
48
|
|
|
39
49
|
private
|
|
40
50
|
|
|
51
|
+
# clear assigns to `Liquid::Template` instance prior to rendering since
|
|
52
|
+
# `Liquid::Template` instances are cached in Jekyll 4.
|
|
53
|
+
def reset_template_assigns
|
|
54
|
+
@template.instance_assigns.clear
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def measure_counts
|
|
58
|
+
@renderer.increment_count(@filename)
|
|
59
|
+
yield
|
|
60
|
+
end
|
|
61
|
+
|
|
41
62
|
def measure_bytes
|
|
42
63
|
yield.tap do |str|
|
|
43
64
|
@renderer.increment_bytes(@filename, str.bytesize)
|