sassc 0.0.7 → 0.0.8

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a212192b55be4390eb3420aefcbb2b9c0240852
4
- data.tar.gz: 24aa593a9b043f454dd0da299cc18572eb480bee
3
+ metadata.gz: 993be013b98cbdeb9f4a4bcb1839cbd5438e0812
4
+ data.tar.gz: 5bb1391019da6ae3c231116248d1fdfe8ab06c84
5
5
  SHA512:
6
- metadata.gz: e04ff420d46edf08fc4cf3a330d35f0212ddf294e6228e20768d86c9cc9ef628863477e34e3f143c2fd546a9979781701a3c991d44cb8c908f6062eceef6c1ca
7
- data.tar.gz: 2a356fd1f4f954d4cd8a60c9e79eba076398d60afa48822fe12f51edf58738ea79bf83f4eb60dcb07395d9ebcdba7a937277f4e6d6a59bb37e0561633c4816fd
6
+ metadata.gz: 9c516bab484b989c7c560ed4463ade3f4064ed3206a3eb58d43ae062a81778543b243c9f4531eb676b995fcd5062bf7d8ea44c9296afd2c6221040fbcf584cc7
7
+ data.tar.gz: 81a118cc6d8d05814a6a740666e1b3c968cb1ee654d9132655cf0a6a866a9626ef9f70b979afe461ef1144d687b5a556b55b83c1eb805a684423115b9bd61800
data/lib/sassc.rb CHANGED
@@ -4,6 +4,7 @@ end
4
4
  require_relative "sassc/version"
5
5
  require_relative "sassc/native"
6
6
  require_relative "sassc/engine"
7
+ require_relative "sassc/importer"
7
8
  require_relative "sassc/script"
8
9
  require_relative "sassc/cache_stores"
9
10
  require_relative "sassc/dependency"
data/lib/sassc/engine.rb CHANGED
@@ -16,6 +16,8 @@ module SassC
16
16
  Native.option_set_input_path(options, filename) if filename
17
17
  Native.option_set_include_path(options, load_paths)
18
18
 
19
+ importer.setup(options) if importer
20
+
19
21
  status = Script.setup_custom_functions(options, @options) do
20
22
  Native.compile_data_context(data_context)
21
23
  end
@@ -53,6 +55,16 @@ module SassC
53
55
  @options[:syntax] && @options[:syntax].to_sym == :sass
54
56
  end
55
57
 
58
+ def importer
59
+ @importer ||= begin
60
+ if @options[:importer]
61
+ @options[:importer].new
62
+ else
63
+ nil
64
+ end
65
+ end
66
+ end
67
+
56
68
  def load_paths
57
69
  paths = @options[:load_paths]
58
70
  paths.join(":") if paths
@@ -0,0 +1,4 @@
1
+ module SassC
2
+ class ImportHandler
3
+ end
4
+ end
@@ -0,0 +1,57 @@
1
+ module SassC
2
+ class Importer
3
+ def imports(path)
4
+ # A custom importer must override this method.
5
+ raise NotImplementedError
6
+ end
7
+
8
+ def setup(native_options)
9
+ @function = FFI::Function.new(:pointer, [:string, :pointer, :pointer]) do |path, prev, cookie|
10
+ imports = [*imports(path)]
11
+ self.class.imports_to_native(imports)
12
+ end
13
+
14
+ callback = SassC::Native.make_importer(@function, nil)
15
+ SassC::Native.option_set_importer(native_options, callback)
16
+ end
17
+
18
+ def self.empty_imports
19
+ SassC::Native.make_import_list(0)
20
+ end
21
+
22
+ def self.imports_to_native(imports)
23
+ import_list = SassC::Native.make_import_list(imports.size)
24
+
25
+ imports.each_with_index do |import, i|
26
+ source = import.source ? native_string(import.source) : nil
27
+ source_map_path = nil
28
+
29
+ entry = SassC::Native.make_import_entry(import.path, source, source_map_path)
30
+ SassC::Native.import_set_list_entry(import_list, i, entry)
31
+ end
32
+
33
+ import_list
34
+ end
35
+
36
+ def self.native_string(string)
37
+ string += "\0"
38
+ data = SassC::Native::LibC.malloc(string.size)
39
+ data.write_string(string)
40
+ data
41
+ end
42
+
43
+ class Import
44
+ attr_accessor :path, :source, :source_map_path
45
+
46
+ def initialize(path, source: nil, source_map_path: nil)
47
+ @path = path
48
+ @source = source
49
+ @source_map_path = source_map_path
50
+ end
51
+
52
+ def to_s
53
+ "Import: #{path} #{source} #{source_map_path}"
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/sassc/native.rb CHANGED
@@ -19,11 +19,17 @@ module SassC
19
19
  typedef :pointer, :sass_c_function_callback_ptr
