jekyll 3.10.0 → 4.0.0.pre.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|