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

Ruby Sass:从SassEngine#to_树访问插入的@debug和@warn消息,ruby,sass,Ruby,Sass,我们在CodePen中使用SASS和SCSS,我正试图通过在格式化数组中使用@warn和@debug指令来做出响应,从而让它变得超级花哨。我们不想解析STDOUT,所以我试图通过Sass::Engine#to_树方法捕获调试和警告节点的结果 Buuuut,我们遇到麻烦了。我确信这只是因为我读lib的时间不够长,但是一些跳转会有所帮助 下面是一个最低测试用例: #好的,这个类有点稀疏,但是它封装了 #空库的逻辑,这是转换的目标 CSS类服务 属性读取器:引擎、:调试、:警告、:附加 #标记-sa

我们在CodePen中使用SASS和SCSS,我正试图通过在格式化数组中使用@warn和@debug指令来做出响应,从而让它变得超级花哨。我们不想解析STDOUT,所以我试图通过Sass::Engine#to_树方法捕获调试和警告节点的结果

Buuuut,我们遇到麻烦了。我确信这只是因为我读lib的时间不够长,但是一些跳转会有所帮助

下面是一个最低测试用例:

#好的,这个类有点稀疏,但是它封装了
#空库的逻辑,这是转换的目标
CSS类服务
属性读取器:引擎、:调试、:警告、:附加
#标记-sass/csss
#语法-其中一个[:sass,:scss]
#lib-其中一个%w(波旁指南针)
def进程(标记:,语法:,库:nil)
@标记=标记
@语法=语法
@lib=lib
@调试=[]
@警告=[]
#我们在这里创建一个Sass::引擎,带有默认值
@engine=SassEngine.new.get(语法:语法,标记:带有导入的标记)
输出=渲染
写入非渲染节点
输出
结束
私有的
def write_非渲染_节点
漫游节点(引擎到树的子节点)
@附加=调试+警告
结束
#循环节点以获取DebugNode和WarnNode实例
def walk_节点(节点)
节点。每个do |节点|
推送节点(节点)
#编程就是人
#重复就是德文
如果node.has_子节点,则遍历_节点(node.children)
结束
结束
#筛选到适当的节点
def push_节点(节点)
@调试
# 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