archetype 0.0.1.pre.12 → 0.0.1.pre.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/lib/archetype.rb +4 -0
  3. data/lib/archetype/actions/help.rb +16 -0
  4. data/lib/archetype/actions/theme.rb +73 -0
  5. data/lib/archetype/executor.rb +27 -0
  6. data/lib/archetype/functions/hash.rb +28 -12
  7. data/lib/archetype/functions/helpers.rb +46 -13
  8. data/lib/archetype/functions/styleguide_memoizer.rb +10 -2
  9. data/lib/archetype/sass_extensions/functions/lists.rb +36 -42
  10. data/lib/archetype/sass_extensions/functions/locale.rb +32 -16
  11. data/lib/archetype/sass_extensions/functions/styleguide.rb +127 -38
  12. data/lib/archetype/sass_extensions/functions/ui.rb +3 -2
  13. data/lib/archetype/sass_extensions/functions/version.rb +11 -6
  14. data/lib/archetype/sass_extensions/monkey_patches.rb +1 -1
  15. data/lib/archetype/version.rb +2 -2
  16. data/stylesheets/archetype/_base.scss +7 -2
  17. data/stylesheets/archetype/_config.scss +8 -1
  18. data/stylesheets/archetype/_hacks.scss +51 -17
  19. data/stylesheets/archetype/_ui.scss +16 -5
  20. data/stylesheets/archetype/base/_h5bp.scss +12 -12
  21. data/stylesheets/archetype/base/_normalize.scss +178 -139
  22. data/stylesheets/archetype/grid/_grid.scss +13 -13
  23. data/stylesheets/archetype/styleguide/components/_buttons.scss +1 -0
  24. data/stylesheets/archetype/util/_debug.scss +4 -4
  25. data/stylesheets/archetype/util/_lists.scss +1 -1
  26. data/stylesheets/archetype/util/_misc.scss +1 -1
  27. data/stylesheets/archetype/util/_rtl.scss +1 -1
  28. data/stylesheets/archetype/util/_spacing.scss +6 -6
  29. data/stylesheets/archetype/util/_styles.scss +21 -10
  30. data/stylesheets/archetype/util/_targeting.scss +1 -1
  31. data/test/fixtures/stylesheets/archetype/assets/images/vendor/archetype/animations/loaders-s7889ccc8c1.png +0 -0
  32. data/test/fixtures/stylesheets/archetype/config.rb +2 -0
  33. data/test/fixtures/stylesheets/archetype/source/base.scss +3 -0
  34. data/test/fixtures/stylesheets/archetype/source/hacks/transparent_focusable.scss +5 -0
  35. data/test/fixtures/stylesheets/archetype/source/locale.scss +43 -0
  36. data/test/fixtures/stylesheets/archetype/source/styleguide/alerts.scss +21 -0
  37. data/test/fixtures/stylesheets/archetype/source/styleguide/buttons.scss +5 -1
  38. data/test/fixtures/stylesheets/archetype/source/styleguide/drop.scss +101 -0
  39. data/test/fixtures/stylesheets/archetype/source/styleguide/extend.scss +24 -0
  40. data/test/fixtures/stylesheets/archetype/source/styleguide/invalid_structures.scss +85 -0
  41. data/test/fixtures/stylesheets/archetype/source/styleguide/multi_value.scss +18 -0
  42. data/test/fixtures/stylesheets/archetype/source/styleguide/nested_styleguides.scss +1 -1
  43. data/test/fixtures/stylesheets/archetype/source/styleguide/selective_state.scss +1 -1
  44. data/test/fixtures/stylesheets/archetype/source/ui/glyph_icon.scss +30 -0
  45. data/test/fixtures/stylesheets/archetype/source/utilities/associative.scss +24 -0
  46. data/test/fixtures/stylesheets/archetype/source/utilities/custom_output_styler.scss +4 -3
  47. data/test/fixtures/stylesheets/archetype/source/utilities/targeting/target-browser.scss +8 -1
  48. data/test/fixtures/stylesheets/archetype/tmp/b.css +14 -0
  49. data/test/fixtures/stylesheets/archetype/tmp/base.css +349 -0
  50. data/test/fixtures/stylesheets/archetype/tmp/hacks/ie_pseudo.css +11 -0
  51. data/test/fixtures/stylesheets/archetype/tmp/hacks/transparent_focusable.css +4 -0
  52. data/test/fixtures/stylesheets/archetype/tmp/locale.css +23 -0
  53. data/test/fixtures/stylesheets/archetype/tmp/styleguide/alerts.css +711 -0
  54. data/test/fixtures/stylesheets/archetype/tmp/styleguide/buttons.css +2119 -0
  55. data/test/fixtures/stylesheets/archetype/tmp/styleguide/drop.css +63 -0
  56. data/test/fixtures/stylesheets/archetype/tmp/styleguide/extend.css +11 -0
  57. data/test/fixtures/stylesheets/archetype/tmp/styleguide/fallback_styles.css +10 -0
  58. data/test/fixtures/stylesheets/archetype/tmp/styleguide/invalid_structures.css +21 -0
  59. data/test/fixtures/stylesheets/archetype/tmp/styleguide/multi_value.css +13 -0
  60. data/test/fixtures/stylesheets/archetype/tmp/styleguide/nested_styleguides.css +28 -0
  61. data/test/fixtures/stylesheets/archetype/tmp/styleguide/selective_state.css +177 -0
  62. data/test/fixtures/stylesheets/archetype/tmp/ui/glyph_icon.css +127 -0
  63. data/test/fixtures/stylesheets/archetype/tmp/ui/hide_element.css +8 -0
  64. data/test/fixtures/stylesheets/archetype/tmp/ui/stroke.css +17 -0
  65. data/test/fixtures/stylesheets/archetype/tmp/ui/triangle.css +35 -0
  66. data/test/fixtures/stylesheets/archetype/tmp/utilities/associative.css +9 -0
  67. data/test/fixtures/stylesheets/archetype/tmp/utilities/custom_output_styler.css +8 -0
  68. data/test/fixtures/stylesheets/archetype/tmp/utilities/if-set.css +9 -0
  69. data/test/fixtures/stylesheets/archetype/tmp/utilities/spacing/horizontal-spacing.css +29 -0
  70. data/test/fixtures/stylesheets/archetype/tmp/utilities/spacing/vertical-spacing.css +29 -0
  71. data/test/fixtures/stylesheets/archetype/tmp/utilities/styles/filter.css +11 -0
  72. data/test/fixtures/stylesheets/archetype/tmp/utilities/styles/font-family.css +16 -0
  73. data/test/fixtures/stylesheets/archetype/tmp/utilities/styles/z-index.css +15 -0
  74. data/test/fixtures/stylesheets/archetype/tmp/utilities/targeting/target-browser.css +105 -0
  75. data/test/fixtures/stylesheets/archetype/tmp/utilities/targeting/target-os.css +55 -0
  76. data/test/helpers/test_case.rb +2 -2
  77. data/test/integrations/archetype_test.rb +3 -1
  78. data/test/units/sass_extensions_test.rb +18 -25
  79. metadata +81 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de11d6f34cd0100f0c778cbcc6934c7f309aa600
