jekyll 3.0.5 → 3.1.0.pre.beta1

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +1 -1
  3. data/lib/jekyll.rb +6 -5
  4. data/lib/jekyll/cleaner.rb +1 -1
  5. data/lib/jekyll/collection.rb +8 -11
  6. data/lib/jekyll/commands/clean.rb +2 -2
  7. data/lib/jekyll/commands/doctor.rb +23 -1
  8. data/lib/jekyll/commands/serve.rb +148 -103
  9. data/lib/jekyll/commands/serve/servlet.rb +61 -0
  10. data/lib/jekyll/configuration.rb +26 -46
  11. data/lib/jekyll/converters/markdown.rb +51 -36
  12. data/lib/jekyll/converters/markdown/kramdown_parser.rb +70 -17
  13. data/lib/jekyll/convertible.rb +5 -4
  14. data/lib/jekyll/document.rb +19 -63
  15. data/lib/jekyll/drops/collection_drop.rb +24 -0
  16. data/lib/jekyll/drops/document_drop.rb +28 -0
  17. data/lib/jekyll/drops/drop.rb +128 -0
  18. data/lib/jekyll/drops/jekyll_drop.rb +21 -0
  19. data/lib/jekyll/drops/site_drop.rb +39 -0
  20. data/lib/jekyll/drops/unified_payload_drop.rb +26 -0
  21. data/lib/jekyll/drops/url_drop.rb +51 -0
  22. data/lib/jekyll/entry_filter.rb +1 -1
  23. data/lib/jekyll/errors.rb +3 -4
  24. data/lib/jekyll/excerpt.rb +0 -2
  25. data/lib/jekyll/external.rb +1 -0
  26. data/lib/jekyll/filters.rb +10 -0
  27. data/lib/jekyll/frontmatter_defaults.rb +8 -1
  28. data/lib/jekyll/liquid_renderer/file.rb +1 -1
  29. data/lib/jekyll/page.rb +15 -11
  30. data/lib/jekyll/plugin_manager.rb +4 -10
  31. data/lib/jekyll/renderer.rb +12 -19
  32. data/lib/jekyll/site.rb +2 -20
  33. data/lib/jekyll/tags/highlight.rb +5 -5
  34. data/lib/jekyll/tags/include.rb +13 -2
  35. data/lib/jekyll/url.rb +22 -12
  36. data/lib/jekyll/utils.rb +48 -8
  37. data/lib/jekyll/utils/ansi.rb +59 -0
  38. data/lib/jekyll/utils/platforms.rb +2 -1
  39. data/lib/jekyll/version.rb +1 -1
  40. metadata +14 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ddbc11845878ea9db18f6417f18dd359b33e54da
4
- data.tar.gz: 2c9c6dd7446f39fa3e71a3f85c39adbfdb418bac
3
+ metadata.gz: d1829f10339d166e837fcab131e2a71f8b7354ef
4
+ data.tar.gz: 9e9401c86a39df7af91aa72ce6f427fcbbff3c48
5
5
  SHA512:
