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
@@ -12,11 +12,13 @@ module Jekyll
12
12
 
13
13
  # Create a new Document.
14
14
  #
15
- # site - the Jekyll::Site instance to which this Document belongs
16
15
  # path - the path to the file
16
+ # relations - a hash with keys :site and :collection, the values of which
17
+ # are the Jekyll::Site and Jekyll::Collection to which this
18
+ # Document belong.
17
19
  #
18
20
  # Returns nothing.
19
- def initialize(path, relations)
21
+ def initialize(path, relations = {})
20
22
  @site = relations[:site]
21
23
  @path = path
22
24
  @extname = File.extname(path)
@@ -38,12 +40,10 @@ module Jekyll
38
40
  end
39
41
 
40
42
  def output=(output)
41
- @to_liquid = nil
42
43
  @output = output
43
44
  end
44
45
 
45
46
  def content=(content)
46
- @to_liquid = nil
47
47
  @content = content
48
48
  end
49
49
 
@@ -58,7 +58,7 @@ module Jekyll
58
58
  # Merge some data in with this document's data.
59
59
  #
60
60
  # Returns the merged data.
61
- def merge_data!(other, source: "YAML front matter")
61
+ def merge_data!(other)
62
62
  if other.key?('categories') && !other['categories'].nil?
63
63
  if other['categories'].is_a?(String)
64
64
  other['categories'] = other['categories'].split(" ").map(&:strip)
@@ -67,7 +67,7 @@ module Jekyll
67
67
  end
68
68
  Utils.deep_merge_hashes!(data, other)
69
69
  if data.key?('date') && !data['date'].is_a?(Time)
70
- data['date'] = Utils.parse_date(data['date'].to_s, "Document '#{relative_path}' does not have a valid date in the #{source}.")
70
+ data['date'] = Utils.parse_date(data['date'].to_s, "Document '#{relative_path}' does not have a valid date in the YAML front matter.")
71
71
  end
72
72
  data
73
73
  end
@@ -181,27 +181,7 @@ module Jekyll
181
181
  #
182
182
  # Returns the Hash of key-value pairs for replacement in the URL.
183
183
  def url_placeholders
184
- {
185
- collection: collection.label,
186
- path: cleaned_relative_path,
187
- output_ext: output_ext,
188
- name: Utils.slugify(basename_without_ext),
189
- title: Utils.slugify(data['slug'], mode: "pretty", cased: true) || Utils
190
- .slugify(basename_without_ext, mode: "pretty", cased: true),
191
- slug: Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext),
192
- year: date.strftime("%Y"),
193
- month: date.strftime("%m"),
194
- day: date.strftime("%d"),
195
- hour: date.strftime("%H"),
196
- minute: date.strftime("%M"),
197
- second: date.strftime("%S"),
198
- i_day: date.strftime("%-d"),
199
- i_month: date.strftime("%-m"),
200
- categories: (data['categories'] || []).map { |c| c.to_s.downcase }.uniq.join('/'),
201
- short_month: date.strftime("%b"),
202
- short_year: date.strftime("%y"),
203
- y_day: date.strftime("%j"),
204
- }
184
+ @url_placeholders ||= Drops::UrlDrop.new(self)
205
185
  end
206
186
 
207
187
  # The permalink for this Document.
@@ -235,11 +215,8 @@ module Jekyll
235
215
  def destination(base_directory)
236
216
  dest = site.in_dest_dir(base_directory)
237
217
  path = site.in_dest_dir(dest, URL.unescape_path(url))
238
- if url.end_with? "/"
239
- path = File.join(path, "index.html")
240
- else
241
- path << output_ext unless path.end_with?(output_ext)
242
- end
218
+ path = File.join(path, "index.html") if url.end_with?("/")
219
+ path << output_ext unless path.end_with?(output_ext)
243
220
  path
244
221
  end
245
222
 
