我们在CodePen上使用SASS和SCSS,并且我试图通过在格式化数组中使用@warn和@debug指令来使其超级华丽。我们不想解析STDOUT,所以我试图通过Sass :: Engine#to_tree方法捕获Debug和Warn节点的结果。
Buuuut,我们遇到了麻烦。我确定只是因为我没有足够长时间阅读这篇文章,但是一些快速启动会有所帮助。
这是最小的测试用例:
https://gist.github.com/tsabat/a91e8ebf9b8ec65f5c77
# Ok, this class is a bit sparse, but it encapsulates the
# logic for an empty lib, which is the goal of the conversion
class CssService
attr_reader :engine, :debugs, :warns, :extras
# markup - the sass/csss
# syntax - one of [:sass, :scss]
# lib - one of %w(bourbon compass)
def process(markup:, syntax:, lib: nil)
@markup = markup
@syntax = syntax
@lib = lib
@debugs = []
@warns = []
# we create a Sass::Engine here, with defaults
@engine = SassEngine.new.get(syntax: syntax, markup: markup_with_imports)
output = rendered
write_non_render_nodes
output
end
private
def write_non_render_nodes
walk_nodes(engine.to_tree.children)
@extras = debugs + warns
end
# loop over nodes to to get DebugNode and WarnNode instances
def walk_nodes(nodes)
nodes.each do |node|
push_node(node)
# to program is human
# to recurse is devine
walk_nodes(node.children) if node.has_children
end
end
# filter to appropriate nodes
def push_node(node)
@debugs << message(node, :debug) if node.class == Sass::Tree::DebugNode
@warns << message(node, :warn) if node.class == Sass::Tree::WarnNode
end
# some cleanup
def message(child, type)
message = child.expr.to_sass.gsub!(/\A"|"\Z/, '')
{type: type, message: message, line: child.line}
end
def rendered
engine.render
end
# I can get the correct, interpolated output from here if i monkey-patch
# the class
class Sass::Tree::Visitors::Perform
def visit_debug(node)
res = node.expr.perform(@environment)
if res.is_a?(Sass::Script::Value::String)
res = res.value
else
res = res.to_sass
end
#ap res
end
end
# this can be ignored, it does CodePen specific stuff
def markup_with_imports
return @markup if lib_empty?
"#{imports}\n#{@markup}"
end
def lib_empty?
@lib.nil? || @lib == ''
end
def imports
if @lib == 'bourbon'
(@syntax == :scss) ? "@import \"bourbon\";" : "@import \"bourbon\""
elsif @lib == 'compass'
(@syntax == :scss) ? "@import \"compass/css3\";" : "@import \"compass/css3\""
else
nil
end
end
end
基本上,我可以得到我想要的节点,但我无法进行内插。例如,DebugNode填充
&#34;颜色名称无效:#{$ color},返回白色。&#34 ;;
不会在此处expr.to_sass
进行插值。
所以,问题仍然存在。如何获得插值调试节点?