diff --git a/lib/sassc/native/native_functions_api.rb b/lib/sassc/native/native_functions_api.rb index 5c30943a..920f7f5b 100644 --- a/lib/sassc/native/native_functions_api.rb +++ b/lib/sassc/native/native_functions_api.rb @@ -26,7 +26,10 @@ module Native # ADDAPI union Sass_Value* ADDCALL sass_make_map (size_t len); attach_function :sass_make_map, [:size_t], :sass_value_ptr - + + # ADDAPI union Sass_Value* ADDCALL sass_make_list (size_t len, enum Sass_Separator sep) + attach_function :sass_make_list, [:size_t, SassSeparator], :sass_value_ptr + # ADDAPI union Sass_Value* ADDCALL sass_make_boolean (boolean val); attach_function :sass_make_boolean, [:bool], :sass_value_ptr @@ -45,6 +48,15 @@ module Native # ADDAPI size_t ADDCALL sass_map_get_length (const union Sass_Value* v); attach_function :sass_map_get_length, [:sass_value_ptr], :size_t + # ADDAPI union Sass_Value* ADDCALL sass_list_get_value (const union Sass_Value* v, size_t i); + attach_function :sass_list_get_value, [:sass_value_ptr, :size_t], :sass_value_ptr + + # ADDAPI void ADDCALL sass_list_set_value (union Sass_Value* v, size_t i, union Sass_Value* value); + attach_function :sass_list_set_value, [:sass_value_ptr, :size_t, :sass_value_ptr], :void + + # ADDAPI size_t ADDCALL sass_list_get_length (const union Sass_Value* v); + attach_function :sass_list_get_length, [:sass_value_ptr], :size_t + # ADDAPI union Sass_Value* ADDCALL sass_make_error (const char* msg); attach_function :sass_make_error, [:string], :sass_value_ptr diff --git a/lib/sassc/script/value_conversion.rb b/lib/sassc/script/value_conversion.rb index 895a39ae..5d07e567 100644 --- a/lib/sassc/script/value_conversion.rb +++ b/lib/sassc/script/value_conversion.rb @@ -41,6 +41,13 @@ def self.from_native(native_value, options) argument = Sass::Script::Value::Map.new values argument + when :sass_list + length = Native::list_get_length(native_value) + items = (0...length).map do |index| + native_item = Native::list_get_value(native_value, index) + from_native(native_item, options) + end + Sass::Script::Value::List.new(items, :space) else raise UnsupportedValue.new("Sass argument of type #{value_tag} unsupported") end @@ -56,6 +63,8 @@ def self.to_native(value) Number.new(value).to_native when "Map" Map.new(value).to_native + when "List" + List.new(value).to_native when "Bool" Bool.new(value).to_native else @@ -71,4 +80,5 @@ def self.to_native(value) require_relative "value_conversion/number" require_relative "value_conversion/color" require_relative "value_conversion/map" -require_relative "value_conversion/bool" \ No newline at end of file +require_relative "value_conversion/list" +require_relative "value_conversion/bool" diff --git a/lib/sassc/script/value_conversion/list.rb b/lib/sassc/script/value_conversion/list.rb new file mode 100644 index 00000000..7bbcc0c2 --- /dev/null +++ b/lib/sassc/script/value_conversion/list.rb @@ -0,0 +1,23 @@ +module SassC + module Script + module ValueConversion + SEPARATORS = { + space: :sass_space, + comma: :sass_comma + } + + class List < Base + def to_native + list = @value.to_a + sep = SEPARATORS.fetch(@value.separator) + native_list = Native::make_list(list.size, sep) + list.each_with_index do |item, index| + native_item = ValueConversion.to_native(item) + Native::list_set_value(native_list, index, native_item) + end + native_list + end + end + end + end +end diff --git a/test/functions_test.rb b/test/functions_test.rb index 420a2636..87713035 100644 --- a/test/functions_test.rb +++ b/test/functions_test.rb @@ -119,6 +119,7 @@ def test_functions_may_accept_sass_color_type end def test_function_with_unsupported_tag + skip('What are other unsupported tags?') engine = Engine.new("div {url: function_with_unsupported_tag(());}") exception = assert_raises(SassC::SyntaxError) do @@ -166,6 +167,23 @@ def test_function_that_takes_a_sass_map CSS end + def test_function_that_returns_a_sass_list + assert_sass <<-SCSS, <<-CSS + $my-list: returns-sass-list(); + div { width: nth( $my-list, 2 ); } + SCSS + div { width: 20; } + CSS + end + + def test_function_that_takes_a_sass_list + assert_sass <<-SCSS, <<-CSS + div { width: nth(inspect-list((10 20 30)), 2); } + SCSS + div { width: 20; } + CSS + end + private def assert_sass(sass, expected_css) @@ -250,6 +268,11 @@ def inspect_map ( argument ) return argument end + def inspect_list(argument) + raise StandardError.new "passed value is not a Sass::Script::Value::List" unless argument.is_a? Sass::Script::Value::List + return argument + end + def returns_sass_value return Sass::Script::Value::Color.new(red: 0, green: 0, blue: 0) end @@ -263,6 +286,13 @@ def returns_sass_map return map end + def returns_sass_list + numbers = [10, 20, 30].map do |n| + Sass::Script::Value::Number.new(n, '') + end + Sass::Script::Value::List.new(numbers, :space) + end + module Compass def stylesheet_path(path) Script::String.new("/css/#{path.value}", :identifier)