Sass:从SassEngine访问插入的@debug和@warn消息#to_tree

时间:2016-02-02 22:00:29

标签: ruby sass

我们在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进行插值。

所以,问题仍然存在。如何获得插值调试节点?

0 个答案:

没有答案