Class/Module Index [+]

Quicksearch

Sass::Tree::Visitors::Convert

A visitor for converting a Sass tree into a source string.

Public Class Methods

new(options, format) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 15
def initialize(options, format)
  @options = options
  @format = format
  @tabs = 0
  # 2 spaces by default
  @tab_chars = @options[:indent] || "  "
end
visit(root, options, format) click to toggle source

Runs the visitor on a tree.

@param root [Tree::Node] The root node of the Sass tree. @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize}). @param format [Symbol] `:sass` or `:scss`. @return [String] The Sass or SCSS source for the tree.

# File lib/sass/tree/visitors/convert.rb, line 9
def self.visit(root, options, format)
  new(options, format).send(:visit, root)
end

Protected Instance Methods

visit_charset(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 49
def visit_charset(node)
  "#{tab_str}@charset \"#{node.name}\"#{semi}\n"
end
visit_children(parent) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 23
def visit_children(parent)
  @tabs += 1
  return @format == :sass ? "\n" : " {}\n" if parent.children.empty?
  (@format == :sass ? "\n" : " {\n") + super.join.rstrip + (@format == :sass ? "\n" : "\n#{ @tab_chars * (@tabs-1)}}\n")
ensure
  @tabs -= 1
end
visit_comment(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 53
def visit_comment(node)
  value = interp_to_src(node.value)
  content = if @format == :sass
    content = value.gsub(/\*\/$/, '').rstrip
    if content =~ /\A[ \t]/
      # Re-indent SCSS comments like this:
      #     /* foo
      #   bar
      #       baz */
      content.gsub!(/^/, '   ')
      content.sub!(/\A([ \t]*)\/\*/, '/*\1')
    end

    content =
      unless content.include?("\n")
        content
      else
        content.gsub!(/\n( \*|\/\/)/, "\n  ")
        spaces = content.scan(/\n( *)/).map {|s| s.first.size}.min
        sep = node.type == :silent ? "\n//" : "\n *"
        if spaces >= 2
          content.gsub(/\n  /, sep)
        else
          content.gsub(/\n#{' ' * spaces}/, sep)
        end
      end

    content.gsub!(/\A\/\*/, '//') if node.type == :silent
    content.gsub!(/^/, tab_str)
    content.rstrip + "\n"
  else
    spaces = (@tab_chars * [@tabs - value[/^ */].size, 0].max)
    content = if node.type == :silent
      value.gsub(/^[\/ ]\*/, '//').gsub(/ *\*\/$/, '')
    else
      value
    end.gsub(/^/, spaces) + "\n"
    content
  end
  content.sub!(%{^\s*(/\*)}, '/*!') if node.type == :loud #'
  content
end
visit_content(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 217
def visit_content(node)
  "#{tab_str}@content#{semi}\n"
end
visit_cssimport(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 162
def visit_cssimport(node)
  if node.uri.is_a?(Sass::Script::Node)
    str = "#{tab_str}@import #{node.uri.to_sass(@options)}"
  else
    str = "#{tab_str}@import #{node.uri}"
  end
  str << " #{interp_to_src(node.query)}" unless node.query.empty?
  "#{str}#{semi}\n"
end
visit_debug(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 96
def visit_debug(node)
  "#{tab_str}@debug #{node.expr.to_sass(@options)}#{semi}\n"
end
visit_directive(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 100
def visit_directive(node)
  res = "#{tab_str}#{interp_to_src(node.value)}"
  res.gsub!(/^@import \#\{(.*)\}([^}]*)$/, '@import \1\2');
  return res + "#{semi}\n" unless node.has_children
  res + yield + "\n"
end
visit_each(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 107
def visit_each(node)
  "#{tab_str}@each $#{dasherize(node.var)} in #{node.list.to_sass(@options)}#{yield}"
end
visit_extend(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 111
def visit_extend(node)
  "#{tab_str}@extend #{selector_to_src(node.selector).lstrip}#{semi}#{" !optional" if node.optional?}\n"
end
visit_for(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 115
def visit_for(node)
  "#{tab_str}@for $#{dasherize(node.var)} from #{node.from.to_sass(@options)} " +
    "#{node.exclusive ? "to" : "through"} #{node.to.to_sass(@options)}#{yield}"
end
visit_function(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 120
def visit_function(node)
  args = node.args.map do |v, d|
    d ? "#{v.to_sass(@options)}: #{d.to_sass(@options)}" : v.to_sass(@options)
  end.join(", ")
  if node.splat
    args << ", " unless node.args.empty?
    args << node.splat.to_sass(@options) << "..."
  end

  "#{tab_str}@function #{dasherize(node.name)}(#{args})#{yield}"
end
visit_if(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 132
def visit_if(node)
  name =
    if !@is_else; "if"
    elsif node.expr; "else if"
    else; "else"
    end
  @is_else = false
  str = "#{tab_str}@#{name}"
  str << " #{node.expr.to_sass(@options)}" if node.expr
  str << yield
  @is_else = true
  str << visit(node.else) if node.else
  str
ensure
  @is_else = false
end
visit_import(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 149
def visit_import(node)
  quote = @format == :scss ? '"' : ''
  "#{tab_str}@import #{quote}#{node.imported_filename}#{quote}#{semi}\n"
end
visit_media(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 154
def visit_media(node)
  "#{tab_str}@media #{media_interp_to_src(node.query)}#{yield}"
end
visit_mixin(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 197
def visit_mixin(node)
  arg_to_sass = lambda do |arg|
    sass = arg.to_sass(@options)
    sass = "(#{sass})" if arg.is_a?(Sass::Script::List) && arg.separator == :comma
    sass
  end

  unless node.args.empty? && node.keywords.empty? && node.splat.nil?
    args = node.args.map(&arg_to_sass).join(", ")
    keywords = Sass::Util.hash_to_a(node.keywords).
      map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}.join(', ')
    if node.splat
      splat = (args.empty? && keywords.empty?) ? "" : ", "
      splat = "#{splat}#{arg_to_sass[node.splat]}..."
    end
    arglist = "(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords}#{splat})"
  end
  "#{tab_str}#{@format == :sass ? '+' : '@include '}#{dasherize(node.name)}#{arglist}#{node.has_children ? yield : semi}\n"
end
visit_mixindef(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 172
def visit_mixindef(node)
  args =
    if node.args.empty? && node.splat.nil?
      ""
    else
      str = '('
      str << node.args.map do |v, d|
        if d
          "#{v.to_sass(@options)}: #{d.to_sass(@options)}"
        else
          v.to_sass(@options)
        end
      end.join(", ")

      if node.splat
        str << ", " unless node.args.empty?
        str << node.splat.to_sass(@options) << '...'
      end

      str << ')'
    end

  "#{tab_str}#{@format == :sass ? '=' : '@mixin '}#{dasherize(node.name)}#{args}#{yield}"
end
visit_prop(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 221
def visit_prop(node)
  res = tab_str + node.declaration(@options, @format)
  return res + semi + "\n" if node.children.empty?
  res + yield.rstrip + semi + "\n"
end
visit_return(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 227
def visit_return(node)
  "#{tab_str}@return #{node.expr.to_sass(@options)}#{semi}\n"
end
visit_root(node) click to toggle source

Ensures proper spacing between top-level nodes.

# File lib/sass/tree/visitors/convert.rb, line 32
def visit_root(node)
  Sass::Util.enum_cons(node.children + [nil], 2).map do |child, nxt|
    visit(child) +
      if nxt &&
          (child.is_a?(Sass::Tree::CommentNode) &&
            child.line + child.lines + 1 == nxt.line) ||
          (child.is_a?(Sass::Tree::ImportNode) && nxt.is_a?(Sass::Tree::ImportNode) &&
            child.line + 1 == nxt.line) ||
          (child.is_a?(Sass::Tree::VariableNode) && nxt.is_a?(Sass::Tree::VariableNode) &&
            child.line + 1 == nxt.line)
        ""
      else
        "\n"
      end
  end.join.rstrip + "\n"
end
visit_rule(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 231
def visit_rule(node)
  if @format == :sass
    name = selector_to_sass(node.rule)
    name = "\\" + name if name[0] == ::
    name.gsub(/^/, tab_str) + yield
  elsif @format == :scss
    name = selector_to_scss(node.rule)
    res = name + yield
    if node.children.last.is_a?(Sass::Tree::CommentNode) && node.children.last.type == :silent
      res.slice!(-3..-1)
      res << "\n" << tab_str << "}\n"
    end
    res
  end
end
visit_supports(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 158
def visit_supports(node)
  "#{tab_str}@#{node.name} #{node.condition.to_src(@options)}#{yield}"
end
visit_variable(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 247
def visit_variable(node)
  "#{tab_str}$#{dasherize(node.name)}: #{node.expr.to_sass(@options)}#{' !default' if node.guarded}#{semi}\n"
end
visit_warn(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 251
def visit_warn(node)
  "#{tab_str}@warn #{node.expr.to_sass(@options)}#{semi}\n"
end
visit_while(node) click to toggle source
# File lib/sass/tree/visitors/convert.rb, line 255
def visit_while(node)
  "#{tab_str}@while #{node.expr.to_sass(@options)}#{yield}"
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.