4
- data.tar.gz: 322e13961821f4017eabbc64680da8ffe970a62d
3
+ metadata.gz: d73c8fbdab53ce9a623ba9c8f8bfa25defd2dca3
4
+ data.tar.gz: bde34dc53d79e37772e9c1397509ffcdfb778f43
5
5
  SHA512:
6
- metadata.gz: 7ddb73df40c54934eacaefe7e5ebe95e01b474f6f2625e0712e3b77cd5014ef68236e45ce3595b4c750b097c3806137db7dc89ecda31a97e5fd8530f2cd2350f
7
- data.tar.gz: 440f5eded8d3a1deeeb79fddb99ae6582fe712b5caa9c5d8349a431321c9d203b21cf9a2d20058743dc9ef7ec6d705688c9042795ea95679f79797cb910f3d37
6
+ metadata.gz: 367183d15630183a4e101f58b913a1c85028064a74b0cd269586157bf19818a39288ef0eaee64ffed617fe002653b3e245931fb9c94ca9f0bf3975c03fc3c22e
7
+ data.tar.gz: 892fb1fa496f0d55ec61fefbeef8404d35df8458034b8f8b5dd5983f5d1793c019e7fccb4cb9179aea7b77f1e992bdccd302c83926c47570aeeee247fa3ab202
data/lib/archetype.rb CHANGED
@@ -33,6 +33,10 @@ module Archetype
33
33
  Compass::Configuration.add_configuration_property(:memoize, "should the memoizer be used to improve compilation speed") do
