jekyll 3.9.3 → 4.4.1
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 +511 -89
- data/LICENSE +1 -1
- data/README.markdown +48 -27
- data/lib/blank_template/_config.yml +3 -0
- data/lib/blank_template/_layouts/default.html +12 -0
- data/lib/blank_template/_sass/base.scss +9 -0
- data/lib/blank_template/assets/css/main.scss +4 -0
- data/lib/blank_template/index.md +8 -0
- data/lib/jekyll/cache.rb +186 -0
- data/lib/jekyll/cleaner.rb +8 -7
- data/lib/jekyll/collection.rb +84 -11
- data/lib/jekyll/command.rb +33 -6
- data/lib/jekyll/commands/build.rb +8 -28
- data/lib/jekyll/commands/clean.rb +3 -2
- data/lib/jekyll/commands/doctor.rb +46 -35
- data/lib/jekyll/commands/help.rb +1 -1
- data/lib/jekyll/commands/new.rb +44 -50
- data/lib/jekyll/commands/new_theme.rb +27 -28
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +9 -16
- data/lib/jekyll/commands/serve/servlet.rb +21 -22
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/commands/serve.rb +75 -97
- data/lib/jekyll/configuration.rb +66 -158
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +83 -33
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +36 -34
- data/lib/jekyll/deprecator.rb +2 -4
- data/lib/jekyll/document.rb +107 -72
- data/lib/jekyll/drops/collection_drop.rb +3 -4
- data/lib/jekyll/drops/document_drop.rb +9 -3
- data/lib/jekyll/drops/drop.rb +115 -33
- data/lib/jekyll/drops/excerpt_drop.rb +8 -0
- data/lib/jekyll/drops/site_drop.rb +9 -8
- data/lib/jekyll/drops/static_file_drop.rb +4 -4
- data/lib/jekyll/drops/theme_drop.rb +39 -0
- data/lib/jekyll/drops/unified_payload_drop.rb +7 -2
- data/lib/jekyll/drops/url_drop.rb +55 -3
- data/lib/jekyll/entry_filter.rb +42 -51
- data/lib/jekyll/excerpt.rb +48 -38
- data/lib/jekyll/external.rb +20 -19
- 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 +50 -15
- data/lib/jekyll/filters.rb +211 -50
- data/lib/jekyll/frontmatter_defaults.rb +45 -36
- data/lib/jekyll/hooks.rb +26 -26
- data/lib/jekyll/inclusion.rb +32 -0
- data/lib/jekyll/layout.rb +12 -19
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer/file.rb +24 -3
- data/lib/jekyll/liquid_renderer/table.rb +26 -77
- data/lib/jekyll/liquid_renderer.rb +31 -16
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/page.rb +51 -23
- data/lib/jekyll/page_excerpt.rb +25 -0
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/path_manager.rb +74 -0
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +15 -5
- data/lib/jekyll/profiler.rb +51 -0
- data/lib/jekyll/reader.rb +65 -10
- data/lib/jekyll/readers/collection_reader.rb +1 -0
- data/lib/jekyll/readers/data_reader.rb +48 -10
- 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 +32 -19
- 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/related_posts.rb +1 -1
- data/lib/jekyll/renderer.rb +34 -49
- data/lib/jekyll/site.rb +151 -58
- data/lib/jekyll/static_file.rb +64 -28
- data/lib/jekyll/stevenson.rb +4 -8
- data/lib/jekyll/tags/highlight.rb +44 -57
- data/lib/jekyll/tags/include.rb +114 -80
- data/lib/jekyll/tags/link.rb +12 -7
- data/lib/jekyll/tags/post_url.rb +33 -30
- data/lib/jekyll/theme.rb +20 -18
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +18 -10
- data/lib/jekyll/utils/ansi.rb +2 -2
- data/lib/jekyll/utils/exec.rb +0 -1
- data/lib/jekyll/utils/internet.rb +2 -4
- data/lib/jekyll/utils/platforms.rb +37 -52
- data/lib/jekyll/utils/thread_event.rb +1 -5
- data/lib/jekyll/utils.rb +29 -28
- data/lib/jekyll/version.rb +1 -1
- data/lib/jekyll.rb +9 -14
- data/lib/site_template/.gitignore +2 -0
- data/lib/site_template/404.html +2 -1
- 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/theme_template/README.md.erb +1 -3
- 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 +150 -0
- data/rubocop/jekyll/no_p_allowed.rb +5 -6
- data/rubocop/jekyll/no_puts_allowed.rb +5 -6
- metadata +149 -37
- 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
- /data/lib/site_template/{about.md → about.markdown} +0 -0
- /data/lib/site_template/{index.md → index.markdown} +0 -0
data/lib/jekyll/hooks.rb
CHANGED
|
@@ -22,22 +22,25 @@ module Jekyll
|
|
|
22
22
|
:post_write => [],
|
|
23
23
|
},
|
|
24
24
|
:pages => {
|
|
25
|
-
:post_init
|
|
26
|
-
:pre_render
|
|
27
|
-
:
|
|
28
|
-
:
|
|
25
|
+
:post_init => [],
|
|
26
|
+
:pre_render => [],
|
|
27
|
+
:post_convert => [],
|
|
28
|
+
:post_render => [],
|
|
29
|
+
:post_write => [],
|
|
29
30
|
},
|
|
30
31
|
:posts => {
|
|
31
|
-
:post_init
|
|
32
|
-
:pre_render
|
|
33
|
-
:
|
|
34
|
-
:
|
|
32
|
+
:post_init => [],
|
|
33
|
+
:pre_render => [],
|
|
34
|
+
:post_convert => [],
|
|
35
|
+
:post_render => [],
|
|
36
|
+
:post_write => [],
|
|
35
37
|
},
|
|
36
38
|
:documents => {
|
|
37
|
-
:post_init
|
|
38
|
-
:pre_render
|
|
39
|
-
:
|
|
40
|
-
:
|
|
39
|
+
:post_init => [],
|
|
40
|
+
:pre_render => [],
|
|
41
|
+
:post_convert => [],
|
|
42
|
+
:post_render => [],
|
|
43
|
+
:post_write => [],
|
|
41
44
|
},
|
|
42
45
|
:clean => {
|
|
43
46
|
:on_obsolete => [],
|
|
@@ -60,26 +63,26 @@ module Jekyll
|
|
|
60
63
|
# Ensure the priority is a Fixnum
|
|
61
64
|
def self.priority_value(priority)
|
|
62
65
|
return priority if priority.is_a?(Integer)
|
|
66
|
+
|
|
63
67
|
PRIORITY_MAP[priority] || DEFAULT_PRIORITY
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
# register a single hook to be called later, internal API
|
|
67
71
|
def self.register_one(owner, event, priority, &block)
|
|
68
72
|
@registry[owner] ||= {
|
|
69
|
-
:post_init
|
|
70
|
-
:pre_render
|
|
71
|
-
:
|
|
72
|
-
:
|
|
73
|
+
:post_init => [],
|
|
74
|
+
:pre_render => [],
|
|
75
|
+
:post_convert => [],
|
|
76
|
+
:post_render => [],
|
|
77
|
+
:post_write => [],
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
unless @registry[owner][event]
|
|
76
|
-
raise NotAvailable, "Invalid hook. #{owner} supports only the " \
|
|
77
|
-
|
|
81
|
+
raise NotAvailable, "Invalid hook. #{owner} supports only the following hooks " \
|
|
82
|
+
"#{@registry[owner].keys.inspect}"
|
|
78
83
|
end
|
|
79
84
|
|
|
80
|
-
unless block.respond_to? :call
|
|
81
|
-
raise Uncallable, "Hooks must respond to :call"
|
|
82
|
-
end
|
|
85
|
+
raise Uncallable, "Hooks must respond to :call" unless block.respond_to? :call
|
|
83
86
|
|
|
84
87
|
insert_hook owner, event, priority, &block
|
|
85
88
|
end
|
|
@@ -92,11 +95,8 @@ module Jekyll
|
|
|
92
95
|
# interface for Jekyll core components to trigger hooks
|
|
93
96
|
def self.trigger(owner, event, *args)
|
|
94
97
|
# 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]
|
|
98
|
+
hooks = @registry.dig(owner, event)
|
|
99
|
+
return if hooks.nil? || hooks.empty?
|
|
100
100
|
|
|
101
101
|
# sort and call hooks according to priority and load order
|
|
102
102
|
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
|
data/lib/jekyll/layout.rb
CHANGED
|
@@ -4,26 +4,14 @@ module Jekyll
|
|
|
4
4
|
class Layout
|
|
5
5
|
include Convertible
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
|
|
7
|
+
attr_accessor :content, # content of layout
|
|
8
|
+
:data, # the Hash that holds the metadata for this layout
|
|
9
|
+
:ext # extension of layout
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
attr_reader :path
|
|
15
|
-
|
|
16
|
-
# Gets the path to this layout relative to its base
|
|
17
|
-
attr_reader :relative_path
|
|
18
|
-
|
|
19
|
-
# Gets/Sets the extension of this layout.
|
|
20
|
-
attr_accessor :ext
|
|
21
|
-
|
|
22
|
-
# Gets/Sets the Hash that holds the metadata for this layout.
|
|
23
|
-
attr_accessor :data
|
|
24
|
-
|
|
25
|
-
# Gets/Sets the content of this layout.
|
|
26
|
-
attr_accessor :content
|
|
11
|
+
attr_reader :name, # name of layout
|
|
12
|
+
:path, # path to layout
|
|
13
|
+
:site, # the Site object
|
|
14
|
+
:relative_path # path to layout relative to its base
|
|
27
15
|
|
|
28
16
|
# Initialize a new Layout.
|
|
29
17
|
#
|
|
@@ -58,5 +46,10 @@ module Jekyll
|
|
|
58
46
|
def process(name)
|
|
59
47
|
self.ext = File.extname(name)
|
|
60
48
|
end
|
|
49
|
+
|
|
50
|
+
# Returns the object as a debug String.
|
|
51
|
+
def inspect
|
|
52
|
+
"#<#{self.class} @path=#{@path.inspect}>"
|
|
53
|
+
end
|
|
61
54
|
end
|
|
62
55
|
end
|
|
@@ -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)
|
|
@@ -1,96 +1,45 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Jekyll
|
|
4
|
-
class LiquidRenderer
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def to_s(num_of_rows = 50)
|
|
10
|
-
data = data_for_table(num_of_rows)
|
|
11
|
-
widths = table_widths(data)
|
|
12
|
-
generate_table(data, widths)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
def generate_table(data, widths)
|
|
18
|
-
str = String.new("\n")
|
|
19
|
-
|
|
20
|
-
table_head = data.shift
|
|
21
|
-
str << generate_row(table_head, widths)
|
|
22
|
-
str << generate_table_head_border(table_head, widths)
|
|
4
|
+
class LiquidRenderer
|
|
5
|
+
class Table
|
|
6
|
+
GAUGES = [:count, :bytes, :time].freeze
|
|
23
7
|
|
|
24
|
-
|
|
25
|
-
|
|
8
|
+
def initialize(stats)
|
|
9
|
+
@stats = stats
|
|
26
10
|
end
|
|
27
11
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def generate_table_head_border(row_data, widths)
|
|
33
|
-
str = String.new("")
|
|
34
|
-
|
|
35
|
-
row_data.each_index do |cell_index|
|
|
36
|
-
str << "-" * widths[cell_index]
|
|
37
|
-
str << "-+-" unless cell_index == row_data.length - 1
|
|
12
|
+
def to_s(num_of_rows = 50)
|
|
13
|
+
Jekyll::Profiler.tabulate(data_for_table(num_of_rows))
|
|
38
14
|
end
|
|
39
15
|
|
|
40
|
-
|
|
41
|
-
str
|
|
42
|
-
end
|
|
16
|
+
private
|
|
43
17
|
|
|
44
|
-
|
|
45
|
-
|
|
18
|
+
def data_for_table(num_of_rows)
|
|
19
|
+
sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
|
|
20
|
+
sorted = sorted.slice(0, num_of_rows)
|
|
46
21
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
22
|
+
table = [header_labels]
|
|
23
|
+
sorted.each do |filename, file_stats|
|
|
24
|
+
row = []
|
|
25
|
+
row << filename
|
|
26
|
+
row << file_stats[:count].to_s
|
|
27
|
+
row << format_bytes(file_stats[:bytes])
|
|
28
|
+
row << format("%.3f", file_stats[:time])
|
|
29
|
+
table << row
|
|
30
|
+
end
|
|
53
31
|
|
|
54
|
-
|
|
32
|
+
table
|
|
55
33
|
end
|
|
56
34
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def table_widths(data)
|
|
62
|
-
widths = []
|
|
63
|
-
|
|
64
|
-
data.each do |row|
|
|
65
|
-
row.each_with_index do |cell, index|
|
|
66
|
-
widths[index] = [cell.length, widths[index]].compact.max
|
|
67
|
-
end
|
|
35
|
+
def header_labels
|
|
36
|
+
GAUGES.map { |gauge| gauge.to_s.capitalize }.unshift("Filename")
|
|
68
37
|
end
|
|
69
38
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def data_for_table(num_of_rows)
|
|
74
|
-
sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
|
|
75
|
-
sorted = sorted.slice(0, num_of_rows)
|
|
76
|
-
|
|
77
|
-
table = [%w(Filename Count Bytes Time)]
|
|
78
|
-
|
|
79
|
-
sorted.each do |filename, file_stats|
|
|
80
|
-
row = []
|
|
81
|
-
row << filename
|
|
82
|
-
row << file_stats[:count].to_s
|
|
83
|
-
row << format_bytes(file_stats[:bytes])
|
|
84
|
-
row << format("%.3f", file_stats[:time])
|
|
85
|
-
table << row
|
|
39
|
+
def format_bytes(bytes)
|
|
40
|
+
bytes /= 1024.0
|
|
41
|
+
format("%.2fK", bytes)
|
|
86
42
|
end
|
|
87
|
-
|
|
88
|
-
table
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def format_bytes(bytes)
|
|
92
|
-
bytes /= 1024.0
|
|
93
|
-
format("%.2fK", bytes)
|
|
94
43
|
end
|
|
95
44
|
end
|
|
96
45
|
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
|
|
data/lib/jekyll/log_adapter.rb
CHANGED
|
@@ -29,7 +29,9 @@ module Jekyll
|
|
|
29
29
|
#
|
|
30
30
|
# Returns nothing
|
|
31
31
|
def log_level=(level)
|
|
32
|
-
writer.level =
|
|
32
|
+
writer.level = level if level.is_a?(Integer) && level.between?(0, 3)
|
|
33
|
+
writer.level = LOG_LEVELS[level] ||
|
|
34
|
+
raise(ArgumentError, "unknown log level")
|
|
33
35
|
@level = level
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -41,6 +43,7 @@ module Jekyll
|
|
|
41
43
|
self.log_level = :debug
|
|
42
44
|
end
|
|
43
45
|
debug "Logging at level:", LOG_LEVELS.key(writer.level).to_s
|
|
46
|
+
debug "Jekyll Version:", Jekyll::VERSION
|
|
44
47
|
end
|
|
45
48
|
|
|
46
49
|
# Public: Print a debug message
|
|
@@ -141,6 +144,7 @@ module Jekyll
|
|
|
141
144
|
# the appropriate writer method, e.g. writer.info.
|
|
142
145
|
def write(level_of_message, topic, message = nil, &block)
|
|
143
146
|
return false unless write_message?(level_of_message)
|
|
147
|
+
|
|
144
148
|
writer.public_send(level_of_message, message(topic, message, &block))
|
|
145
149
|
end
|
|
146
150
|
end
|
data/lib/jekyll/page.rb
CHANGED
|
@@ -5,18 +5,15 @@ module Jekyll
|
|
|
5
5
|
include Convertible
|
|
6
6
|
|
|
7
7
|
attr_writer :dir
|
|
8
|
-
attr_accessor :
|
|
9
|
-
attr_accessor :name, :ext, :basename
|
|
10
|
-
attr_accessor :data, :content, :output
|
|
8
|
+
attr_accessor :basename, :content, :data, :ext, :name, :output, :pager, :site
|
|
11
9
|
|
|
12
10
|
alias_method :extname, :ext
|
|
13
11
|
|
|
14
|
-
FORWARD_SLASH = "/".freeze
|
|
15
|
-
|
|
16
12
|
# Attributes for Liquid templates
|
|
17
13
|
ATTRIBUTES_FOR_LIQUID = %w(
|
|
18
14
|
content
|
|
19
15
|
dir
|
|
16
|
+
excerpt
|
|
20
17
|
name
|
|
21
18
|
path
|
|
22
19
|
url
|
|
@@ -49,10 +46,11 @@ module Jekyll
|
|
|
49
46
|
end
|
|
50
47
|
|
|
51
48
|
process(name)
|
|
52
|
-
read_yaml(
|
|
49
|
+
read_yaml(PathManager.join(base, dir), name)
|
|
50
|
+
generate_excerpt if site.config["page_excerpts"]
|
|
53
51
|
|
|
54
52
|
data.default_proc = proc do |_, key|
|
|
55
|
-
site.frontmatter_defaults.find(
|
|
53
|
+
site.frontmatter_defaults.find(relative_path, type, key)
|
|
56
54
|
end
|
|
57
55
|
|
|
58
56
|
Jekyll::Hooks.trigger :pages, :post_init, self
|
|
@@ -64,12 +62,7 @@ module Jekyll
|
|
|
64
62
|
#
|
|
65
63
|
# Returns the String destination directory.
|
|
66
64
|
def dir
|
|
67
|
-
|
|
68
|
-
url
|
|
69
|
-
else
|
|
70
|
-
url_dir = File.dirname(url)
|
|
71
|
-
url_dir.end_with?(FORWARD_SLASH) ? url_dir : "#{url_dir}/"
|
|
72
|
-
end
|
|
65
|
+
url.end_with?("/") ? url : url_dir
|
|
73
66
|
end
|
|
74
67
|
|
|
75
68
|
# The full path and filename of the post. Defined in the YAML of the post
|
|
@@ -97,11 +90,11 @@ module Jekyll
|
|
|
97
90
|
#
|
|
98
91
|
# Returns the String url.
|
|
99
92
|
def url
|
|
100
|
-
@url ||= URL.new(
|
|
93
|
+
@url ||= URL.new(
|
|
101
94
|
:template => template,
|
|
102
95
|
:placeholders => url_placeholders,
|
|
103
|
-
:permalink => permalink
|
|
104
|
-
|
|
96
|
+
:permalink => permalink
|
|
97
|
+
).to_s
|
|
105
98
|
end
|
|
106
99
|
|
|
107
100
|
# Returns a hash of URL placeholder names (as symbols) mapping to the
|
|
@@ -118,10 +111,13 @@ module Jekyll
|
|
|
118
111
|
#
|
|
119
112
|
# name - The String filename of the page file.
|
|
120
113
|
#
|
|
114
|
+
# NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
|
|
121
115
|
# Returns nothing.
|
|
122
116
|
def process(name)
|
|
117
|
+
return unless name
|
|
118
|
+
|
|
123
119
|
self.ext = File.extname(name)
|
|
124
|
-
self.basename = name[0..-ext.length - 1]
|
|
120
|
+
self.basename = name[0..-ext.length - 1].gsub(%r!\.*\z!, "")
|
|
125
121
|
end
|
|
126
122
|
|
|
127
123
|
# Add any necessary layouts to this post
|
|
@@ -146,7 +142,7 @@ module Jekyll
|
|
|
146
142
|
|
|
147
143
|
# The path to the page source file, relative to the site source
|
|
148
144
|
def relative_path
|
|
149
|
-
|
|
145
|
+
@relative_path ||= PathManager.join(@dir, @name).delete_prefix("/")
|
|
150
146
|
end
|
|
151
147
|
|
|
152
148
|
# Obtain destination path.
|
|
@@ -155,15 +151,18 @@ module Jekyll
|
|
|
155
151
|
#
|
|
156
152
|
# Returns the destination file path String.
|
|
157
153
|
def destination(dest)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
@destination ||= {}
|
|
155
|
+
@destination[dest] ||= begin
|
|
156
|
+
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
|
157
|
+
path = File.join(path, "index") if url.end_with?("/")
|
|
158
|
+
path << output_ext unless path.end_with? output_ext
|
|
159
|
+
path
|
|
160
|
+
end
|
|
162
161
|
end
|
|
163
162
|
|
|
164
163
|
# Returns the object as a debug String.
|
|
165
164
|
def inspect
|
|
166
|
-
"
|
|
165
|
+
"#<#{self.class} @relative_path=#{relative_path.inspect}>"
|
|
167
166
|
end
|
|
168
167
|
|
|
169
168
|
# Returns the Boolean of whether this Page is HTML or not.
|
|
@@ -183,5 +182,34 @@ module Jekyll
|
|
|
183
182
|
def write?
|
|
184
183
|
true
|
|
185
184
|
end
|
|
185
|
+
|
|
186
|
+
def excerpt_separator
|
|
187
|
+
@excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def excerpt
|
|
191
|
+
return @excerpt if defined?(@excerpt)
|
|
192
|
+
|
|
193
|
+
@excerpt = data["excerpt"] ? data["excerpt"].to_s : nil
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def generate_excerpt?
|
|
197
|
+
!excerpt_separator.empty? && instance_of?(Jekyll::Page) && html?
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
private
|
|
201
|
+
|
|
202
|
+
def generate_excerpt
|
|
203
|
+
return unless generate_excerpt?
|
|
204
|
+
|
|
205
|
+
data["excerpt"] ||= Jekyll::PageExcerpt.new(self)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def url_dir
|
|
209
|
+
@url_dir ||= begin
|
|
210
|
+
value = File.dirname(url)
|
|
211
|
+
value.end_with?("/") ? value : "#{value}/"
|
|
212
|
+
end
|
|
213
|
+
end
|
|
186
214
|
end
|
|
187
215
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
class PageExcerpt < Excerpt
|
|
5
|
+
attr_reader :doc
|
|
6
|
+
alias_method :id, :relative_path
|
|
7
|
+
|
|
8
|
+
EXCERPT_ATTRIBUTES = (Page::ATTRIBUTES_FOR_LIQUID - %w(excerpt)).freeze
|
|
9
|
+
private_constant :EXCERPT_ATTRIBUTES
|
|
10
|
+
|
|
11
|
+
def to_liquid
|
|
12
|
+
@to_liquid ||= doc.to_liquid(EXCERPT_ATTRIBUTES)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render_with_liquid?
|
|
16
|
+
return false if data["render_with_liquid"] == false
|
|
17
|
+
|
|
18
|
+
Jekyll::Utils.has_liquid_construct?(content)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def inspect
|
|
22
|
+
"#<#{self.class} id=#{id.inspect}>"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|