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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +511 -89
  3. data/LICENSE +1 -1
  4. data/README.markdown +48 -27
  5. data/lib/blank_template/_config.yml +3 -0
  6. data/lib/blank_template/_layouts/default.html +12 -0
  7. data/lib/blank_template/_sass/base.scss +9 -0
  8. data/lib/blank_template/assets/css/main.scss +4 -0
  9. data/lib/blank_template/index.md +8 -0
  10. data/lib/jekyll/cache.rb +186 -0
  11. data/lib/jekyll/cleaner.rb +8 -7
  12. data/lib/jekyll/collection.rb +84 -11
  13. data/lib/jekyll/command.rb +33 -6
  14. data/lib/jekyll/commands/build.rb +8 -28
  15. data/lib/jekyll/commands/clean.rb +3 -2
  16. data/lib/jekyll/commands/doctor.rb +46 -35
  17. data/lib/jekyll/commands/help.rb +1 -1
  18. data/lib/jekyll/commands/new.rb +44 -50
  19. data/lib/jekyll/commands/new_theme.rb +27 -28
  20. data/lib/jekyll/commands/serve/live_reload_reactor.rb +9 -16
  21. data/lib/jekyll/commands/serve/servlet.rb +21 -22
  22. data/lib/jekyll/commands/serve/websockets.rb +1 -1
  23. data/lib/jekyll/commands/serve.rb +75 -97
  24. data/lib/jekyll/configuration.rb +66 -158
  25. data/lib/jekyll/converters/identity.rb +18 -0
  26. data/lib/jekyll/converters/markdown/kramdown_parser.rb +83 -33
  27. data/lib/jekyll/converters/markdown.rb +49 -40
  28. data/lib/jekyll/converters/smartypants.rb +34 -14
  29. data/lib/jekyll/convertible.rb +36 -34
  30. data/lib/jekyll/deprecator.rb +2 -4
  31. data/lib/jekyll/document.rb +107 -72
  32. data/lib/jekyll/drops/collection_drop.rb +3 -4
  33. data/lib/jekyll/drops/document_drop.rb +9 -3
  34. data/lib/jekyll/drops/drop.rb +115 -33
  35. data/lib/jekyll/drops/excerpt_drop.rb +8 -0
  36. data/lib/jekyll/drops/site_drop.rb +9 -8
  37. data/lib/jekyll/drops/static_file_drop.rb +4 -4
  38. data/lib/jekyll/drops/theme_drop.rb +39 -0
  39. data/lib/jekyll/drops/unified_payload_drop.rb +7 -2
  40. data/lib/jekyll/drops/url_drop.rb +55 -3
  41. data/lib/jekyll/entry_filter.rb +42 -51
  42. data/lib/jekyll/excerpt.rb +48 -38
  43. data/lib/jekyll/external.rb +20 -19
  44. data/lib/jekyll/filters/date_filters.rb +6 -3
  45. data/lib/jekyll/filters/grouping_filters.rb +1 -2
  46. data/lib/jekyll/filters/url_filters.rb +50 -15
  47. data/lib/jekyll/filters.rb +211 -50
  48. data/lib/jekyll/frontmatter_defaults.rb +45 -36
  49. data/lib/jekyll/hooks.rb +26 -26
  50. data/lib/jekyll/inclusion.rb +32 -0
  51. data/lib/jekyll/layout.rb +12 -19
  52. data/lib/jekyll/liquid_extensions.rb +0 -2
  53. data/lib/jekyll/liquid_renderer/file.rb +24 -3
  54. data/lib/jekyll/liquid_renderer/table.rb +26 -77
  55. data/lib/jekyll/liquid_renderer.rb +31 -16
  56. data/lib/jekyll/log_adapter.rb +5 -1
  57. data/lib/jekyll/page.rb +51 -23
  58. data/lib/jekyll/page_excerpt.rb +25 -0
  59. data/lib/jekyll/page_without_a_file.rb +0 -4
  60. data/lib/jekyll/path_manager.rb +74 -0
  61. data/lib/jekyll/plugin.rb +5 -11
  62. data/lib/jekyll/plugin_manager.rb +15 -5
  63. data/lib/jekyll/profiler.rb +51 -0
  64. data/lib/jekyll/reader.rb +65 -10
  65. data/lib/jekyll/readers/collection_reader.rb +1 -0
  66. data/lib/jekyll/readers/data_reader.rb +48 -10
  67. data/lib/jekyll/readers/layout_reader.rb +3 -12
  68. data/lib/jekyll/readers/page_reader.rb +5 -5
  69. data/lib/jekyll/readers/post_reader.rb +32 -19
  70. data/lib/jekyll/readers/static_file_reader.rb +4 -4
  71. data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
  72. data/lib/jekyll/regenerator.rb +4 -12
  73. data/lib/jekyll/related_posts.rb +1 -1
  74. data/lib/jekyll/renderer.rb +34 -49
  75. data/lib/jekyll/site.rb +151 -58
  76. data/lib/jekyll/static_file.rb +64 -28
  77. data/lib/jekyll/stevenson.rb +4 -8
  78. data/lib/jekyll/tags/highlight.rb +44 -57
  79. data/lib/jekyll/tags/include.rb +114 -80
  80. data/lib/jekyll/tags/link.rb +12 -7
  81. data/lib/jekyll/tags/post_url.rb +33 -30
  82. data/lib/jekyll/theme.rb +20 -18
  83. data/lib/jekyll/theme_builder.rb +91 -89
  84. data/lib/jekyll/url.rb +18 -10
  85. data/lib/jekyll/utils/ansi.rb +2 -2
  86. data/lib/jekyll/utils/exec.rb +0 -1
  87. data/lib/jekyll/utils/internet.rb +2 -4
  88. data/lib/jekyll/utils/platforms.rb +37 -52
  89. data/lib/jekyll/utils/thread_event.rb +1 -5
  90. data/lib/jekyll/utils.rb +29 -28
  91. data/lib/jekyll/version.rb +1 -1
  92. data/lib/jekyll.rb +9 -14
  93. data/lib/site_template/.gitignore +2 -0
  94. data/lib/site_template/404.html +2 -1
  95. data/lib/site_template/_config.yml +17 -5
  96. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
  97. data/lib/theme_template/README.md.erb +1 -3
  98. data/lib/theme_template/gitignore.erb +1 -0
  99. data/lib/theme_template/theme.gemspec.erb +1 -4
  100. data/rubocop/jekyll/assert_equal_literal_actual.rb +150 -0
  101. data/rubocop/jekyll/no_p_allowed.rb +5 -6
  102. data/rubocop/jekyll/no_puts_allowed.rb +5 -6
  103. metadata +149 -37
  104. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
  105. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
  106. data/lib/jekyll/utils/rouge.rb +0 -22
  107. /data/lib/site_template/{about.md → about.markdown} +0 -0
  108. /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.info "", "Custom processors are not loaded in safe mode"