34
34
  not (Compass.configuration.environment || :development).to_s.include?('dev')
35
35
  end
36
+ # testing (for running unit tests)
37
+ Compass::Configuration.add_configuration_property(:testing, "is this a testing environment") do
38
+ ENV['CI']
39
+ end
36
40
  end
37
41
  end
38
42
 
@@ -0,0 +1,16 @@
1
+ description = "Get help on an Archetype action"
2
+ if @description.nil?
3
+ # do stuff...
4
+ @help = true
5
+
6
+ if not ARGV[1].nil? and ARGV[1] != 'help'
7
+ action = File.join(@actions_path, ARGV[1])
8
+ begin
9
+ load "#{action}.rb"
10
+ rescue
11
+ puts "unknown action: #{ARGV[1]}"
12
+ end
13
+ end
14
+ else
15
+ @description = description
16
+ end
@@ -0,0 +1,73 @@
1
+ require 'fileutils'
2
+ description = "Generate a new Archetype theme"
3
+
4
+ if @description.nil?
5
+ options = {
6
+ :extends => 'archetype'
7
+ }
8
+ OptionParser.new do |opts|
9
+ opts.banner = description
10
+ opts.define_head "Usage: archetype theme [path] [options]"
11
+ opts.separator ""
12
+ opts.separator "Example usage:"
13
+ opts.separator " archetype theme /path/to/scss/ --name=myCustomTheme"
14
+ opts.separator " archetype theme --name=themes/myExtendedTheme --extends=themes/myBaseTheme"
15
+
16
+ opts.on('-n', '--name THEME', 'theme name') do |v|
17
+ options[:theme] = v
18
+ end
19
+
20
+ opts.on('-x', '--extends THEME', 'theme name to extend') do |v|
21
+ options[:extends] = v
22
+ end
23
+
24
+ opts.on('-h', '--help', 'shows this help message') do
25
+ puts opts
26
+ exit
27
+ end
28
+
29
+ if not @help.nil?
30
+ puts opts
31
+ exit
32
+ end
33
+ end.parse!
34
+
35
+ if not options[:theme].nil?
36
+ base = ARGV[1] || '.'
37
+ tmp = '/tmp/theme_' + rand(36**8).to_s(36)
38
+ theme_template = File.join(File.dirname(__FILE__), '../../../templates/_theme/')
39
+ theme_path = File.join(base, options[:theme])
40
+ extends = "#{options[:extends]}"
41
+ if options[:extends] != 'archetype'
42
+ extends = "#{extends}/core"
43
+ end
44
+ theme_name = File.basename(options[:theme])
45
+ # copy template files to tmp dir
46
+ FileUtils.mkdir_p(tmp)
47
+ FileUtils.cp_r(Dir["#{theme_template}/**"], tmp)
48
+
49
+ puts "Creating theme '#{theme_name}' in #{File.expand_path(theme_path)}..."
50
+ puts "extending from #{options[:extends]}" if options[:extends] != 'archetype'
51
+
52
+ # update all placeholders in template files
53
+ Dir.glob("#{tmp}/**/*.scss") do |filename|
54
+ out = File.read(filename).gsub(/__THEME_NAME__/, theme_name).gsub(/__THEME_EXTENDS__/, extends)
55
+ File.open(filename, "w") { |file| file.puts out }
56
+ end
57
+
58
+ # now move all the theme files to their destination
59
+ FileUtils.mkdir_p(theme_path)
60
+ FileUtils.cp_r(Dir["#{tmp}/**"], theme_path)
61
+
62
+ # create convenience file _<theme>.scss ...
63
+ File.open(File.join(File.dirname(theme_path), "_#{theme_name}.scss"), "w") { |file| file.puts "// #{theme_name} theme\n@import \"#{theme_name}/core\";\n" }
64
+
65
+ # remove tmp dir
66
+ FileUtils.rm_rf(tmp)
67
+ puts "Congratulations! Your new theme has been created!"
68
+ puts "Use @import \"#{options[:theme]}\" in your scss files."
69
+ exit
70
+ end
71
+ else
72
+ @description = description
73
+ end
@@ -0,0 +1,27 @@
1
+ require 'optparse'
2
+
3
+ @actions_path = File.join(File.dirname(__FILE__), 'actions')
4
+
5
+ if not ARGV[0].nil? and not ARGV[0].empty?
6
+ action_name = ARGV[0]
7
+ action = File.join(@actions_path, action_name)
8
+ begin
9
+ require action
10
+ rescue
11
+ puts "unknown action: #{action_name}"
12
+ end
13
+ end
14
+
15
+ # if we got here, there was either no action, or the action was invalid
16
+ OptionParser.new do |opts|
17
+ opts.banner = "Archetype command line actions\n\n"
18
+ opts.define_head "Usage: archetype <action> [options]"
19
+ opts.separator ""
20
+ opts.separator "Available Actions:"
21
+ Dir.glob("#{@actions_path}/*.rb") do |action|
22
+ @description = true
23
+ load action
24
+ opts.separator " * #{File.basename(action, '.rb')}\t- #{@description}"
25
+ end
26
+ puts opts
27
+ end.parse!
@@ -1,6 +1,8 @@
1
1
  # :stopdoc:
