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.
- checksums.yaml +4 -4
- data/.rubocop.yml +71 -62
- data/LICENSE +1 -1
- data/README.markdown +46 -17
- data/lib/blank_template/_config.yml +3 -0
- data/lib/blank_template/_layouts/default.html +12 -0
- data/lib/blank_template/_sass/main.scss +9 -0
- data/lib/blank_template/assets/css/main.scss +4 -0
- data/lib/blank_template/index.md +8 -0
- data/lib/jekyll.rb +10 -1
- data/lib/jekyll/cache.rb +190 -0
- data/lib/jekyll/cleaner.rb +5 -4
- data/lib/jekyll/collection.rb +82 -10
- data/lib/jekyll/command.rb +33 -6
- data/lib/jekyll/commands/build.rb +11 -20
- data/lib/jekyll/commands/clean.rb +2 -0
- data/lib/jekyll/commands/doctor.rb +15 -8
- data/lib/jekyll/commands/help.rb +1 -1
- data/lib/jekyll/commands/new.rb +37 -35
- data/lib/jekyll/commands/new_theme.rb +30 -28
- data/lib/jekyll/commands/serve.rb +55 -81
- data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
- data/lib/jekyll/commands/serve/servlet.rb +22 -25
- data/lib/jekyll/commands/serve/websockets.rb +1 -1
- data/lib/jekyll/configuration.rb +61 -149
- data/lib/jekyll/converters/identity.rb +18 -0
- data/lib/jekyll/converters/markdown.rb +49 -40
- data/lib/jekyll/converters/markdown/kramdown_parser.rb +84 -11
- data/lib/jekyll/converters/smartypants.rb +34 -14
- data/lib/jekyll/convertible.rb +30 -31
- data/lib/jekyll/deprecator.rb +1 -3
- data/lib/jekyll/document.rb +89 -61
- data/lib/jekyll/drops/collection_drop.rb +2 -3
- data/lib/jekyll/drops/document_drop.rb +14 -1
- data/lib/jekyll/drops/drop.rb +17 -14
- data/lib/jekyll/drops/excerpt_drop.rb +4 -0
- data/lib/jekyll/drops/page_drop.rb +18 -0
- data/lib/jekyll/drops/site_drop.rb +6 -5
- data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
- data/lib/jekyll/drops/url_drop.rb +53 -1
- data/lib/jekyll/entry_filter.rb +42 -45
- data/lib/jekyll/excerpt.rb +45 -34
- data/lib/jekyll/external.rb +10 -5
- data/lib/jekyll/filters.rb +200 -40
- data/lib/jekyll/filters/date_filters.rb +6 -3
- data/lib/jekyll/filters/grouping_filters.rb +1 -2
- data/lib/jekyll/filters/url_filters.rb +46 -14
- data/lib/jekyll/frontmatter_defaults.rb +46 -35
- data/lib/jekyll/hooks.rb +4 -8
- data/lib/jekyll/inclusion.rb +32 -0
- data/lib/jekyll/liquid_extensions.rb +0 -2
- data/lib/jekyll/liquid_renderer.rb +31 -16
- data/lib/jekyll/liquid_renderer/file.rb +24 -3
- data/lib/jekyll/liquid_renderer/table.rb +36 -77
- data/lib/jekyll/log_adapter.rb +5 -1
- data/lib/jekyll/mime.types +53 -11
- data/lib/jekyll/page.rb +54 -12
- data/lib/jekyll/page_excerpt.rb +26 -0
- data/lib/jekyll/page_without_a_file.rb +0 -4
- data/lib/jekyll/path_manager.rb +31 -0
- data/lib/jekyll/plugin.rb +5 -11
- data/lib/jekyll/plugin_manager.rb +2 -0
- data/lib/jekyll/profiler.rb +58 -0
- data/lib/jekyll/reader.rb +42 -9
- data/lib/jekyll/readers/collection_reader.rb +1 -0
- data/lib/jekyll/readers/data_reader.rb +8 -9
- data/lib/jekyll/readers/layout_reader.rb +3 -12
- data/lib/jekyll/readers/page_reader.rb +5 -5
- data/lib/jekyll/readers/post_reader.rb +31 -18
- data/lib/jekyll/readers/static_file_reader.rb +4 -4
- data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
- data/lib/jekyll/regenerator.rb +4 -12
- data/lib/jekyll/renderer.rb +23 -40
- data/lib/jekyll/site.rb +91 -38
- data/lib/jekyll/static_file.rb +62 -21
- data/lib/jekyll/stevenson.rb +2 -3
- data/lib/jekyll/tags/highlight.rb +19 -51
- data/lib/jekyll/tags/include.rb +82 -42
- data/lib/jekyll/tags/link.rb +11 -7
- data/lib/jekyll/tags/post_url.rb +25 -21
- data/lib/jekyll/theme.rb +16 -18
- data/lib/jekyll/theme_builder.rb +91 -89
- data/lib/jekyll/url.rb +10 -5
- data/lib/jekyll/utils.rb +18 -21
- data/lib/jekyll/utils/ansi.rb +1 -1
- data/lib/jekyll/utils/exec.rb +0 -1
- data/lib/jekyll/utils/internet.rb +2 -4
- data/lib/jekyll/utils/platforms.rb +8 -8
- data/lib/jekyll/utils/thread_event.rb +1 -5
- data/lib/jekyll/utils/win_tz.rb +2 -2
- data/lib/jekyll/version.rb +1 -1
- data/lib/site_template/.gitignore +2 -0
- data/lib/site_template/404.html +1 -0
- data/lib/site_template/_config.yml +17 -5
- data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
- data/lib/site_template/{about.md → about.markdown} +0 -0
- data/lib/site_template/{index.md → index.markdown} +0 -0
- data/lib/theme_template/gitignore.erb +1 -0
- data/lib/theme_template/theme.gemspec.erb +1 -4
- data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -0
- metadata +69 -31
- data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
- data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
- data/lib/jekyll/utils/rouge.rb +0 -22
data/lib/jekyll/external.rb
CHANGED
|
@@ -9,6 +9,7 @@ module Jekyll
|
|
|
9
9
|
#
|
|
10
10
|
def blessed_gems
|
|
11
11
|
%w(
|
|
12
|
+
jekyll-compose
|
|
12
13
|
jekyll-docs
|
|
13
14
|
jekyll-import
|
|
14
15
|
)
|
|
@@ -41,6 +42,7 @@ module Jekyll
|
|
|
41
42
|
# RubyGems.
|
|
42
43
|
def version_constraint(gem_name)
|
|
43
44
|
return "= #{Jekyll::VERSION}" if gem_name.to_s.eql?("jekyll-docs")
|
|
45
|
+
|
|
44
46
|
"> 0"
|
|
45
47
|
end
|
|
46
48
|
|
|
@@ -57,13 +59,16 @@ module Jekyll
|
|
|
57
59
|
Jekyll.logger.debug "Requiring:", name.to_s
|
|
58
60
|
require name
|
|
59
61
|
rescue LoadError => e
|
|
60
|
-
Jekyll.logger.error "Dependency Error:",
|
|
61
|
-
Yikes! It looks like you don't have #{name} or one of its dependencies installed.
|
|
62
|
-
In order to use Jekyll as currently configured, you'll need to install this gem.
|
|
62
|
+
Jekyll.logger.error "Dependency Error:", <<~MSG
|
|
63
|
+
Yikes! It looks like you don't have #{name} or one of its dependencies installed.
|
|
64
|
+
In order to use Jekyll as currently configured, you'll need to install this gem.
|
|
65
|
+
|
|
66
|
+
If you've run Jekyll with `bundle exec`, ensure that you have included the #{name}
|
|
67
|
+
gem in your Gemfile as well.
|
|
63
68
|
|
|
64
|
-
The full error message from Ruby is: '#{e.message}'
|
|
69
|
+
The full error message from Ruby is: '#{e.message}'
|
|
65
70
|
|
|
66
|
-
If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!
|
|
71
|
+
If you run into trouble, you can find helpful resources at https://jekyllrb.com/help/!
|
|
67
72
|
MSG
|
|
68
73
|
raise Jekyll::Errors::MissingDependencyException, name
|
|
69
74
|
end
|
data/lib/jekyll/filters.rb
CHANGED
|
@@ -121,8 +121,20 @@ module Jekyll
|
|
|
121
121
|
# input - The String on which to operate.
|
|
122
122
|
#
|
|
123
123
|
# Returns the Integer word count.
|
|
124
|
-
def number_of_words(input)
|
|
125
|
-
|
|
124
|
+
def number_of_words(input, mode = nil)
|
|
125
|
+
cjk_charset = '\p{Han}\p{Katakana}\p{Hiragana}\p{Hangul}'
|
|
126
|
+
cjk_regex = %r![#{cjk_charset}]!o
|
|
127
|
+
word_regex = %r![^#{cjk_charset}\s]+!o
|
|
128
|
+
|
|
129
|
+
case mode
|
|
130
|
+
when "cjk"
|
|
131
|
+
input.scan(cjk_regex).length + input.scan(word_regex).length
|
|
132
|
+
when "auto"
|
|
133
|
+
cjk_count = input.scan(cjk_regex).length
|
|
134
|
+
cjk_count.zero? ? input.split.length : cjk_count + input.scan(word_regex).length
|
|
135
|
+
else
|
|
136
|
+
input.split.length
|
|
137
|
+
end
|
|
126
138
|
end
|
|
127
139
|
|
|
128
140
|
# Join an array of things into a string by separating with commas and the
|
|
@@ -161,14 +173,17 @@ module Jekyll
|
|
|
161
173
|
|
|
162
174
|
# Filter an array of objects
|
|
163
175
|
#
|
|
164
|
-
# input
|
|
165
|
-
# property - property within each object to filter by
|
|
166
|
-
# value
|
|
176
|
+
# input - the object array.
|
|
177
|
+
# property - the property within each object to filter by.
|
|
178
|
+
# value - the desired value.
|
|
179
|
+
# Cannot be an instance of Array nor Hash since calling #to_s on them returns
|
|
180
|
+
# their `#inspect` string object.
|
|
167
181
|
#
|
|
168
182
|
# Returns the filtered array of objects
|
|
169
183
|
def where(input, property, value)
|
|
170
|
-
return input if property.
|
|
184
|
+
return input if !property || value.is_a?(Array) || value.is_a?(Hash)
|
|
171
185
|
return input unless input.respond_to?(:select)
|
|
186
|
+
|
|
172
187
|
input = input.values if input.is_a?(Hash)
|
|
173
188
|
input_id = input.hash
|
|
174
189
|
|
|
@@ -181,8 +196,8 @@ module Jekyll
|
|
|
181
196
|
# stash or retrive results to return
|
|
182
197
|
@where_filter_cache[input_id][property][value] ||= begin
|
|
183
198
|
input.select do |object|
|
|
184
|
-
|
|
185
|
-
end
|
|
199
|
+
compare_property_vs_target(item_property(object, property), value)
|
|
200
|
+
end.to_a
|
|
186
201
|
end
|
|
187
202
|
end
|
|
188
203
|
|
|
@@ -195,6 +210,7 @@ module Jekyll
|
|
|
195
210
|
# Returns the filtered array of objects
|
|
196
211
|
def where_exp(input, variable, expression)
|
|
197
212
|
return input unless input.respond_to?(:select)
|
|
213
|
+
|
|
198
214
|
input = input.values if input.is_a?(Hash) # FIXME
|
|
199
215
|
|
|
200
216
|
condition = parse_condition(expression)
|
|
@@ -206,6 +222,66 @@ module Jekyll
|
|
|
206
222
|
end || []
|
|
207
223
|
end
|
|
208
224
|
|
|
225
|
+
# Search an array of objects and returns the first object that has the queried attribute
|
|
226
|
+
# with the given value or returns nil otherwise.
|
|
227
|
+
#
|
|
228
|
+
# input - the object array.
|
|
229
|
+
# property - the property within each object to search by.
|
|
230
|
+
# value - the desired value.
|
|
231
|
+
# Cannot be an instance of Array nor Hash since calling #to_s on them returns
|
|
232
|
+
# their `#inspect` string object.
|
|
233
|
+
#
|
|
234
|
+
# Returns the found object or nil
|
|
235
|
+
#
|
|
236
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
237
|
+
def find(input, property, value)
|
|
238
|
+
return input if !property || value.is_a?(Array) || value.is_a?(Hash)
|
|
239
|
+
return input unless input.respond_to?(:find)
|
|
240
|
+
|
|
241
|
+
input = input.values if input.is_a?(Hash)
|
|
242
|
+
input_id = input.hash
|
|
243
|
+
|
|
244
|
+
# implement a hash based on method parameters to cache the end-result for given parameters.
|
|
245
|
+
@find_filter_cache ||= {}
|
|
246
|
+
@find_filter_cache[input_id] ||= {}
|
|
247
|
+
@find_filter_cache[input_id][property] ||= {}
|
|
248
|
+
|
|
249
|
+
# stash or retrive results to return
|
|
250
|
+
# Since `enum.find` can return nil or false, we use a placeholder string "<__NO MATCH__>"
|
|
251
|
+
# to validate caching.
|
|
252
|
+
result = @find_filter_cache[input_id][property][value] ||= begin
|
|
253
|
+
input.find do |object|
|
|
254
|
+
compare_property_vs_target(item_property(object, property), value)
|
|
255
|
+
end || "<__NO MATCH__>"
|
|
256
|
+
end
|
|
257
|
+
return nil if result == "<__NO MATCH__>"
|
|
258
|
+
|
|
259
|
+
result
|
|
260
|
+
end
|
|
261
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
262
|
+
|
|
263
|
+
# Searches an array of objects against an expression and returns the first object for which
|
|
264
|
+
# the expression evaluates to true, or returns nil otherwise.
|
|
265
|
+
#
|
|
266
|
+
# input - the object array
|
|
267
|
+
# variable - the variable to assign each item to in the expression
|
|
268
|
+
# expression - a Liquid comparison expression passed in as a string
|
|
269
|
+
#
|
|
270
|
+
# Returns the found object or nil
|
|
271
|
+
def find_exp(input, variable, expression)
|
|
272
|
+
return input unless input.respond_to?(:find)
|
|
273
|
+
|
|
274
|
+
input = input.values if input.is_a?(Hash)
|
|
275
|
+
|
|
276
|
+
condition = parse_condition(expression)
|
|
277
|
+
@context.stack do
|
|
278
|
+
input.find do |object|
|
|
279
|
+
@context[variable] = object
|
|
280
|
+
condition.evaluate(@context)
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
209
285
|
# Convert the input into integer
|
|
210
286
|
#
|
|
211
287
|
# input - the object string
|
|
@@ -214,6 +290,7 @@ module Jekyll
|
|
|
214
290
|
def to_integer(input)
|
|
215
291
|
return 1 if input == true
|
|
216
292
|
return 0 if input == false
|
|
293
|
+
|
|
217
294
|
input.to_i
|
|
218
295
|
end
|
|
219
296
|
|
|
@@ -225,9 +302,8 @@ module Jekyll
|
|
|
225
302
|
#
|
|
226
303
|
# Returns the filtered array of objects
|
|
227
304
|
def sort(input, property = nil, nils = "first")
|
|
228
|
-
if input.nil?
|
|
229
|
-
|
|
230
|
-
end
|
|
305
|
+
raise ArgumentError, "Cannot sort a null object." if input.nil?
|
|
306
|
+
|
|
231
307
|
if property.nil?
|
|
232
308
|
input.sort
|
|
233
309
|
else
|
|
@@ -246,6 +322,7 @@ module Jekyll
|
|
|
246
322
|
|
|
247
323
|
def pop(array, num = 1)
|
|
248
324
|
return array unless array.is_a?(Array)
|
|
325
|
+
|
|
249
326
|
num = Liquid::Utils.to_integer(num)
|
|
250
327
|
new_ary = array.dup
|
|
251
328
|
new_ary.pop(num)
|
|
@@ -254,6 +331,7 @@ module Jekyll
|
|
|
254
331
|
|
|
255
332
|
def push(array, input)
|
|
256
333
|
return array unless array.is_a?(Array)
|
|
334
|
+
|
|
257
335
|
new_ary = array.dup
|
|
258
336
|
new_ary.push(input)
|
|
259
337
|
new_ary
|
|
@@ -261,6 +339,7 @@ module Jekyll
|
|
|
261
339
|
|
|
262
340
|
def shift(array, num = 1)
|
|
263
341
|
return array unless array.is_a?(Array)
|
|
342
|
+
|
|
264
343
|
num = Liquid::Utils.to_integer(num)
|
|
265
344
|
new_ary = array.dup
|
|
266
345
|
new_ary.shift(num)
|
|
@@ -269,6 +348,7 @@ module Jekyll
|
|
|
269
348
|
|
|
270
349
|
def unshift(array, input)
|
|
271
350
|
return array unless array.is_a?(Array)
|
|
351
|
+
|
|
272
352
|
new_ary = array.dup
|
|
273
353
|
new_ary.unshift(input)
|
|
274
354
|
new_ary
|
|
@@ -276,6 +356,7 @@ module Jekyll
|
|
|
276
356
|
|
|
277
357
|
def sample(input, num = 1)
|
|
278
358
|
return input unless input.respond_to?(:sample)
|
|
359
|
+
|
|
279
360
|
num = Liquid::Utils.to_integer(num) rescue 1
|
|
280
361
|
if num == 1
|
|
281
362
|
input.sample
|
|
@@ -301,35 +382,86 @@ module Jekyll
|
|
|
301
382
|
# We also utilize the Schwartzian transform to make this more efficient.
|
|
302
383
|
def sort_input(input, property, order)
|
|
303
384
|
input.map { |item| [item_property(item, property), item] }
|
|
304
|
-
.sort! do |
|
|
305
|
-
|
|
306
|
-
|
|
385
|
+
.sort! do |a_info, b_info|
|
|
386
|
+
a_property = a_info.first
|
|
387
|
+
b_property = b_info.first
|
|
307
388
|
|
|
308
|
-
if !
|
|
389
|
+
if !a_property.nil? && b_property.nil?
|
|
309
390
|
- order
|
|
310
|
-
elsif
|
|
391
|
+
elsif a_property.nil? && !b_property.nil?
|
|
311
392
|
+ order
|
|
312
393
|
else
|
|
313
|
-
|
|
394
|
+
a_property <=> b_property || a_property.to_s <=> b_property.to_s
|
|
314
395
|
end
|
|
315
396
|
end
|
|
316
397
|
.map!(&:last)
|
|
317
398
|
end
|
|
318
399
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
400
|
+
# `where` filter helper
|
|
401
|
+
#
|
|
402
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
403
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
404
|
+
def compare_property_vs_target(property, target)
|
|
405
|
+
case target
|
|
406
|
+
when NilClass
|
|
407
|
+
return true if property.nil?
|
|
408
|
+
when Liquid::Expression::MethodLiteral # `empty` or `blank`
|
|
409
|
+
target = target.to_s
|
|
410
|
+
return true if property == target || Array(property).join == target
|
|
327
411
|
else
|
|
328
|
-
|
|
412
|
+
target = target.to_s
|
|
413
|
+
if property.is_a? String
|
|
414
|
+
return true if property == target
|
|
415
|
+
else
|
|
416
|
+
Array(property).each do |prop|
|
|
417
|
+
return true if prop.to_s == target
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
false
|
|
423
|
+
end
|
|
424
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
425
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
426
|
+
|
|
427
|
+
def item_property(item, property)
|
|
428
|
+
@item_property_cache ||= {}
|
|
429
|
+
@item_property_cache[property] ||= {}
|
|
430
|
+
@item_property_cache[property][item] ||= begin
|
|
431
|
+
property = property.to_s
|
|
432
|
+
property = if item.respond_to?(:to_liquid)
|
|
433
|
+
read_liquid_attribute(item.to_liquid, property)
|
|
434
|
+
elsif item.respond_to?(:data)
|
|
435
|
+
item.data[property]
|
|
436
|
+
else
|
|
437
|
+
item[property]
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
parse_sort_input(property)
|
|
329
441
|
end
|
|
330
442
|
end
|
|
331
443
|
|
|
332
|
-
|
|
444
|
+
def read_liquid_attribute(liquid_data, property)
|
|
445
|
+
return liquid_data[property] unless property.include?(".")
|
|
446
|
+
|
|
447
|
+
property.split(".").reduce(liquid_data) do |data, key|
|
|
448
|
+
data.respond_to?(:[]) && data[key]
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
FLOAT_LIKE = %r!\A\s*-?(?:\d+\.?\d*|\.\d+)\s*\Z!.freeze
|
|
453
|
+
INTEGER_LIKE = %r!\A\s*-?\d+\s*\Z!.freeze
|
|
454
|
+
private_constant :FLOAT_LIKE, :INTEGER_LIKE
|
|
455
|
+
|
|
456
|
+
# return numeric values as numbers for proper sorting
|
|
457
|
+
def parse_sort_input(property)
|
|
458
|
+
stringified = property.to_s
|
|
459
|
+
return property.to_i if INTEGER_LIKE.match?(stringified)
|
|
460
|
+
return property.to_f if FLOAT_LIKE.match?(stringified)
|
|
461
|
+
|
|
462
|
+
property
|
|
463
|
+
end
|
|
464
|
+
|
|
333
465
|
def as_liquid(item)
|
|
334
466
|
case item
|
|
335
467
|
when Hash
|
|
@@ -352,25 +484,53 @@ module Jekyll
|
|
|
352
484
|
end
|
|
353
485
|
end
|
|
354
486
|
|
|
487
|
+
# ----------- The following set of code was *adapted* from Liquid::If
|
|
488
|
+
# ----------- ref: https://git.io/vp6K6
|
|
489
|
+
|
|
355
490
|
# Parse a string to a Liquid Condition
|
|
356
|
-
private
|
|
357
491
|
def parse_condition(exp)
|
|
358
|
-
parser
|
|
359
|
-
|
|
360
|
-
operator = parser.consume?(:comparison)
|
|
361
|
-
condition =
|
|
362
|
-
if operator
|
|
363
|
-
Liquid::Condition.new(Liquid::Expression.parse(left_expr),
|
|
364
|
-
operator,
|
|
365
|
-
Liquid::Expression.parse(parser.expression))
|
|
366
|
-
else
|
|
367
|
-
Liquid::Condition.new(Liquid::Expression.parse(left_expr))
|
|
368
|
-
end
|
|
369
|
-
parser.consume(:end_of_string)
|
|
492
|
+
parser = Liquid::Parser.new(exp)
|
|
493
|
+
condition = parse_binary_comparison(parser)
|
|
370
494
|
|
|
495
|
+
parser.consume(:end_of_string)
|
|
371
496
|
condition
|
|
372
497
|
end
|
|
373
498
|
|
|
499
|
+
# Generate a Liquid::Condition object from a Liquid::Parser object additionally processing
|
|
500
|
+
# the parsed expression based on whether the expression consists of binary operations with
|
|
501
|
+
# Liquid operators `and` or `or`
|
|
502
|
+
#
|
|
503
|
+
# - parser: an instance of Liquid::Parser
|
|
504
|
+
#
|
|
505
|
+
# Returns an instance of Liquid::Condition
|
|
506
|
+
def parse_binary_comparison(parser)
|
|
507
|
+
condition = parse_comparison(parser)
|
|
508
|
+
first_condition = condition
|
|
509
|
+
while (binary_operator = parser.id?("and") || parser.id?("or"))
|
|
510
|
+
child_condition = parse_comparison(parser)
|
|
511
|
+
condition.send(binary_operator, child_condition)
|
|
512
|
+
condition = child_condition
|
|
513
|
+
end
|
|
514
|
+
first_condition
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
# Generates a Liquid::Condition object from a Liquid::Parser object based on whether the parsed
|
|
518
|
+
# expression involves a "comparison" operator (e.g. <, ==, >, !=, etc)
|
|
519
|
+
#
|
|
520
|
+
# - parser: an instance of Liquid::Parser
|
|
521
|
+
#
|
|
522
|
+
# Returns an instance of Liquid::Condition
|
|
523
|
+
def parse_comparison(parser)
|
|
524
|
+
left_operand = Liquid::Expression.parse(parser.expression)
|
|
525
|
+
operator = parser.consume?(:comparison)
|
|
526
|
+
|
|
527
|
+
# No comparison-operator detected. Initialize a Liquid::Condition using only left operand
|
|
528
|
+
return Liquid::Condition.new(left_operand) unless operator
|
|
529
|
+
|
|
530
|
+
# Parse what remained after extracting the left operand and the `:comparison` operator
|
|
531
|
+
# and initialize a Liquid::Condition object using the operands and the comparison-operator
|
|
532
|
+
Liquid::Condition.new(left_operand, operator, Liquid::Expression.parse(parser.expression))
|
|
533
|
+
end
|
|
374
534
|
end
|
|
375
535
|
end
|
|
376
536
|
|
|
@@ -45,6 +45,7 @@ module Jekyll
|
|
|
45
45
|
# Returns the formatted String.
|
|
46
46
|
def date_to_xmlschema(date)
|
|
47
47
|
return date if date.to_s.empty?
|
|
48
|
+
|
|
48
49
|
time(date).xmlschema
|
|
49
50
|
end
|
|
50
51
|
|
|
@@ -60,10 +61,12 @@ module Jekyll
|
|
|
60
61
|
# Returns the formatted String.
|
|
61
62
|
def date_to_rfc822(date)
|
|
62
63
|
return date if date.to_s.empty?
|
|
64
|
+
|
|
63
65
|
time(date).rfc822
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
private
|
|
69
|
+
|
|
67
70
|
# month_type: Notations that evaluate to 'Month' via `Time#strftime` ("%b", "%B")
|
|
68
71
|
# type: nil (default) or "ordinal"
|
|
69
72
|
# style: nil (default) or "US"
|
|
@@ -71,17 +74,18 @@ module Jekyll
|
|
|
71
74
|
# Returns a stringified date or the empty input.
|
|
72
75
|
def stringify_date(date, month_type, type = nil, style = nil)
|
|
73
76
|
return date if date.to_s.empty?
|
|
77
|
+
|
|
74
78
|
time = time(date)
|
|
75
79
|
if type == "ordinal"
|
|
76
80
|
day = time.day
|
|
77
81
|
ordinal_day = "#{day}#{ordinal(day)}"
|
|
78
82
|
return time.strftime("#{month_type} #{ordinal_day}, %Y") if style == "US"
|
|
83
|
+
|
|
79
84
|
return time.strftime("#{ordinal_day} #{month_type} %Y")
|
|
80
85
|
end
|
|
81
86
|
time.strftime("%d #{month_type} %Y")
|
|
82
87
|
end
|
|
83
88
|
|
|
84
|
-
private
|
|
85
89
|
def ordinal(number)
|
|
86
90
|
return "th" if (11..13).cover?(number)
|
|
87
91
|
|
|
@@ -93,12 +97,11 @@ module Jekyll
|
|
|
93
97
|
end
|
|
94
98
|
end
|
|
95
99
|
|
|
96
|
-
private
|
|
97
100
|
def time(input)
|
|
98
101
|
date = Liquid::Utils.to_date(input)
|
|
99
102
|
unless date.respond_to?(:to_time)
|
|
100
103
|
raise Errors::InvalidDateError,
|
|
101
|
-
|
|
104
|
+
"Invalid Date: '#{input.inspect}' is not a valid datetime."
|
|
102
105
|
end
|
|
103
106
|
date.to_time.dup.localtime
|
|
104
107
|
end
|
|
@@ -41,16 +41,15 @@ module Jekyll
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
private
|
|
44
|
+
|
|
44
45
|
def parse_expression(str)
|
|
45
46
|
Liquid::Variable.new(str, Liquid::ParseContext.new)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
|
-
private
|
|
49
49
|
def groupable?(element)
|
|
50
50
|
element.respond_to?(:group_by)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
private
|
|
54
53
|
def grouped_array(groups)
|
|
55
54
|
groups.each_with_object([]) do |item, array|
|
|
56
55
|
array << {
|