Class: Sass::Tree::Visitors::Convert

### Home Classes Methods

### In Files

- lib/sass/tree/visitors/convert.rb

### Parent

Sass::Tree::Visitors::Base

### Methods

- ::new
- ::visit
- #visit_atroot
- #visit_charset
- #visit_children
- #visit_comment
- #visit_content
- #visit_cssimport
- #visit_debug
- #visit_directive
- #visit_each
- #visit_error
- #visit_extend
- #visit_for
- #visit_function
- #visit_if
- #visit_import
- #visit_keyframerule
- #visit_media
- #visit_mixin
- #visit_mixindef
- #visit_prop
- #visit_return
- #visit_root
- #visit_rule
- #visit_supports
- #visit_variable
- #visit_warn
- #visit_while

### Class/Module Index

Quicksearch

- Sass
- Sass::BaseEnvironment
- Sass::CSS
- Sass::CacheStores
- Sass::CacheStores::Base
- Sass::CacheStores::Chain
- Sass::CacheStores::Filesystem
- Sass::CacheStores::Memory
- Sass::CacheStores::Null
- Sass::Callbacks
- Sass::Callbacks::InstanceMethods
- Sass::Engine
- Sass::Engine::Line
- Sass::Environment
- Sass::Exec
- Sass::Exec::Base
- Sass::Exec::SassConvert
- Sass::Exec::SassScss
- Sass::Exec::SassScss::Sass::Plugin.compiler
- Sass::Features
- Sass::Importers
- Sass::Importers::Base
- Sass::Importers::Filesystem
- Sass::Logger
- Sass::Logger::Base
- Sass::Logger::LogLevel
- Sass::Logger::LogLevel::ClassMethods
- Sass::Media
- Sass::Media::Query
- Sass::Media::QueryList
- Sass::Plugin
- Sass::Plugin::Compiler
- Sass::Plugin::Configuration
- Sass::Plugin::MerbBootLoader
- Sass::Plugin::Rack
- Sass::Plugin::StalenessChecker
- Sass::ReadOnlyEnvironment
- Sass::Repl
- Sass::SCSS
- Sass::SCSS::CssParser
- Sass::SCSS::Parser
- Sass::SCSS::RX
- Sass::SCSS::ScriptLexer
- Sass::SCSS::ScriptParser
- Sass::SCSS::StaticParser
- Sass::Script
- Sass::Script::CssLexer
- Sass::Script::CssParser
- Sass::Script::Functions
- Sass::Script::Functions::EvaluationContext
- Sass::Script::Lexer
- Sass::Script::Parser
- Sass::Script::Tree
- Sass::Script::Tree::Funcall
- Sass::Script::Tree::Interpolation
- Sass::Script::Tree::ListLiteral
- Sass::Script::Tree::Literal
- Sass::Script::Tree::MapLiteral
- Sass::Script::Tree::Node
- Sass::Script::Tree::Operation
- Sass::Script::Tree::Selector
- Sass::Script::Tree::StringInterpolation
- Sass::Script::Tree::UnaryOperation
- Sass::Script::Tree::Variable
- Sass::Script::Value
- Sass::Script::Value::ArgList
- Sass::Script::Value::Base
- Sass::Script::Value::Bool
- Sass::Script::Value::Color
- Sass::Script::Value::Helpers
- Sass::Script::Value::List
- Sass::Script::Value::Map
- Sass::Script::Value::Null
- Sass::Script::Value::Number
- Sass::Selector
- Sass::Selector::AbstractSequence
- Sass::Selector::Attribute
- Sass::Selector::Class
- Sass::Selector::CommaSequence
- Sass::Selector::Element
- Sass::Selector::Id
- Sass::Selector::Parent
- Sass::Selector::Placeholder
- Sass::Selector::Pseudo
- Sass::Selector::Sequence
- Sass::Selector::Simple
- Sass::Selector::SimpleSequence
- Sass::Selector::Universal
- Sass::SemiGlobalEnvironment
- Sass::Shared
- Sass::Source
- Sass::Source::Map
- Sass::Source::Map::Mapping
- Sass::Source::Position
- Sass::Source::Range
- Sass::Stack
- Sass::Stack::Frame
- Sass::Supports
- Sass::Supports::Condition
- Sass::Supports::Declaration
- Sass::Supports::Interpolation
- Sass::Supports::Negation
- Sass::Supports::Operator
- Sass::SyntaxError
- Sass::Tree
- Sass::Tree::AtRootNode
- Sass::Tree::CharsetNode
- Sass::Tree::CommentNode
- Sass::Tree::ContentNode
- Sass::Tree::CssImportNode
- Sass::Tree::DebugNode
- Sass::Tree::DirectiveNode
- Sass::Tree::EachNode
- Sass::Tree::ErrorNode
- Sass::Tree::ExtendNode
- Sass::Tree::ForNode
- Sass::Tree::FunctionNode
- Sass::Tree::IfNode
- Sass::Tree::ImportNode
- Sass::Tree::KeyframeRuleNode
- Sass::Tree::MediaNode
- Sass::Tree::MixinDefNode
- Sass::Tree::MixinNode
- Sass::Tree::Node
- Sass::Tree::PropNode
- Sass::Tree::ReturnNode
- Sass::Tree::RootNode
- Sass::Tree::RuleNode
- Sass::Tree::SupportsNode
- Sass::Tree::TraceNode
- Sass::Tree::VariableNode
- Sass::Tree::Visitors
- Sass::Tree::Visitors::Base
- Sass::Tree::Visitors::CheckNesting
- Sass::Tree::Visitors::Convert
- Sass::Tree::Visitors::Cssize
- Sass::Tree::Visitors::Cssize::Bubble
- Sass::Tree::Visitors::DeepCopy
- Sass::Tree::Visitors::Extend
- Sass::Tree::Visitors::Perform
- Sass::Tree::Visitors::SetOptions
- Sass::Tree::Visitors::ToCss
- Sass::Tree::WarnNode
- Sass::Tree::WhileNode
- Sass::UnitConversionError
- Sass::Util
- Sass::Util::CrossPlatformRandom
- Sass::Util::MultibyteStringScanner
- Sass::Util::NormalizedMap
- Sass::Util::SubsetMap
- Sass::Util::Test
- Sass::Version
- ActionController
- ActionController::Base
- Object
- OrderedHash