2
2
  # This module extends the native Ruby Hash class to support deep merging
3
3
  # and comparing the difference between hashes.
4
+ # This functionality mimics that found in ActiveSupport
5
+ # @see https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/hash/deep_merge.rb
4
6
  #
5
7
  module Archetype::Functions::Hash
6
8
  #
@@ -11,13 +13,10 @@ module Archetype::Functions::Hash
11
13
  # *Returns*:
12
14
  # - {Hash} a new hash containing the contents of other_hash and the contents of hsh, deep merged
13
15
  #
14
- def rmerge(other_hash)
15
- new_hash = {}
16
- merge(other_hash) do |key, oldval, newval|
17
- new_hash[key] = oldval.class == self.class ? oldval.rmerge(newval) : newval
18
- end
16
+ def rmerge(other_hash, &block)
17
+ dup.rmerge!(other_hash, &block)
19
18
  end
20
-
19
+
21
20
  #
22
21
  # adds the contents of other_hash to hsh, deep merged
23
22
  #
@@ -26,10 +25,16 @@ module Archetype::Functions::Hash
26
25
  # *Returns*:
27
26
  # - {Hash} the original hash with the addition of the contents of other_hash
28
27
  #
29
- def rmerge!(other_hash)
30
- merge!(other_hash) do |key, oldval, newval|
31
- oldval.class == self.class ? oldval.rmerge!(newval) : newval
28
+ def rmerge!(other_hash, &block)
29
+ other_hash.each_pair do |k,v|
30
+ tv = self[k]
31
+ if tv.is_a?(Hash) && v.is_a?(Hash)
32
+ self[k] = tv.rmerge(v, &block)
33
+ else
34
+ self[k] = block && tv ? block.call(k, tv, v) : v
35
+ end
32
36
  end
37
+ return self
33
38
  end
34
39
 
35
40
  #
@@ -41,7 +46,7 @@ module Archetype::Functions::Hash
41
46
  # - {Hash} a representation of the difference between the two hashes
42
47
  #
43
48
  def diff(other_hash)
44
- (self.keys + other_hash.keys).uniq.inject({}) do |tmp, key|
49
+ (self.keys + other_hash.keys).uniq.inject(Archetype::Hash.new) do |tmp, key|
45
50
  # special comparison for gradients
46
51
  are_gradients = self[key].is_a?(Compass::SassExtensions::Functions::GradientSupport::LinearGradient) and other_hash[key].is_a?(Compass::SassExtensions::Functions::GradientSupport::LinearGradient)
