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
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "thread"
4
-
5
3
  module Jekyll
6
4
  module Commands
7
5
  class Serve < Command
@@ -19,31 +17,36 @@ module Jekyll
19
17
  "host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
20
18
  "open_url" => ["-o", "--open-url", "Launch your site in a browser"],
21
19
  "detach" => ["-B", "--detach",
22
- "Run the server in the background",],
20
+ "Run the server in the background",],
23
21
  "ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
24
22
  "port" => ["-P", "--port [PORT]", "Port to listen on"],
25
23
  "show_dir_listing" => ["--show-dir-listing",
26
- "Show a directory listing instead of loading your index file.",],
24
+ "Show a directory listing instead of loading " \
25
+ "your index file.",],
27
26
  "skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
28
- "Skips the initial site build which occurs before the server is started.",],
27
+ "Skips the initial site build which occurs before " \
28
+ "the server is started.",],
29
29
  "livereload" => ["-l", "--livereload",
30
- "Use LiveReload to automatically refresh browsers",],
31
- "livereload_ignore" => ["--livereload-ignore ignore GLOB1[,GLOB2[,...]]",
32
- Array,
33
- "Files for LiveReload to ignore. Remember to quote the values so your shell "\
34
- "won't expand them",],
30
+ "Use LiveReload to automatically refresh browsers",],
31
+ "livereload_ignore" => ["--livereload-ignore GLOB1[,GLOB2[,...]]",
32
+ Array,
33
+ "Files for LiveReload to ignore. " \
34
+ "Remember to quote the values so your shell " \
35
+ "won't expand them",],
35
36
  "livereload_min_delay" => ["--livereload-min-delay [SECONDS]",
36
- "Minimum reload delay",],
37
+ "Minimum reload delay",],
37
38
  "livereload_max_delay" => ["--livereload-max-delay [SECONDS]",
38
- "Maximum reload delay",],
39
+ "Maximum reload delay",],
39
40
  "livereload_port" => ["--livereload-port [PORT]", Integer,
40
- "Port for LiveReload to listen on",],
41
+ "Port for LiveReload to listen on",],
41
42
  }.freeze
42
43
 
43
44
  DIRECTORY_INDEX = %w(
44
45
  index.htm
45
46
  index.html
46
47
  index.rhtml
48
+ index.xht
49
+ index.xhtml
47
50
  index.cgi
48
51
  index.xml
49
52
  index.json
@@ -68,29 +71,20 @@ module Jekyll
68
71
  end
69
72
 
70
73
  cmd.action do |_, opts|
71
- opts["livereload_port"] ||= LIVERELOAD_PORT
72
74
  opts["serving"] = true
73
75
  opts["watch"] = true unless opts.key?("watch")
74
76
 
75
- start(opts)
76
- end
77
- end
78
- end
77
+ # Set the reactor to nil so any old reactor will be GCed.
78
+ # We can't unregister a hook so while running tests we don't want to
79
+ # inadvertently keep using a reactor created by a previous test.
80
+ @reload_reactor = nil
79
81
 
80
- #
81
-
82
- def start(opts)
83
- # Set the reactor to nil so any old reactor will be GCed.
84
- # We can't unregister a hook so in testing when Serve.start is
85
- # called multiple times we don't want to inadvertently keep using
86
- # a reactor created by a previous test when our test might not
87
- @reload_reactor = nil
82
+ config = configuration_from_options(opts)
83
+ config["url"] = default_url(config) if Jekyll.env == "development"
88
84
 
89
- config = configuration_from_options(opts)
90
- if Jekyll.env == "development"
91
- config["url"] = default_url(config)
85
+ process_with_graceful_fail(cmd, config, Build, Serve)
86
+ end
92
87
  end
93
- [Build, Serve].each { |klass| klass.process(config) }
94
88
  end
95
89
 
96
90
  #
@@ -98,7 +92,11 @@ module Jekyll
98
92
  def process(opts)
99
93
  opts = configuration_from_options(opts)
100
94
  destination = opts["destination"]
101
- register_reload_hooks(opts) if opts["livereload"]
95
+ if opts["livereload"]
96
+ opts["livereload_port"] ||= LIVERELOAD_PORT
97
+ validate_options(opts)
98
+ register_reload_hooks(opts)
99
+ end
102
100
  setup(destination)
103
101
 
104
102
  start_up_webrick(opts, destination)
@@ -111,11 +109,12 @@ module Jekyll
111
109
  # Perform logical validation of CLI options
112
110
 
113
111
  private
112
+
114
113
  def validate_options(opts)
115
114
  if opts["livereload"]
116
115
  if opts["detach"]
117
- Jekyll.logger.warn "Warning:",
118
- "--detach and --livereload are mutually exclusive. Choosing --livereload"
116
+ Jekyll.logger.warn "Warning:", "--detach and --livereload are mutually exclusive. " \
117
+ "Choosing --livereload"
119
118
  opts["detach"] = false
120
119
  end
121
120
  if opts["ssl_cert"] || opts["ssl_key"]
@@ -130,27 +129,23 @@ module Jekyll
130
129
  opts["watch"] = true
131
130
  end
132
131
  elsif %w(livereload_min_delay
133
- livereload_max_delay
134
- livereload_ignore
135
- livereload_port).any? { |o| opts[o] }
136
- Jekyll.logger.abort_with "--livereload-min-delay, "\
137
- "--livereload-max-delay, --livereload-ignore, and "\
138
- "--livereload-port require the --livereload option."
132
+ livereload_max_delay
133
+ livereload_ignore
134
+ livereload_port).any? { |o| opts[o] }
135
+ Jekyll.logger.abort_with "--livereload-min-delay, --livereload-max-delay, " \
136
+ "--livereload-ignore, and --livereload-port require " \
137
+ "the --livereload option."
139
138
  end
