jekyll 3.8.7 → 4.1.0

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +71 -62
  3. data/LICENSE +1 -1
  4. data/README.markdown +46 -17
  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/main.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.rb +10 -1
  11. data/lib/jekyll/cache.rb +190 -0
  12. data/lib/jekyll/cleaner.rb +5 -4
  13. data/lib/jekyll/collection.rb +82 -10
  14. data/lib/jekyll/command.rb +33 -6
  15. data/lib/jekyll/commands/build.rb +11 -20
  16. data/lib/jekyll/commands/clean.rb +2 -0
  17. data/lib/jekyll/commands/doctor.rb +15 -8
  18. data/lib/jekyll/commands/help.rb +1 -1
  19. data/lib/jekyll/commands/new.rb +37 -35
  20. data/lib/jekyll/commands/new_theme.rb +30 -28
  21. data/lib/jekyll/commands/serve.rb +55 -81
  22. data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
  23. data/lib/jekyll/commands/serve/servlet.rb +22 -25
  24. data/lib/jekyll/commands/serve/websockets.rb +1 -1
  25. data/lib/jekyll/configuration.rb +61 -149
  26. data/lib/jekyll/converters/identity.rb +18 -0
  27. data/lib/jekyll/converters/markdown.rb +49 -40
  28. data/lib/jekyll/converters/markdown/kramdown_parser.rb +84 -11
  29. data/lib/jekyll/converters/smartypants.rb +34 -14
  30. data/lib/jekyll/convertible.rb +30 -31
  31. data/lib/jekyll/deprecator.rb +1 -3
  32. data/lib/jekyll/document.rb +89 -61
  33. data/lib/jekyll/drops/collection_drop.rb +2 -3
  34. data/lib/jekyll/drops/document_drop.rb +14 -1
  35. data/lib/jekyll/drops/drop.rb +17 -14
  36. data/lib/jekyll/drops/excerpt_drop.rb +4 -0
  37. data/lib/jekyll/drops/page_drop.rb +18 -0
  38. data/lib/jekyll/drops/site_drop.rb +6 -5
  39. data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
  40. data/lib/jekyll/drops/url_drop.rb +53 -1
  41. data/lib/jekyll/entry_filter.rb +42 -45
  42. data/lib/jekyll/excerpt.rb +45 -34
  43. data/lib/jekyll/external.rb +10 -5
  44. data/lib/jekyll/filters.rb +200 -40
  45. data/lib/jekyll/filters/date_filters.rb +6 -3
  46. data/lib/jekyll/filters/grouping_filters.rb +1 -2
  47. data/lib/jekyll/filters/url_filters.rb +46 -14
  48. data/lib/jekyll/frontmatter_defaults.rb +46 -35
  49. data/lib/jekyll/hooks.rb +4 -8
  50. data/lib/jekyll/inclusion.rb +32 -0
  51. data/lib/jekyll/liquid_extensions.rb +0 -2
  52. data/lib/jekyll/liquid_renderer.rb +31 -16
  53. data/lib/jekyll/liquid_renderer/file.rb +24 -3
  54. data/lib/jekyll/liquid_renderer/table.rb +36 -77
  55. data/lib/jekyll/log_adapter.rb +5 -1
  56. data/lib/jekyll/mime.types +53 -11
  57. data/lib/jekyll/page.rb +54 -12
  58. data/lib/jekyll/page_excerpt.rb +26 -0
  59. data/lib/jekyll/page_without_a_file.rb +0 -4
  60. data/lib/jekyll/path_manager.rb +31 -0
  61. data/lib/jekyll/plugin.rb +5 -11
  62. data/lib/jekyll/plugin_manager.rb +2 -0
  63. data/lib/jekyll/profiler.rb +58 -0
  64. data/lib/jekyll/reader.rb +42 -9
  65. data/lib/jekyll/readers/collection_reader.rb +1 -0
  66. data/lib/jekyll/readers/data_reader.rb +8 -9
  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 +31 -18
  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/renderer.rb +23 -40
  74. data/lib/jekyll/site.rb +91 -38
  75. data/lib/jekyll/static_file.rb +62 -21
  76. data/lib/jekyll/stevenson.rb +2 -3
  77. data/lib/jekyll/tags/highlight.rb +19 -51
  78. data/lib/jekyll/tags/include.rb +82 -42
  79. data/lib/jekyll/tags/link.rb +11 -7
  80. data/lib/jekyll/tags/post_url.rb +25 -21
  81. data/lib/jekyll/theme.rb +16 -18
  82. data/lib/jekyll/theme_builder.rb +91 -89
  83. data/lib/jekyll/url.rb +10 -5
  84. data/lib/jekyll/utils.rb +18 -21
  85. data/lib/jekyll/utils/ansi.rb +1 -1
  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 +8 -8
  89. data/lib/jekyll/utils/thread_event.rb +1 -5
  90. data/lib/jekyll/utils/win_tz.rb +2 -2
  91. data/lib/jekyll/version.rb +1 -1
  92. data/lib/site_template/.gitignore +2 -0
  93. data/lib/site_template/404.html +1 -0
  94. data/lib/site_template/_config.yml +17 -5
  95. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
  96. data/lib/site_template/{about.md → about.markdown} +0 -0
  97. data/lib/site_template/{index.md → index.markdown} +0 -0
  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 +149 -0
  101. metadata +69 -31
  102. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
  103. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
  104. data/lib/jekyll/utils/rouge.rb +0 -22
