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 +4 -4
- data/lib/sassc.rb +1 -0
- data/lib/sassc/engine.rb +12 -0
- data/lib/sassc/import_handler.rb +4 -0
- data/lib/sassc/importer.rb +57 -0
- data/lib/sassc/native.rb +6 -0
- data/lib/sassc/native/lib_c.rb +19 -0
- data/lib/sassc/native/native_context_api.rb +2 -1
- data/lib/sassc/native/native_functions_api.rb +41 -4
- data/lib/sassc/script.rb +1 -0
- data/lib/sassc/version.rb +1 -1
- data/test/custom_importer_test.rb +87 -0
- data/test/functions_test.rb +20 -4
- data/test/native_test.rb +39 -2
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 993be013b98cbdeb9f4a4bcb1839cbd5438e0812
|
4
|
+
data.tar.gz: 5bb1391019da6ae3c231116248d1fdfe8ab06c84
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c516bab484b989c7c560ed4463ade3f4064ed3206a3eb58d43ae062a81778543b243c9f4531eb676b995fcd5062bf7d8ea44c9296afd2c6221040fbcf584cc7
|
7
|
+
data.tar.gz: 81a118cc6d8d05814a6a740666e1b3c968cb1ee654d9132655cf0a6a866a9626ef9f70b979afe461ef1144d687b5a556b55b83c1eb805a684423115b9bd61800
|
data/lib/sassc.rb
CHANGED
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,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
|
-
|
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
|
-
#
|
41
|
-
|
42
|
-
|
43
|
-
|
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
data/lib/sassc/version.rb
CHANGED
@@ -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
|
data/test/functions_test.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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
|