sassc 0.0.7 → 0.0.8

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