17
+ Jekyll.logger.warn "Build Warning:", "Custom processors are not loaded in safe mode"
16
18
  end
17
- Jekyll.logger.error(
18
- "",
19
- "Available processors are: #{valid_processors.join(", ")}"
20
- )
21
- raise Errors::FatalException, "Bailing out; invalid Markdown processor."
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
- # Rubocop does not allow reader methods to have names starting with `get_`
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 "redcarpet" then return RedcarpetParser.new(@config)
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, the ones we
43
- # support internally and the ones that you have provided to us (if you
44
- # are not in safe mode.)
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
- %w(rdiscount kramdown redcarpet) + third_party_processors
49
+ [:kramdown] + third_party_processors
48
50
  end
49
51
 
50
52
  # Public: A list of processors that you provide via plugins.
51
- # This is really only available if you are not in safe mode, if you are
52
- # in safe mode (re: GitHub) then there will be none.
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
- @parser.convert(content)
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
- # characters and is defined within Jekyll::Converters::Markdown
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
- class Kramdown::Parser::SmartyPants < Kramdown::Parser::Kramdown
4
- def initialize(source, options)
5
- super
6
- @block_parsers = [:block_html, :content]
7
- @span_parsers = [:smart_quotes, :html_entity, :typographic_syms, :span_html]
8
- end
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
- def parse_content
11
- add_text @src.scan(%r!\A.*\n!)
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
- def matches(_)
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
- def output_ext(_)
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
@@ -35,21 +35,21 @@ module Jekyll
35
35
  # Returns nothing.
36
36
  # rubocop:disable Metrics/AbcSize
37
37
  def read_yaml(base, name, opts = {})
38
- filename = File.join(base, name)
38
+ filename = @path || site.in_source_dir(base, name)
39
+ Jekyll.logger.debug "Reading:", relative_path
39
40
 
40
41
  begin
41
- self.content = File.read(@path || site.in_source_dir(base, name),
42
- **Utils.merged_file_read_opts(site, opts))
42
+ self.content = File.read(filename, **Utils.merged_file_read_opts(site, opts))
43
43
  if content =~ Document::YAML_FRONT_MATTER_REGEXP
44
- self.content = $POSTMATCH
44
+ self.content = Regexp.last_match.post_match
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 self.site.config["strict_front_matter"]
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 self.site.config["strict_front_matter"]
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
- "Invalid YAML front matter in #{filename}"
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"] && self.data["permalink"].to_s.empty?
72
+ if self.data["permalink"] == ""
73
73
  raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
74
74
  end
75
75
  end
@@ -78,7 +78,7 @@ module Jekyll
78
78
  #
79
79
  # Returns the transformed contents.
80
80
  def transform
81
- _renderer.convert(content)
81
+ renderer.convert(content)
82
82
  end
83
83
 
84
84
  # Determine the extension depending on content_type.
@@ -86,7 +86,7 @@ module Jekyll
86
86
  # Returns the String extension for the output file.