20
20
  typedef :pointer, :sass_value_ptr
21
21
 
22
+ typedef :pointer, :sass_import_list_ptr
23
+ typedef :pointer, :sass_importer
24
+ typedef :pointer, :sass_import_ptr
25
+
22
26
  callback :sass_c_function, [:pointer, :pointer], :pointer
27
+ callback :sass_c_import_function, [:pointer, :pointer, :pointer], :pointer
23
28
 
24
29
  require_relative "native/sass_input_style"
25
30
  require_relative "native/sass_output_style"
26
31
  require_relative "native/string_list"
32
+ require_relative "native/lib_c"
27
33
 
28
34
  # Remove the redundant "sass_" from the beginning of every method name
29
35
  def self.attach_function(*args)
@@ -0,0 +1,19 @@
1
+ module SassC
2
+ module Native
3
+ module LibC
4
+ extend FFI::Library
5
+ ffi_lib FFI::Library::LIBC
6
+
7
+ # memory allocators
8
+ attach_function :malloc, [:size_t], :pointer
9
+ # attach_function :calloc, [:size_t], :pointer
10
+ # attach_function :valloc, [:size_t], :pointer
11
+ # attach_function :realloc, [:pointer, :size_t], :pointer
12
+ # attach_function :free, [:pointer], :void
13
+
14
+ # memory movers
15
+ # attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
16
+ # attach_function :bcopy, [:pointer, :pointer, :size_t], :void
17
+ end
18
+ end
19
+ end
@@ -98,6 +98,7 @@ module SassC
98
98
  # ADDAPI void ADDCALL sass_option_set_include_path (struct Sass_Options* options, const char* include_path);
99
99
  # ADDAPI void ADDCALL sass_option_set_source_map_file (struct Sass_Options* options, const char* source_map_file);
100
100
  # ADDAPI void ADDCALL sass_option_set_c_functions (struct Sass_Options* options, Sass_C_Function_List c_functions);
101
+ # ADDAPI void ADDCALL sass_option_set_importer (struct Sass_Options* options, Sass_C_Import_Callback importer);
101
102
  attach_function :sass_option_set_precision, [:sass_options_ptr, :int], :void
102
103
  attach_function :sass_option_set_output_style, [:sass_options_ptr, SassOutputStyle], :void
103
104
  attach_function :sass_option_set_source_comments, [:sass_options_ptr, :bool], :void
@@ -111,7 +112,7 @@ module SassC
111
112
  attach_function :sass_option_set_include_path, [:sass_options_ptr, :string], :void
112
113
  attach_function :sass_option_set_source_map_file, [:sass_options_ptr, :string], :void
113
114
  attach_function :sass_option_set_c_functions, [:sass_options_ptr, :pointer], :void
114
- # ADDAPI void ADDCALL sass_option_set_importer (struct Sass_Options* options, Sass_C_Import_Callback importer);
115
+ attach_function :sass_option_set_importer, [:sass_options_ptr, :sass_importer], :void
115
116
 
116
117
  # Getter for context
117
118
  # ADDAPI const char* ADDCALL sass_context_get_output_string (struct Sass_Context* ctx);
@@ -36,10 +36,47 @@ module SassC
36
36
  attach_function :sass_function_get_function, [:sass_c_function_callback_ptr], :sass_c_function
37
37
  attach_function :sass_function_get_cookie, [:sass_c_function_callback_ptr], :pointer
38
38
 
