bunto 3.0.0 → 3.2.1
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 +124 -76
- data/README.markdown +49 -12
- data/{bin → exe}/bunto +18 -14
- data/lib/bunto.rb +83 -78
- data/lib/bunto/cleaner.rb +10 -8
- data/lib/bunto/collection.rb +33 -17
- data/lib/bunto/command.rb +19 -13
- data/lib/bunto/commands/build.rb +22 -14
- data/lib/bunto/commands/clean.rb +9 -8
- data/lib/bunto/commands/doctor.rb +10 -8
- data/lib/bunto/commands/help.rb +4 -3
- data/lib/bunto/commands/new.rb +30 -21
- data/lib/bunto/commands/new_theme.rb +36 -0
- data/lib/bunto/commands/serve.rb +26 -20
- data/lib/bunto/commands/serve/servlet.rb +4 -5
- data/lib/bunto/configuration.rb +187 -125
- data/lib/bunto/converters/markdown.rb +19 -9
- data/lib/bunto/converters/markdown/kramdown_parser.rb +12 -5
- data/lib/bunto/converters/markdown/rdiscount_parser.rb +4 -4
- data/lib/bunto/converters/markdown/redcarpet_parser.rb +90 -84
- data/lib/bunto/convertible.rb +38 -25
- data/lib/bunto/deprecator.rb +11 -6
- data/lib/bunto/desktop.ini +2 -0
- data/lib/bunto/document.rb +53 -51
- data/lib/bunto/drops/bunto_drop.rb +12 -0
- data/lib/bunto/drops/document_drop.rb +40 -5
- data/lib/bunto/drops/drop.rb +49 -10
- data/lib/bunto/drops/excerpt_drop.rb +15 -0
- data/lib/bunto/drops/site_drop.rb +4 -2
- data/lib/bunto/drops/url_drop.rb +4 -4
- data/lib/bunto/entry_filter.rb +64 -19
- data/lib/bunto/errors.rb +6 -3
- data/lib/bunto/excerpt.rb +4 -6
- data/lib/bunto/external.rb +4 -4
- data/lib/bunto/filters.rb +72 -39
- data/lib/bunto/frontmatter_defaults.rb +45 -38
- data/lib/bunto/hooks.rb +21 -21
- data/lib/bunto/layout.rb +4 -8
- data/lib/bunto/liquid_renderer.rb +14 -3
- data/lib/bunto/liquid_renderer/file.rb +5 -1
- data/lib/bunto/liquid_renderer/table.rb +11 -11
- data/lib/bunto/log_adapter.rb +2 -2
- data/lib/bunto/page.rb +10 -10
- data/lib/bunto/plugin.rb +5 -5
- data/lib/bunto/plugin_manager.rb +12 -8
- data/lib/bunto/publisher.rb +1 -1
- data/lib/bunto/reader.rb +11 -7
- data/lib/bunto/readers/data_reader.rb +9 -9
- data/lib/bunto/readers/layout_reader.rb +7 -7
- data/lib/bunto/readers/page_reader.rb +3 -1
- data/lib/bunto/readers/post_reader.rb +9 -10
- data/lib/bunto/readers/static_file_reader.rb +3 -1
- data/lib/bunto/regenerator.rb +50 -28
- data/lib/bunto/related_posts.rb +1 -1
- data/lib/bunto/renderer.rb +33 -23
- data/lib/bunto/site.rb +94 -51
- data/lib/bunto/static_file.rb +33 -26
- data/lib/bunto/stevenson.rb +6 -5
- data/lib/bunto/tags/highlight.rb +50 -35
- data/lib/bunto/tags/include.rb +42 -31
- data/lib/bunto/tags/link.rb +11 -4
- data/lib/bunto/tags/post_url.rb +8 -7
- data/lib/bunto/theme.rb +10 -8
- data/lib/bunto/theme_builder.rb +117 -0
- data/lib/bunto/url.rb +21 -14
- data/lib/bunto/utils.rb +57 -28
- data/lib/bunto/utils/ansi.rb +9 -9
- data/lib/bunto/utils/platforms.rb +2 -2
- data/lib/bunto/version.rb +1 -1
- data/lib/site_template/_config.yml +3 -1
- data/lib/site_template/_posts/0000-00-00-welcome-to-bunto.markdown.erb +3 -3
- data/lib/site_template/about.md +3 -3
- data/lib/site_template/css/main.scss +3 -17
- data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
- data/lib/theme_template/Gemfile +2 -0
- data/lib/theme_template/LICENSE.txt.erb +21 -0
- data/lib/theme_template/README.md.erb +48 -0
- data/lib/theme_template/_layouts/default.html +1 -0
- data/lib/theme_template/_layouts/page.html +5 -0
- data/lib/theme_template/_layouts/post.html +5 -0
- data/lib/theme_template/example/_config.yml.erb +1 -0
- data/lib/theme_template/example/_post.md +12 -0
- data/lib/theme_template/example/index.html +14 -0
- data/lib/theme_template/example/style.scss +7 -0
- data/lib/theme_template/gitignore.erb +4 -0
- data/lib/theme_template/theme.gemspec.erb +18 -0
- metadata +40 -19
- data/lib/site_template/_includes/footer.html +0 -38
- data/lib/site_template/_includes/head.html +0 -12
- data/lib/site_template/_includes/header.html +0 -27
- data/lib/site_template/_includes/icon-github.html +0 -1
- data/lib/site_template/_includes/icon-github.svg +0 -1
- data/lib/site_template/_includes/icon-twitter.html +0 -1
- data/lib/site_template/_includes/icon-twitter.svg +0 -1
- data/lib/site_template/_layouts/default.html +0 -20
- data/lib/site_template/_layouts/page.html +0 -14
- data/lib/site_template/_layouts/post.html +0 -15
- data/lib/site_template/_sass/_base.scss +0 -200
- data/lib/site_template/_sass/_layout.scss +0 -242
- data/lib/site_template/_sass/_syntax-highlighting.scss +0 -71
|
@@ -24,11 +24,13 @@ module Bunto
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def html_pages
|
|
27
|
-
@site_html_pages ||= @obj.pages.select
|
|
27
|
+
@site_html_pages ||= @obj.pages.select do |page|
|
|
28
|
+
page.html? || page.url.end_with?("/")
|
|
29
|
+
end
|
|
28
30
|
end
|
|
29
31
|
|
|
30
32
|
def collections
|
|
31
|
-
@site_collections ||= @obj.collections.values.map(&:to_liquid)
|
|
33
|
+
@site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
private
|
data/lib/bunto/drops/url_drop.rb
CHANGED
|
@@ -19,20 +19,20 @@ module Bunto
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def title
|
|
22
|
-
Utils.slugify(@obj.data[
|
|
22
|
+
Utils.slugify(@obj.data["slug"], :mode => "pretty", :cased => true) ||
|
|
23
23
|
Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def slug
|
|
27
|
-
Utils.slugify(@obj.data[
|
|
27
|
+
Utils.slugify(@obj.data["slug"]) || Utils.slugify(@obj.basename_without_ext)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def categories
|
|
31
31
|
category_set = Set.new
|
|
32
|
-
Array(@obj.data[
|
|
32
|
+
Array(@obj.data["categories"]).each do |category|
|
|
33
33
|
category_set << category.to_s.downcase
|
|
34
34
|
end
|
|
35
|
-
category_set.to_a.join(
|
|
35
|
+
category_set.to_a.join("/")
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def year
|
data/lib/bunto/entry_filter.rb
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
module Bunto
|
|
2
2
|
class EntryFilter
|
|
3
|
-
SPECIAL_LEADING_CHARACTERS = ['.', '_', '#', '~'].freeze
|
|
4
|
-
|
|
5
3
|
attr_reader :site
|
|
4
|
+
SPECIAL_LEADING_CHARACTERS = [
|
|
5
|
+
".", "_", "#", "~"
|
|
6
|
+
].freeze
|
|
6
7
|
|
|
7
8
|
def initialize(site, base_directory = nil)
|
|
8
9
|
@site = site
|
|
9
|
-
@base_directory = derive_base_directory(
|
|
10
|
+
@base_directory = derive_base_directory(
|
|
11
|
+
@site, base_directory.to_s.dup
|
|
12
|
+
)
|
|
10
13
|
end
|
|
11
14
|
|
|
12
15
|
def base_directory
|
|
@@ -14,14 +17,14 @@ module Bunto
|
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
def derive_base_directory(site, base_dir)
|
|
17
|
-
if base_dir.start_with?(site.source)
|
|
18
|
-
base_dir[site.source] = ""
|
|
19
|
-
end
|
|
20
|
+
base_dir[site.source] = "" if base_dir.start_with?(site.source)
|
|
20
21
|
base_dir
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def relative_to_source(entry)
|
|
24
|
-
File.join(
|
|
25
|
+
File.join(
|
|
26
|
+
base_directory, entry
|
|
27
|
+
)
|
|
25
28
|
end
|
|
26
29
|
|
|
27
30
|
def filter(entries)
|
|
@@ -33,7 +36,8 @@ module Bunto
|
|
|
33
36
|
end
|
|
34
37
|
|
|
35
38
|
def included?(entry)
|
|
36
|
-
glob_include?(site.include,
|
|
39
|
+
glob_include?(site.include,
|
|
40
|
+
entry)
|
|
37
41
|
end
|
|
38
42
|
|
|
39
43
|
def special?(entry)
|
|
@@ -42,34 +46,75 @@ module Bunto
|
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def backup?(entry)
|
|
45
|
-
entry[-1..-1] ==
|
|
49
|
+
entry[-1..-1] == "~"
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
def excluded?(entry)
|
|
49
53
|
excluded = glob_include?(site.exclude, relative_to_source(entry))
|
|
50
|
-
|
|
54
|
+
if excluded
|
|
55
|
+
Bunto.logger.debug(
|
|
56
|
+
"EntryFilter:",
|
|
57
|
+
"excluded #{relative_to_source(entry)}"
|
|
58
|
+
)
|
|
59
|
+
end
|
|
51
60
|
excluded
|
|
52
61
|
end
|
|
53
62
|
|
|
63
|
+
# --
|
|
64
|
+
# Check if a file is a symlink.
|
|
65
|
+
# NOTE: This can be converted to allowing even in safe,
|
|
66
|
+
# since we use Pathutil#in_path? now.
|
|
67
|
+
# --
|
|
54
68
|
def symlink?(entry)
|
|
55
69
|
site.safe && File.symlink?(entry) && symlink_outside_site_source?(entry)
|
|
56
70
|
end
|
|
57
71
|
|
|
72
|
+
# --
|
|
73
|
+
# NOTE: Pathutil#in_path? gets the realpath.
|
|
74
|
+
# @param [<Anything>] entry the entry you want to validate.
|
|
75
|
+
# Check if a path is outside of our given root.
|
|
76
|
+
# --
|
|
58
77
|
def symlink_outside_site_source?(entry)
|
|
59
|
-
!
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def ensure_leading_slash(path)
|
|
63
|
-
path[0..0] == "/" ? path : "/#{path}"
|
|
78
|
+
!Pathutil.new(entry).in_path?(
|
|
79
|
+
site.in_source_dir
|
|
80
|
+
)
|
|
64
81
|
end
|
|
65
82
|
|
|
83
|
+
# --
|
|
84
|
+
# Check if an entry matches a specific pattern and return true,false.
|
|
66
85
|
# Returns true if path matches against any glob pattern.
|
|
67
|
-
#
|
|
86
|
+
# --
|
|
68
87
|
def glob_include?(enum, e)
|
|
69
|
-
entry =
|
|
88
|
+
entry = Pathutil.new(site.in_source_dir).join(e)
|
|
70
89
|
enum.any? do |exp|
|
|
71
|
-
|
|
72
|
-
|
|
90
|
+
# Users who send a Regexp knows what they want to
|
|
91
|
+
# exclude, so let them send a Regexp to exclude files,
|
|
92
|
+
# we will not bother caring if it works or not, it's
|
|
93
|
+
# on them at this point.
|
|
94
|
+
|
|
95
|
+
if exp.is_a?(Regexp)
|
|
96
|
+
entry =~ exp
|
|
97
|
+
|
|
98
|
+
else
|
|
99
|
+
item = Pathutil.new(site.in_source_dir).join(exp)
|
|
100
|
+
|
|
101
|
+
# If it's a directory they want to exclude, AKA
|
|
102
|
+
# ends with a "/" then we will go on to check and
|
|
103
|
+
# see if the entry falls within that path and
|
|
104
|
+
# exclude it if that's the case.
|
|
105
|
+
|
|
106
|
+
if e.end_with?("/")
|
|
107
|
+
entry.in_path?(
|
|
108
|
+
item
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
else
|
|
112
|
+
File.fnmatch?(item, entry) ||
|
|
113
|
+
entry.to_path.start_with?(
|
|
114
|
+
item
|
|
115
|
+
)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
73
118
|
end
|
|
74
119
|
end
|
|
75
120
|
end
|
data/lib/bunto/errors.rb
CHANGED
|
@@ -2,13 +2,16 @@ module Bunto
|
|
|
2
2
|
module Errors
|
|
3
3
|
FatalException = Class.new(::RuntimeError)
|
|
4
4
|
|
|
5
|
+
InvalidThemeName = Class.new(FatalException)
|
|
6
|
+
|
|
5
7
|
DropMutationException = Class.new(FatalException)
|
|
6
8
|
InvalidPermalinkError = Class.new(FatalException)
|
|
7
9
|
InvalidYAMLFrontMatterError = Class.new(FatalException)
|
|
8
10
|
MissingDependencyException = Class.new(FatalException)
|
|
9
11
|
|
|
10
|
-
InvalidDateError
|
|
11
|
-
InvalidPostNameError
|
|
12
|
-
PostURLError
|
|
12
|
+
InvalidDateError = Class.new(FatalException)
|
|
13
|
+
InvalidPostNameError = Class.new(FatalException)
|
|
14
|
+
PostURLError = Class.new(FatalException)
|
|
15
|
+
InvalidURLError = Class.new(FatalException)
|
|
13
16
|
end
|
|
14
17
|
end
|
data/lib/bunto/excerpt.rb
CHANGED
|
@@ -7,7 +7,8 @@ module Bunto
|
|
|
7
7
|
attr_writer :output
|
|
8
8
|
|
|
9
9
|
def_delegators :@doc, :site, :name, :ext, :relative_path, :extname,
|
|
10
|
-
:render_with_liquid?, :collection, :related_posts
|
|
10
|
+
:render_with_liquid?, :collection, :related_posts,
|
|
11
|
+
:url, :next_doc, :previous_doc
|
|
11
12
|
|
|
12
13
|
# Initialize this Excerpt instance.
|
|
13
14
|
#
|
|
@@ -59,10 +60,7 @@ module Bunto
|
|
|
59
60
|
end
|
|
60
61
|
|
|
61
62
|
def to_liquid
|
|
62
|
-
|
|
63
|
-
@to_liquid ||= doc.to_liquid
|
|
64
|
-
doc.data['excerpt'] = self
|
|
65
|
-
@to_liquid
|
|
63
|
+
Bunto::Drops::ExcerptDrop.new(self)
|
|
66
64
|
end
|
|
67
65
|
|
|
68
66
|
# Returns the shorthand String identifier of this doc.
|
|
@@ -120,7 +118,7 @@ module Bunto
|
|
|
120
118
|
if tail.empty?
|
|
121
119
|
head
|
|
122
120
|
else
|
|
123
|
-
"" << head << "\n\n" << tail.scan(
|
|
121
|
+
"" << head << "\n\n" << tail.scan(%r!^\[[^\]]+\]:.+$!).join("\n")
|
|
124
122
|
end
|
|
125
123
|
end
|
|
126
124
|
end
|
data/lib/bunto/external.rb
CHANGED
|
@@ -17,13 +17,13 @@ module Bunto
|
|
|
17
17
|
#
|
|
18
18
|
# names - a string gem name or array of gem names
|
|
19
19
|
#
|
|
20
|
-
def require_if_present(names
|
|
20
|
+
def require_if_present(names)
|
|
21
21
|
Array(names).each do |name|
|
|
22
22
|
begin
|
|
23
23
|
require name
|
|
24
24
|
rescue LoadError
|
|
25
25
|
Bunto.logger.debug "Couldn't load #{name}. Skipping."
|
|
26
|
-
|
|
26
|
+
yield(name) if block_given?
|
|
27
27
|
false
|
|
28
28
|
end
|
|
29
29
|
end
|
|
@@ -39,7 +39,7 @@ module Bunto
|
|
|
39
39
|
def require_with_graceful_fail(names)
|
|
40
40
|
Array(names).each do |name|
|
|
41
41
|
begin
|
|
42
|
-
Bunto.logger.debug "Requiring:",
|
|
42
|
+
Bunto.logger.debug "Requiring:", name.to_s
|
|
43
43
|
require name
|
|
44
44
|
rescue LoadError => e
|
|
45
45
|
Bunto.logger.error "Dependency Error:", <<-MSG
|
|
@@ -50,7 +50,7 @@ The full error message from Ruby is: '#{e.message}'
|
|
|
50
50
|
|
|
51
51
|
If you run into trouble, you can find helpful resources at http://bunto.github.io/help/!
|
|
52
52
|
MSG
|
|
53
|
-
raise Bunto::Errors::MissingDependencyException
|
|
53
|
+
raise Bunto::Errors::MissingDependencyException, name
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
end
|
data/lib/bunto/filters.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
require "uri"
|
|
2
|
+
require "json"
|
|
3
|
+
require "date"
|
|
4
|
+
require "liquid"
|
|
5
5
|
|
|
6
6
|
module Bunto
|
|
7
7
|
module Filters
|
|
@@ -13,7 +13,7 @@ module Bunto
|
|
|
13
13
|
def markdownify(input)
|
|
14
14
|
site = @context.registers[:site]
|
|
15
15
|
converter = site.find_converter_instance(Bunto::Converters::Markdown)
|
|
16
|
-
converter.convert(input)
|
|
16
|
+
converter.convert(input.to_s)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
# Convert quotes into smart quotes.
|
|
@@ -24,7 +24,7 @@ module Bunto
|
|
|
24
24
|
def smartify(input)
|
|
25
25
|
site = @context.registers[:site]
|
|
26
26
|
converter = site.find_converter_instance(Bunto::Converters::SmartyPants)
|
|
27
|
-
converter.convert(input)
|
|
27
|
+
converter.convert(input.to_s)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# Convert a Sass string into CSS output.
|
|
@@ -56,7 +56,7 @@ module Bunto
|
|
|
56
56
|
#
|
|
57
57
|
# Returns the given filename or title as a lowercase URL String.
|
|
58
58
|
# See Utils.slugify for more detail.
|
|
59
|
-
def slugify(input, mode=nil)
|
|
59
|
+
def slugify(input, mode = nil)
|
|
60
60
|
Utils.slugify(input, :mode => mode)
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -118,7 +118,7 @@ module Bunto
|
|
|
118
118
|
#
|
|
119
119
|
# Returns the escaped String.
|
|
120
120
|
def xml_escape(input)
|
|
121
|
-
input.to_s.encode(:xml => :attr).gsub(
|
|
121
|
+
input.to_s.encode(:xml => :attr).gsub(%r!\A"|"\Z!, "")
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
# CGI escape a string for use in a URL. Replaces any special characters
|
|
@@ -133,7 +133,7 @@ module Bunto
|
|
|
133
133
|
#
|
|
134
134
|
# Returns the escaped String.
|
|
135
135
|
def cgi_escape(input)
|
|
136
|
-
CGI
|
|
136
|
+
CGI.escape(input)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
# URI escape a string.
|
|
@@ -150,6 +150,15 @@ module Bunto
|
|
|
150
150
|
URI.escape(input)
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
+
# Replace any whitespace in the input string with a single space
|
|
154
|
+
#
|
|
155
|
+
# input - The String on which to operate.
|
|
156
|
+
#
|
|
157
|
+
# Returns the formatted String
|
|
158
|
+
def normalize_whitespace(input)
|
|
159
|
+
input.to_s.gsub(%r!\s+!, " ").strip
|
|
160
|
+
end
|
|
161
|
+
|
|
153
162
|
# Count the number of words in the input string.
|
|
154
163
|
#
|
|
155
164
|
# input - The String on which to operate.
|
|
@@ -180,7 +189,7 @@ module Bunto
|
|
|
180
189
|
when 2
|
|
181
190
|
"#{array[0]} #{connector} #{array[1]}"
|
|
182
191
|
else
|
|
183
|
-
"#{array[0...-1].join(
|
|
192
|
+
"#{array[0...-1].join(", ")}, #{connector} #{array[-1]}"
|
|
184
193
|
end
|
|
185
194
|
end
|
|
186
195
|
|
|
@@ -203,11 +212,14 @@ module Bunto
|
|
|
203
212
|
# "items" => [...] } # all the items where `property` == "larry"
|
|
204
213
|
def group_by(input, property)
|
|
205
214
|
if groupable?(input)
|
|
206
|
-
input.group_by
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
215
|
+
input.group_by { |item| item_property(item, property).to_s }
|
|
216
|
+
.each_with_object([]) do |item, array|
|
|
217
|
+
array << {
|
|
218
|
+
"name" => item.first,
|
|
219
|
+
"items" => item.last,
|
|
220
|
+
"size" => item.last.size
|
|
221
|
+
}
|
|
222
|
+
end
|
|
211
223
|
else
|
|
212
224
|
input
|
|
213
225
|
end
|
|
@@ -221,9 +233,11 @@ module Bunto
|
|
|
221
233
|
#
|
|
222
234
|
# Returns the filtered array of objects
|
|
223
235
|
def where(input, property, value)
|
|
224
|
-
return input unless input.
|
|
236
|
+
return input unless input.respond_to?(:select)
|
|
225
237
|
input = input.values if input.is_a?(Hash)
|
|
226
|
-
input.select
|
|
238
|
+
input.select do |object|
|
|
239
|
+
Array(item_property(object, property)).map(&:to_s).include?(value.to_s)
|
|
240
|
+
end || []
|
|
227
241
|
end
|
|
228
242
|
|
|
229
243
|
# Filters an array of objects against an expression
|
|
@@ -234,7 +248,7 @@ module Bunto
|
|
|
234
248
|
#
|
|
235
249
|
# Returns the filtered array of objects
|
|
236
250
|
def where_exp(input, variable, expression)
|
|
237
|
-
return input unless input.
|
|
251
|
+
return input unless input.respond_to?(:select)
|
|
238
252
|
input = input.values if input.is_a?(Hash) # FIXME
|
|
239
253
|
|
|
240
254
|
condition = parse_condition(expression)
|
|
@@ -243,7 +257,18 @@ module Bunto
|
|
|
243
257
|
@context[variable] = object
|
|
244
258
|
condition.evaluate(@context)
|
|
245
259
|
end
|
|
246
|
-
end
|
|
260
|
+
end || []
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# Convert the input into integer
|
|
264
|
+
#
|
|
265
|
+
# input - the object string
|
|
266
|
+
#
|
|
267
|
+
# Returns the integer value
|
|
268
|
+
def to_integer(input)
|
|
269
|
+
return 1 if input == true
|
|
270
|
+
return 0 if input == false
|
|
271
|
+
input.to_i
|
|
247
272
|
end
|
|
248
273
|
|
|
249
274
|
# Sort an array of objects
|
|
@@ -255,33 +280,21 @@ module Bunto
|
|
|
255
280
|
# Returns the filtered array of objects
|
|
256
281
|
def sort(input, property = nil, nils = "first")
|
|
257
282
|
if input.nil?
|
|
258
|
-
raise ArgumentError
|
|
283
|
+
raise ArgumentError, "Cannot sort a null object."
|
|
259
284
|
end
|
|
260
285
|
if property.nil?
|
|
261
286
|
input.sort
|
|
262
287
|
else
|
|
263
|
-
|
|
264
|
-
when nils == "first"
|
|
288
|
+
if nils == "first"
|
|
265
289
|
order = - 1
|
|
266
|
-
|
|
290
|
+
elsif nils == "last"
|
|
267
291
|
order = + 1
|
|
268
292
|
else
|
|
269
|
-
raise ArgumentError
|
|
270
|
-
"'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
|
|
293
|
+
raise ArgumentError, "Invalid nils order: " \
|
|
294
|
+
"'#{nils}' is not a valid nils order. It must be 'first' or 'last'."
|
|
271
295
|
end
|
|
272
296
|
|
|
273
|
-
input
|
|
274
|
-
apple_property = item_property(apple, property)
|
|
275
|
-
orange_property = item_property(orange, property)
|
|
276
|
-
|
|
277
|
-
if !apple_property.nil? && orange_property.nil?
|
|
278
|
-
- order
|
|
279
|
-
elsif apple_property.nil? && !orange_property.nil?
|
|
280
|
-
+ order
|
|
281
|
-
else
|
|
282
|
-
apple_property <=> orange_property
|
|
283
|
-
end
|
|
284
|
-
end
|
|
297
|
+
sort_input(input, property, order)
|
|
285
298
|
end
|
|
286
299
|
end
|
|
287
300
|
|
|
@@ -332,6 +345,22 @@ module Bunto
|
|
|
332
345
|
xml_escape(input.inspect)
|
|
333
346
|
end
|
|
334
347
|
|
|
348
|
+
private
|
|
349
|
+
def sort_input(input, property, order)
|
|
350
|
+
input.sort do |apple, orange|
|
|
351
|
+
apple_property = item_property(apple, property)
|
|
352
|
+
orange_property = item_property(orange, property)
|
|
353
|
+
|
|
354
|
+
if !apple_property.nil? && orange_property.nil?
|
|
355
|
+
- order
|
|
356
|
+
elsif apple_property.nil? && !orange_property.nil?
|
|
357
|
+
+ order
|
|
358
|
+
else
|
|
359
|
+
apple_property <=> orange_property
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
335
364
|
private
|
|
336
365
|
def time(input)
|
|
337
366
|
case input
|
|
@@ -344,15 +373,17 @@ module Bunto
|
|
|
344
373
|
when Numeric
|
|
345
374
|
Time.at(input)
|
|
346
375
|
else
|
|
347
|
-
|
|
348
|
-
|
|
376
|
+
raise Errors::InvalidDateError,
|
|
377
|
+
"Invalid Date: '#{input.inspect}' is not a valid datetime."
|
|
349
378
|
end.localtime
|
|
350
379
|
end
|
|
351
380
|
|
|
381
|
+
private
|
|
352
382
|
def groupable?(element)
|
|
353
383
|
element.respond_to?(:group_by)
|
|
354
384
|
end
|
|
355
385
|
|
|
386
|
+
private
|
|
356
387
|
def item_property(item, property)
|
|
357
388
|
if item.respond_to?(:to_liquid)
|
|
358
389
|
item.to_liquid[property.to_s]
|
|
@@ -363,6 +394,7 @@ module Bunto
|
|
|
363
394
|
end
|
|
364
395
|
end
|
|
365
396
|
|
|
397
|
+
private
|
|
366
398
|
def as_liquid(item)
|
|
367
399
|
case item
|
|
368
400
|
when Hash
|
|
@@ -386,6 +418,7 @@ module Bunto
|
|
|
386
418
|
end
|
|
387
419
|
|
|
388
420
|
# Parse a string to a Liquid Condition
|
|
421
|
+
private
|
|
389
422
|
def parse_condition(exp)
|
|
390
423
|
parser = Liquid::Parser.new(exp)
|
|
391
424
|
left_expr = parser.expression
|