87
87
  # e.g. ".html" for an HTML output file.
88
88
  def output_ext
89
- _renderer.output_ext
89
+ renderer.output_ext
90
90
  end
91
91
 
92
92
  # Determine which converter to use based on this convertible's
@@ -94,7 +94,7 @@ module Jekyll
94
94
  #
95
95
  # Returns the Converter instance.
96
96
  def converters
97
- _renderer.converters
97
+ renderer.converters
98
98
  end
99
99
 
100
100
  # Render Liquid in the content
@@ -105,18 +105,18 @@ module Jekyll
105
105
  #
106
106
  # Returns the converted content
107
107
  def render_liquid(content, payload, info, path)
108
- _renderer.render_liquid(content, payload, info, path)
108
+ renderer.render_liquid(content, payload, info, path)
109
109
  end
110
110
 
111
111
  # Convert this Convertible's data to a Hash suitable for use by Liquid.
112
112
  #
113
113
  # Returns the Hash representation of this Convertible.
114
114
  def to_liquid(attrs = nil)
115
- further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map do |attribute|
116
- [attribute, send(attribute)]
117
- end]
115
+ further_data = \
116
+ (attrs || self.class::ATTRIBUTES_FOR_LIQUID).each_with_object({}) do |attribute, hsh|
117
+ hsh[attribute] = send(attribute)
118
+ end
118
119
 
119
- defaults = site.frontmatter_defaults.all(relative_path, type)
120
120
  Utils.deep_merge_hashes defaults, Utils.deep_merge_hashes(data, further_data)
121
121
  end
122
122
 
@@ -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.
@@ -150,7 +146,7 @@ module Jekyll
150
146
  #
151
147
  # Returns true if extname == .sass or .scss, false otherwise.
152
148
  def sass_file?
153
- %w(.sass .scss).include?(ext)
149
+ Jekyll::Document::SASS_FILE_EXTS.include?(ext)
154
150
  end
155
151
 
156
152
  # Determine whether the document is a CoffeeScript 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? && !(self.is_a? Jekyll::Excerpt)
182
+ !data["layout"].nil? && layout.nil? && !(is_a? Jekyll::Excerpt)
185
183
  end
186
184
 
187
185
  # Recursively render layouts
@@ -192,10 +190,10 @@ module Jekyll
192
190
  #
193
191
  # Returns nothing
194
192
  def render_all_layouts(layouts, payload, info)
195
- _renderer.layouts = layouts
196
- self.output = _renderer.place_in_layouts(output, payload, info)
193
+ renderer.layouts = layouts
194
+ self.output = renderer.place_in_layouts(output, payload, info)
197
195
  ensure
198
- @_renderer = nil # this will allow the modifications above to disappear
196
+ @renderer = nil # this will allow the modifications above to disappear
199
197
  end
200
198
 
201
199
  # Add any necessary layouts to this convertible document.
@@ -205,15 +203,15 @@ module Jekyll
205
203
  #
206
204
  # Returns nothing.
207
205
  def do_layout(payload, layouts)
208
- self.output = _renderer.tap do |renderer|
209
- renderer.layouts = layouts
210
- renderer.payload = payload
206
+ self.output = renderer.tap do |doc_renderer|
207
+ doc_renderer.layouts = layouts
208
+ doc_renderer.payload = payload
211
209
  end.run
212
210
 
213
- Jekyll.logger.debug "Post-Render Hooks:", self.relative_path
211
+ Jekyll.logger.debug "Post-Render Hooks:", relative_path
214
212
  Jekyll::Hooks.trigger hook_owner, :post_render, self
215
213
  ensure
216
- @_renderer = nil # this will allow the modifications above to disappear
214
+ @renderer = nil # this will allow the modifications above to disappear
217
215
  end
218
216
 
219
217
  # Write the generated page file to the destination directory.
@@ -242,10 +240,14 @@ module Jekyll
242
240
  end
243
241
  end
244
242
 
243
+ def renderer
244
+ @renderer ||= Jekyll::Renderer.new(site, self)
245
+ end
246
+
245
247
  private
246
248
 
247
- def _renderer
248
- @_renderer ||= Jekyll::Renderer.new(site, self)
249
+ def defaults
250
+ @defaults ||= site.frontmatter_defaults.all(relative_path, type)
249
251
  end
250
252
 
251
253
  def no_layout?
@@ -15,7 +15,7 @@ module Jekyll
15
15
  '--watch'."
16
16
  arg_is_present? args, "--no-auto", "To disable auto-replication, simply leave off \
17
17
  the '--watch' switch."
18
- arg_is_present? args, "--pygments", "The 'pygments'settings has been removed in \
18
+ arg_is_present? args, "--pygments", "The 'pygments' settings has been removed in \
19
19
  favour of 'highlighter'."
20
20
  arg_is_present? args, "--paginate", "The 'paginate' setting can only be set in \
21
21
  your config files."
@@ -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)