47
52
  eq_gradients = are_gradients ? (self[key].to_s == other_hash[key].to_s) : true
@@ -128,6 +133,17 @@ private
128
133
  end
129
134
  end
130
135
 
131
- class Hash
132
- include Archetype::Functions::Hash
136
+ # this shims the Hash functionality to ensure we have an ordered hash guarantee
137
+ module Archetype
138
+ if RUBY_VERSION < '1.9'
139
+ require 'hashery/ordered_hash'
140
+ class Hash < Hashery::OrderedHash
141
+ include Archetype::Functions::Hash
142
+ end
143
+ else
144
+ class Hash < ::Hash
145
+ include Archetype::Functions::Hash
146
+ end
147
+ end
133
148
  end
149
+
@@ -24,7 +24,8 @@ private
24
24
  def self.hash_to_list(hsh, depth = 0, separator = :comma)
25
25
  if hsh.is_a? Hash
26
26
  list = []
27
- hsh.each do |item|
27
+ hsh.each do |key, item|
28
+ item = [key, item]
28
29
  # if its a hash, convert it to a List
29
30
  if item.is_a? Hash or item.is_a? Array
30
31
  tmp = []
@@ -54,30 +55,56 @@ private
54
55
  #
55
56
  def self.list_to_hash(list, depth = 0, nest = [], additives = [])
56
57
  list = list.to_a
57
- hsh = {}
58
+ previous = nil
59
+ hsh = Archetype::Hash.new
58
60
  list.each do |item|
59
61
  item = item.to_a
62
+
60
63
  # convert the key to a string and strip off quotes
61
- key = to_str(item[0]).gsub(/\A"|"\Z/, '')
64
+ key = to_str(item[0], ' ' , :quotes)
65
+ # capture the value
62
66
  value = item[1]
67
+
63
68
  if key != 'nil'
69
+ if is_value(value, :blank)
70
+ if previous.nil?
71
+ previous = key
72
+ next
73
+ else
74
+ value = item[0]
75
+ key = previous
76
+ previous = nil
77
+ end
78
+ elsif not previous.nil?
79
+ # if we got here, something is wrong with the structure
80
+ list.shift if to_str(list[0]) == previous # remove the first item if it's the previous key, which is now the parent key
81
+ list = list[0].to_a # now the remaining items were munged, so split them out
82
+ hsh = Archetype::Hash.new
83
+ hsh[previous] = list_to_hash(list, depth - 1, nest, additives)
84
+ return hsh
85
+ end
86
+ end
87
+
88
+ # update the hash if we have a valid key and hash
89
+ if key != 'nil' and not is_value(value, :blank)
64
90
  # check if if it's a nesting hash
65
91
  nested = nest.include?(key)
66
92
  # if it's nested or we haven't reached out depth, recurse
67
93
  if nested or depth > 0
68
94
  value = list_to_hash(value, nested ? depth + 1 : depth - 1, nest, additives)
69
95
  end
70
- # update the hash key
71
- if not is_value(value, :blank)
72
- if additives.include?(key)
73
- hsh[key] ||= []
74
- hsh[key].push(value)
75
- else
76
- hsh[key] = value
77
- end
96
+
97
+ if additives.include?(key)
98
+ hsh[key] ||= []
99
+ hsh[key].push(value)
100
+ else
101
+ hsh[key] = value
78
102
  end
79
103
  end
80
104
  end
105
+
106
+ logger.record(:warning, "one of your data structures is ambiguous, please double check near `#{previous}`") if not previous.nil?
107
+
81
108
  return hsh
82
109
  end
83
110
 
@@ -90,8 +117,12 @@ private
90
117
  # *Returns*:
91
118
  # - {String} the converted String
92
119
  #
93
- def self.to_str(value, separator = ' ')
94
- return value.is_a?(String) ? value : ((value.to_a).each{ |i| i.is_a?(String) ? i : i.value }).join(separator || '')
120
+ def self.to_str(value, separator = ' ', strip = nil)
121
+ if not value.is_a?(String)
122
+ value = ((value.to_a).each{ |i| i.nil? ? 'nil' : (i.is_a?(String) ? i : i.value) }).join(separator || '')
123
+ end
124
+ strip = /\A"|"\Z/ if strip == :quotes
125
+ return strip.nil? ? value : value.gsub(strip, '')
95
126
  end