39
+ # Creators for custom importer callback (with some additional pointer)
40
+ # The pointer is mostly used to store the callback into the actual binding
41
+ # ADDAPI Sass_C_Import_Callback ADDCALL sass_make_importer (Sass_C_Import_Fn, void* cookie);
42
+ attach_function :sass_make_importer, [:sass_c_import_function, :pointer], :sass_importer
39
43
 
40
- #callback :sass_c_function, [SassValue.ptr, :pointer], SassValue.ptr
41
- Callback = FFI::Function.new(:pointer, [:pointer, :pointer]) do |s_args, cookie|
42
- SassC::Native.make_number(43, "px")
43
- end
44
+ # Getters for import function descriptors
45
+ # ADDAPI Sass_C_Import_Fn ADDCALL sass_import_get_function (Sass_C_Import_Callback fn);
46
+ # ADDAPI void* ADDCALL sass_import_get_cookie (Sass_C_Import_Callback fn);
47
+
48
+ # Deallocator for associated memory
49
+ # ADDAPI void ADDCALL sass_delete_importer (Sass_C_Import_Callback fn);
50
+
51
+ # Creator for sass custom importer return argument list
52
+ # ADDAPI struct Sass_Import** ADDCALL sass_make_import_list (size_t length);
53
+ attach_function :sass_make_import_list, [:size_t], :sass_import_list_ptr
54
+
55
+ # Creator for a single import entry returned by the custom importer inside the list
56
+ # ADDAPI struct Sass_Import* ADDCALL sass_make_import_entry (const char* path, char* source, char* srcmap);
57
+ # ADDAPI struct Sass_Import* ADDCALL sass_make_import (const char* path, const char* base, char* source, char* srcmap);
58
+ attach_function :sass_make_import_entry, [:string, :pointer, :pointer], :sass_import_ptr
59
+
60
+ # Setters to insert an entry into the import list (you may also use [] access directly)
61
+ # Since we are dealing with pointers they should have a guaranteed and fixed size
62
+ # ADDAPI void ADDCALL sass_import_set_list_entry (struct Sass_Import** list, size_t idx, struct Sass_Import* entry);
63
+ attach_function :sass_import_set_list_entry, [:sass_import_list_ptr, :size_t, :sass_import_ptr], :void
64
+ # ADDAPI struct Sass_Import* ADDCALL sass_import_get_list_entry (struct Sass_Import** list, size_t idx);
65
+
66
+ # Getters for import entry
67
+ # ADDAPI const char* ADDCALL sass_import_get_path (struct Sass_Import*);
68
+ # ADDAPI const char* ADDCALL sass_import_get_base (struct Sass_Import*);
69
+ # ADDAPI const char* ADDCALL sass_import_get_source (struct Sass_Import*);
70
+ attach_function :sass_import_get_source, [:sass_import_ptr], :string
71
+ # ADDAPI const char* ADDCALL sass_import_get_srcmap (struct Sass_Import*);
72
+ # Explicit functions to take ownership of these items
73
+ # The property on our struct will be reset to NULL
74
+ # ADDAPI char* ADDCALL sass_import_take_source (struct Sass_Import*);
75
+ # ADDAPI char* ADDCALL sass_import_take_srcmap (struct Sass_Import*);
76
+
77
+ # Deallocator for associated memory (incl. entries)
78
+ # ADDAPI void ADDCALL sass_delete_import_list (struct Sass_Import**);
79
+ # Just in case we have some stray import structs
80
+ # ADDAPI void ADDCALL sass_delete_import (struct Sass_Import*);
44
81
  end
45
82
  end
data/lib/sassc/script.rb CHANGED
@@ -32,6 +32,7 @@ module SassC
32
32
  value = functs.send(custom_function, s)
33
33
 
34
34
  if value
35
+ value = String.new(String.unquote(value.to_s), value.type)
35
36
  value.to_native
36
37
  else
37
38
  String.new("").to_native