No matching classes.

# 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_atroot(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 272
    def visit_atroot(node)
      if node.query
        "#{tab_str}@at-root #{query_interp_to_src(node.query)}#{yield}"
      elsif node.children.length == 1 && node.children.first.is_a?(Sass::Tree::RuleNode)
        rule = node.children.first
        "#{tab_str}@at-root #{selector_to_src(rule.rule).lstrip}#{visit_children(rule)}"
      else
        "#{tab_str}@at-root#{yield}"
      end
    end

visit_charset(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 53
    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?
      if @format == :sass
        "\n"  + super.join.rstrip + "\n"
      else
        " {\n" + super.join.rstrip + "\n#{ @tab_chars * (@tabs - 1)}}\n"
      end
    ensure
      @tabs -= 1
    end

visit_comment(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 57
    def visit_comment(node)
      value = interp_to_src(node.value)
      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

        if content.include?("\n")
          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 = 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"
      end
      content
    end

visit_content(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 228
    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 170
    def visit_cssimport(node)
      if node.uri.is_a?(Sass::Script::Tree::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 95
    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 103
    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 110
    def visit_each(node)
      vars = node.vars.map {|var| "$#{dasherize(var)}"}.join(", ")
      "#{tab_str}@each #{vars} in #{node.list.to_sass(@options)}#{yield}"
    end

visit_error(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 99
    def visit_error(node)
      "#{tab_str}@error #{node.expr.to_sass(@options)}#{semi}\n"
    end

visit_extend(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 115
    def visit_extend(node)
      "#{tab_str}@extend #{selector_to_src(node.selector).lstrip}" +
        "#{" !optional" if node.optional?}#{semi}\n"
    end

visit_for(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 120
    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 125
    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 137
    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 157
    def visit_import(node)
      quote = @format == :scss ? '"' : ''
      "#{tab_str}@import #{quote}#{node.imported_filename}#{quote}#{semi}\n"
    end

visit_keyframerule(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 283
    def visit_keyframerule(node)
      "#{tab_str}#{node.resolved_value}#{yield}\n"
    end

visit_media(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 162
    def visit_media(node)
      "#{tab_str}@media #{query_interp_to_src(node.query)}#{yield}"
    end

visit_mixin(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 205
    def visit_mixin(node)
      arg_to_sass = lambda do |arg|
        sass = arg.to_sass(@options)
        sass = "(#{sass})" if arg.is_a?(Sass::Script::Tree::ListLiteral) && arg.separator == :comma
        sass
      end

      unless node.args.empty? && node.keywords.empty? && node.splat.nil?
        args = node.args.map(&arg_to_sass)
        keywords = Sass::Util.hash_to_a(node.keywords.as_stored).
          map {|k, v| "$#{dasherize(k)}: #{arg_to_sass[v]}"}

        if node.splat
          splat = "#{arg_to_sass[node.splat]}..."
          kwarg_splat = "#{arg_to_sass[node.kwarg_splat]}..." if node.kwarg_splat
        end

        arglist = "(#{[args, splat, keywords, kwarg_splat].flatten.compact.join(', ')})"
      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 180
    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 232
    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 238
    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 36
    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 242
    def visit_rule(node)
      rule = node.parsed_rules ? [node.parsed_rules.to_s] : node.rule
      if @format == :sass
        name = selector_to_sass(rule)
        name = "\\" + name if name[0] == ::
        name.gsub(/^/, tab_str) + yield
      elsif @format == :scss
        name = selector_to_scss(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 166
    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 259
    def visit_variable(node)
      "#{tab_str}$#{dasherize(node.name)}: #{node.expr.to_sass(@options)}" +
        "#{' !global' if node.global}#{' !default' if node.guarded}#{semi}\n"
    end

visit_warn(node) click to toggle source

    # File lib/sass/tree/visitors/convert.rb, line 264
    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 268
    def visit_while(node)
      "#{tab_str}@while #{node.expr.to_sass(@options)}#{yield}"
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.