jekyll-sass-converter 1.4.0 → 2.0.1

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
- SHA1:
3
- metadata.gz: 71288fcd81a667822653dc71bd95ccedd9be0428
4
- data.tar.gz: 71e8375de0f5aa7795850292b905c079a33054ba
2
+ SHA256:
3
+ metadata.gz: c5b921d811e2917d86c33ad5cef0e1ecabe286eaf4ec33ee5e8c117fba6dfaab
4
+ data.tar.gz: 80f915a76b159e6f0b28cbd55ffc2d02b85cb4f445972adfd33aff1310dbb373
5
5
  SHA512:
6
- metadata.gz: 0cc730a8eac61db90a74430bf0c0d865b580262bd19e2d0697fb66b0edb2bc704c10ec2996dbb7db826e1485223e5cda882434e92ad564a02bbee3ef252ea060
7
- data.tar.gz: fee08ad83bd90778f43e144e48775ea00594d820c8e78f435f9f14eed19fb9584f9d41497e5217d4184cc51d1c05501b42ab07dc8a14131c077ceca975371163
6
+ metadata.gz: 4655abdc23cd0fa9439a5756d0a87b28419ace412327944c18adda840cbf9b3a8fc8132b05cc27a246b44e00811b23e2454003380888b6e78e7804d8818bf1c6
7
+ data.tar.gz: c8761b552a2b8ea6847af50f0083489d99f536fb53862001ff21b5a5fb72ab839955a388523147e1b83ee0c1f533072267f2182315165bd12cea345a5ae7a5e9
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "jekyll-sass-converter/version"
2
4
  require "jekyll/converters/scss"
3
5
  require "jekyll/converters/sass"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JekyllSassConverter
2
- VERSION = "1.4.0"
4
+ VERSION = "2.0.1"
3
5
  end
@@ -1,17 +1,17 @@
1
- require 'sass'
2
- require 'jekyll/utils'
3
- require 'jekyll/converters/scss'
1
+ # frozen_string_literal: true
2
+
3
+ require "sassc"
4
+ require "jekyll/utils"
5
+ require "jekyll/converters/scss"
4
6
 
5
7
  module Jekyll
6
8
  module Converters
7
9
  class Sass < Scss
10
+ EXTENSION_PATTERN = %r!^\.sass$!i.freeze
11
+
8
12
  safe true
9
13
  priority :low
10
14
 
11
- def matches(ext)
12
- ext =~ /^\.sass$/i
13
- end
14
-
15
15
  def syntax
16
16
  :sass
17
17
  end
@@ -1,24 +1,78 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'sass'
4
- require 'jekyll/utils'
3
+ require "sassc"
4
+ require "jekyll/utils"
5
+ require "jekyll/source_map_page"
5
6
 
6
7
  module Jekyll
7
8
  module Converters
8
9
  class Scss < Converter
9
- BYTE_ORDER_MARK = /^\xEF\xBB\xBF/
10
+ BYTE_ORDER_MARK = %r!^\xEF\xBB\xBF!.freeze
11
+ EXTENSION_PATTERN = %r!^\.scss$!i.freeze
12
+
10
13
  SyntaxError = Class.new(ArgumentError)
11
14
 
12
15
  safe true
13
16
  priority :low
14
17
 
18
+ # This hook is triggered just before the method {#convert(content)} is executed, it
19
+ # associates the Scss (and Sass) converters with their respective sass_page objects.
20
+ Jekyll::Hooks.register :pages, :pre_render do |page|
21
+ next unless page.is_a?(Jekyll::Page)
22
+
23
+ page.converters.each do |converter|
24
+ converter.associate_page(page) if converter.is_a?(Jekyll::Converters::Scss)
25
+ end
26
+ end
27
+
28
+ # This hook is triggered just after the method {#convert(content)} has been executed, it
29
+ # dissociates the Scss (and Sass) converters with their respective sass_page objects.
30
+ Jekyll::Hooks.register :pages, :post_render do |page|
31
+ next unless page.is_a?(Jekyll::Page)
32
+
33
+ page.converters.each do |converter|
34
+ converter.dissociate_page(page) if converter.is_a?(Jekyll::Converters::Scss)
35
+ end
36
+ end
37
+
15
38
  ALLOWED_STYLES = %w(nested expanded compact compressed).freeze
16
39
 
