jekyll-sass-converter 1.4.0 → 2.0.1

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 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.