jekyll 4.0.0.pre.alpha1 → 4.0.0.pre.beta1

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.
@@ -34,7 +34,6 @@ module Jekyll
34
34
  @config["syntax_highlighter_opts"]["guess_lang"] = @config["guess_lang"]
35
35
  @config["coderay"] ||= {} # XXX: Legacy.
36
36
  modernize_coderay_config
37
- make_accessible
38
37
  end
39
38
 
40
39
  def convert(content)
@@ -64,13 +63,6 @@ module Jekyll
64
63
  end
65
64
  end
66
65
 
67
- def make_accessible(hash = @config)
68
- hash.keys.each do |key|
69
- hash[key.to_sym] = hash[key]
70
- make_accessible(hash[key]) if hash[key].is_a?(Hash)
71
- end
72
- end
73
-
74
66
  # config[kramdown][syntax_higlighter] >
75
67
  # config[kramdown][enable_coderay] >
76
68
  # config[highlighter]
@@ -146,7 +146,7 @@ module Jekyll
146
146
  #
147
147
  # Returns true if extname == .sass or .scss, false otherwise.
148
148
  def sass_file?
149
- %w(.sass .scss).include?(ext)
149
+ Jekyll::Document::SASS_FILE_EXTS.include?(ext)
150
150
  end
151
151
 
152
152
  # Determine whether the document is a CoffeeScript file.
@@ -5,7 +5,7 @@ module Jekyll
5
5
  include Comparable
6
6
  extend Forwardable
7
7
 
8
- attr_reader :path, :site, :extname, :collection
8
+ attr_reader :path, :site, :extname, :collection, :type
9
9
  attr_accessor :content, :output
10
10
 
11
11
  def_delegator :self, :read_post_data, :post_read
@@ -14,6 +14,23 @@ module Jekyll
14
14
  DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!.freeze
15
15
  DATE_FILENAME_MATCHER = %r!^(?>.+/)*?(\d{2,4}-\d{1,2}-\d{1,2})-([^/]*)(\.[^.]+)$!.freeze
16
16
 
17
+ SASS_FILE_EXTS = %w(.sass .scss).freeze
18
+ YAML_FILE_EXTS = %w(.yaml .yml).freeze
19
+
20
+ #
21
+
22
+ # Class-wide cache to stash and retrieve regexp to detect "super-directories"
23
+ # of a particular Jekyll::Document object.
24
+ #
25
+ # dirname - The *special directory* for the Document.
26
+ # e.g. "_posts" or "_drafts" for Documents from the `site.posts` collection.
27
+ def self.superdirs_regex(dirname)
28
+ @superdirs_regex ||= {}
29
+ @superdirs_regex[dirname] ||= %r!#{dirname}.*!
30
+ end
31
+
32
+ #
33
+
17
34
  # Create a new Document.
18
35
  #
19
36
  # path - the path to the file
@@ -27,6 +44,8 @@ module Jekyll
27
44
  @path = path
28
45
  @extname = File.extname(path)
29
46
  @collection = relations[:collection]
47
+ @type = @collection.label.to_sym
48
+
30
49
  @has_yaml_header = nil
31
50
 
32
51
  if draft?
@@ -36,7 +55,7 @@ module Jekyll
36
55
  end
37
56
 
38
57
  data.default_proc = proc do |_, key|
39
- site.frontmatter_defaults.find(relative_path, collection.label, key)
58
+ site.frontmatter_defaults.find(relative_path, type, key)
40
59
  end
41
60
 
42
61
  trigger_hooks(:post_init)
@@ -138,7 +157,7 @@ module Jekyll
138
157
  #
139
158
  # Returns true if the extname is either .yml or .yaml, false otherwise.
140
159
  def yaml_file?
141
- %w(.yaml .yml).include?(extname)
160
+ YAML_FILE_EXTS.include?(extname)
142
161
  end
143
162
 
144
163
  # Determine whether the document is an asset file.
@@ -154,7 +173,7 @@ module Jekyll
154
173
  #
155
174
  # Returns true if extname == .sass or .scss, false otherwise.
156
175
  def sass_file?
157
- %w(.sass .scss).include?(extname)
176
+ SASS_FILE_EXTS.include?(extname)
158
177
  end
159
178
 
160
179
  # Determine whether the document is a CoffeeScript file.