140
139
  end
141
140
 
142
- #
143
-
144
- private
145
- # rubocop:disable Metrics/AbcSize
146
141
  def register_reload_hooks(opts)
147
142
  require_relative "serve/live_reload_reactor"
148
143
  @reload_reactor = LiveReloadReactor.new
149
144
 
150
145
  Jekyll::Hooks.register(:site, :post_render) do |site|
151
- regenerator = Jekyll::Regenerator.new(site)
152
- @changed_pages = site.pages.select do |p|
153
- regenerator.regenerate?(p)
146
+ @changed_pages = []
147
+ site.each_site_file do |item|
148
+ @changed_pages << item if site.regenerator.regenerate?(item)
154
149
  end
155
150
  end
156
151
 
@@ -164,7 +159,7 @@ module Jekyll
164
159
  if @changed_pages && @reload_reactor && @reload_reactor.running?
165
160
  ignore, @changed_pages = @changed_pages.partition do |p|
166
161
  Array(opts["livereload_ignore"]).any? do |filter|
167
- File.fnmatch(filter, Jekyll.sanitized_path(p.relative_path))
162
+ File.fnmatch(filter, p.relative_path)
168
163
  end
169
164
  end
170
165
  Jekyll.logger.debug "LiveReload:", "Ignoring #{ignore.map(&:relative_path)}"
@@ -173,13 +168,12 @@ module Jekyll
173
168
  @changed_pages = nil
174
169
  end
175
170
  end
176
- # rubocop:enable Metrics/AbcSize
177
171
 
178
172
  # Do a base pre-setup of WEBRick so that everything is in place
179
173
  # when we get ready to party, checking for an setting up an error page
180
174
  # and making sure our destination exists.
181
-
182
- private
175
+ #
176
+ # rubocop:disable Security/IoMethods
183
177
  def setup(destination)
184
178
  require_relative "serve/servlet"
185
179
 
@@ -193,10 +187,8 @@ module Jekyll
193
187
  end
194
188
  end
195
189
  end
190
+ # rubocop:enable Security/IoMethods
196
191
 
197
- #
198
-
199
- private
200
192
  def webrick_opts(opts)
201
193
  opts = {
202
194
  :JekyllOptions => opts,
@@ -218,13 +210,8 @@ module Jekyll
218
210
  opts
219
211
  end
220
212
 
221
- #
222
-
223
- private
224
213
  def start_up_webrick(opts, destination)
225
- if opts["livereload"]
226
- @reload_reactor.start(opts)
227
- end
214
+ @reload_reactor.start(opts) if opts["livereload"]
228
215
 
229
216
  @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
230
217
  @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
@@ -235,20 +222,15 @@ module Jekyll
235
222
  end
236
223
 
237
224
  # Recreate NondisclosureName under utf-8 circumstance
238
-
239
- private
240
225
  def file_handler_opts
241
- WEBrick::Config::FileHandler.merge({
226
+ WEBrick::Config::FileHandler.merge(
242
227
  :FancyIndexing => true,
243
228
  :NondisclosureName => [
244
229
  ".ht*", "~*",
245
- ],
246
- })
230
+ ]
231
+ )
247
232
  end
248
233
 
249
- #
250
-
251
- private
252
234
  def server_address(server, options = {})
253
235
  format_url(
254
236
  server.config[:SSLEnable],
@@ -258,19 +240,14 @@ module Jekyll
258
240
  )
259
241
  end
260
242
 
261
- private
262
243
  def format_url(ssl_enabled, address, port, baseurl = nil)
