sass-embedded 0.9.1 → 0.11.0

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.
data/lib/sass/embedded.rb CHANGED
@@ -1,14 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'base64'
4
- require 'json'
3
+ require_relative 'compile_error'
4
+ require_relative 'compile_result'
5
+ require_relative 'importer_result'
5
6
  require_relative 'embedded/channel'
6
7
  require_relative 'embedded/compile_context'
7
- require_relative 'embedded/error'
8
- require_relative 'embedded/result'
9
- require_relative 'embedded/util'
8
+ require_relative 'embedded/render'
9
+ require_relative 'embedded/url'
10
10
  require_relative 'embedded/version'
11
11
  require_relative 'embedded/version_context'
12
+ require_relative 'logger'
12
13
 
13
14
  module Sass
14
15
  # The {Embedded} host for using dart-sass-embedded. Each instance creates
@@ -16,241 +17,117 @@ module Sass
16
17
  #
17
18
  # @example
18
19
  # embedded = Sass::Embedded.new
19
- # result = embedded.render(data: 'h1 { font-size: 40px; }')
20
- # result = embedded.render(file: 'style.css')
20
+ # result = embedded.compile_string('h1 { font-size: 40px; }')
21
+ # result = embedded.compile('style.scss')
21
22
  # embedded.close
22
23
  class Embedded
23
- def self.include_paths
24
- @include_paths ||= if ENV['SASS_PATH']
25
- ENV['SASS_PATH'].split(File::PATH_SEPARATOR)
26
- else
27
- []
28
- end
29
- end
30
-
31
24
  def initialize
32
25
  @channel = Channel.new
33
26
  end
34
27
 
35
- # The {Embedded#info} method.
28
+ # The {Embedded#compile} method.
36
29
  #
30
+ # @return [CompileResult]
31
+ # @raise [CompileError]
37
32
  # @raise [ProtocolError]
38
- def info
39
- @info ||= VersionContext.new(@channel).receive_message
40
- end
33
+ def compile(path,
34
+ load_paths: [],
41
35
 
42
- # The {Embedded#render} method.
43
- #
44
- # See {file:README.md#options} for supported options.
45
- #
46
- # @return [RenderResult]
47
- # @raise [ProtocolError]
48
- # @raise [RenderError]
49
- def render(data: nil,
50
- file: nil,
51
- indented_syntax: false,
52
- include_paths: [],
53
- output_style: :expanded,
54
- indent_type: :space,
55
- indent_width: 2,
56
- linefeed: :lf,
57
- source_map: false,
58
- out_file: nil,
59
- omit_source_map_url: false,
60
- source_map_contents: false,
61
- source_map_embed: false,
62
- source_map_root: '',
63
- functions: {},
64
- importer: [])
65
- start = Util.now
36
+ source_map: false,
37
+ style: :expanded,
66
38
 
67
- indent_type = parse_indent_type(indent_type)
68
- indent_width = parse_indent_width(indent_width)
69
- linefeed = parse_linefeed(linefeed)
39
+ functions: {},
40
+ importers: [],
41
+
42
+ alert_ascii: false,
43
+ alert_color: $stderr.tty?,
44
+ logger: nil,
45
+ quiet_deps: false,
46
+ verbose: false)
47
+
48
+ raise ArgumentError, 'path must be set' if path.nil?
70
49
 
71
50
  message = CompileContext.new(@channel,
72
- data: data,
73
- file: file,
74
- indented_syntax: indented_syntax,
75
- include_paths: include_paths,
76
- output_style: output_style,
51
+ path: path,
52
+ source: nil,
53
+ importer: nil,
54
+ load_paths: load_paths,
55
+ syntax: nil,
56
+ url: nil,
77
57
  source_map: source_map,
78
- out_file: out_file,
58
+ style: style,
79
59
  functions: functions,
80
- importer: importer).receive_message
81
-
82
- if message.failure
83
- raise RenderError.new(
84
- message.failure.message,
85
- message.failure.formatted,
86
- if message.failure.span.nil?
87
- nil
88
- elsif message.failure.span.url == ''
89
- 'stdin'
90
- else
91
- Util.path_from_file_uri(message.failure.span.url)
92
- end,
93
- message.failure.span ? message.failure.span.start.line + 1 : nil,
94
- message.failure.span ? message.failure.span.start.column + 1 : nil,
95
- 1
96
- )
97
- end
60
+ importers: importers,
61
+ alert_color: alert_color,
62
+ alert_ascii: alert_ascii,
63
+ logger: logger,
64
+ quiet_deps: quiet_deps,
65
+ verbose: verbose).receive_message
98
66
 
99
- map, source_map = post_process_map(map: message.success.source_map,
100
- data: data,
101
- file: file,
102
- out_file: out_file,
103
- source_map: source_map,
104
- source_map_contents: source_map_contents,
105
- source_map_root: source_map_root)
67
+ raise CompileError.from_proto(message.failure) if message.failure
106
68
 