96
127
 
97
128
  #
@@ -109,11 +140,13 @@ private
109
140
  when :blank
110
141
  is_it = false
111
142
  value = value.value if value.is_a?(Sass::Script::String)
143
+ is_it = value.nil?
112
144
  is_it = value.empty? if value.is_a?(String)
113
145
  is_it = value.to_a.empty? if value.is_a?(Sass::Script::List) or value.is_a?(Array)
114
146
  when :nil
115
147
  is_it = false
116
148
  value = value.value if value.is_a?(Sass::Script::String)
149
+ is_it = value.nil?
117
150
  is_it = value == 'nil' if value.is_a?(String)
118
151
  is_it = to_str(value) == 'nil' if value.is_a?(Sass::Script::List) or value.is_a?(Array)
119
152
  end
@@ -20,7 +20,7 @@ private
20
20
  #
21
21
  def self.tokenize(theme, extensions, id, modifiers, state)
22
22
  return nil if extensions.nil? or id.nil?
23
- return "#{id}::#{(modifiers.to_a.sort + extensions).join('$')}::#{state}".hash
23
+ return "#{id}::#{(modifiers.to_a.sort + extensions).join('$')}::#{state}"
24
24
  end
25
25
 
26
26
  #
@@ -50,7 +50,7 @@ private
50
50
  end
51
51
 
52
52
  #
53
- # invalidate the entire memoizer for the theme
53
+ # invalidate the memoizer for the theme
54
54
  #
55
55
  # *Parameters*:
56
56
  # - <tt>theme</tt> {String} the theme name
@@ -58,4 +58,12 @@ private
58
58
  def self.clear(theme)
59
59
  @components[theme] = {}
60
60
  end
61
+
62
+
63
+ #
64
+ # resets the entire memoizer
65
+ #
66
+ def self.reset!
67
+ @components = {}
68
+ end
61
69
  end
@@ -6,7 +6,7 @@ require 'archetype/functions/helpers'
6
6
  module Archetype::SassExtensions::Lists
7
7
  #
8
8
  # replace an index in a list
9
- #
9
+ #
10
10
  # *Parameters*:
11
11
  # - <tt>$list</tt> {List} the list to replace from
12
12
  # - <tt>$value</tt> {\*} the value to replace (if nil, it's a removal)
@@ -47,8 +47,8 @@ module Archetype::SassExtensions::Lists
47
47
  def list_remove(list, idx = false, separator = nil)
48
48
  return list_replace(list, idx, nil, separator)
49
49
  end
50
- Sass::Script::Functions.declare :list_replace, [:list, :idx]
51
- Sass::Script::Functions.declare :list_replace, [:list, :idx, :separator]
50
+ Sass::Script::Functions.declare :list_remove, [:list, :idx]
51
+ Sass::Script::Functions.declare :list_remove, [:list, :idx, :separator]
52
52
 
53
53
  #
54
54
  # insert an item into a list
@@ -67,41 +67,9 @@ module Archetype::SassExtensions::Lists
67
67
  return list if (not idx or idx == Sass::Script::Bool.new(false)) or value.nil?
68
68
  return list_replace(list, idx, value, separator, -1)
69
69
  end