40
+ # Associate this Converter with the "page" object that manages input and output files for
41
+ # this converter.
42
+ #
43
+ # Note: changing the associated sass_page during the live time of this Converter instance
44
+ # may result in inconsistent results.
45
+ #
46
+ # @param [Jekyll:Page] page The sass_page for which this object acts as converter.
47
+ def associate_page(page)
48
+ if @sass_page
49
+ Jekyll.logger.debug "Sass Converter:",
50
+ "sass_page re-assigned: #{@sass_page.name} to #{page.name}"
51
+ dissociate_page(page)
52
+ return
53
+ end
54
+ @sass_page = page
55
+ end
56
+
57
+ # Dissociate this Converter with the "page" object.
58
+ #
59
+ # @param [Jekyll:Page] page The sass_page for which this object has acted as a converter.
60
+ def dissociate_page(page)
61
+ unless page.equal?(@sass_page)
62
+ Jekyll.logger.debug "Sass Converter:",
63
+ "dissociating a page that was never associated #{page.name}"
64
+ end
65
+
66
+ @source_map_page = nil
67
+ @sass_page = nil
68
+ @site = nil
69
+ end
70
+
17
71
  def matches(ext)
18
- ext =~ /^\.scss$/i
72
+ ext =~ self.class::EXTENSION_PATTERN
19
73
  end
20
74
 
21
- def output_ext(ext)
75
+ def output_ext(_ext)
22
76
  ".css"
23
77
  end
24
78
 
@@ -27,21 +81,18 @@ module Jekyll
27
81
  end
28
82
 
29
83
  def jekyll_sass_configuration
30
- options = @config["sass"] || {}
31
- unless options["style"].nil?
32
- options["style"] = options["style"].to_s.gsub(/\A:/, '').to_sym
84
+ @jekyll_sass_configuration ||= begin
85
+ options = @config["sass"] || {}
86
+ unless options["style"].nil?
87
+ options["style"] = options["style"].to_s.gsub(%r!\A:!, "").to_sym
88
+ end
89
+ options
33
90
  end
34
- options
35
91
  end
36
92
 
37
93
  def sass_build_configuration_options(overrides)
38
94
  if safe?
39
- {
40
- :load_paths => sass_load_paths,
41
- :syntax => syntax,
42
- :style => sass_style,
43
- :cache => false
44
- }
95
+ overrides
45
96
  else