107
- css = post_process_css(css: message.success.css,
108
- indent_type: indent_type,
109
- indent_width: indent_width,
110
- linefeed: linefeed,
111
- map: map,
112
- out_file: out_file,
113
- omit_source_map_url: omit_source_map_url,
114
- source_map: source_map,
115
- source_map_embed: source_map_embed)
116
-
117
- finish = Util.now
118
-
119
- stats = RenderResultStats.new(file.nil? ? 'data' : file, start, finish, finish - start)
120
-
121
- RenderResult.new(css, map, stats)
122
- end
123
-
124
- def close
125
- @channel.close
126
- end
127
-
128
- def closed?
129
- @channel.closed?
69
+ CompileResult.from_proto(message.success)
130
70
  end
131
71
 
132
- private
133
-
134
- def post_process_map(map:,
135
- data:,
136
- file:,
137
- out_file:,
138
- source_map:,
139
- source_map_contents:,
140
- source_map_root:)
141
- return if map.nil? || map.empty?
142
-
143
- map_data = JSON.parse(map)
144
-
145
- map_data['sourceRoot'] = source_map_root
146
-
147
- source_map_path = if source_map.is_a? String
148
- source_map
149
- else
150
- "#{out_file}.map"
151
- end
152
-
153
- source_map_dir = File.dirname(source_map_path)
154
-
155
- if out_file
156
- map_data['file'] = Util.relative_path(source_map_dir, out_file)
157
- elsif file
158
- ext = File.extname(file)
159
- map_data['file'] = "#{file[0..(ext.empty? ? -1 : -ext.length - 1)]}.css"
160
- else
161
- map_data['file'] = 'stdin.css'
162
- end
163
-
164
- map_data['sourcesContent'] = [] if source_map_contents
72
+ # The {Embedded#compile_string} method.
73
+ #
74
+ # @return [CompileResult]
75
+ # @raise [CompileError]
76
+ # @raise [ProtocolError]
77
+ def compile_string(source,
78
+ importer: nil,
79
+ load_paths: [],
80
+ syntax: :scss,
81
+ url: nil,
165
82
 
166
- file = File.absolute_path(file) unless file.nil?
83
+ source_map: false,
84
+ style: :expanded,
167
85
 
168
- map_data['sources'].map! do |source|
169
- if source.start_with? 'file://'
170
- path = Util.path_from_file_uri(source)
171
- content = if path == file && !data.nil?
172
- data
173
- else
174
- begin
175
- File.read(path)
176
- rescue StandardError
177
- nil
178
- end
179
- end
180
- map_data['sourcesContent'].push(content) if source_map_contents
181
- Util.relative_path(source_map_dir, path)
182
- else
183
- map_data['sourcesContent'].push(nil) if source_map_contents
184
- source
185
- end
186
- end
86
+ functions: {},
87
+ importers: [],
187
88
 
188
- [-JSON.generate(map_data), source_map_path]
189
- end
89
+ alert_ascii: false,
90
+ alert_color: $stderr.tty?,
91
+ logger: nil,
92
+ quiet_deps: false,
93
+ verbose: false)
94
+ raise ArgumentError, 'source must be set' if source.nil?
190
95
 
191
- def post_process_css(css:,
192
- indent_type:,
193
- indent_width:,
194
- linefeed:,
195
- map:,
196
- omit_source_map_url:,
197
- out_file:,
198
- source_map:,
199
- source_map_embed:)
200
- css = +css
201
- if indent_width != 2 || indent_type.to_sym != :space
202
- indent = indent_type * indent_width
203
- css.gsub!(/^ +/) do |space|
204
- indent * (space.length / 2)
205
- end
206
- end
207
- css.gsub!("\n", linefeed) if linefeed != "\n"
96
+ message = CompileContext.new(@channel,
97
+ path: nil,
98
+ source: source,
99
+ importer: importer,
100
+ load_paths: load_paths,
101
+ syntax: syntax,
102
+ url: url,
103
+ source_map: source_map,
104
+ style: style,
105
+ functions: functions,
106
+ importers: importers,
107
+ alert_color: alert_color,
108
+ alert_ascii: alert_ascii,
109
+ logger: logger,
110
+ quiet_deps: quiet_deps,
111
+ verbose: verbose).receive_message
208
112
 
209
- unless map.nil? || omit_source_map_url == true
210
- url = if source_map_embed
211
- "data:application/json;base64,#{Base64.strict_encode64(map)}"
212
- elsif out_file
213
- Util.relative_path(File.dirname(out_file), source_map)
214
- else
215
- source_map
216
- end
217
- css += "#{linefeed}#{linefeed}/*# sourceMappingURL=#{url} */"
218
- end
113
+ raise CompileError.from_proto(message.failure) if message.failure
219
114
 