70
- Sass::Script::Functions.declare :list_replace, [:list, :idx]
71
- Sass::Script::Functions.declare :list_replace, [:list, :idx, :value]
72
- Sass::Script::Functions.declare :list_replace, [:list, :idx, :value, :separator]
73
-
74
- #
75
- # sort a list
76
- #
77
- # *Parameters*:
78
- # - <tt>$list</tt> {List} the list to sort
79
- # - <tt>$reverse</tt> {Boolean} sort the list in reverse order
80
- # *Returns*:
81
- # - {List} the sorted list
82
- #
83
- # TODO - this is failing, fix this
84
- #def list_sort(list, reverse = false)
85
- # separator = list.separator if list.is_a?(Sass::Script::List)
86
- # list = list.to_a.sort
87
- # list = list.reverse if (reverse == Sass::Script::Bool.new(true))
88
- # return Sass::Script::List.new(list, separator)
89
- #end
90
-
91
- #
92
- # reverse order a list
93
- #
94
- # *Parameters*:
95
- # - <tt>$list</tt> {List} the list to reverse
96
- # *Returns*:
97
- # - {List} the reversed list
98
- #
99
- # TODO - this is failing, fix this
100
- #def list_reverse(list)
101
- # separator = list.separator if list.is_a?(Sass::Script::List)
102
- # list = list.to_a.reverse
103
- # return Sass::Script::List.new(list, separator)
104
- #end
70
+ Sass::Script::Functions.declare :list_insert, [:list, :idx]
71
+ Sass::Script::Functions.declare :list_insert, [:list, :idx, :value]
72
+ Sass::Script::Functions.declare :list_insert, [:list, :idx, :value, :separator]
105
73
 
106
74
  #
107
75
  # add values(s) to a list
@@ -176,7 +144,7 @@ module Archetype::SassExtensions::Lists
176
144
  # - <tt>$haystack</tt> {List} input list
177
145
  # - <tt>$needle</tt> {List} the value(s) to search for
178
146
  # *Returns*:
179
- # - {Number|Bool} if an item is found, returns the index, otherwise returns false
147
+ # - {Number|Boolean} if an item is found, returns the index, otherwise returns false
180
148
  #
181
149
  def index2(haystack, needle)
182
150
  haystack = haystack.to_a
@@ -210,14 +178,14 @@ module Archetype::SassExtensions::Lists
210
178
  # *Parameters*:
211
179
  # - <tt>$list</tt> {List} the list to search in
212
180
  # - <tt>$key</tt> {String} the key identifier (name)
213
- # - <tt>$strict</tt> {Bool} if true, does a strict match against the key
181
+ # - <tt>$strict</tt> {Boolean} if true, does a strict match against the key
214
182
  # *Returns*:
215
183
  # - {*} the data associated with $key
216
184
  #
217
185
  def associative(list, key, strict = false)
218
186
  separator = list.separator if list.is_a?(Sass::Script::List)
219
187
  list = helpers.list_to_hash(list)
220
- item = list[helpers.to_str(key)]
188
+ item = list[helpers.to_str(key, ' ' , :quotes)]
221
189
  item ||= list.first[1] if not strict
222
190
  return Sass::Script::List.new([], separator) if item.nil?
223
191
  return helpers.hash_to_list(item, 0, separator) if item.is_a?(Array) or item.is_a?(Hash)
@@ -243,7 +211,33 @@ module Archetype::SassExtensions::Lists
243
211
  list = list.rmerge(extender)
244
212
  return helpers.hash_to_list(list, 0, separator)
245
213
  end
246
- Sass::Script::Functions.declare :list_extend, [:list, :extender]
214
+ Sass::Script::Functions.declare :associative_merge, [:list, :extender]
215
+
216
+ #
217
+ # given a string of styles, convert it into a key-value pair list
218
+ #
219
+ # *Parameters*:
220
+ # - <tt>$string</tt> {String} the string to convert
221
+ # *Returns*:
222
+ # - <tt>$list</tt> {List} the converted list of styles
223
+ #
224
+ def _style_string_to_list(string = '')
225
+ # convert to string and strip all comments
226
+ string = helpers.to_str(string, ' ').gsub(/\/\*[^\*\/]*\*\//, '')
227
+ # then split it on each rule
228
+ tmp = string.split(';')
229
+ styles = []
230
+ # and for each rule break it into it's key-value pairs
231
+ tmp.each do |rule|
232
+ kvp = []
233
+ rule.split(':').each do |str|
234
+ kvp.push Sass::Script::String.new(str)
235
+ end
236
+ styles.push Sass::Script::List.new(kvp, :comma)
237
+ end
238
+ # the recompose the list
239
+ return Sass::Script::List.new(styles, :comma)
240
+ end
247
241
 
248
242
  private
249
243
  def helpers