jekyll 3.6.3 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of jekyll might be problematic. Click here for more details.

Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -9
  3. data/LICENSE +1 -1
  4. data/README.markdown +1 -1
  5. data/lib/jekyll.rb +3 -0
  6. data/lib/jekyll/cleaner.rb +3 -1
  7. data/lib/jekyll/collection.rb +7 -3
  8. data/lib/jekyll/commands/clean.rb +1 -1
  9. data/lib/jekyll/commands/doctor.rb +3 -1
  10. data/lib/jekyll/commands/new.rb +5 -2
  11. data/lib/jekyll/commands/serve.rb +183 -41
  12. data/lib/jekyll/commands/serve/live_reload_reactor.rb +127 -0
  13. data/lib/jekyll/commands/serve/livereload_assets/livereload.js +1183 -0
  14. data/lib/jekyll/commands/serve/servlet.rb +142 -1
  15. data/lib/jekyll/commands/serve/websockets.rb +80 -0
  16. data/lib/jekyll/configuration.rb +9 -17
  17. data/lib/jekyll/converters/markdown.rb +1 -1
  18. data/lib/jekyll/converters/markdown/kramdown_parser.rb +8 -2
  19. data/lib/jekyll/converters/smartypants.rb +14 -2
  20. data/lib/jekyll/convertible.rb +10 -4
  21. data/lib/jekyll/document.rb +2 -2
  22. data/lib/jekyll/entry_filter.rb +3 -6
  23. data/lib/jekyll/filters/url_filters.rb +6 -1
  24. data/lib/jekyll/frontmatter_defaults.rb +18 -3
  25. data/lib/jekyll/hooks.rb +3 -0
  26. data/lib/jekyll/liquid_renderer.rb +8 -6
  27. data/lib/jekyll/page.rb +1 -1
  28. data/lib/jekyll/page_without_a_file.rb +18 -0
  29. data/lib/jekyll/regenerator.rb +1 -1
  30. data/lib/jekyll/renderer.rb +2 -2
  31. data/lib/jekyll/site.rb +1 -3
  32. data/lib/jekyll/tags/highlight.rb +2 -2
  33. data/lib/jekyll/tags/include.rb +1 -1
  34. data/lib/jekyll/tags/post_url.rb +1 -1
  35. data/lib/jekyll/theme.rb +3 -2
  36. data/lib/jekyll/theme_builder.rb +8 -8
  37. data/lib/jekyll/utils.rb +41 -22
  38. data/lib/jekyll/utils/ansi.rb +0 -2
  39. data/lib/jekyll/utils/internet.rb +39 -0
  40. data/lib/jekyll/utils/thread_event.rb +35 -0
  41. data/lib/jekyll/version.rb +1 -1
  42. metadata +41 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65785b9f0149bc22d4f5b51549606b1a6399ded5d55accb541d5489b7acfaf9e
4
- data.tar.gz: 7e2321db1c5829d29a1286009c258c5cbaeaa4747c6cbaf8f321a45c2db600d5
3
+ metadata.gz: dc90aec85835d915ea7cb5f56a489a923d0bc78681a23ea5ee0b1df2c1382a6b
4
+ data.tar.gz: e0131966b4f2abf57be7744559b7e5ff207ec6c200615dc2646c96847d92af7b
5
5
  SHA512:
6
- metadata.gz: 000b80a3d6fe47ea36b4530655c13854598f3668841b3c506da867d54c86e98cc40bddeb5964aca9d6ef22224030d55f0e004b6deb2f941613b8ebc0d45582eb
7
- data.tar.gz: b890e22bcd20536898b3b7061c858c4d5a55c060cf1437cb6feccbdc5bb4bbf630e30a1e36ae99044f99e9f6488d5832cbc1288ce63f58f315f6b2aa3f246561
6
+ metadata.gz: 6baa34eeb5717fbbc2919bb03b54a21857785167c1f178a0add5d301bd9f56735a8e14948b69966b65498555f1002460ae8972c76ebac6b28ccada1447e660cc
7
+ data.tar.gz: 4b36b7255f94a8221cae77714214711fc3909ddc9bb984ab4e852e0c3cde915a2dc2756a7c92b2ead11e0b86cf0e3cbf500eabeeb4680fc5a96c6083d2d16cce
@@ -38,14 +38,10 @@ Layout/MultilineMethodCallIndentation:
38
38
  EnforcedStyle: indented
39
39
  Layout/MultilineOperationIndentation:
40
40
  EnforcedStyle: indented
