sassc 2.1.0.pre1-x86-linux

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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +11 -0
  5. data/CHANGELOG.md +66 -0
  6. data/CODE_OF_CONDUCT.md +10 -0
  7. data/Gemfile +2 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +68 -0
  10. data/Rakefile +30 -0
  11. data/lib/sassc.rb +57 -0
  12. data/lib/sassc/dependency.rb +17 -0
  13. data/lib/sassc/engine.rb +139 -0
  14. data/lib/sassc/error.rb +37 -0
  15. data/lib/sassc/functions_handler.rb +75 -0
  16. data/lib/sassc/import_handler.rb +50 -0
  17. data/lib/sassc/importer.rb +31 -0
  18. data/lib/sassc/native.rb +70 -0
  19. data/lib/sassc/native/lib_c.rb +21 -0
  20. data/lib/sassc/native/native_context_api.rb +147 -0
  21. data/lib/sassc/native/native_functions_api.rb +164 -0
  22. data/lib/sassc/native/sass2scss_api.rb +10 -0
  23. data/lib/sassc/native/sass_input_style.rb +13 -0
  24. data/lib/sassc/native/sass_output_style.rb +12 -0
  25. data/lib/sassc/native/sass_value.rb +97 -0
  26. data/lib/sassc/native/string_list.rb +10 -0
  27. data/lib/sassc/sass_2_scss.rb +9 -0
  28. data/lib/sassc/script.rb +19 -0
  29. data/lib/sassc/script/functions.rb +8 -0
  30. data/lib/sassc/script/value.rb +137 -0
  31. data/lib/sassc/script/value/bool.rb +32 -0
  32. data/lib/sassc/script/value/color.rb +95 -0
  33. data/lib/sassc/script/value/list.rb +136 -0
  34. data/lib/sassc/script/value/map.rb +69 -0
  35. data/lib/sassc/script/value/number.rb +389 -0
  36. data/lib/sassc/script/value/string.rb +96 -0
  37. data/lib/sassc/script/value_conversion.rb +69 -0
  38. data/lib/sassc/script/value_conversion/base.rb +13 -0
  39. data/lib/sassc/script/value_conversion/bool.rb +13 -0
  40. data/lib/sassc/script/value_conversion/color.rb +18 -0
  41. data/lib/sassc/script/value_conversion/list.rb +25 -0
  42. data/lib/sassc/script/value_conversion/map.rb +21 -0
  43. data/lib/sassc/script/value_conversion/number.rb +13 -0
  44. data/lib/sassc/script/value_conversion/string.rb +17 -0
  45. data/lib/sassc/util.rb +231 -0
  46. data/lib/sassc/util/normalized_map.rb +117 -0
  47. data/lib/sassc/version.rb +5 -0
  48. data/sassc.gemspec +57 -0
  49. data/test/custom_importer_test.rb +127 -0
  50. data/test/engine_test.rb +314 -0
  51. data/test/error_test.rb +29 -0
  52. data/test/fixtures/paths.scss +10 -0
  53. data/test/functions_test.rb +303 -0
  54. data/test/native_test.rb +213 -0
  55. data/test/output_style_test.rb +107 -0
  56. data/test/sass_2_scss_test.rb +14 -0
  57. data/test/test_helper.rb +45 -0
  58. metadata +242 -0
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ # ADDAPI char* ADDCALL sass2scss (const char* sass, const int options);
6
+ attach_function :sass2scss, [:string, :int], :string
7
+
8
+ # ADDAPI const char* ADDCALL sass2scss_version(void);
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ SassInputStyle = enum(
6
+ :sass_context_null,
7
+ :sass_context_file,
8
+ :sass_context_data,
9
+ :sass_context_folder
10
+ )
11
+ end
12
+ end
13
+
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ SassOutputStyle = enum(
6
+ :sass_style_nested,
7
+ :sass_style_expanded,
8
+ :sass_style_compact,
9
+ :sass_style_compressed
10
+ )
11
+ end
12
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ class SassValue < FFI::Union; end
6
+
7
+ SassTag = enum(
8
+ :sass_boolean,
9
+ :sass_number,
10
+ :sass_color,
11
+ :sass_string,
12
+ :sass_list,
13
+ :sass_map,
14
+ :sass_null,
15
+ :sass_error,
16
+ :sass_warning
17
+ )
18
+
19
+ SassSeparator = enum(
20
+ :sass_comma,
21
+ :sass_space
22
+ )
23
+
24
+ class SassUnknown < FFI::Struct
25
+ layout :tag, SassTag
26
+ end
27
+
28
+ class SassBoolean < FFI::Struct
29
+ layout :tag, SassTag,
30
+ :value, :bool
31
+ end
32
+
33
+ class SassNumber < FFI::Struct
34
+ layout :tag, SassTag,
35
+ :value, :double,
36
+ :unit, :string
37
+ end
38
+
39
+ class SassColor < FFI::Struct
40
+ layout :tag, SassTag,
41
+ :r, :double,
42
+ :g, :double,
43
+ :b, :double,
44
+ :a, :double
45
+ end
46
+
47
+ class SassString < FFI::Struct
48
+ layout :tag, SassTag,
49
+ :value, :string
50
+ end
51
+
52
+ class SassList < FFI::Struct
53
+ layout :tag, SassTag,
54
+ :separator, SassSeparator,
55
+ :length, :size_t,
56
+ :values, :pointer
57
+ end
58
+
59
+ class SassMapPair < FFI::Struct
60
+ layout :key, SassValue.ptr,
61
+ :value, SassValue.ptr
62
+ end
63
+
64
+ class SassMap < FFI::Struct
65
+ layout :tag, SassTag,
66
+ :length, :size_t,
67
+ :pairs, SassMapPair.ptr
68
+ end
69
+
70
+ class SassNull < FFI::Struct
71
+ layout :tag, SassTag
72
+ end
73
+
74
+ class SassError < FFI::Struct
75
+ layout :tag, SassTag,
76
+ :message, :string
77
+ end
78
+
79
+ class SassWarning < FFI::Struct
80
+ layout :tag, SassTag,
81
+ :message, :string
82
+ end
83
+
84
+ class SassValue # < FFI::Union
85
+ layout :unknown, SassUnknown,
86
+ :boolean, SassBoolean,
87
+ :number, SassNumber,
88
+ :color, SassColor,
89
+ :string, SassString,
90
+ :list, SassList,
91
+ :map, SassMap,
92
+ :null, SassNull,
93
+ :error, SassError,
94
+ :warning, SassWarning
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Native
5
+ class StringList < FFI::Struct
6
+ layout :string_list, StringList.ptr,
7
+ :string, :string
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ class Sass2Scss
5
+ def self.convert(sass)
6
+ Native.sass2scss(sass, 0)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Script
5
+
6
+ def self.custom_functions
7
+ Functions.instance_methods.select do |function|
8
+ Functions.public_method_defined?(function)
9
+ end
10
+ end
11
+
12
+ def self.formatted_function_name(function_name)
13
+ params = Functions.instance_method(function_name).parameters
14
+ params = params.map { |param_type, name| "$#{name}#{': null' if param_type == :opt}" }.join(", ")
15
+ return "#{function_name}(#{params})"
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SassC
4
+ module Script
5
+ module Functions
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The abstract superclass for SassScript objects.
4
+ # Many of these methods, especially the ones that correspond to SassScript operations,
5
+ # are designed to be overridden by subclasses which may change the semantics somewhat.
6
+ # The operations listed here are just the defaults.
7
+
8
+ class SassC::Script::Value
9
+
10
+ # Returns the pure Ruby value of the value.
11
+ # The type of this value varies based on the subclass.
12
+ attr_reader :value
13
+
14
+ # The source range in the document on which this node appeared.
15
+ attr_accessor :source_range
16
+
17
+ # Creates a new value.
18
+ def initialize(value = nil)
19
+ value.freeze unless value.nil? || value == true || value == false
20
+ @value = value
21
+ @options = nil
22
+ end
23
+
24
+ # Sets the options hash for this node,
25
+ # as well as for all child nodes.
26
+ # See the official Sass reference for options.
27
+ attr_writer :options
28
+
29
+ # Returns the options hash for this node.
30
+ # Raises SassC::SyntaxError if the value was created
31
+ # outside of the parser and \{#to\_s} was called on it
32
+ def options
33
+ return @options if @options
34
+ raise SassC::SyntaxError.new("The #options attribute is not set on this #{self.class}. This error is probably occurring because #to_s was called on this value within a custom Sass function without first setting the #options attribute.")
35
+ end
36
+
37
+ # Returns the hash code of this value. Two objects' hash codes should be
38
+ # equal if the objects are equal.
39
+ def hash
40
+ value.hash
41
+ end
42
+
43
+ # True if this Value is the same as `other`
44
+ def eql?(other)
45
+ self == other
46
+ end
47
+
48
+ # Returns a system inspect value for this object
49
+ def inspect
50
+ value.inspect
51
+ end
52
+
53
+ # Returns `true` (all Values are truthy)
54
+ def to_bool
55
+ true
56
+ end
57
+
58
+ # Compares this object to `other`
59
+ def ==(other)
60
+ self.class == other.class && value == other.value
61
+ end
62
+
63
+ # Returns the integer value of this value.
64
+ # Raises SassC::SyntaxError if this value doesn’t implment integer conversion.
65
+ def to_i
66
+ raise SassC::SyntaxError.new("#{inspect} is not an integer.")
67
+ end
68
+
69
+ # @raise [SassC::SyntaxError] if this value isn't an integer
70
+ def assert_int!; to_i; end
71
+
72
+ # Returns the separator for this value. For non-list-like values or the
73
+ # empty list, this will be `nil`. For lists or maps, it will be `:space` or `:comma`.
74
+ def separator
75
+ nil
76
+ end
77
+
78
+ # Whether the value is surrounded by square brackets. For non-list values,
79
+ # this will be `false`.
80
+ def bracketed
81
+ false
82
+ end
83
+
84
+ # Returns the value of this Value as an array.
85
+ # Single Values are considered the same as single-element arrays.
86
+ def to_a
87
+ [self]
88
+ end
89
+
90
+ # Returns the value of this value as a hash. Most values don't have hash
91
+ # representations, but [Map]s and empty [List]s do.
92
+ #
93
+ # @return [Hash<Value, Value>] This value as a hash
94
+ # @raise [SassC::SyntaxError] if this value doesn't have a hash representation
95
+ def to_h
96
+ raise SassC::SyntaxError.new("#{inspect} is not a map.")
97
+ end
98
+
99
+ # Returns the string representation of this value
100
+ # as it would be output to the CSS document.
101
+ #
102
+ # @options opts :quote [String]
103
+ # The preferred quote style for quoted strings. If `:none`, strings are
104
+ # always emitted unquoted.
105
+ # @return [String]
106
+ def to_s(opts = {})
107
+ SassC::Util.abstract(self)
108
+ end
109
+ alias_method :to_sass, :to_s
110
+
111
+ # Returns `false` (all Values are truthy)
112
+ def null?
113
+ false
114
+ end
115
+
116
+ # Creates a new list containing `contents` but with the same brackets and
117
+ # separators as this object, when interpreted as a list.
118
+ #
119
+ # @param contents [Array<Value>] The contents of the new list.
120
+ # @param separator [Symbol] The separator of the new list. Defaults to \{#separator}.
121
+ # @param bracketed [Boolean] Whether the new list is bracketed. Defaults to \{#bracketed}.
122
+ # @return [Sass::Script::Value::List]
123
+ def with_contents(contents, separator: self.separator, bracketed: self.bracketed)
124
+ SassC::Script::Value::List.new(contents, separator: separator, bracketed: bracketed)
125
+ end
126
+
127
+ protected
128
+
129
+ # Evaluates the value.
130
+ #
131
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
132
+ # @return [Value] This value
133
+ def _perform(environment)
134
+ self
135
+ end
136
+
137
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A SassScript object representing a boolean (true or false) value.
4
+
5
+ class SassC::Script::Value::Bool < SassC::Script::Value
6
+
7
+ # The true value in SassScript.
8
+ # This is assigned before new is overridden below so that we use the default implementation.
9
+ TRUE = new(true)
10
+
11
+ # The false value in SassScript.
12
+ # This is assigned before new is overridden below so that we use the default implementation.
13
+ FALSE = new(false)
14
+
15
+ # We override object creation so that users of the core API
16
+ # will not need to know that booleans are specific constants.
17
+ # Tests `value` for truthiness and returns the TRUE or FALSE constant.
18
+ def self.new(value)
19
+ value ? TRUE : FALSE
20
+ end
21
+
22
+ # The pure Ruby value of this Boolean
23
+ attr_reader :value
24
+ alias_method :to_bool, :value
25
+
26
+ # Returns the string "true" or "false" for this value
27
+ def to_s(opts = {})
28
+ @value.to_s
29
+ end
30
+ alias_method :to_sass, :to_s
31
+
32
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A SassScript object representing a CSS color.
4
+ # This class provides a very bare-bones system for storing a RGB(A) or HSL(A)
5
+ # color and converting it to a CSS color function.
6
+ #
7
+ # If your Sass method accepts a color you will need to perform any
8
+ # needed color mathematics or transformations yourself.
9
+
10
+ class SassC::Script::Value::Color < SassC::Script::Value
11
+
12
+ attr_reader :red
13
+ attr_reader :green
14
+ attr_reader :blue
15
+ attr_reader :hue
16
+ attr_reader :saturation
17
+ attr_reader :lightness
18
+ attr_reader :alpha
19
+
20
+ # Creates a new color with (`red`, `green`, `blue`) or (`hue`, `saturation`, `lightness`
21
+ # values, plus an optional `alpha` transparency value.
22
+ def initialize(red:nil, green:nil, blue:nil, hue:nil, saturation:nil, lightness:nil, alpha:1.0)
23
+ if red && green && blue && alpha
24
+ @mode = :rgba
25
+ @red = SassC::Util.clamp(red.to_i, 0, 255)
26
+ @green = SassC::Util.clamp(green.to_i, 0, 255)
27
+ @blue = SassC::Util.clamp(blue.to_i, 0, 255)
28
+ @alpha = SassC::Util.clamp(alpha.to_f, 0.0, 1.0)
29
+ elsif hue && saturation && lightness && alpha
30
+ @mode = :hsla
31
+ @hue = SassC::Util.clamp(hue.to_i, 0, 360)
32
+ @saturation = SassC::Util.clamp(saturation.to_i, 0, 100)
33
+ @lightness = SassC::Util.clamp(lightness.to_i, 0, 100)
34
+ @alpha = SassC::Util.clamp(alpha.to_f, 0.0, 1.0)
35
+ else
36
+ raise SassC::UnsupportedValue, "Unable to determine color configuration for "
37
+ end
38
+ end
39
+
40
+ # Returns a CSS color declaration in the form
41
+ # `rgb(…)`, `rgba(…)`, `hsl(…)`, or `hsla(…)`.
42
+ def to_s
43
+ if rgba? && @alpha == 1.0
44
+ return "rgb(#{@red}, #{@green}, #{@blue})"
45
+ elsif rgba?
46
+ return "rgba(#{@red}, #{@green}, #{@blue}, #{alpha_string})"
47
+ elsif hsla? && @alpha == 1.0
48
+ return "hsl(#{@hue}, #{@saturation}%, #{@lightness}%)"
49
+ else # hsla?
50
+ return "hsla(#{@hue}, #{@saturation}%, #{@lightness}%, #{alpha_string})"
51
+ end
52
+ end
53
+
54
+ # True if this color has RGBA values
55
+ def rgba?
56
+ @mode == :rgba
57
+ end
58
+
59
+ # True if this color has HSLA values
60
+ def hlsa?
61
+ @mode == :hlsa
62
+ end
63
+
64
+ # Returns the alpha value of this color as a string
65
+ # and rounded to 8 decimal places.
66
+ def alpha_string
67
+ alpha.round(8).to_s
68
+ end
69
+
70
+ # Returns the values of this color in an array.
71
+ # Provided for compatibility between different SassC::Script::Value classes
72
+ def value
73
+ return [
74
+ red, green, blue,
75
+ hue, saturation, lightness,
76
+ alpha,
77
+ ].compact
78
+ end
79
+
80
+ # True if this Color is equal to `other_color`
81
+ def eql?(other_color)
82
+ unless other_color.is_a?(self.class)
83
+ raise ArgumentError, "No implicit conversion of #{other_color.class} to #{self.class}"
84
+ end
85
+ self.value == other_color.value
86
+ end
87
+ alias_method :==, :eql?
88
+
89
+ # Returns a numeric value for comparing two Color objects
90
+ # This method is used internally by the Hash class and is not the same as `.to_h`
91
+ def hash
92
+ value.hash
93
+ end
94
+
95
+ end