data/lib/sassc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module SassC
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -0,0 +1,87 @@
1
+ require_relative "test_helper"
2
+
3
+ class FunctionsTest < SassCTest
4
+ class CustomImporter < SassC::Importer
5
+ def imports(path)
6
+ if path =~ /styles/
7
+ [
8
+ Import.new("#{path}1.scss", source: "$var1: #000;"),
9
+ Import.new("#{path}2.scss")
10
+ ]
11
+ else
12
+ Import.new(path)
13
+ end
14
+ end
15
+ end
16
+
17
+ class NoFilesImporter < SassC::Importer
18
+ def imports(path)
19
+ []
20
+ end
21
+ end
22
+
23
+ def around
24
+ within_construct do |construct|
25
+ @construct = construct
26
+ yield
27
+ end
28
+
29
+ @construct = nil
30
+ end
31
+
32
+ def test_custom_importer_works
33
+ @construct.file("styles2.scss", ".hi { color: $var1; }")
34
+ @construct.file("fonts.scss", ".font { color: $var1; }")
35
+
36
+ data = <<SCSS
37
+ @import "styles";
38
+ @import "fonts";
39
+ SCSS
40
+
41
+ engine = SassC::Engine.new(data, {
42
+ importer: CustomImporter
43
+ })
44
+
45
+ assert_equal <<CSS, engine.render
46
+ .hi {
47
+ color: #000; }
48
+
49
+ .font {
50
+ color: #000; }
51
+ CSS
52
+ end
53
+
54
+ def test_dependency_list
55
+ @construct.file("styles2.scss", ".hi { color: $var1; }")
56
+ @construct.file("fonts.scss", ".font { color: $var1; }")
57
+
58
+ data = <<SCSS
59
+ @import "styles";
60
+ @import "fonts";
61
+ SCSS
62
+
63
+ engine = SassC::Engine.new(data, {
64
+ importer: CustomImporter
65
+ })
66
+ engine.render
67
+
68
+ dependencies = engine.dependencies.map(&:options).map { |o| o[:filename] }
69
+
70
+ # TODO: this behavior is kind of weird (styles1.scss is not included)
71
+ # not sure why.
72
+
73
+ assert_equal [
74
+ "fonts.scss",
75
+ "styles",
76
+ "styles2.scss"
77
+ ], dependencies
78
+ end
79
+
80
+ def test_custom_importer_works_with_no_files
81
+ engine = SassC::Engine.new("@import 'fake.scss';", {
82
+ importer: NoFilesImporter
83
+ })
84
+
85
+ assert_equal "", engine.render
86
+ end
87
+ end
@@ -1,6 +1,12 @@
1
1
  require_relative "test_helper"
2
2
 
3
3
  class FunctionsTest < SassCTest
4
+ SassString = Struct.new(:value, :type) do
5
+ def to_s
6
+ value
7
+ end
8
+ end
9
+
4
10
  module ::SassC::Script::Functions
5
11
  def javascript_path(path)
6
12
  ::SassC::Script::String.new("/js/#{path.value}", :string)
@@ -10,6 +16,10 @@ class FunctionsTest < SassCTest
10
16
  nil
11
17
  end
12
18
 
19
+ def sass_return_path(path)
20
+ return SassString.new("'#{path.value}'", :string)
21
+ end
22
+
13
23
  module Compass
14
24
  def stylesheet_path(path)
15
25
  ::SassC::Script::String.new("/css/#{path.value}", :identifier)
@@ -18,9 +28,18 @@ class FunctionsTest < SassCTest
18
28
  include Compass
19
29
  end
20
30
 
31
+ def test_functions_may_return_sass_string_type
32
+ engine = ::SassC::Engine.new("div {url: url(sass_return_path('foo.svg'));}")
33
+
34
+ assert_equal <<-EOS, engine.render
35
+ div {
36
+ url: url("foo.svg"); }
37
+ EOS
38
+ end
39
+
21
40
  def test_functions_work
22
41
  filename = fixture_path('paths.scss')
23
- assert data = File.read(filename)
42
+ data = File.read(filename)
24
43
 
25
44
  engine = ::SassC::Engine.new(data, {
26
45
  filename: filename,
@@ -44,9 +63,6 @@ div {
44
63
  end
45
64
 
46
65
  def test_function_with_no_return_value
47
- filename = fixture_path('paths.scss')
48
- assert data = File.read(filename)
49
-
50
66
  engine = ::SassC::Engine.new("div {url: url(no-return-path('foo.svg'));}")
51
67
 
52
68
  assert_equal <<-EOS, engine.render
data/test/native_test.rb CHANGED
@@ -57,9 +57,13 @@ module NativeTest
57
57
 
58
58
  random_thing = FFI::MemoryPointer.from_string("hi")
59
59
 
60
+ funct = FFI::Function.new(:pointer, [:pointer, :pointer]) do |s_args, cookie|
61
+ SassC::Native.make_number(43, "px")
62
+ end
63
+
60
64
  callback = SassC::Native.make_function(
61
65
  "foo()",
62
- SassC::Native::Callback,
66
+ funct,
63
67
  random_thing
64
68
  )
65
69
 
@@ -71,7 +75,7 @@ module NativeTest
71
75
 
72
76
  first_list_entry = SassC::Native.function_get_list_entry(list, 0)
73
77
  assert_equal SassC::Native.function_get_function(first_list_entry),
74
- SassC::Native::Callback
78
+ funct
75
79
  assert_equal SassC::Native.function_get_signature(first_list_entry),
76
80
  "foo()"
77
81
  assert_equal SassC::Native.function_get_cookie(first_list_entry),
@@ -164,5 +168,38 @@ module NativeTest
164
168
  assert_match /import_parent.scss/, included_files[1]
165
169
  assert_match /styles.scss/, included_files[2]
166
170
  end
171
+
172
+ def test_custom_importer
173
+ @construct.file("not_included.scss", "$size: $var + 25;")
174
+ @construct.file("styles.scss", "@import 'import.scss'; .hi { width: $size; }")
175
+
176
+ @file_context = SassC::Native.make_file_context("styles.scss")
177
+ context = SassC::Native.file_context_get_context(@file_context)
178
+ options = SassC::Native.context_get_options(context)
179
+
180
+ funct = FFI::Function.new(:pointer, [:pointer, :pointer, :pointer]) do |url, prev, cookie|
181
+ list = SassC::Native.make_import_list(2)
182
+
183
+ str = "$var: 5px;\0"
184
+ data = SassC::Native::LibC.malloc(str.size)
185
+ data.write_string(str)
186
+
187
+ entry0 = SassC::Native.make_import_entry("fake_includ.scss", data, nil)
188
+ entry1 = SassC::Native.make_import_entry("not_included.scss", nil, nil)
189
+ SassC::Native.import_set_list_entry(list, 0, entry0)
190
+ SassC::Native.import_set_list_entry(list, 1, entry1)
191
+ list
192
+ end
193
+
194
+ callback = SassC::Native.make_importer(funct, nil)
195
+
196
+ SassC::Native.option_set_importer(options, callback)
197
+
198
+ status = SassC::Native.compile_file_context(@file_context)
199
+ assert_equal 0, status
200
+
201
+ css = SassC::Native.context_get_output_string(context)
202
+ assert_equal SAMPLE_CSS_OUTPUT, css
203
+ end
167
204
  end
168
205
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sassc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Boland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-02 00:00:00.000000000 Z
11
+ date: 2015-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -244,7 +244,10 @@ files:
244
244
  - lib/sassc/dependency.rb
245
245
  - lib/sassc/engine.rb
246
246
  - lib/sassc/error.rb
247
+ - lib/sassc/import_handler.rb
248
+ - lib/sassc/importer.rb
247
249
  - lib/sassc/native.rb
250
+ - lib/sassc/native/lib_c.rb
248
251
  - lib/sassc/native/native_context_api.rb
249
252
  - lib/sassc/native/native_functions_api.rb
250
253
  - lib/sassc/native/sass_input_style.rb
@@ -256,6 +259,7 @@ files:
256
259
  - lib/sassc/script/string.rb
257
260
  - lib/sassc/version.rb
258
261
  - sassc.gemspec
262
+ - test/custom_importer_test.rb
259
263
  - test/engine_test.rb
260
264
  - test/fixtures/paths.scss
261
265
  - test/functions_test.rb
@@ -287,6 +291,7 @@ signing_key:
287
291
  specification_version: 4
288
292
  summary: Use libsass with Ruby!
289
293
  test_files:
294
+ - test/custom_importer_test.rb
290
295
  - test/engine_test.rb
291
296
  - test/fixtures/paths.scss
292
297
  - test/functions_test.rb