41
- Layout/SpaceAroundOperators:
42
- Enabled: true
43
41
  Layout/SpaceInsideBrackets:
44
42
  Enabled: false
45
43
  Lint/EndAlignment:
46
44
  Severity: error
47
- Lint/RescueWithoutErrorClass:
48
- Enabled: false
49
45
  Lint/UnreachableCode:
50
46
  Severity: error
51
47
  Lint/UselessAccessModifier:
@@ -102,14 +98,11 @@ Style/Alias:
102
98
  Enabled: false
103
99
  Style/AndOr:
104
100
  Severity: error
105
- Style/Attr:
106
- Enabled: false
107
101
  Style/BracesAroundHashParameters:
108
102
  Enabled: false
109
103
  Style/ClassAndModuleChildren:
110
104
  Enabled: false
111
105
  Style/FrozenStringLiteralComment:
112
- Enabled: true
113
106
  EnforcedStyle: always
114
107
  Style/Documentation:
115
108
  Enabled: false
@@ -159,5 +152,3 @@ Style/SymbolArray:
159
152
  Enabled: false
160
153
  Style/TrailingCommaInLiteral:
161
154
  EnforcedStyleForMultiline: consistent_comma
162
- Style/UnneededCapitalW:
163
- Enabled: false
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2008-2017 Tom Preston-Werner and Jekyll contributors
3
+ Copyright (c) 2008-2018 Tom Preston-Werner and Jekyll contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -45,7 +45,7 @@ conduct.
45
45
  Please adhere to this code of conduct in any interactions you have in the
46
46
  Jekyll community. It is strictly enforced on all official Jekyll
47
47
  repositories, websites, and resources. If you encounter someone violating