@@ -373,12 +392,6 @@ module Jekyll
373
392
  @related_posts ||= Jekyll::RelatedPosts.new(self).build
374
393
  end
375
394
 
376
- # Override of normal respond_to? to match method_missing's logic for
377
- # looking in @data.
378
- def respond_to?(method, include_private = false)
379
- data.key?(method.to_s) || super
380
- end
381
-
382
395
  # Override of method_missing to check in @data for the key.
383
396
  def method_missing(method, *args, &blck)
384
397
  if data.key?(method.to_s)
@@ -401,28 +414,29 @@ module Jekyll
401
414
  #
402
415
  # Returns nothing.
403
416
  def categories_from_path(special_dir)
404
- superdirs = relative_path.sub(%r!#{special_dir}(.*)!, "")
405
- .split(File::SEPARATOR)
406
- .reject do |c|
407
- c.empty? || c == special_dir || c == basename
408
- end
417
+ superdirs = relative_path.sub(Document.superdirs_regex(special_dir), "")
418
+ superdirs = superdirs.split(File::SEPARATOR)
419
+ superdirs.reject! { |c| c.empty? || c == special_dir || c == basename }
420
+
409
421
  merge_data!({ "categories" => superdirs }, :source => "file path")
410
422
  end
411
423
 
412
424
  def populate_categories
413
- merge_data!(
414
- "categories" => (
415
- Array(data["categories"]) + Utils.pluralized_array_from_hash(
416
- data, "category", "categories"
417
- )
418
- ).map(&:to_s).flatten.uniq
425
+ categories = Array(data["categories"]) + Utils.pluralized_array_from_hash(
426
+ data, "category", "categories"
419
427
  )
428
+ categories.map!(&:to_s)
429
+ categories.flatten!
430
+ categories.uniq!
431
+
432
+ merge_data!("categories" => categories)
420
433
  end
421
434
 
422
435
  def populate_tags
423
- merge_data!(
424
- "tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
425
- )
436
+ tags = Utils.pluralized_array_from_hash(data, "tag", "tags")
437
+ tags.flatten!
438
+
439
+ merge_data!("tags" => tags)
426
440
  end
427
441
 
428
442
  private
@@ -444,10 +458,7 @@ module Jekyll
444
458
  end
445
459
 
446
460
  def merge_defaults
447
- defaults = @site.frontmatter_defaults.all(
448
- relative_path,
449
- collection.label.to_sym
450
- )
461
+ defaults = @site.frontmatter_defaults.all(relative_path, type)
451
462
  merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
452
463
  end
453
464
 
@@ -30,7 +30,6 @@ module Jekyll
30
30
  # Returns nothing
31
31
  def initialize(obj)
32
32
  @obj = obj
33
- @mutations = {} # only if mutable: true
34
33
  end
35
34
 
36
35
  # Access a method in the Drop or a field in the underlying hash data.
@@ -42,8 +41,8 @@ module Jekyll
42
41
  #
43
42
  # Returns the value for the given key, or nil if none exists
44
43
  def [](key)
45
- if self.class.mutable? && @mutations.key?(key)
46
- @mutations[key]
44
+ if self.class.mutable? && mutations.key?(key)
45
+ mutations[key]
47
46
  elsif self.class.invokable? key
48
47
  public_send key
49
48
  else
@@ -66,11 +65,12 @@ module Jekyll
66
65
  # and the key matches a method in which case it raises a
67
66
  # DropMutationException.
68
67
  def []=(key, val)
69
- if respond_to?("#{key}=")
70
- public_send("#{key}=", val)
68
+ setter = "#{key}="
69
+ if respond_to?(setter)
70
+ public_send(setter, val)
71
71
  elsif respond_to?(key.to_s)
72
72
  if self.class.mutable?
73
- @mutations[key] = val
73
+ mutations[key] = val
74
74
  else
75
75
  raise Errors::DropMutationException, "Key #{key} cannot be set in the drop."
76
76
  end
@@ -100,7 +100,7 @@ module Jekyll
100
100
  # Returns true if the given key is present
101
101
  def key?(key)
102
102
  return false if key.nil?
103
- return true if self.class.mutable? && @mutations.key?(key)
103
+ return true if self.class.mutable? && mutations.key?(key)
104
104
 
105
105
  respond_to?(key) || fallback_data.key?(key)
106
106
  end
@@ -113,7 +113,7 @@ module Jekyll
113
113
  # Returns an Array of unique keys for content for the Drop.
114
114
  def keys
115
115
  (content_methods |
116
- @mutations.keys |
116
+ mutations.keys |
117
117
  fallback_data.keys).flatten
118
118
  end
119
119
 
@@ -204,6 +204,12 @@ module Jekyll
204
204
  return yield(key) unless block.nil?
205
205
  return default unless default.nil?
206
206
  end
207
+
208
+ private
209
+
210
+ def mutations
211
+ @mutations ||= {}
212
+ end
207
213
  end
208
214
  end
209
215
  end
@@ -8,7 +8,7 @@ module Jekyll
8
8
  mutable false
9
9
 
10
10
  def_delegator :@obj, :site_data, :data
11
- def_delegators :@obj, :time, :pages, :static_files, :documents, :tags, :categories
11
+ def_delegators :@obj, :time, :pages, :static_files, :tags, :categories
12
12
 
13
13
  private def_delegator :@obj, :config, :fallback_data
14
14
 
@@ -38,6 +38,16 @@ module Jekyll
38
38
  @site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
39
39
  end
40
40
 
41
+ # `Site#documents` cannot be memoized so that `Site#docs_to_write` can access the
42
+ # latest state of the attribute.
43
+ #
44
+ # Since this method will be called after `Site#pre_render` hook, the `Site#documents`
45
+ # array shouldn't thereafter change and can therefore be safely memoized to prevent
46
+ # additional computation of `Site#documents`.
47
+ def documents
48
+ @documents ||= @obj.documents
49
+ end
50
+
41
51
  # `{{ site.related_posts }}` is how posts can get posts related to
42
52
  # them, either through LSI if it's enabled, or through the most
43
53
  # recent posts.
@@ -35,46 +35,89 @@ module Jekyll
35
35
  category_set.to_a.join("/")
36
36
  end
37
37
 
38
+ # CCYY
38
39
  def year
39
40
  @obj.date.strftime("%Y")
40
41
  end
41
42
 
43
+ # MM: 01..12
42
44
  def month
43
45
  @obj.date.strftime("%m")
44
46
  end
45
47
 
48
+ # DD: 01..31
46
49
  def day
47
50
  @obj.date.strftime("%d")
48
51
  end
49
52
 
53
+ # hh: 00..23
50
54
  def hour
51
55
  @obj.date.strftime("%H")
52
56
  end
53
57
 
58
+ # mm: 00..59
54
59
  def minute
55
60
  @obj.date.strftime("%M")
56
61
  end
57
62
 
63
+ # ss: 00..59
58
64
  def second
59
65
  @obj.date.strftime("%S")
60
66
  end
61
67
 
68
+ # D: 1..31
62
69
  def i_day
63
70
  @obj.date.strftime("%-d")
64
71
  end
65
72
 
73
+ # M: 1..12
66
74
  def i_month
67
75
  @obj.date.strftime("%-m")
68
76
  end
69
77
 
78
+ # MMM: Jan..Dec
70
79
  def short_month
71
80
  @obj.date.strftime("%b")
72
81
  end
73
82
 
83
+ # MMMM: January..December
84
+ def long_month
85
+ @obj.date.strftime("%B")
86
+ end
87
+
88
+ # YY: 00..99
74
89
  def short_year
75
90
  @obj.date.strftime("%y")
76
91
  end
77
92
 
93
+ # CCYYw, ISO week year
94
+ # may differ from CCYY for the first days of January and last days of December
95
+ def w_year
96
+ @obj.date.strftime("%G")
97
+ end
98
+
99
+ # WW: 01..53
100
+ # %W and %U do not comply with ISO 8601-1
101
+ def week
102
+ @obj.date.strftime("%V")
103
+ end
104
+
105
+ # d: 1..7 (Monday..Sunday)
106
+ def w_day
107
+ @obj.date.strftime("%u")
108
+ end
109
+
110
+ # dd: Mon..Sun
111
+ def short_day
112
+ @obj.date.strftime("%a")
113
+ end
114
+
115
+ # ddd: Monday..Sunday
116
+ def long_day
117
+ @obj.date.strftime("%A")
118
+ end
119
+
120
+ # DDD: 001..366
78
121
  def y_day
79
122
  @obj.date.strftime("%j")
80
123
  end
@@ -3,9 +3,7 @@
3
3
  module Jekyll
4
4
  class EntryFilter
5
5
  attr_reader :site
6
- SPECIAL_LEADING_CHARACTERS = [
7
- ".", "_", "#", "~",
8
- ].freeze
6
+ SPECIAL_LEADING_CHAR_REGEX = %r!\A#{Regexp.union([".", "_", "#", "~"])}!o.freeze
9
7
 
10
8
  def initialize(site, base_directory = nil)
11
9
  @site = site
@@ -31,6 +29,9 @@ module Jekyll
31
29
 
32
30
  def filter(entries)
33
31
  entries.reject do |e|
32
+ # Reject this entry if it is just a "dot" representation.
33
+ # e.g.: '.', '..', '_movies/.', 'music/..', etc
34
+ next true if e.end_with?(".")
34
35
  # Reject this entry if it is a symlink.
35
36
  next true if symlink?(e)
36
37
  # Do not reject this entry if it is included.
@@ -47,8 +48,8 @@ module Jekyll
47
48
  end
48
49
 
49
50
  def special?(entry)
50
- SPECIAL_LEADING_CHARACTERS.include?(entry[0..0]) ||
51
- SPECIAL_LEADING_CHARACTERS.include?(File.basename(entry)[0..0])
51
+ SPECIAL_LEADING_CHAR_REGEX.match?(entry) ||
52
+ SPECIAL_LEADING_CHAR_REGEX.match?(File.basename(entry))
52
53
  end
53
54
 
54
55
  def backup?(entry)
@@ -86,40 +87,22 @@ module Jekyll
86
87
  )
87
88
  end
88
89
 
89
- # --
90
- # Check if an entry matches a specific pattern and return true,false.
91
- # Returns true if path matches against any glob pattern.
92
- # --
93
- def glob_include?(enum, entry)
94
- entry_path = Pathutil.new(site.in_source_dir).join(entry)
95
- enum.any? do |exp|
96
- # Users who send a Regexp knows what they want to
97
- # exclude, so let them send a Regexp to exclude files,
98
- # we will not bother caring if it works or not, it's
99
- # on them at this point.
90
+ # Check if an entry matches a specific pattern.
91
+ # Returns true if path matches against any glob pattern, else false.
92
+ def glob_include?(enumerator, entry)
93
+ entry_with_source = PathManager.join(site.source, entry)
100
94
 
101
- if exp.is_a?(Regexp)
102
- entry_path =~ exp
95
+ enumerator.any? do |pattern|
96
+ case pattern
97
+ when String
98
+ pattern_with_source = PathManager.join(site.source, pattern)
103
99
 
100
+ File.fnmatch?(pattern_with_source, entry_with_source) ||
101
+ entry_with_source.start_with?(pattern_with_source)
102
+ when Regexp
103
+ pattern.match?(entry_with_source)
104
104
  else
105
- item = Pathutil.new(site.in_source_dir).join(exp)
106
-
107
- # If it's a directory they want to exclude, AKA
108
- # ends with a "/" then we will go on to check and
109
- # see if the entry falls within that path and
110
- # exclude it if that's the case.
111
-
112
- if entry.end_with?("/")
113
- entry_path.in_path?(
114
- item
115
- )
116
-
117
- else
118
- File.fnmatch?(item, entry_path) ||
119
- entry_path.to_path.start_with?(
120
- item
121
- )
122
- end
105
+ false
123
106
  end
124
107
  end
125
108
  end
@@ -10,7 +10,7 @@ module Jekyll
10
10
 
11
11
  def_delegators :@doc,
12
12
  :site, :name, :ext, :extname,
13
- :collection, :related_posts,
13
+ :collection, :related_posts, :type,
14
14
  :coffeescript_file?, :yaml_file?,
15
15
  :url, :next_doc, :previous_doc
16
16
 
@@ -155,7 +155,7 @@ module Jekyll
155
155
  tag_names.flatten!
156
156
  tag_names.reverse_each do |tag_name|
157
157
  next unless liquid_block?(tag_name)
158
- next if head =~ endtag_regex_stash(tag_name)
158
+ next if endtag_regex_stash(tag_name).match?(head)
159
159
 
160
160
  modified = true
161
161
  head << "\n{% end#{tag_name} %}"