46
97
  Jekyll::Utils.symbolize_hash_keys(
47
98
  Jekyll::Utils.deep_merge_hashes(
@@ -58,6 +109,7 @@ module Jekyll
58
109
 
59
110
  def sass_dir
60
111
  return "_sass" if jekyll_sass_configuration["sass_dir"].to_s.empty?
112
+
61
113
  jekyll_sass_configuration["sass_dir"]
62
114
  end
63
115
 
@@ -71,16 +123,36 @@ module Jekyll
71
123
  end
72
124
 
73
125
  def sass_dir_relative_to_site_source
74
- Jekyll.sanitized_path(@config["source"], sass_dir)
126
+ Jekyll.sanitized_path(site_source, sass_dir)
75
127
  end
76
128
 
129
+ # rubocop:disable Metrics/AbcSize
77
130
  def sass_load_paths
131
+ paths = user_sass_load_paths + [sass_dir_relative_to_site_source]
132
+
78
133
  if safe?
79
- [sass_dir_relative_to_site_source]
80
- else
81
- (user_sass_load_paths + [sass_dir_relative_to_site_source]).uniq
82
- end.select { |load_path| File.directory?(load_path) }
134
+ # Sanitize paths to prevent any attack vectors (.e.g. `/**/*`)
135
+ paths.map! { |path| Jekyll.sanitized_path(site_source, path) }
136
+ end
137
+
138
+ # Expand file globs (e.g. `node_modules/*/node_modules` )
139
+ Dir.chdir(site_source) do
140
+ paths = paths.flat_map { |path| Dir.glob(path) }.uniq
141
+
142
+ paths.map! do |path|
143
+ if safe?
144
+ # Sanitize again in case globbing was able to do something crazy.
145
+ Jekyll.sanitized_path(site_source, path)
146
+ else
147
+ File.expand_path(path)
148
+ end
149
+ end
150
+ end
151
+
152
+ paths << site.theme.sass_path if site.theme&.sass_path
153
+ paths.select { |path| File.directory?(path) }
83
154
  end
155
+ # rubocop:enable Metrics/AbcSize
84
156
 
85
157
  def allow_caching?
86
158
  !safe?
@@ -91,19 +163,125 @@ module Jekyll
91
163
  end
92
164
 
93
165
  def sass_configs
94
- sass_build_configuration_options({
95
- "syntax" => syntax,
96
- "cache" => allow_caching?,
97
- "load_paths" => sass_load_paths
98
- })
166
+ sass_build_configuration_options(
167
+ :style => sass_style,
168
+ :syntax => syntax,
169
+ :filename => filename,
170
+ :output_path => output_path,
171
+ :source_map_file => source_map_file,
172
+ :load_paths => sass_load_paths,
173
+ :omit_source_map_url => !sourcemap_required?,
174
+ :source_map_contents => true,
175
+ :line_comments_option => line_comments_option
176
+ )
99
177
  end
100
178
 
101
179
  def convert(content)
102
- output = ::Sass.compile(content, sass_configs)
103
- replacement = add_charset? ? '@charset "UTF-8";' : ''
180
+ config = sass_configs
181
+ engine = SassC::Engine.new(content.dup, config)
182
+ output = engine.render
183
+ generate_source_map(engine) if sourcemap_required?
184
+ replacement = add_charset? ? '@charset "UTF-8";' : ""
104
185
  output.sub(BYTE_ORDER_MARK, replacement)
105
- rescue ::Sass::SyntaxError => e
106
- raise SyntaxError.new("#{e.to_s} on line #{e.sass_line}")
186
+ rescue SassC::SyntaxError => e
187
+ raise SyntaxError, e.to_s
188
+ end
189
+
190
+ private
191
+
192
+ # The Page instance for which this object acts as a converter.
193
+ attr_reader :sass_page
194
+
195
+ def associate_page_failed?
196
+ !sass_page
197
+ end
198
+
199
+ # The name of the input scss (or sass) file. This information will be used for error
200
+ # reporting and will written into the source map file as main source.
201
+ #
202
+ # Returns the name of the input file or "stdin" if #associate_page failed
203
+ def filename
204
+ return "stdin" if associate_page_failed?
205
+
206
+ sass_page.name
207
+ end
208
+
209
+ # The value of the `line_comments` option.
210
+ # When set to `true` causes the line number and filename of the source be emitted into the
211
+ # compiled CSS-file. Useful for debugging when the source-map is not available.
212
+ #
213
+ # Returns the value of the `line_comments`-option chosen by the user or 'false' by default.
214
+ def line_comments_option
215
+ jekyll_sass_configuration.fetch("line_comments", false)
216
+ end
217
+
218
+ # The value of the `sourcemap` option chosen by the user.
219
+ #
220
+ # This option controls when sourcemaps shall be generated or not.
221
+ #
222
+ # Returns the value of the `sourcemap`-option chosen by the user or ':always' by default.
223
+ def sourcemap_option
224
+ jekyll_sass_configuration.fetch("sourcemap", :always).to_sym
225
+ end
226
+
227
+ # Determines whether a sourcemap shall be generated or not.
228
+ #
229
+ # Returns `true` if a sourcemap shall be generated, `false` otherwise.
230
+ def sourcemap_required?
231
+ return false if associate_page_failed? || sourcemap_option == :never
232
+ return true if sourcemap_option == :always
233
+
234
+ !(sourcemap_option == :development && Jekyll.env != "development")
235
+ end
236
+
237
+ # The name of the generated css file. This information will be written into the source map
238
+ # file as a backward reference to the input.
239
+ #
240
+ # Returns the name of the css file or "stdin.css" if #associate_page failed
241
+ def output_path
242
+ return "stdin.css" if associate_page_failed?
243
+
244
+ sass_page.basename + ".css"
245
+ end
246
+
247
+ # The name of the generated source map file. This information will be written into the
248
+ # css file to reference to the source map.
249
+ #
250
+ # Returns the name of the css file or "" if #associate_page failed
251
+ def source_map_file
252
+ return "" if associate_page_failed?
253
+
254
+ sass_page.basename + ".css.map"
255
+ end
256
+
257
+ def source_map_page
258
+ return if associate_page_failed?
259
+
260
+ @source_map_page ||= SourceMapPage.new(sass_page)
261
+ end
262
+
263
+ # Reads the source-map from the engine and adds it to the source-map-page.
264
+ #
265
+ # @param [::SassC::Engine] engine The sass Compiler engine.
266
+ def generate_source_map(engine)
267
+ return if associate_page_failed?
268
+
269
+ source_map_page.source_map(engine.source_map)
270
+ site.pages << source_map_page
271
+ rescue ::SassC::NotRenderedError => e
272
+ Jekyll.logger.warn "Could not generate source map #{e.message} => #{e.cause}"
273
+ end
274
+
275
+ def site
276
+ if associate_page_failed?
277
+ Jekyll.sites.last
278
+ else
279
+ sass_page.site
280
+ end
281
+ end
282
+
283
+ def site_source
284
+ site.source
107
285
  end
108
286
  end
109
287
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ # A Jekyll::Page subclass to manage the source map file associated with
5
+ # a given scss / sass page.
6
+ class SourceMapPage < Page
7
+ # Initialize a new SourceMapPage.
8
+ #
9
+ # @param [Jekyll::Page] css_page The Page object that manages the css file.
10
+ def initialize(css_page)
11
+ @site = css_page.site
12
+ @dir = css_page.dir
13
+ @data = css_page.data
14
+ @name = css_page.basename + ".css.map"
15
+
16
+ process(@name)
17
+ Jekyll::Hooks.trigger :pages, :post_init, self
18
+ end
19
+
20
+ def source_map(map)
21
+ self.content = map
22
+ end
23
+
24
+ def ext
25
+ ".map"
26
+ end
27
+
28
+ def asset_file?
29
+ true
30
+ end
31
+
32
+ # @return[String] the object as a debug String.
33
+ def inspect
34
+ "#<#{self.class} @name=#{name.inspect}>"
35
+ end
36
+ end
37
+ end
metadata CHANGED
@@ -1,43 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-sass-converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Parker Moore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-26 00:00:00.000000000 Z
11
+ date: 2019-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: sass
14
+ name: sassc
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.1
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '3.4'
22
+ version: '3.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">"
28
+ - !ruby/object:Gem::Version
29
+ version: 2.0.1
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '3.4'
32
+ version: '3.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: bundler
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - "~>"
37
+ - - ">="
32
38
  - !ruby/object:Gem::Version
33
- version: '1.5'
39
+ version: '0'
34
40
  type: :development
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
- - - "~>"
44
+ - - ">="
39
45
  - !ruby/object:Gem::Version
40
- version: '1.5'
46
+ version: '0'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: rake
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -67,19 +73,19 @@ dependencies:
67
73
  - !ruby/object:Gem::Version
68
74
  version: '0'
69
75
  - !ruby/object:Gem::Dependency
70
- name: jekyll
76
+ name: rubocop-jekyll
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
- - - ">="
79
+ - - "~>"
74
80
  - !ruby/object:Gem::Version
75
- version: '2.0'
81
+ version: '0.4'
76
82
  type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
85
  requirements:
80
- - - ">="
86
+ - - "~>"
81
87
  - !ruby/object:Gem::Version
82
- version: '2.0'
88
+ version: '0.4'
83
89
  description:
84
90
  email:
85
91
  - parkrmoore@gmail.com
@@ -91,6 +97,7 @@ files:
91
97
  - lib/jekyll-sass-converter/version.rb
92
98
  - lib/jekyll/converters/sass.rb
93
99
  - lib/jekyll/converters/scss.rb
100
+ - lib/jekyll/source_map_page.rb
94
101
  homepage: https://github.com/jekyll/jekyll-sass-converter
95
102
  licenses:
96
103
  - MIT
@@ -103,15 +110,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
110
  requirements:
104
111
  - - ">="
105
112
  - !ruby/object:Gem::Version
106
- version: '0'
113
+ version: 2.4.0
107
114
  required_rubygems_version: !ruby/object:Gem::Requirement
108
115
  requirements:
109
116
  - - ">="
110
117
  - !ruby/object:Gem::Version
111
118
  version: '0'
112
119
  requirements: []
113
- rubyforge_project:
114
- rubygems_version: 2.2.5
120
+ rubygems_version: 3.0.4
115
121
  signing_key:
116
122
  specification_version: 4
117
123
  summary: A basic Sass converter for Jekyll.