@@ -281,32 +258,27 @@ module Jekyll
281
258
  #
282
259
  # Returns nothing.
283
260
  def read(opts = {})
284
- @to_liquid = nil
285
-
286
261
  Jekyll.logger.debug "Reading:", relative_path
287
262
 
288
263
  if yaml_file?
289
264
  @data = SafeYAML.load_file(path)
290
265
  else
291
266
  begin
292
- defaults = @site.frontmatter_defaults.all(relative_path, collection.label.to_sym)
293
- merge_data!(defaults, source: "front matter defaults") unless defaults.empty?
267
+ defaults = @site.frontmatter_defaults.all(url, collection.label.to_sym)
268
+ merge_data!(defaults) unless defaults.empty?
294
269
 
295
270
  self.content = File.read(path, merged_file_read_opts(opts))
296
271
  if content =~ YAML_FRONT_MATTER_REGEXP
297
272
  self.content = $POSTMATCH
298
273
  data_file = SafeYAML.load($1)
299
- merge_data!(data_file, source: "YAML front matter") if data_file
274
+ merge_data!(data_file) if data_file
300
275
  end
301
276
 
302
277
  post_read
303
278
  rescue SyntaxError => e
304
- Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{e.message}"
279
+ puts "YAML Exception reading #{path}: #{e.message}"
305
280
  rescue Exception => e
306
- if e.is_a? Jekyll::Errors::FatalException
307
- raise e
308
- end
309
- Jekyll.logger.error "Error:", "could not read file #{path}: #{e.message}"
281
+ puts "Error reading file #{path}: #{e.message}"
310
282
  end
311
283
  end
312
284
  end
@@ -317,10 +289,8 @@ module Jekyll
317
289
  merge_data!({
318
290
  "slug" => slug,
319
291
  "ext" => ext
320
- }, source: "filename")
321
- if data['date'].nil? || data['date'].to_i == site.time.to_i
322
- merge_data!({"date" => date}, source: "filename")
323
- end
292
+ })
293
+ merge_data!({"date" => date}) if data['date'].nil? || data['date'].to_i == site.time.to_i
324
294
  data['title'] ||= slug.split('-').select {|w| w.capitalize! || w }.join(' ')
325
295
  end
326
296
  populate_categories
