Class: Jekyll::Converters::Scss

Inherits:
Converter
  • Object
show all
Defined in:
lib/jekyll/converters/scss.rb

Direct Known Subclasses

Sass

Constant Summary collapse

EXTENSION_PATTERN =
%r!^\.scss$!i.freeze
SyntaxError =
Class.new(ArgumentError)
ALLOWED_STYLES =
%w(expanded compressed).freeze

Instance Method Summary collapse

Instance Method Details

#associate_page(page) ⇒ Object

Associate this Converter with the “page” object that manages input and output files for this converter.

Note: changing the associated sass_page during the live time of this Converter instance may result in inconsistent results.

Parameters:

  • page (Jekyll:Page)

    The sass_page for which this object acts as converter.



52
53
54
55
56
57
58
59
60
# File 'lib/jekyll/converters/scss.rb', line 52

def associate_page(page)
  if @sass_page
    Jekyll.logger.debug "Sass Converter:",
                        "sass_page re-assigned: #{@sass_page.name} to #{page.name}"
    dissociate_page(page)
    return
  end
  @sass_page = page
end

#convert(content) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/jekyll/converters/scss.rb', line 159

def convert(content)
  output = ::Sass.compile_string(content, **sass_configs)
  result = output.css

  if sourcemap_required?
    source_map = process_source_map(output.source_map)
    generate_source_map_page(source_map)

    if (sm_url = source_mapping_url)
      result += "#{sass_style == :compressed ? "" : "\n\n"}/*# sourceMappingURL=#{sm_url} */"
    end
  end

  result
rescue ::Sass::CompileError => e
  Jekyll.logger.error e.full_message
  raise SyntaxError, e.message
end

#dissociate_page(page) ⇒ Object

Dissociate this Converter with the “page” object.

Parameters:

  • page (Jekyll:Page)

    The sass_page for which this object has acted as a converter.



65
66
67
68
69
70
71
72
73
74
# File 'lib/jekyll/converters/scss.rb', line 65

def dissociate_page(page)
  unless page.equal?(@sass_page)
    Jekyll.logger.debug "Sass Converter:",
                        "dissociating a page that was never associated #{page.name}"
  end

  @source_map_page = nil
  @sass_page = nil
  @site = nil
end

#jekyll_sass_configurationObject



88
89
90
91
92
93
94
95
96
# File 'lib/jekyll/converters/scss.rb', line 88

def jekyll_sass_configuration
  @jekyll_sass_configuration ||= begin
    options = @config["sass"] || {}
    unless options["style"].nil?
      options["style"] = options["style"].to_s.delete_prefix(":").to_sym
    end
    options
  end
end

#matches(ext) ⇒ Object



76
77
78
# File 'lib/jekyll/converters/scss.rb', line 76

def matches(ext)
  ext =~ self.class::EXTENSION_PATTERN
end

#output_ext(_ext) ⇒ Object



80
81
82
# File 'lib/jekyll/converters/scss.rb', line 80

def output_ext(_ext)
  ".css"
end

#safe?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/jekyll/converters/scss.rb', line 84

def safe?
  !!@config["safe"]
end

#sass_configsObject

rubocop:enable Metrics/AbcSize



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/jekyll/converters/scss.rb', line 145

def sass_configs
  {
    :load_paths                 => sass_load_paths,
    :charset                    => !associate_page_failed?,
    :source_map                 => sourcemap_required?,
    :source_map_include_sources => true,
    :style                      => sass_style,
    :syntax                     => syntax,
    :url                        => sass_file_url,
    :quiet_deps                 => quiet_deps_option,
    :verbose                    => verbose_option,
  }
end

#sass_dirObject



102
103
104
105
106
# File 'lib/jekyll/converters/scss.rb', line 102

def sass_dir
  return "_sass" if jekyll_sass_configuration["sass_dir"].to_s.empty?

  jekyll_sass_configuration["sass_dir"]
end

#sass_dir_relative_to_site_sourceObject



117
118
119
120
# File 'lib/jekyll/converters/scss.rb', line 117

def sass_dir_relative_to_site_source
  @sass_dir_relative_to_site_source ||=
    Jekyll.sanitized_path(site_source, sass_dir).sub(site.source + "/", "")
end

#sass_load_pathsObject

rubocop:disable Metrics/AbcSize



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/jekyll/converters/scss.rb', line 123

def sass_load_paths
  paths = user_sass_load_paths + [sass_dir_relative_to_site_source]

  # Sanitize paths to prevent any attack vectors (.e.g. `/**/*`)
  paths.map! { |path| Jekyll.sanitized_path(site_source, path) } if safe?

  # Expand file globs (e.g. `node_modules/*/node_modules` )
  Dir.chdir(site_source) do
    paths = paths.flat_map { |path| Dir.glob(path) }

    paths.map! do |path|
      # Sanitize again in case globbing was able to do something crazy.
      safe? ? Jekyll.sanitized_path(site_source, path) : File.expand_path(path)
    end
  end

  paths.uniq!
  paths << site.theme.sass_path if site.theme&.sass_path
  paths.select { |path| File.directory?(path) }
end

#sass_styleObject



108
109
110
111
# File 'lib/jekyll/converters/scss.rb', line 108

def sass_style
  style = jekyll_sass_configuration["style"]
  ALLOWED_STYLES.include?(style.to_s) ? style.to_sym : :expanded
end

#syntaxObject



98
99
100
# File 'lib/jekyll/converters/scss.rb', line 98

def syntax
  :scss
end

#user_sass_load_pathsObject



113
114
115
# File 'lib/jekyll/converters/scss.rb', line 113

def user_sass_load_paths
  Array(jekyll_sass_configuration["load_paths"])
end