6
- metadata.gz: 3cb98db7e488b274d6a517b265832971543b9f60aaa145b646ca416ea5d7e1a02d27b9f236f90957952480c0b1141b1b3942d5c5427fdc6ef044e958dd8966ae
7
- data.tar.gz: 8578324c400324af7915929d82e11390cfbd765e9ecf7f8fc9e4cf3f951c66730aff22c2ec29ce59798f4563afbd272371a896e59413173af78b20bc2098abed
6
+ metadata.gz: 57d2d84faf740f163963b8649ae08b1dc27f84352e4f9e6539bef4ce0eb20582efe75a15b16b05aab41369f2cdcab7b0d3f371bd6ab1b2cdeabcd31d0dfe504c
7
+ data.tar.gz: 440f77af890b49b98f74f389b204c0f3c920215ad366fab6727fcea45c562113a8decd99de82c5ce1fe5fb32ad8755727d5705ee60ffe663bb213de7cf2354be
@@ -3,7 +3,7 @@
3
3
  [![Gem Version](https://img.shields.io/gem/v/jekyll.svg)](https://rubygems.org/gems/jekyll)
4
4
  [![Build Status](https://img.shields.io/travis/jekyll/jekyll/master.svg)](https://travis-ci.org/jekyll/jekyll)
5
5
  [![Code Climate](https://img.shields.io/codeclimate/github/jekyll/jekyll.svg)](https://codeclimate.com/github/jekyll/jekyll)
6
- [![Dependency Status](https://img.shields.io/gemnasium/jekyll/jekyll.svg)](https://gemnasium.com/jekyll/jekyll)
6
+ [![Dependency Status](https://gemnasium.com/jekyll/jekyll.svg)](https://gemnasium.com/jekyll/jekyll)
7
7
  [![Security](https://hakiri.io/github/jekyll/jekyll/master.svg)](https://hakiri.io/github/jekyll/jekyll/master)
8
8
 
9
9
  By Tom Preston-Werner, Nick Quaranto, Parker Moore, and many [awesome contributors](https://github.com/jekyll/jekyll/graphs/contributors)!
@@ -16,6 +16,7 @@ end
16
16
  require 'rubygems'
17
17
 
18
18
  # stdlib
19
+ require 'forwardable'
19
20
  require 'fileutils'
20
21
  require 'time'
21
22
  require 'English'
@@ -32,7 +33,6 @@ require 'colorator'
32
33
  SafeYAML::OPTIONS[:suppress_warnings] = true
33
34
 
34
35
  module Jekyll
35
-
36
36
  # internal requires
37
37
  autoload :Cleaner, 'jekyll/cleaner'
38
38
  autoload :Collection, 'jekyll/collection'
@@ -96,13 +96,14 @@ module Jekyll
96
96
  #
97
97
  # Returns the final configuration Hash.
98
98
  def configuration(override = Hash.new)
99
- config = Configuration.new
99
+ config = Configuration[Configuration::DEFAULTS]
100
+ override = Configuration[override].stringify_keys
100
101
  unless override.delete('skip_config_files')
101
102
  config = config.read_config_files(config.config_files(override))
102
103
  end
103
104
 
104
105
  # Merge DEFAULTS < _config.yml < override
105
- config = Configuration.from Utils.deep_merge_hashes(config, override).stringify_keys
106
+ config = Utils.deep_merge_hashes(config, override).stringify_keys
106
107
  set_timezone(config['timezone']) if config['timezone']
107
108
 
108
109
  config
@@ -152,9 +153,8 @@ module Jekyll
152
153
  def sanitized_path(base_directory, questionable_path)
153
154
  return base_directory if base_directory.eql?(questionable_path)
154
155
 
155
- questionable_path.insert(0, '/') if questionable_path.start_with?('~')
156
156
  clean_path = File.expand_path(questionable_path, "/")
157
- clean_path.sub!(/\A\w\:\//, '/')
157
+ clean_path = clean_path.sub(/\A\w\:\//, '/')
158
158
 
159
159
  unless clean_path.start_with?(base_directory.sub(/\A\w\:\//, '/'))
160
160
  File.join(base_directory, clean_path)
@@ -172,6 +172,7 @@ end
172
172
  require_all 'jekyll/commands'
173
173
  require_all 'jekyll/converters'
174
174
  require_all 'jekyll/converters/markdown'
175
+ require_all 'jekyll/drops'
175
176
  require_all 'jekyll/generators'
176
177
  require_all 'jekyll/tags'
177
178
 
@@ -40,7 +40,7 @@ module Jekyll
40
40
  regex = keep_file_regex
41
41
  dirs = keep_dirs
42
42
 
43
- Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file|
43
+ Utils.safe_glob(site.in_dest_dir, ["**", "*"], File::FNM_DOTMATCH).each do |file|
44
44
  next if file =~ HIDDEN_FILE_REGEX || file =~ regex || dirs.include?(file)
45
45
  files << file
46
46
  end
@@ -32,7 +32,7 @@ module Jekyll
32
32
  # Override of method_missing to check in @data for the key.
33
33
  def method_missing(method, *args, &blck)
34
34
  if docs.respond_to?(method.to_sym)
35
- Jekyll.logger.warn "Deprecation:", "Collection##{method} should be called on the #docs array directly."
35
+ Jekyll.logger.warn "Deprecation:", "#{label}.#{method} should be changed to #{label}.docs.#{method}."
36
36
  Jekyll.logger.warn "", "Called by #{caller.first}."
37
37
  docs.public_send(method.to_sym, *args, &blck)
38
38
  else
@@ -58,7 +58,11 @@ module Jekyll
58
58
  if Utils.has_yaml_header? full_path
59
59
  doc = Jekyll::Document.new(full_path, { site: site, collection: self })
60
60
  doc.read
61
- docs << doc if site.publisher.publish?(doc) || !write?
61
+ if site.publisher.publish?(doc) || !write?
62
+ docs << doc
63
+ else
64
+ Jekyll.logger.debug "Skipped From Publishing:", doc.relative_path
65
+ end
62
66
  else
63
67
  relative_dir = Jekyll.sanitized_path(relative_directory, File.dirname(file_path)).chomp("/.")
64
68
  files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
@@ -74,7 +78,7 @@ module Jekyll
74
78
  def entries
75
79
  return Array.new unless exists?
76
80
  @entries ||=
77
- Dir.glob(collection_dir("**", "*.*")).map do |entry|
81
+ Utils.safe_glob(collection_dir, ["**", "*.*"]).map do |entry|
78
82
  entry["#{collection_dir}/"] = ''; entry
79
83
  end
80
84
  end
@@ -166,14 +170,7 @@ module Jekyll
166
170
  #
167
171
  # Returns a representation of this collection for use in Liquid.
168
172
  def to_liquid
169
- metadata.merge({
170
- "label" => label,
171
- "docs" => docs,
172
- "files" => files,
173
- "directory" => directory,
174
- "output" => write?,
175
- "relative_directory" => relative_directory
176
- })
173
+ Drops::CollectionDrop.new self
177
174
  end
178
175
 
179
176
  # Whether the collection's documents ought to be written as individual
@@ -10,8 +10,8 @@ module Jekyll
10
10
 
11
11
  add_build_options(c)
12
12
 
13
- c.action do |args, _|
14
- Jekyll::Commands::Clean.process({})
13
+ c.action do |args, options|
14
+ Jekyll::Commands::Clean.process(options)
15
15
  end
16
16
  end
17
17
  end
@@ -32,7 +32,8 @@ module Jekyll
32
32
  [
33
33
  fsnotify_buggy?(site),
34
34
  !deprecated_relative_permalinks(site),
35
- !conflicting_urls(site)
35
+ !conflicting_urls(site),
36
+ !urls_only_differ_by_case(site)
36
37
  ].all?
37
38
  end
38
39
 
@@ -76,6 +77,20 @@ module Jekyll
76
77
  true
77
78
  end
78
79
 
80
+ def urls_only_differ_by_case(site)
81
+ urls_only_differ_by_case = false
82
+ urls = case_insensitive_urls(site.pages + site.docs_to_write, site.dest)
83
+ urls.each do |case_insensitive_url, real_urls|
84
+ if real_urls.uniq.size > 1
85
+ urls_only_differ_by_case = true
86
+ Jekyll.logger.warn "Warning:", "The following URLs only differ" +
87
+ " by case. On a case-insensitive file system one of the URLs" +
88
+ " will be overwritten by the other: #{real_urls.join(", ")}"
89
+ end
90
+ end
91
+ urls_only_differ_by_case
92
+ end
93
+
79
94
  private
80
95
  def collect_urls(urls, things, destination)
81
96
  things.each do |thing|
@@ -89,6 +104,13 @@ module Jekyll
89
104
  urls
90
105
  end
91
106
 
107
+ def case_insensitive_urls(things, destination)
108
+ things.inject(Hash.new) do |memo, thing|
109
+ dest = thing.destination(destination)
110
+ (memo[dest.downcase] ||= []) << dest
111
+ memo
112
+ end
113
+ end
92
114
  end
93
115
 
94
116
  end
@@ -1,151 +1,196 @@
1
- # -*- encoding: utf-8 -*-
2
1
  module Jekyll
3
2
  module Commands
4
3
  class Serve < Command
5
-
6
4
  class << self
5
+ COMMAND_OPTIONS = {
6
+ "ssl_cert" => ["--ssl-cert [CERT]", "X.509 (SSL) certificate."],
7
+ "host" => ["host", "-H", "--host [HOST]", "Host to bind to"],
8
+ "open_url" => ["-o", "--open-url", "Launch your browser with your site."],
9
+ "detach" => ["-B", "--detach", "Run the server in the background (detach)"],
10
+ "ssl_key" => ["--ssl-key [KEY]", "X.509 (SSL) Private Key."],
11
+ "port" => ["-P", "--port [PORT]", "Port to listen on"],
12
+ "baseurl" => ["-b", "--baseurl [URL]", "Base URL"],
13
+ "skip_initial_build" => ["skip_initial_build", "--skip-initial-build",
14
+ "Skips the initial site build which occurs before the server is started."]
15
+ }
16
+
17
+ #
7
18
 
8
19
  def init_with_program(prog)
9
- prog.command(:serve) do |c|
10
- c.syntax 'serve [options]'
11
- c.description 'Serve your site locally'
12
- c.alias :server
13
- c.alias :s
14
-
15
- add_build_options(c)
16
-
17
- c.option 'detach', '-B', '--detach', 'Run the server in the background (detach)'
18
- c.option 'port', '-P', '--port [PORT]', 'Port to listen on'
19
- c.option 'host', '-H', '--host [HOST]', 'Host to bind to'
20
- c.option 'baseurl', '-b', '--baseurl [URL]', 'Base URL'
21
- c.option 'skip_initial_build', '--skip-initial-build', 'Skips the initial site build which occurs before the server is started.'
22
-
23
- c.action do |args, options|
24
- options["serving"] = true
25
- options["watch"] = true unless options.key?("watch")
26
- Jekyll::Commands::Build.process(options)
27
- Jekyll::Commands::Serve.process(options)
20
+ prog.command(:serve) do |cmd|
21
+ cmd.description "Serve your site locally"
22
+ cmd.syntax "serve [options]"
23
+ cmd.alias :server
24
+ cmd.alias :s
25
+
26
+ add_build_options(cmd)
27
+ COMMAND_OPTIONS.each do |key, val|
28
+ cmd.option key, *val
29
+ end
30
+
31
+ cmd.action do |_, opts|
32
+ opts["serving"] = true
33
+ opts["watch" ] = true unless opts.key?("watch")
34
+ Build.process(opts)
35
+ Serve.process(opts)
28
36
  end
29
37
  end
30
38
  end
31
39
 
32
- # Boot up a WEBrick server which points to the compiled site's root.
33
- def process(options)
34
- options = configuration_from_options(options)
35
- destination = options['destination']
36
- setup(destination)
40
+ #
37
41
 
38
- s = WEBrick::HTTPServer.new(webrick_options(options))
39
- s.unmount("")
40
-
41
- s.mount(
42
- options['baseurl'],
43
- custom_file_handler,
44
- destination,
45
- file_handler_options
46
- )
47
-
48
- Jekyll.logger.info "Server address:", server_address(s, options)
42
+ def process(opts)
43
+ opts = configuration_from_options(opts)
44
+ destination = opts["destination"]
45
+ setup(destination)
49
46
 
50
- if options['detach'] # detach the server
51
- pid = Process.fork { s.start }
52
- Process.detach(pid)
53
- Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
54
- else # create a new server thread, then join it with current terminal
55
- t = Thread.new { s.start }
56
- trap("INT") { s.shutdown }
57
- t.join
58
- end
47
+ server = WEBrick::HTTPServer.new(webrick_opts(opts)).tap { |o| o.unmount("") }
48
+ server.mount(opts["baseurl"], Servlet, destination, file_handler_opts)
49
+ Jekyll.logger.info "Server address:", server_address(server, opts)
50
+ launch_browser server, opts if opts["open_url"]
51
+ boot_or_detach server, opts
59
52
  end
60
53
 
54
+ # Do a base pre-setup of WEBRick so that everything is in place
55
+ # when we get ready to party, checking for an setting up an error page
56
+ # and making sure our destination exists.
57
+
58
+ private
61
59
  def setup(destination)
62
- require 'webrick'
60
+ require_relative "serve/servlet"
63
61
 
64
62
  FileUtils.mkdir_p(destination)
65
-
66
- # monkey patch WEBrick using custom 404 page (/404.html)
67
- if File.exist?(File.join(destination, '404.html'))
63
+ if File.exist?(File.join(destination, "404.html"))
68
64
  WEBrick::HTTPResponse.class_eval do
69
65
  def create_error_page
70
- @header['content-type'] = "text/html; charset=UTF-8"
71
- @body = IO.read(File.join(@config[:DocumentRoot], '404.html'))
66
+ @header["Content-Type"] = "text/html; charset=UTF-8"
67
+ @body = IO.read(File.join(@config[:DocumentRoot], "404.html"))
72
68
  end
73
69
  end
74
70
  end
75
71
  end
76
72
 
77
- def webrick_options(config)
73
+ #
74
+
75
+ private
76
+ def webrick_opts(opts)
78
77
  opts = {
79
- :BindAddress => config['host'],
80
- :DirectoryIndex => %w(index.html index.htm index.cgi index.rhtml index.xml),
81
- :DocumentRoot => config['destination'],
78
+ :JekyllOptions => opts,
82
79
  :DoNotReverseLookup => true,
83
80
  :MimeTypes => mime_types,
84
- :Port => config['port'],
85
- :StartCallback => start_callback(config['detach'])
81
+ :DocumentRoot => opts["destination"],
82
+ :StartCallback => start_callback(opts["detach"]),
83
+ :BindAddress => opts["host"],
84
+ :Port => opts["port"],
85
+ :DirectoryIndex => %W(
86
+ index.htm
87
+ index.html
88
+ index.rhtml
89
+ index.cgi
90
+ index.xml
91
+ )
86
92
  }
87
93
 
88
- if config['verbose']
89
- opts.merge!({
90
- :Logger => WEBrick::Log.new($stdout, WEBrick::Log::DEBUG)
91
- })
94
+ enable_ssl(opts)
95
+ enable_logging(opts)
96
+ opts
97
+ end
98
+
99
+ # Recreate NondisclosureName under utf-8 circumstance
100
+
101
+ private
102
+ def file_handler_opts
103
+ WEBrick::Config::FileHandler.merge({
104
+ :FancyIndexing => true,
105
+ :NondisclosureName => [
106
+ '.ht*','~*'
107
+ ]
108
+ })
109
+ end
110
+
111
+ #
112
+
113
+ private
114
+ def server_address(server, opts)
115
+ address = server.config[:BindAddress]
116
+ baseurl = "#{opts["baseurl"]}/" if opts["baseurl"]
117
+ port = server.config[:Port]
118
+
119
+ "http://#{address}:#{port}#{baseurl}"
120
+ end
121
+
122
+ #
123
+
124
+ private
125
+ def launch_browser(server, opts)
126
+ command = Utils::Platforms.windows?? "start" : Utils::Platforms.osx?? "open" : "xdg-open"
127
+ system command, server_address(server, opts)
128
+ end
129
+
130
+ # Keep in our area with a thread or detach the server as requested
131
+ # by the user. This method determines what we do based on what you
132
+ # ask us to do.
133
+
134
+ private
135
+ def boot_or_detach(server, opts)
136
+ if opts["detach"]
137
+ pid = Process.fork do
138
+ server.start
139
+ end
140
+
141
+ Process.detach(pid)
142
+ Jekyll.logger.info "Server detached with pid '#{pid}'.", \
143
+ "Run `pkill -f jekyll' or `kill -9 #{pid}' to stop the server."
92
144
  else
93
- opts.merge!({
94
- :AccessLog => [],
95
- :Logger => WEBrick::Log.new([], WEBrick::Log::WARN)
96
- })
145
+ t = Thread.new { server.start }
146
+ trap("INT") { server.shutdown }
147
+ t.join
97
148
  end
149
+ end
98
150
 
99
- opts
151
+ # Make the stack verbose if the user requests it.
152
+
153
+ private
154
+ def enable_logging(opts)
155
+ opts[:AccessLog] = []
156
+ level = WEBrick::Log.const_get(opts[:JekyllOptions]["verbose"] ? :DEBUG : :WARN)
157
+ opts[:Logger] = WEBrick::Log.new($stdout, level)
100
158
  end
101
159
 
102
- # Custom WEBrick FileHandler servlet for serving "/file.html" at "/file"
103
- # when no exact match is found. This mirrors the behavior of GitHub
104
- # Pages and many static web server configs.
105
- def custom_file_handler
106
- Class.new WEBrick::HTTPServlet::FileHandler do
107
- def search_file(req, res, basename)
108
- if file = super
109
- file
110
- else
111
- super(req, res, "#{basename}.html")
112
- end
113
- end
160
+ # Add SSL to the stack if the user triggers --enable-ssl and they
161
+ # provide both types of certificates commonly needed. Raise if they
162
+ # forget to add one of the certificates.
163
+
164
+ private
165
+ def enable_ssl(opts)
166
+ return if !opts[:JekyllOptions]["ssl_cert"] && !opts[:JekyllOptions]["ssl_key"]
167
+ if !opts[:JekyllOptions]["ssl_cert"] || !opts[:JekyllOptions]["ssl_key"]
168
+ raise RuntimeError, "--ssl-cert or --ssl-key missing."
114
169
  end
170
+
171
+ require "openssl"; require "webrick/https"
172
+ source_key = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_key" ])
173
+ source_certificate = Jekyll.sanitized_path(opts[:JekyllOptions]["source"], opts[:JekyllOptions]["ssl_cert"])
174
+ opts[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read(source_certificate))
175
+ opts[:SSLPrivateKey ] = OpenSSL::PKey::RSA.new(File.read(source_key))
176
+ opts[:EnableSSL] = true
115
177
  end
116
178
 
179
+ private
117
180
  def start_callback(detached)
118
181
  unless detached
119
- Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." }
182
+ proc do
183
+ Jekyll.logger.info("Server running...", "press ctrl-c to stop.")
184
+ end
120
185
  end
121
186
  end
122
187
 
188
+ private
123
189
  def mime_types
124
- mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
125
- WEBrick::HTTPUtils::load_mime_types(mime_types_file)
126
- end
127
-
128
- def server_address(server, options)
129
- baseurl = "#{options['baseurl']}/" if options['baseurl']
130
- [
131
- "http://",
132
- server.config[:BindAddress],
133
- ":",
134
- server.config[:Port],
135
- baseurl || ""
136
- ].map(&:to_s).join("")
137
- end
138
-
139
- # recreate NondisclosureName under utf-8 circumstance
140
- def file_handler_options
141
- WEBrick::Config::FileHandler.merge({
142
- :FancyIndexing => true,
143
- :NondisclosureName => ['.ht*','~*']
144
- })
190
+ file = File.expand_path('../mime.types', File.dirname(__FILE__))
191
+ WEBrick::HTTPUtils.load_mime_types(file)
145
192
  end
146
-
147
193
  end
148
-
149
194
  end
150
195
  end
151
196
  end