48
- these terms, please let a [team captain](https://github.com/orgs/jekyll/teams/affinity-team-captains/members) know and we will address it as soon as possible.
48
+ these terms, please let one of our core team members [Olivia](mailto:olivia@jekyllrb.com?subject=Jekyll%20CoC%20Violation), [Pat](mailto:pat@jekyllrb.com?subject=Jekyll%20CoC%20Violation), [Matt](mailto:matt@jekyllrb.com?subject=Jekyll%20CoC%20Violation) or [Parker](mailto:parker@jekyllrb.com?subject=Jekyll%20CoC%20Violation) know and we will address it as soon as possible.
49
49
 
50
50
  ## Diving In
51
51
 
@@ -32,8 +32,10 @@ require "safe_yaml/load"
32
32
  require "liquid"
33
33
  require "kramdown"
34
34
  require "colorator"
35
+ require "i18n"
35
36
 
36
37
  SafeYAML::OPTIONS[:suppress_warnings] = true
38
+ I18n.config.available_locales = :en
37
39
 
38
40
  module Jekyll
39
41
  # internal requires
@@ -59,6 +61,7 @@ module Jekyll
59
61
  autoload :ThemeAssetsReader, "jekyll/readers/theme_assets_reader"
60
62
  autoload :LogAdapter, "jekyll/log_adapter"
61
63
  autoload :Page, "jekyll/page"
64
+ autoload :PageWithoutAFile, "jekyll/page_without_a_file"
62
65
  autoload :PluginManager, "jekyll/plugin_manager"
63
66
  autoload :Publisher, "jekyll/publisher"
64
67
  autoload :Reader, "jekyll/reader"
@@ -24,7 +24,9 @@ module Jekyll
24
24
  #
25
25
  # Returns an Array of the file and directory paths
26
26
  def obsolete_files
27
- (existing_files - new_files - new_dirs + replaced_files).to_a
27
+ out = (existing_files - new_files - new_dirs + replaced_files).to_a
28
+ Jekyll::Hooks.trigger :clean, :on_obsolete, out
29
+ out
28
30
  end
29
31
 
30
32
  # Private: The metadata file storing dependency tree and build history
@@ -100,7 +100,9 @@ module Jekyll
100
100
  # Returns a String containing the directory name where the collection
101
101
  # is stored on the filesystem.
102
102
  def relative_directory
103
- @relative_directory ||= "_#{label}"
103
+ @relative_directory ||= Pathname.new(directory).relative_path_from(
104
+ Pathname.new(site.source)
105
+ ).to_s
104
106
  end
105
107
 
106
108
  # The full path to the directory containing the collection.
@@ -108,7 +110,9 @@ module Jekyll
108
110
  # Returns a String containing th directory name where the collection
109
111
  # is stored on the filesystem.
110
112
  def directory
111
- @directory ||= site.in_source_dir(relative_directory)
113
+ @directory ||= site.in_source_dir(
114
+ File.join(site.config["collections_dir"], "_#{label}")
115
+ )
112
116
  end
113
117
 
114
118
  # The full path to the directory containing the collection, with
@@ -206,7 +210,7 @@ module Jekyll
206
210
  if site.publisher.publish?(doc) || !write?
207
211
  docs << doc
208
212
  else
209
- Jekyll.logger.debug "Skipped From Publishing:", doc.relative_path
213
+ Jekyll.logger.debug "Skipped Publishing:", doc.relative_path
210
214
  end
211
215
  end
212
216
 
@@ -22,7 +22,7 @@ module Jekyll
22
22
  options = configuration_from_options(options)
23
23
  destination = options["destination"]
24
24
  metadata_file = File.join(options["source"], ".jekyll-metadata")
25
- sass_cache = File.join(options["source"], ".sass-cache")
25
+ sass_cache = ".sass-cache"
26
26
 
27
27
  remove(destination, :checker_func => :directory?)
28
28
  remove(metadata_file, :checker_func => :file?)
@@ -135,7 +135,9 @@ module Jekyll
135
135
  def url_valid?(url)
136
136
  Addressable::URI.parse(url)
137
137
  true
138
- rescue
138
+ # Addressable::URI#parse only raises a TypeError
139
+ # https://git.io/vFfbx
140
+ rescue TypeError
139
141
  Jekyll.logger.warn "Warning:", "The site URL does not seem to be valid, "\
140
142
  "check the value of `url` in your config file."
141
143
  false
@@ -87,7 +87,7 @@ group :jekyll_plugins do
87
87
  end
88
88
 
89
89
  # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
90
- gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
90
+ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
91
91
 
92
92
  RUBY
93
93
  end
@@ -143,10 +143,13 @@ RUBY
143
143
  def bundle_install(path)
144
144
  Jekyll.logger.info "Running bundle install in #{path.cyan}..."
145
145
  Dir.chdir(path) do
146
- process, output = Jekyll::Utils::Exec.run("bundle", "install")
146
+ exe = Gem.bin_path("bundler", "bundle")
147
+ process, output = Jekyll::Utils::Exec.run("ruby", exe, "install")
148
+
147
149
  output.to_s.each_line do |line|
148
150
  Jekyll.logger.info("Bundler:".green, line.strip) unless line.to_s.empty?
149
151
  end
152
+
150
153
  raise SystemExit unless process.success?
151
154
  end
152
155
  end
@@ -1,23 +1,59 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "thread"
4
+
3
5
  module Jekyll
4
6
  module Commands
5
7
  class Serve < Command
8
+ # Similar to the pattern in Utils::ThreadEvent except we are maintaining the
9
+ # state of @running instead of just signaling an event. We have to maintain this
10
+ # state since Serve is just called via class methods instead of an instance
11
+ # being created each time.
12
+ @mutex = Mutex.new
13
+ @run_cond = ConditionVariable.new
14
+ @running = false
15
+
6
16
  class << self
7
17
  COMMAND_OPTIONS = {
8
- "ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
9
- "host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
10
- "open_url" => ["-o", "--open-url", "Launch your site in a browser"],
11
- "detach" => ["-B", "--detach", "Run the server in the background"],
12
- "ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
13
- "port" => ["-P", "--port [PORT]", "Port to listen on"],
14
- "show_dir_listing" => ["--show-dir-listing",
18
+ "ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
19
+ "host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
20
+ "open_url" => ["-o", "--open-url", "Launch your site in a browser"],
21
+ "detach" => ["-B", "--detach",
22
+ "Run the server in the background",],
23
+ "ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
24
+ "port" => ["-P", "--port [PORT]", "Port to listen on"],
25
+ "show_dir_listing" => ["--show-dir-listing",
15
26
  "Show a directory listing instead of loading your index file.",],
16
- "skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
27
+ "skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
17
28
  "Skips the initial site build which occurs before the server is started.",],
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",],
35
+ "livereload_min_delay" => ["--livereload-min-delay [SECONDS]",
36
+ "Minimum reload delay",],
37
+ "livereload_max_delay" => ["--livereload-max-delay [SECONDS]",
38
+ "Maximum reload delay",],
39
+ "livereload_port" => ["--livereload-port [PORT]", Integer,
40
+ "Port for LiveReload to listen on",],
18
41
  }.freeze
19
42
 
20
- #
43
+ DIRECTORY_INDEX = %w(
44
+ index.htm
45
+ index.html
46
+ index.rhtml
47
+ index.cgi
48
+ index.xml
49
+ index.json
50
+ ).freeze
51
+
52
+ LIVERELOAD_PORT = 35_729
53
+ LIVERELOAD_DIR = File.join(__dir__, "serve", "livereload_assets")
54
+
55
+ attr_reader :mutex, :run_cond, :running
56
+ alias_method :running?, :running
21
57
 
22
58
  def init_with_program(prog)
23
59
  prog.command(:serve) do |cmd|
@@ -32,28 +68,112 @@ module Jekyll
32
68
  end
33
69
 
34
70
  cmd.action do |_, opts|
71
+ opts["livereload_port"] ||= LIVERELOAD_PORT
35
72
  opts["serving"] = true
36
73
  opts["watch" ] = true unless opts.key?("watch")
37
74
 
38
- config = configuration_from_options(opts)
39
- if Jekyll.env == "development"
40
- config["url"] = default_url(config)
41
- end
42
- [Build, Serve].each { |klass| klass.process(config) }
75
+ start(opts)
43
76
  end
44
77
  end
45
78
  end
46
79
 
47
80
  #
48
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
88
+
89
+ config = configuration_from_options(opts)
90
+ if Jekyll.env == "development"
91
+ config["url"] = default_url(config)
92
+ end
93
+ [Build, Serve].each { |klass| klass.process(config) }
94
+ end
95
+
96
+ #
97
+
49
98
  def process(opts)
50
99
  opts = configuration_from_options(opts)
51
100
  destination = opts["destination"]
101
+ register_reload_hooks(opts) if opts["livereload"]
52
102
  setup(destination)
53
103
 
54
104
  start_up_webrick(opts, destination)
55
105
  end
56
106
 
107
+ def shutdown
108
+ @server.shutdown if running?
109
+ end
110
+
111
+ # Perform logical validation of CLI options
112
+
113
+ private
114
+ def validate_options(opts)
115
+ if opts["livereload"]
116
+ if opts["detach"]
117
+ Jekyll.logger.warn "Warning:",
118
+ "--detach and --livereload are mutually exclusive. Choosing --livereload"
119
+ opts["detach"] = false
120
+ end
121
+ if opts["ssl_cert"] || opts["ssl_key"]
122
+ # This is not technically true. LiveReload works fine over SSL, but
123
+ # EventMachine's SSL support in Windows requires building the gem's
124
+ # native extensions against OpenSSL and that proved to be a process
125
+ # so tedious that expecting users to do it is a non-starter.
126
+ Jekyll.logger.abort_with "Error:", "LiveReload does not support SSL"
127
+ end
128
+ unless opts["watch"]
129
+ # Using livereload logically implies you want to watch the files
130
+ opts["watch"] = true
131
+ end
132
+ 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."
139
+ end
140
+ end
141
+
142
+ #
143
+
144
+ private
145
+ # rubocop:disable Metrics/AbcSize
146
+ def register_reload_hooks(opts)
147
+ require_relative "serve/live_reload_reactor"
148
+ @reload_reactor = LiveReloadReactor.new
149
+
150
+ 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)
154
+ end
155
+ end
156
+
157
+ # A note on ignoring files: LiveReload errs on the side of reloading when it
158
+ # comes to the message it gets. If, for example, a page is ignored but a CSS
159
+ # file linked in the page isn't, the page will still be reloaded if the CSS
160
+ # file is contained in the message sent to LiveReload. Additionally, the
161
+ # path matching is very loose so that a message to reload "/" will always
162
+ # lead the page to reload since every page starts with "/".
163
+ Jekyll::Hooks.register(:site, :post_write) do
164
+ if @changed_pages && @reload_reactor && @reload_reactor.running?
165
+ ignore, @changed_pages = @changed_pages.partition do |p|
166
+ Array(opts["livereload_ignore"]).any? do |filter|
167
+ File.fnmatch(filter, Jekyll.sanitized_path(p.relative_path))
168
+ end
169
+ end
170
+ Jekyll.logger.debug "LiveReload:", "Ignoring #{ignore.map(&:relative_path)}"
171
+ @reload_reactor.reload(@changed_pages)
172
+ end
173
+ @changed_pages = nil
174
+ end
175
+ end
176
+
57
177
  # Do a base pre-setup of WEBRick so that everything is in place
