Skip to content

Commit

Permalink
Merge pull request #1365 from gpakosz/sass-improvements
Browse files Browse the repository at this point in the history
Sass improvements
  • Loading branch information
denisdefreyne committed Oct 14, 2018
2 parents f83b965 + dbd6af6 commit dc459c5
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 191 deletions.
16 changes: 13 additions & 3 deletions common/spec/spec_helper_foot.rb
Expand Up @@ -384,19 +384,29 @@ def sort(coll)

b = dependency_store.objects_causing_outdatedness_of(@from)

(b - a).any?
@actual = b - a

if @onto
values_match?(@onto, @actual)
else
@actual.any?
end
end

chain :onto do |onto|
@onto = onto
end

description do
"create a dependency from #{expected.inspect}"
end

failure_message do |_actual|
"expected a dependency to be created from #{expected.inspect}"
"expected a dependency to be created from #{expected.inspect}#{@onto ? " onto #{@onto.inspect}" : nil}, but generated #{@actual.inspect}"
end

failure_message_when_negated do |_actual|
"expected no dependency to be created from #{expected.inspect}"
"expected no dependency to be created from #{expected.inspect}, but generated #{@actual.inspect}"
end
end

Expand Down
2 changes: 1 addition & 1 deletion nanoc/lib/nanoc/base/services/filter.rb
Expand Up @@ -34,7 +34,7 @@ class Filter < Nanoc::Int::Context
class << self
def define(ident, &block)
filter_class = Class.new(::Nanoc::Filter) { identifier(ident) }
filter_class.send(:define_method, :run) do |content, params|
filter_class.send(:define_method, :run) do |content, params = {}|
instance_exec(content, params, &block)
end
end
Expand Down
168 changes: 138 additions & 30 deletions nanoc/lib/nanoc/filters/sass.rb
@@ -1,45 +1,153 @@
# frozen_string_literal: true

module Nanoc::Filters
# @api private
class Sass < Nanoc::Filter
identifier :sass

requires 'sass', 'nanoc/filters/sass/sass_filesystem_importer'

# Runs the content through [Sass](http://sass-lang.com/).
# Parameters passed to this filter will be passed on to Sass.
#
# @param [String] content The content to filter
#
# @return [String] The filtered content
def run(content, params = {})
Nanoc::Filter.define(:sass) do |content, params = {}|
include Sass
css(self, @item_rep, content, params)
end

Nanoc::Filter.define(:sass_sourcemap) do |content, params = {}|
include Sass
sourcemap(self, @item_rep, content, params)
end

require 'sass'

module Sass
def css(filter, rep, content, params)
css, = render(filter, rep, content, params)
css
end

def sourcemap(filter, rep, content, params)
_, sourcemap = render(filter, rep, content, params)
sourcemap
end

private

def render(filter, rep, content, params = {})
importer = NanocSassImporter.new(filter)

options = params.merge(
nanoc_current_filter: self,
filename: @item&.raw_filename,
load_paths: [importer, *params[:load_paths]&.reject { |p| p.is_a?(String) && %r{^content/} =~ p }],
importer: importer,
filename: rep.item.identifier.to_s,
cache: false,
)
sourcemap_path = options.delete(:sourcemap_path)

engine = ::Sass::Engine.new(content, options)
engine.render
css, sourcemap = sourcemap_path ? engine.render_with_sourcemap(sourcemap_path) : engine.render
[css, sourcemap&.to_json(css_uri: rep.path, type: rep.path.nil? ? :inline : :auto)]
end

def self.item_filename_map_for_config(config, items)
@item_filename_map ||= {}
@item_filename_map[config] ||=
{}.tap do |map|
items.each do |item|
if item.raw_filename
path = Pathname.new(item.raw_filename).realpath.to_s
map[path] = item
# @api private
class NanocSassImporter < ::Sass::Importers::Filesystem
attr_reader :filter

def initialize(filter)
@filter = filter
super('.')
end

def find_relative(name, base_identifier, options)
base_raw_filename = filter.items[base_identifier].raw_filename

# we can't resolve a relative filename from an in-memory item
return unless base_raw_filename

raw_filename, syntax = ::Sass::Util.destructure(find_real_file(File.dirname(base_raw_filename), name, options))
return unless raw_filename

item = raw_filename_to_item(raw_filename)
# it doesn't make sense to import a file, from Nanoc's content if the corresponding item has been deleted
raise "unable to map #{raw_filename} to any item" if item.nil?

filter.depend_on([item])

options[:syntax] = syntax
options[:filename] = item.identifier.to_s
options[:importer] = self
::Sass::Engine.new(item.raw_content, options)
end

def find(identifier, options)
items = filter.items.find_all(identifier)
return if items.empty?

content = if items.size == 1
items.first.compiled_content
else
items.map { |item| %(@import "#{item.identifier}";) }.join("\n")
end

options[:syntax] = :scss
options[:filename] = identifier.to_s
options[:importer] = self
::Sass::Engine.new(content, options)
end

def key(identifier, _options)
[self.class.name + ':' + root, identifier.to_s]
end

def public_url(identifier, _sourcemap_directory)
path = filter.items[identifier].path
return path unless path.nil?

raw_filename = filter.items[identifier].raw_filename
return if raw_filename.nil?

::Sass::Util.file_uri_from_path(raw_filename)
end

def to_s
'Nanoc Sass Importer'
end

def self.raw_filename_to_item_map_for_config(config, items)
@raw_filename_to_item_map ||= {}
@raw_filename_to_item_map[config.object_id] ||=
{}.tap do |map|
items.each do |item|
if item.raw_filename
path = Pathname.new(item.raw_filename).realpath.to_s
map[path] = item
end
end
end
end
end
end

def raw_filename_to_item(filename)
realpath = Pathname.new(filename).realpath.to_s

def imported_filename_to_item(filename)
realpath = Pathname.new(filename).realpath.to_s
map = self.class.raw_filename_to_item_map_for_config(filter.config, filter.items)
map[realpath]
end
end
end

map = self.class.item_filename_map_for_config(@config, @items)
map[realpath]
module ::Sass::Script::Functions
def nanoc(string, params)
assert_type string, :String
assert_type params, :Hash
result = options[:importer].filter.instance_eval(string.value)
case result
when TrueClass, FalseClass
bool(result)
when Array
list(result, :comma)
when Hash
map(result)
when nil
null
when Numeric
number(result)
else
params['unquote'] ? unquoted_string(result) : quoted_string(result)
end
end
declare :nanoc, [:string], var_kwargs: true
end
end
22 changes: 0 additions & 22 deletions nanoc/lib/nanoc/filters/sass/sass_filesystem_importer.rb

This file was deleted.

1 change: 0 additions & 1 deletion nanoc/nanoc.manifest
Expand Up @@ -227,7 +227,6 @@ lib/nanoc/filters/redcloth.rb
lib/nanoc/filters/relativize_paths.rb
lib/nanoc/filters/rubypants.rb
lib/nanoc/filters/sass.rb
lib/nanoc/filters/sass/sass_filesystem_importer.rb
lib/nanoc/filters/slim.rb
lib/nanoc/filters/typogruby.rb
lib/nanoc/filters/uglify_js.rb
Expand Down

0 comments on commit dc459c5

Please sign in to comment.