@@ -2,39 +2,41 @@
2
2
 
3
3
  require "erb"
4
4
 
5
- class Jekyll::Commands::NewTheme < Jekyll::Command
6
- class << self
7
- def init_with_program(prog)
8
- prog.command(:"new-theme") do |c|
9
- c.syntax "new-theme NAME"
10
- c.description "Creates a new Jekyll theme scaffold"
11
- c.option "code_of_conduct", \
12
- "-c", "--code-of-conduct", \
13
- "Include a Code of Conduct. (defaults to false)"
5
+ module Jekyll
6
+ module Commands
7
+ class NewTheme < Jekyll::Command
8
+ class << self
9
+ def init_with_program(prog)
10
+ prog.command(:"new-theme") do |c|
11
+ c.syntax "new-theme NAME"
12
+ c.description "Creates a new Jekyll theme scaffold"
13
+ c.option "code_of_conduct", \
14
+ "-c", "--code-of-conduct", \
15
+ "Include a Code of Conduct. (defaults to false)"
14
16
 
15
- c.action do |args, opts|
16
- Jekyll::Commands::NewTheme.process(args, opts)
17
+ c.action do |args, opts|
18
+ Jekyll::Commands::NewTheme.process(args, opts)
19
+ end
20
+ end
17
21
  end
18
- end
19
- end
20
22
 
21
- # rubocop:disable Metrics/AbcSize
22
- def process(args, opts)
23
- if !args || args.empty?
24
- raise Jekyll::Errors::InvalidThemeName, "You must specify a theme name."
25
- end
23
+ # rubocop:disable Metrics/AbcSize
24
+ def process(args, opts)
25
+ if !args || args.empty?
26
+ raise Jekyll::Errors::InvalidThemeName, "You must specify a theme name."
27
+ end
26
28
 
27
- new_theme_name = args.join("_")
28
- theme = Jekyll::ThemeBuilder.new(new_theme_name, opts)
29
- if theme.path.exist?
30
- Jekyll.logger.abort_with "Conflict:", "#{theme.path} already exists."
31
- end
29
+ new_theme_name = args.join("_")
30
+ theme = Jekyll::ThemeBuilder.new(new_theme_name, opts)
31
+ Jekyll.logger.abort_with "Conflict:", "#{theme.path} already exists." if theme.path.exist?
32
32
 