220
- -css
115
+ CompileResult.from_proto(message.success)
221
116
  end
222
117
 
223
- def parse_indent_type(indent_type)
224
- case indent_type.to_sym
225
- when :space
226
- ' '
227
- when :tab
228
- "\t"
229
- else
230
- raise ArgumentError, 'indent_type must be one of :space, :tab'
231
- end
118
+ # The {Embedded#info} method.
119
+ #
120
+ # @raise [ProtocolError]
121
+ def info
122
+ @info ||= VersionContext.new(@channel).receive_message
232
123
  end
233
124
 
234
- def parse_indent_width(indent_width)
235
- raise ArgumentError, 'indent_width must be an integer' unless indent_width.is_a? Integer
236
- raise RangeError, 'indent_width must be in between 0 and 10 (inclusive)' unless indent_width.between? 0, 10
237
-
238
- indent_width
125
+ def close
126
+ @channel.close
239
127
  end
240
128
 
241
- def parse_linefeed(linefeed)
242
- case linefeed.to_sym
243
- when :lf
244
- "\n"
245
- when :lfcr
246
- "\n\r"
247
- when :cr
248
- "\r"
249
- when :crlf
250
- "\r\n"
251
- else
252
- raise ArgumentError, 'linefeed must be one of :lf, :lfcr, :cr, :crlf'
253
- end
129
+ def closed?
130
+ @channel.closed?
254
131
  end
255
132
  end
