-
Notifications
You must be signed in to change notification settings - Fork 17
/
helpers.rb
155 lines (144 loc) · 4.75 KB
/
helpers.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# :stopdoc:
# This module provides a set of helper functions and methods for working with Sass literals.
#
module Archetype::Functions::Helpers
private
#
# provides a convenience interface to the Compass::Logger
#
def self.logger
@logger ||= Compass::Logger.new
end
#
# convert a Hash to a Sass::List
#
# *Parameters*:
# - <tt>hsh</tt> {Hash} the hash to convert
# - <tt>depth</tt> {Integer} the depth to walk down into the hash
# - <tt>separator</tt> {Symbol} the separator to use for the Sass::List
# *Returns*:
# - {Sass::List} the converted list
#
def self.hash_to_list(hsh, depth = 0, separator = :comma)
if hsh.is_a? Hash
list = []
hsh.each do |key, item|
item = [key, item]
# if its a hash, convert it to a List
if item.is_a? Hash or item.is_a? Array
tmp = []
item[1] = [item[1]] if not item[1].is_a? Array
item[1].each do |i|
list.push Sass::Script::List.new([Sass::Script::String.new(item[0]), hash_to_list(i, depth + 1)], separator)
end
end
end
return Sass::Script::List.new(list, separator)
end
# if its an array, cast to a List
return Sass::Script::List.new(hsh, separator) if hsh.is_a? Array
# otherwise just return it
return hsh
end
#
# convert a Sass::List to a Hash
#
# *Parameters*:
# - <tt>list</tt> {Sass::List} the list to convert
# - <tt>depth</tt> {Integer} the depth to reach into nested Lists
# - <tt>nest</tt> {Array} a list of keys to treat as nested objects
# *Returns*:
# - {Hash} the converted hash
#
def self.list_to_hash(list, depth = 0, nest = [], additives = [])
list = list.to_a
previous = nil
hsh = Archetype::Hash.new
list.each do |item|
item = item.to_a
# convert the key to a string and strip off quotes
key = to_str(item[0], ' ' , :quotes)
# capture the value
value = item[1]
if key != 'nil'
if is_value(value, :blank)
if previous.nil?
previous = key
next
else
value = item[0]
key = previous
previous = nil
end
elsif not previous.nil?
# if we got here, something is wrong with the structure
list.shift if to_str(list[0]) == previous # remove the first item if it's the previous key, which is now the parent key
list = list[0].to_a # now the remaining items were munged, so split them out
hsh = Archetype::Hash.new
hsh[previous] = list_to_hash(list, depth - 1, nest, additives)
return hsh
end
end
# update the hash if we have a valid key and hash
if key != 'nil' and not is_value(value, :blank)
# check if if it's a nesting hash
nested = nest.include?(key)
# if it's nested or we haven't reached out depth, recurse
if nested or depth > 0
value = list_to_hash(value, nested ? depth + 1 : depth - 1, nest, additives)
end
if additives.include?(key)
hsh[key] ||= []
hsh[key].push(value)
else
hsh[key] = value
end
end
end
logger.record(:warning, "one of your data structures is ambiguous, please double check near `#{previous}`") if not previous.nil?
return hsh
end
#
# convert things to a String
#
# *Parameters*:
# - <tt>value</tt> {String|Sass::String|Sass::List} the thing to convert
# - <tt>separator</tt> {String} the separator to use for joining Sass::List
# *Returns*:
# - {String} the converted String
#
def self.to_str(value, separator = ' ', strip = nil)
if not value.is_a?(String)
value = ((value.to_a).each{ |i| i.nil? ? 'nil' : (i.is_a?(String) ? i : i.value) }).join(separator || '')
end
strip = /\A"|"\Z/ if strip == :quotes
return strip.nil? ? value : value.gsub(strip, '')
end
#
# test a value for blankness or nilness
#
# *Parameters*:
# - <tt>value</tt> {String|Array|Sass::String|Sass::List} the thing to test
# - <tt>test</tt> {Symbol} the test to perform [:blank|:nil]
# *Returns*:
# - {Boolean} whether or not the value is nil/blank
#
def self.is_value(value, test = :nil)
is_it = nil
case test
when :blank
is_it = false
value = value.value if value.is_a?(Sass::Script::String)
is_it = value.nil?
is_it = value.empty? if value.is_a?(String)
is_it = value.to_a.empty? if value.is_a?(Sass::Script::List) or value.is_a?(Array)
when :nil
is_it = false
value = value.value if value.is_a?(Sass::Script::String)
is_it = value.nil?
is_it = value == 'nil' if value.is_a?(String)
is_it = to_str(value) == 'nil' if value.is_a?(Sass::Script::List) or value.is_a?(Array)
end
return is_it
end
end