33
- theme.create!
34
- Jekyll.logger.info "Your new Jekyll theme, #{theme.name.cyan}," \
35
- " is ready for you in #{theme.path.to_s.cyan}!"
36
- Jekyll.logger.info "For help getting started, read #{theme.path}/README.md."
33
+ theme.create!
34
+ Jekyll.logger.info "Your new Jekyll theme, #{theme.name.cyan}," \
35
+ " is ready for you in #{theme.path.to_s.cyan}!"
36
+ Jekyll.logger.info "For help getting started, read #{theme.path}/README.md."
37
+ end
38
+ # rubocop:enable Metrics/AbcSize
39
+ end
37
40
  end
38
- # rubocop:enable Metrics/AbcSize
39
41
  end
40
42
  end
@@ -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",],
30
+ "Use LiveReload to automatically refresh browsers",],
31
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",],
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
@@ -72,25 +75,17 @@ module Jekyll
72
75
  opts["serving"] = true
73
76
  opts["watch"] = true unless opts.key?("watch")
74
77
 
75
- start(opts)
76
- end
77
- end
78
- end
78
+ # Set the reactor to nil so any old reactor will be GCed.
79
+ # We can't unregister a hook so while running tests we don't want to
80
+ # inadvertently keep using a reactor created by a previous test.
81
+ @reload_reactor = nil
79
82
 
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
83
+ config = configuration_from_options(opts)
84
+ config["url"] = default_url(config) if Jekyll.env == "development"
88
85
 
89
- config = configuration_from_options(opts)
90
- if Jekyll.env == "development"
91
- config["url"] = default_url(config)
86
+ process_with_graceful_fail(cmd, config, Build, Serve)
87
+ end
92
88
  end
93
- [Build, Serve].each { |klass| klass.process(config) }
94
89
  end
95
90
 
96
91
  #
@@ -98,7 +93,10 @@ module Jekyll
98
93
  def process(opts)
99
94
  opts = configuration_from_options(opts)
100
95
  destination = opts["destination"]
101
- register_reload_hooks(opts) if opts["livereload"]
96
+ if opts["livereload"]
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,18 +129,15 @@ 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] }
132
+ livereload_max_delay
133
+ livereload_ignore
134
+ livereload_port).any? { |o| opts[o] }
136
135
  Jekyll.logger.abort_with "--livereload-min-delay, "\
137
136
  "--livereload-max-delay, --livereload-ignore, and "\
138
137
  "--livereload-port require the --livereload option."
139
138
  end
140
139
  end
141
140
 
142
- #
143
-
144
- private
145
141
  # rubocop:disable Metrics/AbcSize
146
142
  def register_reload_hooks(opts)
147
143
  require_relative "serve/live_reload_reactor"
@@ -179,7 +175,6 @@ module Jekyll
179
175
  # when we get ready to party, checking for an setting up an error page
180
176
  # and making sure our destination exists.
181
177
 
182
- private
183
178
  def setup(destination)
184
179
  require_relative "serve/servlet"
185
180
 
@@ -194,9 +189,6 @@ module Jekyll
194
189
  end
195
190
  end
196
191
 
197
- #
198
-
199
- private
200
192
  def webrick_opts(opts)
201
193
  opts = {
202
194
  :JekyllOptions => opts,
@@ -217,13 +209,8 @@ module Jekyll
217
209
  opts
218
210
  end
219
211
 
220
- #
221
-
222
- private
223
212
  def start_up_webrick(opts, destination)
224
- if opts["livereload"]
225
- @reload_reactor.start(opts)
226
- end
213
+ @reload_reactor.start(opts) if opts["livereload"]
227
214
 
228
215
  @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
229
216
  @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
@@ -234,20 +221,15 @@ module Jekyll
234
221
  end
235
222
 
236
223
  # Recreate NondisclosureName under utf-8 circumstance
237
-
238
- private
239
224
  def file_handler_opts
240
- WEBrick::Config::FileHandler.merge({
225
+ WEBrick::Config::FileHandler.merge(
241
226
  :FancyIndexing => true,
242
227
  :NondisclosureName => [
243
228
  ".ht*", "~*",
244
- ],
245
- })
229
+ ]
230
+ )
246
231
  end