256
133
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {FileImporter} interface.
5
+ class FileImporter
6
+ def find_file_url(url, from_import:) # rubocop:disable Lint/UnusedMethodArgument
7
+ raise NotImplementedError, 'FileImporter#find_file_url must be implemented'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {Importer} interface.
5
+ class Importer
6
+ def canonicalize(url) # rubocop:disable Lint/UnusedMethodArgument
7
+ raise NotImplementedError, 'Importer#canonicalize must be implemented'
8
+ end
9
+
10
+ def load(canonical_url) # rubocop:disable Lint/UnusedMethodArgument
11
+ raise NotImplementedError, 'Importer#load must be implemented'
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {ImporterResult} of {Importer#load}.
5
+ class ImporterResult
6
+ attr_reader :contents, :syntax, :source_map_url
7
+
8
+ def initialize(contents, syntax, source_map_url = nil)
9
+ @contents = contents
10
+ @syntax = syntax
11
+ @source_map_url = source_map_url
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ module Logger
5
+ # The {SourceLocation} in {SourceSpan}.
6
+ class SourceLocation
7
+ attr_reader :offset, :line, :column
8
+
9
+ def initialize(offset, line, column)
10
+ @offset = offset
11
+ @line = line
12
+ @column = column
13
+ end
14
+
15
+ def self.from_proto(source_location)
16
+ return nil if source_location.nil?
17
+
18
+ SourceLocation.new(source_location.offset,
19
+ source_location.line,
20
+ source_location.column)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'source_location'
4
+
5
+ module Sass
6
+ module Logger
7
+ # The {SourceSpan} in {CompileError}.
8
+ class SourceSpan
9
+ attr_reader :start, :end, :text, :url, :context
10
+
11
+ def initialize(start, end_, text, url, context)
12
+ @start = start
13
+ @end = end_
14
+ @text = text
15
+ @url = url == '' ? nil : url
16
+ @context = context == '' ? nil : context
17
+ end
18
+
19
+ def self.from_proto(source_span)
20
+ return nil if source_span.nil?
21
+
22
+ SourceSpan.new(SourceLocation.from_proto(source_span.start),
23
+ SourceLocation.from_proto(source_span.end),
24
+ source_span.text,
25
+ source_span.url,
26
+ source_span.context)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {Logger} module.
5
+ module Logger
6
+ # The instance of a slient {Logger}.
7
+ def self.slient
8
+ @slient ||= Slient.new
9
+ end
10
+
11
+ # The slient {Logger}.
12
+ class Slient
13
+ def warn(message, deprecation: false, span: nil, stack: nil); end
14
+
15
+ def debug(message, span: nil); end
16
+ end
17
+
18
+ private_constant :Slient
19
+ end
20
+ end
data/lib/sass.rb CHANGED
@@ -6,6 +6,35 @@ require_relative 'sass/embedded'
6
6
  # the Embedded Sass protocol.
7
7
  module Sass
8
8
  class << self
9
+ # The global {.compile} method. This instantiates a global {Embedded} instance
10
+ # and calls {Embedded#compile}.
11
+ #
12
+ # See {Embedded#compile} for supported options.
13
+ #
14
+ # @example
15
+ # Sass.compile('style.scss')
16
+ # @return [CompileResult]
17
+ # @raise [CompileError]
18
+ # @raise [ProtocolError]
19
+ def compile(path, **kwargs)
20
+ instance.compile(path, **kwargs)
21
+ end
22
+
23
+ # The global {.compile_string} method. This instantiates a global {Embedded} instance
24
+ # and calls {Embedded#compile_string}.
25
+ #
26
+ # See {Embedded#compile_string} for supported options.
27
+ #
28
+ # @example
29
+ # Sass.compile_string('h1 { font-size: 40px; }')
30
+ # @return [CompileResult]
31
+ # @raise [CompileError]
32
+ # @raise [ProtocolError]
33
+ def compile_string(source, **kwargs)
34
+ instance.compile_string(source, **kwargs)
35
+ end
36
+
37
+ # @deprecated
9
38
  # The global {.include_paths} for Sass files. This is meant for plugins and
10
39
  # libraries to register the paths to their Sass stylesheets to that they may
11
40
  # be included via `@import` or `@use`. This include path is used by every
@@ -32,10 +61,11 @@ module Sass
32
61
  instance.info
33
62
  end
34
63
 
64
+ # @deprecated
35
65
  # The global {.render} method. This instantiates a global {Embedded} instance
36
66
  # and calls {Embedded#render}.
37
67
  #
38
- # See {file:README.md#options} for supported options.
68
+ # See {Embedded#render} for supported options.
39
69
  #
40
70
  # @example
41
71
  # Sass.render(data: 'h1 { font-size: 40px; }')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass-embedded
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - なつき
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-29 00:00:00.000000000 Z
11
+ date: 2022-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.18.0
19
+ version: 3.19.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 3.18.0
26
+ version: 3.19.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 5.14.4
33
+ version: 5.15.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 5.14.4
40
+ version: 5.15.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest-around
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -72,42 +72,42 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.21.0
75
+ version: 1.24.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.21.0
82
+ version: 1.24.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop-minitest
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.15.0
89
+ version: 0.17.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.15.0
96
+ version: 0.17.0
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop-performance
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 1.11.5
103
+ version: 1.13.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 1.11.5
110
+ version: 1.13.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rubocop-rake
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -138,27 +138,34 @@ files:
138
138
  - ext/sass/unzip.vbs
139
139
  - lib/sass-embedded.rb
140
140
  - lib/sass.rb
141
+ - lib/sass/compile_error.rb
142
+ - lib/sass/compile_result.rb
141
143
  - lib/sass/embedded.rb
142
144
  - lib/sass/embedded/channel.rb
143
145
  - lib/sass/embedded/compile_context.rb
144
146
  - lib/sass/embedded/compiler.rb
145
147
  - lib/sass/embedded/compiler/path.rb
146
148
  - lib/sass/embedded/compiler/requirements.rb
147
- - lib/sass/embedded/error.rb
148
149
  - lib/sass/embedded/observer.rb
149
150
  - lib/sass/embedded/platform.rb
150
- - lib/sass/embedded/result.rb
151
- - lib/sass/embedded/struct.rb
152
- - lib/sass/embedded/util.rb
151
+ - lib/sass/embedded/protocol_error.rb
152
+ - lib/sass/embedded/render.rb
153
+ - lib/sass/embedded/url.rb
153
154
  - lib/sass/embedded/version.rb
154
155
  - lib/sass/embedded/version_context.rb
155
156
  - lib/sass/embedded_protocol.rb
157
+ - lib/sass/file_importer.rb
158
+ - lib/sass/importer.rb
159
+ - lib/sass/importer_result.rb
160
+ - lib/sass/logger.rb
161
+ - lib/sass/logger/source_location.rb
162
+ - lib/sass/logger/source_span.rb
156
163
  homepage: https://github.com/ntkme/sass-embedded-host-ruby
157
164
  licenses:
158
165
  - MIT
159
166
  metadata:
160
- documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.9.1
161
- source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.9.1
167
+ documentation_uri: https://www.rubydoc.info/gems/sass-embedded/0.11.0
168
+ source_code_uri: https://github.com/ntkme/sass-embedded-host-ruby/tree/v0.11.0
162
169
  funding_uri: https://github.com/sponsors/ntkme
163
170
  post_install_message:
164
171
  rdoc_options: []
@@ -168,14 +175,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
168
175
  requirements:
169
176
  - - ">="
170
177
  - !ruby/object:Gem::Version
171
- version: 2.6.0
178
+ version: 2.7.0
172
179
  required_rubygems_version: !ruby/object:Gem::Requirement
173
180
  requirements:
174
181
  - - ">="
175
182
  - !ruby/object:Gem::Version
176
183
  version: '0'
177
184
  requirements: []
178
- rubygems_version: 3.2.22
185
+ rubygems_version: 3.3.3
179
186
  signing_key:
180
187
  specification_version: 4
181
188
  summary: Use dart-sass with Ruby!