58
178
  # when we get ready to party, checking for an setting up an error page
59
179
  # and making sure our destination exists.
@@ -83,15 +203,10 @@ module Jekyll
83
203
  :MimeTypes => mime_types,
84
204
  :DocumentRoot => opts["destination"],
85
205
  :StartCallback => start_callback(opts["detach"]),
206
+ :StopCallback => stop_callback(opts["detach"]),
86
207
  :BindAddress => opts["host"],
87
208
  :Port => opts["port"],
88
- :DirectoryIndex => %W(
89
- index.htm
90
- index.html
91
- index.rhtml
92
- index.cgi
93
- index.xml
94
- ),
209
+ :DirectoryIndex => DIRECTORY_INDEX,
95
210
  }
96
211
 
97
212
  opts[:DirectoryIndex] = [] if opts[:JekyllOptions]["show_dir_listing"]
@@ -105,11 +220,16 @@ module Jekyll
105
220
 
106
221
  private
107
222
  def start_up_webrick(opts, destination)
108
- server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
109
- server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
110
- Jekyll.logger.info "Server address:", server_address(server, opts)
111
- launch_browser server, opts if opts["open_url"]
112
- boot_or_detach server, opts
223
+ if opts["livereload"]
224
+ @reload_reactor.start(opts)
225
+ end
226
+
227
+ @server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
228
+ @server.mount(opts["baseurl"].to_s, Servlet, destination, file_handler_opts)
229
+
230
+ Jekyll.logger.info "Server address:", server_address(@server, opts)
231
+ launch_browser @server, opts if opts["open_url"]
232
+ boot_or_detach @server, opts
113
233
  end
