sassc 2.1.0.pre1-x86-linux

Sign up to get free protection for your applications and to get access to all the features.
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