247
232
 
248
- #
249
-
250
- private
251
233
  def server_address(server, options = {})
252
234
  format_url(
253
235
  server.config[:SSLEnable],
@@ -257,19 +239,14 @@ module Jekyll
257
239
  )
258
240
  end
259
241
 
260
- private
261
242
  def format_url(ssl_enabled, address, port, baseurl = nil)
262
- format("%<prefix>s://%<address>s:%<port>i%<baseurl>s", {
263
- :prefix => ssl_enabled ? "https" : "http",
264
- :address => address,
265
- :port => port,
266
- :baseurl => baseurl ? "#{baseurl}/" : "",
267
- })
243
+ format("%<prefix>s://%<address>s:%<port>i%<baseurl>s",
244
+ :prefix => ssl_enabled ? "https" : "http",
245
+ :address => address,
246
+ :port => port,
247
+ :baseurl => baseurl ? "#{baseurl}/" : "")
268
248
  end
269
249
 
270
- #
271
-
272
- private
273
250
  def default_url(opts)
274
251
  config = configuration_from_options(opts)
275
252
  format_url(
@@ -279,14 +256,12 @@ module Jekyll
279
256
  )
280
257
  end
281
258
 
282
- #
283
-
284
- private
285
259
  def launch_browser(server, opts)
286
260
  address = server_address(server, opts)
287
261
  return system "start", address if Utils::Platforms.windows?
288
262
  return system "xdg-open", address if Utils::Platforms.linux?
289
263
  return system "open", address if Utils::Platforms.osx?
264
+
290
265
  Jekyll.logger.error "Refusing to launch browser; " \
291
266
  "Platform launcher unknown."
292
267
  end
@@ -294,8 +269,6 @@ module Jekyll
294
269
  # Keep in our area with a thread or detach the server as requested
295
270
  # by the user. This method determines what we do based on what you
296
271
  # ask us to do.
297
-
298
- private
299
272
  def boot_or_detach(server, opts)
300
273
  if opts["detach"]
301
274
  pid = Process.fork do
@@ -304,7 +277,8 @@ module Jekyll
304
277
 
305
278
  Process.detach(pid)
306
279
  Jekyll.logger.info "Server detached with pid '#{pid}'.", \
307
- "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
280
+ "Run `pkill -f jekyll' or `kill -9 #{pid}'" \
281
+ " to stop the server."
308
282
  else
309
283
  t = Thread.new { server.start }
310
284
  trap("INT") { server.shutdown }
@@ -313,8 +287,6 @@ module Jekyll
313
287
  end
314
288
 
315
289
  # Make the stack verbose if the user requests it.
316
-
317
- private
318
290
  def enable_logging(opts)
319
291
  opts[:AccessLog] = []
320
292
  level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
@@ -324,8 +296,6 @@ module Jekyll
324
296
  # Add SSL to the stack if the user triggers --enable-ssl and they
325
297
  # provide both types of certificates commonly needed. Raise if they
326
298
  # forget to add one of the certificates.
327
-
328
- private
329
299
  def enable_ssl(opts)
330
300
  cert, key, src =
331
301
  opts[:JekyllOptions].values_at("ssl_cert", "ssl_key", "source")
@@ -337,17 +307,24 @@ module Jekyll
337
307
  require "webrick/https"
338
308
 
339
309
  opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(read_file(src, cert))
