jekyll 3.10.0 → 4.0.0.pre.alpha1
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 +27 -50
- 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/cache.rb +183 -0
- data/lib/jekyll/cleaner.rb +2 -1
- data/lib/jekyll/collection.rb +78 -8
- data/lib/jekyll/command.rb +31 -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 -42
- data/lib/jekyll/commands/new_theme.rb +30 -28
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
- data/lib/jekyll/commands/serve/servlet.rb +15 -19
- data/lib/jekyll/commands/serve.rb +46 -86
- data/lib/jekyll/configuration.rb +26 -26
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +1 -10
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +11 -13
- data/lib/jekyll/deprecator.rb +1 -3
- data/lib/jekyll/document.rb +44 -41
- data/lib/jekyll/drops/collection_drop.rb +2 -3
- data/lib/jekyll/drops/document_drop.rb +2 -1
- data/lib/jekyll/drops/drop.rb +3 -6
- data/lib/jekyll/drops/excerpt_drop.rb +4 -0
- data/lib/jekyll/drops/site_drop.rb +4 -13
- data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
- data/lib/jekyll/drops/url_drop.rb +1 -0
- data/lib/jekyll/entry_filter.rb +2 -1
- data/lib/jekyll/excerpt.rb +45 -34
- data/lib/jekyll/external.rb +10 -5
- 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 +6 -1
- data/lib/jekyll/filters.rb +72 -31
- data/lib/jekyll/frontmatter_defaults.rb +35 -19
- data/lib/jekyll/hooks.rb +2 -3
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer/file.rb +14 -3
- data/lib/jekyll/liquid_renderer/table.rb +67 -65
- data/lib/jekyll/liquid_renderer.rb +13 -1
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/mime.types +80 -195
- data/lib/jekyll/page.rb +10 -26
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +2 -0
- data/lib/jekyll/reader.rb +38 -8
- data/lib/jekyll/readers/data_reader.rb +5 -5
- data/lib/jekyll/readers/layout_reader.rb +2 -12
- data/lib/jekyll/readers/post_reader.rb +29 -17
- data/lib/jekyll/readers/static_file_reader.rb +1 -1
- data/lib/jekyll/readers/theme_assets_reader.rb +7 -5
- data/lib/jekyll/regenerator.rb +4 -12
- data/lib/jekyll/renderer.rb +14 -25
- data/lib/jekyll/site.rb +78 -34
- data/lib/jekyll/static_file.rb +47 -11
- data/lib/jekyll/stevenson.rb +7 -5
- data/lib/jekyll/tags/highlight.rb +22 -52
- data/lib/jekyll/tags/include.rb +27 -48
- data/lib/jekyll/tags/link.rb +11 -7
- data/lib/jekyll/tags/post_url.rb +17 -16
- data/lib/jekyll/theme.rb +12 -23
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +3 -2
- 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 +47 -18
- data/lib/jekyll/utils.rb +5 -4
- data/lib/jekyll/version.rb +1 -1
- data/lib/jekyll.rb +5 -0
- 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/theme_template/gitignore.erb +1 -0
- data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -0
- metadata +70 -71
- data/lib/jekyll/commands/serve/mime_types_charset.json +0 -71
- 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
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
module Jekyll
|
4
4
|
module Converters
|
5
|
+
# Markdown converter.
|
6
|
+
# For more info on converters see https://jekyllrb.com/docs/plugins/converters/
|
5
7
|
class Markdown < Converter
|
6
8
|
highlighter_prefix "\n"
|
7
9
|
highlighter_suffix "\n"
|
@@ -9,80 +11,91 @@ module Jekyll
|
|
9
11
|
|
10
12
|
def setup
|
11
13
|
return if @setup ||= false
|
14
|
+
|
12
15
|
unless (@parser = get_processor)
|
13
|
-
Jekyll.logger.error "Invalid Markdown processor given:", @config["markdown"]
|
14
16
|
if @config["safe"]
|
15
|
-
Jekyll.logger.
|
17
|
+
Jekyll.logger.warn "Build Warning:", "Custom processors are not loaded in safe mode"
|
16
18
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
)
|
21
|
-
|
19
|
+
|
20
|
+
Jekyll.logger.error "Markdown processor:",
|
21
|
+
"#{@config["markdown"].inspect} is not a valid Markdown processor."
|
22
|
+
Jekyll.logger.error "", "Available processors are: #{valid_processors.join(", ")}"
|
23
|
+
Jekyll.logger.error ""
|
24
|
+
raise Errors::FatalException, "Invalid Markdown processor given: #{@config["markdown"]}"
|
22
25
|
end
|
23
26
|
|
27
|
+
@cache = Jekyll::Cache.new("Jekyll::Converters::Markdown")
|
24
28
|
@setup = true
|
25
29
|
end
|
26
30
|
|
27
|
-
#
|
31
|
+
# RuboCop does not allow reader methods to have names starting with `get_`
|
28
32
|
# To ensure compatibility, this check has been disabled on this method
|
29
33
|
#
|
30
34
|
# rubocop:disable Naming/AccessorMethodName
|
31
35
|
def get_processor
|
32
36
|
case @config["markdown"].downcase
|
33
|
-
when "
|
34
|
-
when "kramdown" then return KramdownParser.new(@config)
|
35
|
-
when "rdiscount" then return RDiscountParser.new(@config)
|
37
|
+
when "kramdown" then KramdownParser.new(@config)
|
36
38
|
else
|
37
39
|
custom_processor
|
38
40
|
end
|
39
41
|
end
|
40
42
|
# rubocop:enable Naming/AccessorMethodName
|
41
43
|
|
42
|
-
# Public: Provides you with a list of processors
|
43
|
-
#
|
44
|
-
#
|
45
|
-
|
44
|
+
# Public: Provides you with a list of processors comprised of the ones we support internally
|
45
|
+
# and the ones that you have provided to us (if they're whitelisted for use in safe mode).
|
46
|
+
#
|
47
|
+
# Returns an array of symbols.
|
46
48
|
def valid_processors
|
47
|
-
|
49
|
+
[:kramdown] + third_party_processors
|
48
50
|
end
|
49
51
|
|
50
52
|
# Public: A list of processors that you provide via plugins.
|
51
|
-
#
|
52
|
-
#
|
53
|
-
|
53
|
+
#
|
54
|
+
# Returns an array of symbols
|
54
55
|
def third_party_processors
|
55
|
-
self.class.constants -
|
56
|
-
%w(KramdownParser RDiscountParser RedcarpetParser PRIORITIES).map(
|
57
|
-
&:to_sym
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
def extname_list
|
62
|
-
@extname_list ||= @config["markdown_ext"].split(",").map do |e|
|
63
|
-
".#{e.downcase}"
|
64
|
-
end
|
56
|
+
self.class.constants - [:KramdownParser, :PRIORITIES]
|
65
57
|
end
|
66
58
|
|
59
|
+
# Does the given extension match this converter's list of acceptable extensions?
|
60
|
+
# Takes one argument: the file's extension (including the dot).
|
61
|
+
#
|
62
|
+
# ext - The String extension to check.
|
63
|
+
#
|
64
|
+
# Returns true if it matches, false otherwise.
|
67
65
|
def matches(ext)
|
68
66
|
extname_list.include?(ext.downcase)
|
69
67
|
end
|
70
68
|
|
69
|
+
# Public: The extension to be given to the output file (including the dot).
|
70
|
+
#
|
71
|
+
# ext - The String extension or original file.
|
72
|
+
#
|
73
|
+
# Returns The String output file extension.
|
71
74
|
def output_ext(_ext)
|
72
75
|
".html"
|
73
76
|
end
|
74
77
|
|
78
|
+
# Logic to do the content conversion.
|
79
|
+
#
|
80
|
+
# content - String content of file (without front matter).
|
81
|
+
#
|
82
|
+
# Returns a String of the converted content.
|
75
83
|
def convert(content)
|
76
84
|
setup
|
77
|
-
@
|
85
|
+
@cache.getset(content) do
|
86
|
+
@parser.convert(content)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def extname_list
|
91
|
+
@extname_list ||= @config["markdown_ext"].split(",").map! { |e| ".#{e.downcase}" }
|
78
92
|
end
|
79
93
|
|
80
94
|
private
|
95
|
+
|
81
96
|
def custom_processor
|
82
97
|
converter_name = @config["markdown"]
|
83
|
-
if custom_class_allowed?(converter_name)
|
84
|
-
self.class.const_get(converter_name).new(@config)
|
85
|
-
end
|
98
|
+
self.class.const_get(converter_name).new(@config) if custom_class_allowed?(converter_name)
|
86
99
|
end
|
87
100
|
|
88
101
|
# Private: Determine whether a class name is an allowed custom
|
@@ -90,14 +103,10 @@ module Jekyll
|
|
90
103
|
#
|
91
104
|
# parser_name - the name of the parser class
|
92
105
|
#
|
93
|
-
# Returns true if the parser name contains only alphanumeric
|
94
|
-
#
|
95
|
-
|
96
|
-
private
|
106
|
+
# Returns true if the parser name contains only alphanumeric characters and is defined
|
107
|
+
# within Jekyll::Converters::Markdown
|
97
108
|
def custom_class_allowed?(parser_name)
|
98
|
-
parser_name !~ %r![^A-Za-z0-9_]! && self.class.constants.include?(
|
99
|
-
parser_name.to_sym
|
100
|
-
)
|
109
|
+
parser_name !~ %r![^A-Za-z0-9_]! && self.class.constants.include?(parser_name.to_sym)
|
101
110
|
end
|
102
111
|
end
|
103
112
|
end
|
@@ -1,40 +1,60 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module Kramdown
|
4
|
+
module Parser
|
5
|
+
class SmartyPants < Kramdown::Parser::Kramdown
|
6
|
+
def initialize(source, options)
|
7
|
+
super
|
8
|
+
@block_parsers = [:block_html, :content]
|
9
|
+
@span_parsers = [:smart_quotes, :html_entity, :typographic_syms, :span_html]
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
def parse_content
|
13
|
+
add_text @src.scan(%r!\A.*\n!)
|
14
|
+
end
|
15
|
+
define_parser(:content, %r!\A!)
|
16
|
+
end
|
12
17
|
end
|
13
|
-
define_parser(:content, %r!\A!)
|
14
18
|
end
|
15
19
|
|
16
20
|
module Jekyll
|
17
21
|
module Converters
|
22
|
+
# SmartyPants converter.
|
23
|
+
# For more info on converters see https://jekyllrb.com/docs/plugins/converters/
|
18
24
|
class SmartyPants < Converter
|
19
25
|
safe true
|
20
26
|
priority :low
|
21
27
|
|
22
28
|
def initialize(config)
|
23
|
-
unless defined?(Kramdown)
|
24
|
-
Jekyll::External.require_with_graceful_fail "kramdown"
|
25
|
-
end
|
29
|
+
Jekyll::External.require_with_graceful_fail "kramdown" unless defined?(Kramdown)
|
26
30
|
@config = config["kramdown"].dup || {}
|
27
31
|
@config[:input] = :SmartyPants
|
28
32
|
end
|
29
33
|
|
30
|
-
|
34
|
+
# Does the given extension match this converter's list of acceptable extensions?
|
35
|
+
# Takes one argument: the file's extension (including the dot).
|
36
|
+
#
|
37
|
+
# ext - The String extension to check.
|
38
|
+
#
|
39
|
+
# Returns true if it matches, false otherwise.
|
40
|
+
def matches(_ext)
|
31
41
|
false
|
32
42
|
end
|
33
43
|
|
34
|
-
|
44
|
+
# Public: The extension to be given to the output file (including the dot).
|
45
|
+
#
|
46
|
+
# ext - The String extension or original file.
|
47
|
+
#
|
48
|
+
# Returns The String output file extension.
|
49
|
+
def output_ext(_ext)
|
35
50
|
nil
|
36
51
|
end
|
37
52
|
|
53
|
+
# Logic to do the content conversion.
|
54
|
+
#
|
55
|
+
# content - String content of file (without front matter).
|
56
|
+
#
|
57
|
+
# Returns a String of the converted content.
|
38
58
|
def convert(content)
|
39
59
|
document = Kramdown::Document.new(content, @config)
|
40
60
|
html_output = document.to_html.chomp
|
data/lib/jekyll/convertible.rb
CHANGED
@@ -39,17 +39,17 @@ module Jekyll
|
|
39
39
|
|
40
40
|
begin
|
41
41
|
self.content = File.read(@path || site.in_source_dir(base, name),
|
42
|
-
|
42
|
+
Utils.merged_file_read_opts(site, opts))
|
43
43
|
if content =~ Document::YAML_FRONT_MATTER_REGEXP
|
44
44
|
self.content = $POSTMATCH
|
45
45
|
self.data = SafeYAML.load(Regexp.last_match(1))
|
46
46
|
end
|
47
47
|
rescue Psych::SyntaxError => e
|
48
48
|
Jekyll.logger.warn "YAML Exception reading #{filename}: #{e.message}"
|
49
|
-
raise e if
|
49
|
+
raise e if site.config["strict_front_matter"]
|
50
50
|
rescue StandardError => e
|
51
51
|
Jekyll.logger.warn "Error reading file #{filename}: #{e.message}"
|
52
|
-
raise e if
|
52
|
+
raise e if site.config["strict_front_matter"]
|
53
53
|
end
|
54
54
|
|
55
55
|
self.data ||= {}
|
@@ -64,12 +64,12 @@ module Jekyll
|
|
64
64
|
def validate_data!(filename)
|
65
65
|
unless self.data.is_a?(Hash)
|
66
66
|
raise Errors::InvalidYAMLFrontMatterError,
|
67
|
-
|
67
|
+
"Invalid YAML front matter in #{filename}"
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
71
|
def validate_permalink!(filename)
|
72
|
-
if self.data["permalink"]
|
72
|
+
if self.data["permalink"]&.to_s&.empty?
|
73
73
|
raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
|
74
74
|
end
|
75
75
|
end
|
@@ -125,16 +125,12 @@ module Jekyll
|
|
125
125
|
#
|
126
126
|
# Returns the type of self.
|
127
127
|
def type
|
128
|
-
if is_a?(Page)
|
129
|
-
:pages
|
130
|
-
end
|
128
|
+
:pages if is_a?(Page)
|
131
129
|
end
|
132
130
|
|
133
131
|
# returns the owner symbol for hook triggering
|
134
132
|
def hook_owner
|
135
|
-
if is_a?(Page)
|
136
|
-
:pages
|
137
|
-
end
|
133
|
+
:pages if is_a?(Page)
|
138
134
|
end
|
139
135
|
|
140
136
|
# Determine whether the document is an asset file.
|
@@ -164,6 +160,8 @@ module Jekyll
|
|
164
160
|
#
|
165
161
|
# Returns true if the file has Liquid Tags or Variables, false otherwise.
|
166
162
|
def render_with_liquid?
|
163
|
+
return false if data["render_with_liquid"] == false
|
164
|
+
|
167
165
|
Jekyll::Utils.has_liquid_construct?(content)
|
168
166
|
end
|
169
167
|
|
@@ -181,7 +179,7 @@ module Jekyll
|
|
181
179
|
#
|
182
180
|
# Returns true if the layout is invalid, false if otherwise
|
183
181
|
def invalid_layout?(layout)
|
184
|
-
!data["layout"].nil? && layout.nil? && !(
|
182
|
+
!data["layout"].nil? && layout.nil? && !(is_a? Jekyll::Excerpt)
|
185
183
|
end
|
186
184
|
|
187
185
|
# Recursively render layouts
|
@@ -210,7 +208,7 @@ module Jekyll
|
|
210
208
|
renderer.payload = payload
|
211
209
|
end.run
|
212
210
|
|
213
|
-
Jekyll.logger.debug "Post-Render Hooks:",
|
211
|
+
Jekyll.logger.debug "Post-Render Hooks:", relative_path
|
214
212
|
Jekyll::Hooks.trigger hook_owner, :post_render, self
|
215
213
|
ensure
|
216
214
|
@_renderer = nil # this will allow the modifications above to disappear
|
data/lib/jekyll/deprecator.rb
CHANGED
@@ -34,9 +34,7 @@ module Jekyll
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def arg_is_present?(args, deprecated_argument, message)
|
37
|
-
if args.include?(deprecated_argument)
|
38
|
-
deprecation_message(message)
|
39
|
-
end
|
37
|
+
deprecation_message(message) if args.include?(deprecated_argument)
|
40
38
|
end
|
41
39
|
|
42
40
|
def deprecation_message(message)
|
data/lib/jekyll/document.rb
CHANGED
@@ -10,9 +10,9 @@ module Jekyll
|
|
10
10
|
|
11
11
|
def_delegator :self, :read_post_data, :post_read
|
12
12
|
|
13
|
-
YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m
|
14
|
-
DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)
|
15
|
-
DATE_FILENAME_MATCHER = %r!^(
|
13
|
+
YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m.freeze
|
14
|
+
DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!.freeze
|
15
|
+
DATE_FILENAME_MATCHER = %r!^(?>.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.]+)$!.freeze
|
16
16
|
|
17
17
|
# Create a new Document.
|
18
18
|
#
|
@@ -60,12 +60,19 @@ module Jekyll
|
|
60
60
|
data
|
61
61
|
end
|
62
62
|
|
63
|
+
# Returns the document date. If metadata is not present then calculates it
|
64
|
+
# based on Jekyll::Site#time or the document file modification time.
|
65
|
+
#
|
66
|
+
# Return document date string.
|
63
67
|
def date
|
64
68
|
data["date"] ||= (draft? ? source_file_mtime : site.time)
|
65
69
|
end
|
66
70
|
|
71
|
+
# Return document file modification time in the form of a Time object.
|
72
|
+
#
|
73
|
+
# Return document file modification Time object.
|
67
74
|
def source_file_mtime
|
68
|
-
|
75
|
+
File.mtime(path)
|
69
76
|
end
|
70
77
|
|
71
78
|
# Returns whether the document is a draft. This is only the case if
|
@@ -112,15 +119,19 @@ module Jekyll
|
|
112
119
|
# and with the collection's directory removed as well.
|
113
120
|
# This method is useful when building the URL of the document.
|
114
121
|
#
|
122
|
+
# NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
|
123
|
+
#
|
115
124
|
# Examples:
|
116
|
-
# When relative_path is "_methods/site/generate
|
125
|
+
# When relative_path is "_methods/site/generate...md":
|
117
126
|
# cleaned_relative_path
|
118
127
|
# # => "/site/generate"
|
119
128
|
#
|
120
129
|
# Returns the cleaned relative path of the document.
|
121
130
|
def cleaned_relative_path
|
122
131
|
@cleaned_relative_path ||=
|
123
|
-
relative_path[0..-extname.length - 1]
|
132
|
+
relative_path[0..-extname.length - 1]
|
133
|
+
.sub(collection.relative_directory, "")
|
134
|
+
.gsub(%r!\.*\z!, "")
|
124
135
|
end
|
125
136
|
|
126
137
|
# Determine whether the document is a YAML file.
|
@@ -159,6 +170,8 @@ module Jekyll
|
|
159
170
|
# or if the document doesn't contain any Liquid Tags or Variables,
|
160
171
|
# true otherwise.
|
161
172
|
def render_with_liquid?
|
173
|
+
return false if data["render_with_liquid"] == false
|
174
|
+
|
162
175
|
!(coffeescript_file? || yaml_file? || !Utils.has_liquid_construct?(content))
|
163
176
|
end
|
164
177
|
|
@@ -204,11 +217,11 @@ module Jekyll
|
|
204
217
|
#
|
205
218
|
# Returns the computed URL for the document.
|
206
219
|
def url
|
207
|
-
@url ||= URL.new(
|
220
|
+
@url ||= URL.new(
|
208
221
|
:template => url_template,
|
209
222
|
:placeholders => url_placeholders,
|
210
|
-
:permalink => permalink
|
211
|
-
|
223
|
+
:permalink => permalink
|
224
|
+
).to_s
|
212
225
|
end
|
213
226
|
|
214
227
|
def [](key)
|
@@ -266,7 +279,7 @@ module Jekyll
|
|
266
279
|
else
|
267
280
|
begin
|
268
281
|
merge_defaults
|
269
|
-
read_content(
|
282
|
+
read_content(opts)
|
270
283
|
read_post_data
|
271
284
|
rescue StandardError => e
|
272
285
|
handle_read_error(e)
|
@@ -286,7 +299,7 @@ module Jekyll
|
|
286
299
|
#
|
287
300
|
# Returns the inspect string for this document.
|
288
301
|
def inspect
|
289
|
-
"
|
302
|
+
"#<#{self.class} #{relative_path} collection=#{collection.label}>"
|
290
303
|
end
|
291
304
|
|
292
305
|
# The string representation for this document.
|
@@ -303,6 +316,7 @@ module Jekyll
|
|
303
316
|
# equal or greater than the other doc's path. See String#<=> for more details.
|
304
317
|
def <=>(other)
|
305
318
|
return nil unless other.respond_to?(:data)
|
319
|
+
|
306
320
|
cmp = data["date"] <=> other.data["date"]
|
307
321
|
cmp = path <=> other.path if cmp.nil? || cmp.zero?
|
308
322
|
cmp
|
@@ -315,7 +329,7 @@ module Jekyll
|
|
315
329
|
# method returns true, and if the site's Publisher will publish the document.
|
316
330
|
# False otherwise.
|
317
331
|
def write?
|
318
|
-
collection
|
332
|
+
collection&.write? && site.publisher.publish?(self)
|
319
333
|
end
|
320
334
|
|
321
335
|
# The Document excerpt_separator, from the YAML Front-Matter or site
|
@@ -323,7 +337,7 @@ module Jekyll
|
|
323
337
|
#
|
324
338
|
# Returns the document excerpt_separator
|
325
339
|
def excerpt_separator
|
326
|
-
(data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
|
340
|
+
@excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
|
327
341
|
end
|
328
342
|
|
329
343
|
# Whether to generate an excerpt
|
@@ -335,16 +349,12 @@ module Jekyll
|
|
335
349
|
|
336
350
|
def next_doc
|
337
351
|
pos = collection.docs.index { |post| post.equal?(self) }
|
338
|
-
if pos && pos < collection.docs.length - 1
|
339
|
-
collection.docs[pos + 1]
|
340
|
-
end
|
352
|
+
collection.docs[pos + 1] if pos && pos < collection.docs.length - 1
|
341
353
|
end
|
342
354
|
|
343
355
|
def previous_doc
|
344
356
|
pos = collection.docs.index { |post| post.equal?(self) }
|
345
|
-
if pos && pos
|
346
|
-
collection.docs[pos - 1]
|
347
|
-
end
|
357
|
+
collection.docs[pos - 1] if pos && pos.positive?
|
348
358
|
end
|
349
359
|
|
350
360
|
def trigger_hooks(hook_name, *args)
|
@@ -400,32 +410,30 @@ module Jekyll
|
|
400
410
|
end
|
401
411
|
|
402
412
|
def populate_categories
|
403
|
-
merge_data!(
|
413
|
+
merge_data!(
|
404
414
|
"categories" => (
|
405
415
|
Array(data["categories"]) + Utils.pluralized_array_from_hash(
|
406
416
|
data, "category", "categories"
|
407
417
|
)
|
408
|
-
).map(&:to_s).flatten.uniq
|
409
|
-
|
418
|
+
).map(&:to_s).flatten.uniq
|
419
|
+
)
|
410
420
|
end
|
411
421
|
|
412
422
|
def populate_tags
|
413
|
-
merge_data!(
|
414
|
-
"tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
|
415
|
-
|
423
|
+
merge_data!(
|
424
|
+
"tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
|
425
|
+
)
|
416
426
|
end
|
417
427
|
|
418
428
|
private
|
429
|
+
|
419
430
|
def merge_categories!(other)
|
420
431
|
if other.key?("categories") && !other["categories"].nil?
|
421
|
-
if other["categories"].is_a?(String)
|
422
|
-
other["categories"] = other["categories"].split
|
423
|
-
end
|
432
|
+
other["categories"] = other["categories"].split if other["categories"].is_a?(String)
|
424
433
|
other["categories"] = (data["categories"] || []) | other["categories"]
|
425
434
|
end
|
426
435
|
end
|
427
436
|
|
428
|
-
private
|
429
437
|
def merge_date!(source)
|
430
438
|
if data.key?("date")
|
431
439
|
data["date"] = Utils.parse_date(
|
@@ -435,7 +443,6 @@ module Jekyll
|
|
435
443
|
end
|
436
444
|
end
|
437
445
|
|
438
|
-
private
|
439
446
|
def merge_defaults
|
440
447
|
defaults = @site.frontmatter_defaults.all(
|
441
448
|
relative_path,
|
@@ -444,9 +451,8 @@ module Jekyll
|
|
444
451
|
merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
|
445
452
|
end
|
446
453
|
|
447
|
-
|
448
|
-
|
449
|
-
self.content = File.read(path, **Utils.merged_file_read_opts(site, opts))
|
454
|
+
def read_content(opts)
|
455
|
+
self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
|
450
456
|
if content =~ YAML_FRONT_MATTER_REGEXP
|
451
457
|
self.content = $POSTMATCH
|
452
458
|
data_file = SafeYAML.load(Regexp.last_match(1))
|
@@ -454,7 +460,6 @@ module Jekyll
|
|
454
460
|
end
|
455
461
|
end
|
456
462
|
|
457
|
-
private
|
458
463
|
def read_post_data
|
459
464
|
populate_title
|
460
465
|
populate_categories
|
@@ -462,7 +467,6 @@ module Jekyll
|
|
462
467
|
generate_excerpt
|
463
468
|
end
|
464
469
|
|
465
|
-
private
|
466
470
|
def handle_read_error(error)
|
467
471
|
if error.is_a? Psych::SyntaxError
|
468
472
|
Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{error.message}"
|
@@ -475,7 +479,6 @@ module Jekyll
|
|
475
479
|
end
|
476
480
|
end
|
477
481
|
|
478
|
-
private
|
479
482
|
def populate_title
|
480
483
|
if relative_path =~ DATE_FILENAME_MATCHER
|
481
484
|
date, slug, ext = Regexp.last_match.captures
|
@@ -484,6 +487,10 @@ module Jekyll
|
|
484
487
|
slug, ext = Regexp.last_match.captures
|
485
488
|
end
|
486
489
|
|
490
|
+
# slugs shouldn't end with a period
|
491
|
+
# `String#gsub!` removes all trailing periods (in comparison to `String#chomp!`)
|
492
|
+
slug.gsub!(%r!\.*\z!, "")
|
493
|
+
|
487
494
|
# Try to ensure the user gets a title.
|
488
495
|
data["title"] ||= Utils.titleize_slug(slug)
|
489
496
|
# Only overwrite slug & ext if they aren't specified.
|
@@ -491,18 +498,14 @@ module Jekyll
|
|
491
498
|
data["ext"] ||= ext
|
492
499
|
end
|
493
500
|
|
494
|
-
private
|
495
501
|
def modify_date(date)
|
496
502
|
if !data["date"] || data["date"].to_i == site.time.to_i
|
497
503
|
merge_data!({ "date" => date }, :source => "filename")
|
498
504
|
end
|
499
505
|
end
|
500
506
|
|
501
|
-
private
|
502
507
|
def generate_excerpt
|
503
|
-
if generate_excerpt?
|
504
|
-
data["excerpt"] ||= Jekyll::Excerpt.new(self)
|
505
|
-
end
|
508
|
+
data["excerpt"] ||= Jekyll::Excerpt.new(self) if generate_excerpt?
|
506
509
|
end
|
507
510
|
end
|
508
511
|
end
|
@@ -7,9 +7,8 @@ module Jekyll
|
|
7
7
|
|
8
8
|
mutable false
|
9
9
|
|
10
|
-
def_delegator
|
11
|
-
def_delegators :@obj, :label, :docs, :files, :directory,
|
12
|
-
:relative_directory
|
10
|
+
def_delegator :@obj, :write?, :output
|
11
|
+
def_delegators :@obj, :label, :docs, :files, :directory, :relative_directory
|
13
12
|
|
14
13
|
private def_delegator :@obj, :metadata, :fallback_data
|
15
14
|
|
@@ -12,7 +12,7 @@ module Jekyll
|
|
12
12
|
mutable false
|
13
13
|
|
14
14
|
def_delegator :@obj, :relative_path, :path
|
15
|
-
def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
|
15
|
+
def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url, :date
|
16
16
|
|
17
17
|
private def_delegator :@obj, :data, :fallback_data
|
18
18
|
|
@@ -26,6 +26,7 @@ module Jekyll
|
|
26
26
|
|
27
27
|
def <=>(other)
|
28
28
|
return nil unless other.is_a? DocumentDrop
|
29
|
+
|
29
30
|
cmp = self["date"] <=> other["date"]
|
30
31
|
cmp = self["path"] <=> other["path"] if cmp.nil? || cmp.zero?
|
31
32
|
cmp
|
data/lib/jekyll/drops/drop.rb
CHANGED
@@ -15,11 +15,7 @@ module Jekyll
|
|
15
15
|
#
|
16
16
|
# Returns the mutability of the class
|
17
17
|
def self.mutable(is_mutable = nil)
|
18
|
-
@is_mutable =
|
19
|
-
is_mutable
|
20
|
-
else
|
21
|
-
false
|
22
|
-
end
|
18
|
+
@is_mutable = is_mutable || false
|
23
19
|
end
|
24
20
|
|
25
21
|
def self.mutable?
|
@@ -105,6 +101,7 @@ module Jekyll
|
|
105
101
|
def key?(key)
|
106
102
|
return false if key.nil?
|
107
103
|
return true if self.class.mutable? && @mutations.key?(key)
|
104
|
+
|
108
105
|
respond_to?(key) || fallback_data.key?(key)
|
109
106
|
end
|
110
107
|
|
@@ -173,7 +170,7 @@ module Jekyll
|
|
173
170
|
end
|
174
171
|
|
175
172
|
def merge(other, &block)
|
176
|
-
|
173
|
+
dup.tap do |me|
|
177
174
|
if block.nil?
|
178
175
|
me.merge!(other)
|
179
176
|
else
|