@@ -340,7 +310,7 @@ module Jekyll
340
310
  superdirs = relative_path.sub(/#{special_dir}(.*)/, '').split(File::SEPARATOR).reject do |c|
341
311
  c.empty? || c.eql?(special_dir) || c.eql?(basename)
342
312
  end
343
- merge_data!({ 'categories' => superdirs }, source: "file path")
313
+ merge_data!({ 'categories' => superdirs })
344
314
  end
345
315
 
346
316
  def populate_categories
@@ -361,21 +331,7 @@ module Jekyll
361
331
  #
362
332
  # Returns a Hash representing this Document's data.
363
333
  def to_liquid
364
- @to_liquid ||= if data.is_a?(Hash)
365
- Utils.deep_merge_hashes Utils.deep_merge_hashes({
366
- "output" => output,
367
- "content" => content,
368
- "relative_path" => relative_path,
369
- "path" => relative_path,
370
- "url" => url,
371
- "collection" => collection.label,
372
- "next" => next_doc,
373
- "previous" => previous_doc,
374
- "id" => id,
375
- }, data), { 'excerpt' => data['excerpt'].to_s }
376
- else
377
- data
378
- end
334
+ @to_liquid ||= Drops::DocumentDrop.new(self)
379
335
  end
380
336
 
381
337
  # The inspect string for this document.
@@ -399,7 +355,7 @@ module Jekyll
399
355
  # Returns -1, 0, +1 or nil depending on whether this doc's path is less than,
400
356
  # equal or greater than the other doc's path. See String#<=> for more details.
401
357
  def <=>(other)
402
- return nil if !other.respond_to?(:data)
358
+ return nil unless other.respond_to?(:data)
403
359
  cmp = data['date'] <=> other.data['date']
404
360
  cmp = path <=> other.path if cmp.nil? || cmp == 0
405
361
  cmp
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ require "jekyll/drops/drop"
3
+
4
+ module Jekyll
5
+ module Drops
6
+ class CollectionDrop < Drop
7
+ extend Forwardable
8
+
9
+ mutable false
10
+
11
+ def_delegator :@obj, :write?, :output
12
+ def_delegators :@obj, :label, :docs, :files, :directory,
13
+ :relative_directory
14
+
15
+ def to_s
16
+ docs.to_s
17
+ end
18
+
19
+ private
20
+ def_delegator :@obj, :metadata, :fallback_data
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+
3
+ module Jekyll
4
+ module Drops
5
+ class DocumentDrop < Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegator :@obj, :next_doc, :next
11
+ def_delegator :@obj, :previous_doc, :previous
12
+ def_delegator :@obj, :relative_path, :path
13
+ def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
14
+
15
+ def collection
16
+ @obj.collection.label
17
+ end
18
+
19
+ def excerpt
20
+ fallback_data['excerpt'].to_s
21
+ end
22
+
23
+ private
24
+ def_delegator :@obj, :data, :fallback_data
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,128 @@
1
+ # encoding: UTF-8
2
+
3
+ module Jekyll
4
+ module Drops
5
+ class Drop < Liquid::Drop
6
+ NON_CONTENT_METHODS = [:[], :[]=, :inspect, :to_h, :fallback_data].freeze
7
+
8
+ # Get or set whether the drop class is mutable.
9
+ # Mutability determines whether or not pre-defined fields may be
10
+ # overwritten.
11
+ #
12
+ # is_mutable - Boolean set mutability of the class (default: nil)
13
+ #
14
+ # Returns the mutability of the class
15
+ def self.mutable(is_mutable = nil)
16
+ if is_mutable
17
+ @is_mutable = is_mutable
18
+ end
19
+ @is_mutable || false
20
+ end
21
+
22
+ # Create a new Drop
23
+ #
24
+ # obj - the Jekyll Site, Collection, or Document required by the
25
+ # drop.
26
+ #
27
+ # Returns nothing
28
+ def initialize(obj)
29
+ @obj = obj
30
+ @mutations = {} # only if mutable: true
31
+ end
32
+
33
+ # Access a method in the Drop or a field in the underlying hash data.
34
+ # If mutable, checks the mutations first. Then checks the methods,
35
+ # and finally check the underlying hash (e.g. document front matter)
36
+ # if all the previous places didn't match.
37
+ #
38
+ # key - the string key whose value to fetch
39
+ #
40
+ # Returns the value for the given key, or nil if none exists
41
+ def [](key)
42
+ if self.class.mutable && @mutations.key?(key)
43
+ @mutations[key]
44
+ elsif respond_to? key
45
+ public_send key
46
+ else
47
+ fallback_data[key]
48
+ end
49
+ end
50
+
51
+ # Set a field in the Drop. If mutable, sets in the mutations and
52
+ # returns. If not mutable, checks first if it's trying to override a
53
+ # Drop method and raises a DropMutationException if so. If not
54
+ # mutable and the key is not a method on the Drop, then it sets the
55
+ # key to the value in the underlying hash (e.g. document front
56
+ # matter)
57
+ #
58
+ # key - the String key whose value to set
59
+ # val - the Object to set the key's value to
60
+ #
61
+ # Returns the value the key was set to unless the Drop is not mutable
62
+ # and the key matches a method in which case it raises a
63
+ # DropMutationException.
64
+ def []=(key, val)
65
+ if self.class.mutable
66
+ @mutations[key] = val
67
+ elsif respond_to? key
68
+ raise Errors::DropMutationException, "Key #{key} cannot be set in the drop."
69
+ else
70
+ fallback_data[key] = val
71
+ end
72
+ end
73
+
74
+ # Generates a list of strings which correspond to content getter
75
+ # methods.
76
+ #
77
+ # Returns an Array of strings which represent method-specific keys.
78
+ def content_methods
79
+ @content_methods ||= (
80
+ self.class.instance_methods(false) - NON_CONTENT_METHODS
81
+ ).map(&:to_s).reject do |method|
82
+ method.end_with?("=")
83
+ end
84
+ end
85
+
86
+ # Generates a list of keys with user content as their values.
87
+ # This gathers up the Drop methods and keys of the mutations and
88
+ # underlying data hashes and performs a set union to ensure a list
89
+ # of unique keys for the Drop.
90
+ #
91
+ # Returns an Array of unique keys for content for the Drop.
92
+ def keys
93
+ (content_methods |
94
+ @mutations.keys |
95
+ fallback_data.keys).flatten
96
+ end
97
+
98
+ # Generate a Hash representation of the Drop by resolving each key's
99
+ # value. It includes Drop methods, mutations, and the underlying object's
100
+ # data. See the documentation for Drop#keys for more.
101
+ #
102
+ # Returns a Hash with all the keys and values resolved.
103
+ def to_h
104
+ keys.each_with_object({}) do |(key, val), result|
105
+ result[key] = self[key]
106
+ end
107
+ end
108
+
109
+ # Inspect the drop's keys and values through a JSON representation
110
+ # of its keys and values.
111
+ #
112
+ # Returns a pretty generation of the hash representation of the Drop.
113
+ def inspect
114
+ JSON.pretty_generate to_h
115
+ end
116
+
117
+ # Collects all the keys and passes each to the block in turn.
118
+ #
119
+ # block - a block which accepts one argument, the key
120
+ #
121
+ # Returns nothing.
122
+ def each_key(&block)
123
+ keys.each(&block)
124
+ end
125
+
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ module Jekyll
4
+ module Drops
5
+ class JekyllDrop < Liquid::Drop
6
+ class << self
7
+ def global
8
+ @global ||= JekyllDrop.new
9
+ end
10
+ end
11
+
12
+ def version
13
+ Jekyll::VERSION
14
+ end
15
+
16
+ def environment
17
+ Jekyll.env
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+
3
+ module Jekyll
4
+ module Drops
5
+ class SiteDrop < Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegator :@obj, :site_data, :data
11
+ def_delegators :@obj, :time, :pages, :static_files, :documents,
12
+ :tags, :categories
13
+
14
+ def [](key)
15
+ if @obj.collections.key?(key) && key != "posts"
16
+ @obj.collections[key].docs
17
+ else
18
+ super(key)
19
+ end
20
+ end
21
+
22
+ def posts
23
+ @site_posts ||= @obj.posts.docs.sort { |a, b| b <=> a }
24
+ end
25
+
26
+ def html_pages
27
+ @site_html_pages ||= @obj.pages.select { |page| page.html? || page.url.end_with?("/") }
28
+ end
29
+
30
+ def collections
31
+ @site_collections ||= @obj.collections.values.map(&:to_liquid)
32
+ end
33
+
34
+ private
35
+ def_delegator :@obj, :config, :fallback_data
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: UTF-8
2
+
3
+ module Jekyll
4
+ module Drops
5
+ class UnifiedPayloadDrop < Drop
6
+ mutable true
7
+
8
+ attr_accessor :page, :layout, :content, :paginator
9
+ attr_accessor :highlighter_prefix, :highlighter_suffix
10
+
11
+ def jekyll
12
+ JekyllDrop.global
13
+ end
14
+
15
+ def site
16
+ @site_drop ||= SiteDrop.new(@obj)
17
+ end
18
+
19
+ private
20
+ def fallback_data
21
+ @fallback_data ||= {}
22
+ end
23
+
24
+ end
25
+ end
26
+ end