114
234
 
115
235
  # Recreate NondisclosureName under utf-8 circumstance
@@ -205,31 +325,48 @@ module Jekyll
205
325
  # forget to add one of the certificates.
206
326
 
207
327
  private
208
- # rubocop:disable Metrics/AbcSize
209
328
  def enable_ssl(opts)
210
- return if !opts[:JekyllOptions]["ssl_cert"] && !opts[:JekyllOptions]["ssl_key"]
211
- if !opts[:JekyllOptions]["ssl_cert"] || !opts[:JekyllOptions]["ssl_key"]
212
- # rubocop:disable Style/RedundantException
213
- raise RuntimeError, "--ssl-cert or --ssl-key missing."
214
- end
329
+ cert, key, src =
330
+ opts[:JekyllOptions].values_at("ssl_cert", "ssl_key", "source")
331
+
332
+ return if cert.nil? && key.nil?
333
+ raise "Missing --ssl_cert or --ssl_key. Both are required." unless cert && key
334
+
215
335
  require "openssl"
216
336
  require "webrick/https"
217
- source_key = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], \
218
- opts[:JekyllOptions]["ssl_key" ])
219
- source_certificate = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], \
220
- opts[:JekyllOptions]["ssl_cert"])
221
- opts[:SSLCertificate] =
222
- OpenSSL::X509::Certificate.new(File.read(source_certificate))
223
- opts[:SSLPrivateKey ] = OpenSSL::PKey::RSA.new(File.read(source_key))
337
+
338
+ opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(read_file(src, cert))
339
+ opts[:SSLPrivateKey ] = OpenSSL::PKey::RSA.new(read_file(src, key))
224
340
  opts[:SSLEnable] = true
225
341
  end
226
342
 
227
343
  private
228
-
229
344
  def start_callback(detached)
230
345
  unless detached
231
346
  proc do
232
- Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
347
+ mutex.synchronize do
348
+ # Block until EventMachine reactor starts
349
+ @reload_reactor.started_event.wait unless @reload_reactor.nil?
350
+ @running = true
351
+ Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
352
+ @run_cond.broadcast
353
+ end
354
+ end
355
+ end
356
+ end
357
+
358
+ private
359
+ def stop_callback(detached)
360
+ unless detached
361
+ proc do
362
+ mutex.synchronize do
363
+ unless @reload_reactor.nil?
364
+ @reload_reactor.stop
365
+ @reload_reactor.stopped_event.wait
366
+ end
367
+ @running = false
368
+ @run_cond.broadcast
369
+ end
233
370
  end
234
371
  end
235
372
  end
@@ -239,6 +376,11 @@ module Jekyll
239
376
  file = File.expand_path("../mime.types", __dir__)
240
377
  WEBrick::HTTPUtils.load_mime_types(file)
241
378
  end
379
+
380
+ private
381
+ def read_file(source_dir, file_path)
382
+ File.read(Jekyll.sanitized_path(source_dir, file_path))
383
+ end
242
384
  end
243
385
  end
244
386
  end