-
Notifications
You must be signed in to change notification settings - Fork 157
/
engine.rb
141 lines (109 loc) · 3.85 KB
/
engine.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# frozen_string_literal: true
require_relative "error"
module SassC
class Engine
OUTPUT_STYLES = %i[
sass_style_nested
sass_style_expanded
sass_style_compact
sass_style_compressed
]
attr_reader :template, :options
def initialize(template, options = {})
@template = template
@options = options
@functions = options.fetch(:functions, Script::Functions)
end
def render
return @template.dup if @template.empty?
data_context = Native.make_data_context(@template)
context = Native.data_context_get_context(data_context)
native_options = Native.context_get_options(context)
Native.option_set_is_indented_syntax_src(native_options, true) if sass?
Native.option_set_input_path(native_options, filename) if filename
Native.option_set_precision(native_options, precision) if precision
Native.option_set_include_path(native_options, load_paths)
Native.option_set_output_style(native_options, output_style_enum)
Native.option_set_source_comments(native_options, true) if line_comments?
Native.option_set_source_map_file(native_options, source_map_file) if source_map_file
Native.option_set_source_map_embed(native_options, true) if source_map_embed?
Native.option_set_source_map_contents(native_options, true) if source_map_contents?
Native.option_set_omit_source_map_url(native_options, true) if omit_source_map_url?
import_handler.setup(native_options)
functions_handler.setup(native_options, functions: @functions)
status = Native.compile_data_context(data_context)
if status != 0
message = Native.context_get_error_message(context)
filename = Native.context_get_error_file(context)
line = Native.context_get_error_line(context)
raise SyntaxError.new(message, filename: filename, line: line)
end
css = Native.context_get_output_string(context)
@dependencies = Native.context_get_included_files(context)
@source_map = Native.context_get_source_map_string(context)
css.force_encoding(@template.encoding)
@source_map.force_encoding(@template.encoding) if @source_map.is_a?(String)
return css unless quiet?
ensure
Native.delete_data_context(data_context) if data_context
end
def dependencies
raise NotRenderedError unless @dependencies
Dependency.from_filenames(@dependencies)
end
def source_map
raise NotRenderedError unless @source_map
@source_map
end
def filename
@options[:filename]
end
private
def quiet?
@options[:quiet]
end
def precision
@options[:precision]
end
def sass?
@options[:syntax] && @options[:syntax].to_sym == :sass
end
def line_comments?
@options[:line_comments]
end
def source_map_embed?
@options[:source_map_embed]
end
def source_map_contents?
@options[:source_map_contents]
end
def omit_source_map_url?
@options[:omit_source_map_url]
end
def source_map_file
@options[:source_map_file]
end
def import_handler
@import_handler ||= ImportHandler.new(@options)
end
def functions_handler
@functions_handler = FunctionsHandler.new(@options)
end
def output_style_enum
@output_style_enum ||= Native::SassOutputStyle[output_style]
end
def output_style
@output_style ||= begin
style = @options.fetch(:style, :sass_style_nested).to_s
style = "sass_style_#{style}" unless style.include?("sass_style_")
style = style.to_sym
raise InvalidStyleError unless Native::SassOutputStyle.symbols.include?(style)
style
end
end
def load_paths
paths = (@options[:load_paths] || []) + SassC.load_paths
paths.join(File::PATH_SEPARATOR) unless paths.empty?
end
end
end