263
- format("%<prefix>s://%<address>s:%<port>i%<baseurl>s", {
264
- :prefix => ssl_enabled ? "https" : "http",
265
- :address => address,
266
- :port => port,
267
- :baseurl => baseurl ? "#{baseurl}/" : "",
268
- })
244
+ format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
245
+ :prefix => ssl_enabled ? "https" : "http",
246
+ :address => address,
247
+ :port => port,
248
+ :baseurl => baseurl ? "#{baseurl}/" : "")
269
249
  end
270
250
 
271
- #
272
-
273
- private
274
251
  def default_url(opts)
275
252
  config = configuration_from_options(opts)
276
253
  format_url(
@@ -280,32 +257,34 @@ module Jekyll
280
257
  )
281
258
  end
282
259
 
283
- #
284
-
285
- private
286
260
  def launch_browser(server, opts)
287
261
  address = server_address(server, opts)
288
262
  return system "start", address if Utils::Platforms.windows?
289
263
  return system "xdg-open", address if Utils::Platforms.linux?
290
264
  return system "open", address if Utils::Platforms.osx?
291
- Jekyll.logger.error "Refusing to launch browser; " \
292
- "Platform launcher unknown."
265
+
266
+ Jekyll.logger.error "Refusing to launch browser. Platform launcher unknown."
293
267
  end
294
268
 
295
269
  # Keep in our area with a thread or detach the server as requested
296
270
  # by the user. This method determines what we do based on what you
297
271
  # ask us to do.
298
-
299
- private
300
272
  def boot_or_detach(server, opts)
301
273
  if opts["detach"]
302
274
  pid = Process.fork do
275
+ # Detach the process from controlling terminal
276
+ $stdin.reopen("/dev/null", "r")
277
+ $stdout.reopen("/dev/null", "w")
278
+ $stderr.reopen("/dev/null", "w")
303
279
  server.start
304
280
  end
305
281
 
306
282
  Process.detach(pid)
307
- Jekyll.logger.info "Server detached with pid '#{pid}'.", \
308
- "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
283
+ Jekyll.logger.info "Server detached with pid '#{pid}'.",
284
+ "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
285
+
286
+ # Exit without running `at_exit` inherited by the forked process.
287
+ Process.exit! 0
309
288
  else
310
289
  t = Thread.new { server.start }
311
290
  trap("INT") { server.shutdown }
@@ -314,8 +293,6 @@ module Jekyll
314
293
  end
315
294
 
316
295
  # Make the stack verbose if the user requests it.
317
-
318
- private
319
296
  def enable_logging(opts)
320
297
  opts[:AccessLog] = []
321
298
  level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
@@ -325,8 +302,6 @@ module Jekyll
325
302
  # Add SSL to the stack if the user triggers --enable-ssl and they
326
303
  # provide both types of certificates commonly needed. Raise if they
327
304
  # forget to add one of the certificates.
328
-
329
- private
330
305
  def enable_ssl(opts)
331
306
  cert, key, src =
332
307
  opts[:JekyllOptions].values_at("ssl_cert", "ssl_key", "source")
@@ -338,17 +313,24 @@ module Jekyll
338
313
  require "webrick/https"
339
314
 
340
315
  opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(read_file(src, cert))
341
- opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
316
+ begin
317
+ opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
318
+ rescue StandardError
319
+ if defined?(OpenSSL::PKey::EC)
320
+ opts[:SSLPrivateKey] = OpenSSL::PKey::EC.new(read_file(src, key))
321
+ else
322
+ raise
323
+ end
324
+ end
342
325
  opts[:SSLEnable] = true
343
326
  end
344
327
 
345
- private
346
328
  def start_callback(detached)
347
329
  unless detached
348
330
  proc do
349
331
  mutex.synchronize do
350
332
  # Block until EventMachine reactor starts
351
- @reload_reactor.started_event.wait unless @reload_reactor.nil?
333
+ @reload_reactor&.started_event&.wait
352
334
  @running = true
353
335
  Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
354
336
  @run_cond.broadcast
@@ -357,7 +339,6 @@ module Jekyll
357
339
  end
358
340
  end
359
341
 
360
- private
361
342
  def stop_callback(detached)
362
343
  unless detached
363
344
  proc do
@@ -373,14 +354,11 @@ module Jekyll
373
354
  end
374
355
  end
375
356
 
376
- private
377
357
  def mime_types
378
358
  file = File.expand_path("../mime.types", __dir__)
379
359
  WEBrick::HTTPUtils.load_mime_types(file)
380
360
  end
381
361
 
382
- private
383
-
384
362
  def mime_types_charset
385
363
  SafeYAML.load_file(File.expand_path("serve/mime_types_charset.json", __dir__))
386
364
  end