class Jekyll::Converters::Scss

Constants

ALLOWED_STYLES
EXTENSION_PATTERN
SyntaxError

Attributes

sass_page[R]

The Page instance for which this object acts as a converter.

Public Instance Methods

associate_page(page) click to toggle source

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.

@param [Jekyll:Page] page The sass_page for which this object acts as converter.

# 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) click to toggle source
# 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) click to toggle source

Dissociate this Converter with the “page” object.

@param [Jekyll:Page] page The sass_page for which this object has acted as a converter.

# 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_configuration() click to toggle source
# 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) click to toggle source
# File lib/jekyll/converters/scss.rb, line 76
def matches(ext)
  ext =~ self.class::EXTENSION_PATTERN
end
output_ext(_ext) click to toggle source
# File lib/jekyll/converters/scss.rb, line 80
def output_ext(_ext)
  ".css"
end
safe?() click to toggle source
# File lib/jekyll/converters/scss.rb, line 84
def safe?
  !!@config["safe"]
end
sass_configs() click to toggle source

rubocop:enable Metrics/AbcSize

# 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_dir() click to toggle source
# 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_source() click to toggle source
# 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_paths() click to toggle source

rubocop:disable Metrics/AbcSize

# 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_style() click to toggle source
# 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
syntax() click to toggle source
# File lib/jekyll/converters/scss.rb, line 98
def syntax
  :scss
end
user_sass_load_paths() click to toggle source
# File lib/jekyll/converters/scss.rb, line 113
def user_sass_load_paths
  Array(jekyll_sass_configuration["load_paths"])
end

Private Instance Methods

associate_page_failed?() click to toggle source
# File lib/jekyll/converters/scss.rb, line 183
def associate_page_failed?
  !sass_page
end
file_url_from_path(path) click to toggle source
# File lib/jekyll/converters/scss.rb, line 266
def file_url_from_path(path)
  Addressable::URI.encode("file://#{path.start_with?("/") ? "" : "/"}#{path}")
end
generate_source_map_page(source_map) click to toggle source

Adds the source-map to the source-map-page and adds it to ‘site.pages`.

# File lib/jekyll/converters/scss.rb, line 244
def generate_source_map_page(source_map)
  return if associate_page_failed?

  source_map_page.source_map(source_map)
  site.pages << source_map_page
end
process_source_map(source_map) click to toggle source

Converts file urls in source map to relative paths.

Returns processed source map string.

# File lib/jekyll/converters/scss.rb, line 231
def process_source_map(source_map)
  map_data = JSON.parse(source_map)
  unless associate_page_failed?
    map_data["file"] = Addressable::URI.encode(sass_page.basename + ".css")
  end
  source_root_url = Addressable::URI.parse(file_url_from_path("#{sass_source_root}/"))
  map_data["sources"].map! do |s|
    s.start_with?("file:") ? Addressable::URI.parse(s).route_from(source_root_url).to_s : s
  end
  JSON.generate(map_data)
end
quiet_deps_option() click to toggle source

Returns the value of the ‘quiet_deps`-option chosen by the user or ’false’ by default.

# File lib/jekyll/converters/scss.rb, line 271
def quiet_deps_option
  !!jekyll_sass_configuration.fetch("quiet_deps", false)
end
sass_file_url() click to toggle source

The URL of the input scss (or sass) file. This information will be used for error reporting.

# File lib/jekyll/converters/scss.rb, line 188
def sass_file_url
  return if associate_page_failed?

  file_url_from_path(Jekyll.sanitized_path(site_source, sass_page.relative_path))
end
sass_source_root() click to toggle source

Returns the directory that source map sources are relative to.

# File lib/jekyll/converters/scss.rb, line 220
def sass_source_root
  if associate_page_failed?
    site_source
  else
    Jekyll.sanitized_path(site_source, File.dirname(sass_page.relative_path))
  end
end
site() click to toggle source
# File lib/jekyll/converters/scss.rb, line 258
def site
  associate_page_failed? ? Jekyll.sites.last : sass_page.site
end
site_source() click to toggle source
# File lib/jekyll/converters/scss.rb, line 262
def site_source
  site.source
end
source_map_page() click to toggle source
# File lib/jekyll/converters/scss.rb, line 213
def source_map_page
  return if associate_page_failed?

  @source_map_page ||= SourceMapPage.new(sass_page)
end
source_mapping_url() click to toggle source

Returns a source mapping url for given source-map.

# File lib/jekyll/converters/scss.rb, line 252
def source_mapping_url
  return if associate_page_failed?

  Addressable::URI.encode(sass_page.basename + ".css.map")
end
sourcemap_option() click to toggle source

The value of the ‘sourcemap` option chosen by the user.

This option controls when sourcemaps shall be generated or not.

Returns the value of the ‘sourcemap`-option chosen by the user or ’:always’ by default.

# File lib/jekyll/converters/scss.rb, line 199
def sourcemap_option
  jekyll_sass_configuration.fetch("sourcemap", :always).to_sym
end
sourcemap_required?() click to toggle source

Determines whether a sourcemap shall be generated or not.

Returns ‘true` if a sourcemap shall be generated, `false` otherwise.

# File lib/jekyll/converters/scss.rb, line 206
def sourcemap_required?
  return false if associate_page_failed? || sourcemap_option == :never
  return true  if sourcemap_option == :always

  !(sourcemap_option == :development && Jekyll.env != "development")
end
verbose_option() click to toggle source

Returns the value of the ‘verbose`-option chosen by the user or ’false’ by default.

# File lib/jekyll/converters/scss.rb, line 276
def verbose_option
  !!jekyll_sass_configuration.fetch("verbose", false)
end