340
- opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
310
+ begin
311
+ opts[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(read_file(src, key))
312
+ rescue StandardError
313
+ if defined?(OpenSSL::PKey::EC)
314
+ opts[:SSLPrivateKey] = OpenSSL::PKey::EC.new(read_file(src, key))
315
+ else
316
+ raise
317
+ end
318
+ end
341
319
  opts[:SSLEnable] = true
342
320
  end
343
321
 
344
- private
345
322
  def start_callback(detached)
346
323
  unless detached
347
324
  proc do
348
325
  mutex.synchronize do
349
326
  # Block until EventMachine reactor starts
350
- @reload_reactor.started_event.wait unless @reload_reactor.nil?
327
+ @reload_reactor&.started_event&.wait
351
328
  @running = true
352
329
  Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
353
330
  @run_cond.broadcast
@@ -356,7 +333,6 @@ module Jekyll
356
333
  end
357
334
  end
358
335
 
359
- private
360
336
  def stop_callback(detached)
361
337
  unless detached
362
338
  proc do
@@ -372,13 +348,11 @@ module Jekyll
372
348
  end
373
349
  end
374
350
 
375
- private
376
351
  def mime_types
377
352
  file = File.expand_path("../mime.types", __dir__)
378
353
  WEBrick::HTTPUtils.load_mime_types(file)
379
354
  end
380
355
 
381
- private
382
356
  def read_file(source_dir, file_path)
383
357
  File.read(Jekyll.sanitized_path(source_dir, file_path))
384
358
  end
@@ -58,7 +58,7 @@ module Jekyll
58
58
  EM.add_shutdown_hook { @stopped_event.set }
59
59
 
60
60
  Jekyll.logger.info "LiveReload address:",
61
- "http://#{opts["host"]}:#{opts["livereload_port"]}"
61
+ "http://#{opts["host"]}:#{opts["livereload_port"]}"
62
62
  end
63
63
  end
64
64
  @thread.abort_on_exception = true
@@ -68,11 +68,11 @@ module Jekyll
68
68
  # http://feedback.livereload.com/knowledgebase/articles/86174-livereload-protocol
69
69
  def reload(pages)
70
70
  pages.each do |p|
71
- json_message = JSON.dump({
71
+ json_message = JSON.dump(
72
72
  :command => "reload",
73
73
  :path => p.url,
74
- :liveCSS => true,
75
- })
74
+ :liveCSS => true
75
+ )
76
76
 
77
77
  Jekyll.logger.debug "LiveReload:", "Reloading #{p.url}"
78
78
  Jekyll.logger.debug "", json_message
@@ -81,6 +81,7 @@ module Jekyll
81
81
  end
82
82
 
83
83
  private
84
+
84
85
  def connect(websocket, handshake)
85
86
  @connections_count += 1
86
87
  if @connections_count == 1
@@ -99,22 +100,17 @@ module Jekyll
99
100
  @websockets << websocket
100
101
  end
101
102
 
102
- private
103
103
  def disconnect(websocket)
104
104
  @websockets.delete(websocket)
105
105
  end
106
106
 
107
- private
108
107
  def print_message(json_message)
109
108
  msg = JSON.parse(json_message)
110
109
  # Not sure what the 'url' command even does in LiveReload. The spec is silent
111
110
  # on its purpose.
112
- if msg["command"] == "url"
113
- Jekyll.logger.info "LiveReload:", "Browser URL: #{msg["url"]}"
114
- end
111
+ Jekyll.logger.info "LiveReload:", "Browser URL: #{msg["url"]}" if msg["command"] == "url"
115
112
  end
116
113
 
117
- private
118
114
  def log_error(error)
119
115
  Jekyll.logger.error "LiveReload experienced an error. " \
120
116
  "Run with --trace for more information."
@@ -29,21 +29,21 @@ module Jekyll
29
29
  end
30
30
 
31
31
  def inline?
32
- @response["Content-Disposition"] =~ %r!^inline!
32
+ @response["Content-Disposition"].to_s.start_with?("inline")
33
33
  end
34
34
 
35
35
  def bad_browser?
36
- BAD_USER_AGENTS.any? { |pattern| @request["User-Agent"] =~ pattern }
36
+ BAD_USER_AGENTS.any? { |pattern| pattern.match?(@request["User-Agent"]) }
37
37
  end
38
38
 
39
39
  def html?
40
- @response["Content-Type"] =~ %r!text/html!
40
+ @response["Content-Type"].to_s.include?("text/html")
41
41
  end
42
42
  end
43
43
 
44
44
  # This class inserts the LiveReload script tags into HTML as it is served
45
45
  class BodyProcessor
46
- HEAD_TAG_REGEX = %r!<head>|<head[^(er)][^<]*>!
46
+ HEAD_TAG_REGEX = %r!<head>|<head[^(er)][^<]*>!.freeze
47
47
 
48
48
  attr_reader :content_length, :new_body, :livereload_added
49
49
 
@@ -98,17 +98,16 @@ module Jekyll
98
98
  # Complicated JavaScript to ensure that livereload.js is loaded from the
99
99
  # same origin as the page. Mostly useful for dealing with the browser's
100
100
  # distinction between 'localhost' and 127.0.0.1
101
- template = <<-TEMPLATE
102
- <script>
103
- document.write(
104
- '<script src="http://' +
105
- (location.host || 'localhost').split(':')[0] +
106
- ':<%=@options["livereload_port"] %>/livereload.js?snipver=1<%= livereload_args %>"' +
107
- '></' +
108
- 'script>');
109
- </script>
101
+ @template ||= ERB.new(<<~TEMPLATE)
102
+ <script>
103
+ document.write(
104
+ '<script src="http://' +
105
+ (location.host || 'localhost').split(':')[0] +
106
+ ':<%=@options["livereload_port"] %>/livereload.js?snipver=1<%= livereload_args %>"' +
107
+ '></' +
108
+ 'script>');
109
+ </script>
110
110
  TEMPLATE
111
- ERB.new(Jekyll::Utils.strip_heredoc(template))
112
111
  end
113
112
 
114
113
  def livereload_args
@@ -121,9 +120,7 @@ module Jekyll
121
120
  if @options["livereload_max_delay"]
122
121
  src += "&amp;maxdelay=#{@options["livereload_max_delay"]}"
123
122
  end
124
- if @options["livereload_port"]
125
- src += "&amp;port=#{@options["livereload_port"]}"
126
- end
123
+ src += "&amp;port=#{@options["livereload_port"]}" if @options["livereload_port"]
127
124
  src
128
125
  end
129
126
  end
@@ -142,7 +139,9 @@ module Jekyll
142
139
  end
143
140
 
144
141
  def search_index_file(req, res)
145
- super || search_file(req, res, ".html")
142
+ super ||
143
+ search_file(req, res, ".html") ||
144
+ search_file(req, res, ".xhtml")
146
145
  end
147
146
 
148
147
  # Add the ability to tap file.html the same way that Nginx does on our
@@ -151,7 +150,9 @@ module Jekyll
151
150
 
152
151
  def search_file(req, res, basename)
153
152
  # /file.* > /file/index.html > /file.html
154
- super || super(req, res, "#{basename}.html")
153
+ super ||
154
+ super(req, res, "#{basename}.html") ||
155
+ super(req, res, "#{basename}.xhtml")
155
156
  end
156
157
 
157
158
  # rubocop:disable Naming/MethodName
@@ -178,21 +179,17 @@ module Jekyll
178
179
  end
179
180
  # rubocop:enable Naming/MethodName
180
181
 
181
- #
182
-
183
182
  private
183
+
184
184
  def validate_and_ensure_charset(_req, res)
185
185
  key = res.header.keys.grep(%r!content-type!i).first
186
186
  typ = res.header[key]
187
187
 
188
- unless typ =~ %r!;\s*charset=!
188
+ unless %r!;\s*charset=!.match?(typ)
189
189
  res.header[key] = "#{typ}; charset=#{@jekyll_opts["encoding"]}"
190
190
  end
191
191
  end
192
192
 
193
- #
194
-
195
- private
196
193
  def set_defaults
197
194
  hash_ = @jekyll_opts.fetch("webrick", {}).fetch("headers", {})
198
195
  DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|