Class: Sass::Tree::Visitors::ToCss

### Home Classes Methods

### In Files

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

### Parent

Sass::Tree::Visitors::Base

### Methods

- ::new
- #visit
- #visit_charset
- #visit_comment
- #visit_cssimport
- #visit_directive
- #visit_media
- #visit_prop
- #visit_root
- #visit_rule
- #visit_supports
- #with_tabs

### Class/Module Index

Quicksearch

- Sass
- 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::Generic
- Sass::Exec::Sass
- Sass::Exec::SassConvert
- Sass::Exec::Scss
- 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::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::ArgList
- Sass::Script::Bool
- Sass::Script::Color
- Sass::Script::CssLexer
- Sass::Script::CssParser
- Sass::Script::Funcall
- Sass::Script::Functions
- Sass::Script::Functions::EvaluationContext
- Sass::Script::Interpolation
- Sass::Script::Lexer
- Sass::Script::List
- Sass::Script::Literal
- Sass::Script::Node
- Sass::Script::Null
- Sass::Script::Number
- Sass::Script::Operation
- Sass::Script::Parser
- Sass::Script::String
- Sass::Script::StringInterpolation
- Sass::Script::UnaryOperation
- Sass::Script::Variable
- Sass::Selector
- Sass::Selector::AbstractSequence
- Sass::Selector::Attribute
- Sass::Selector::Class
- Sass::Selector::CommaSequence
- Sass::Selector::Element
- Sass::Selector::Id
- Sass::Selector::Interpolation
- Sass::Selector::Parent
- Sass::Selector::Placeholder
- Sass::Selector::Pseudo
- Sass::Selector::SelectorPseudoClass
- Sass::Selector::Sequence
- Sass::Selector::Simple
- Sass::Selector::SimpleSequence
- Sass::Selector::Universal
- Sass::Shared
- Sass::Supports
- Sass::Supports::Condition
- Sass::Supports::Declaration
- Sass::Supports::Interpolation
- Sass::Supports::Negation
- Sass::Supports::Operator
- Sass::SyntaxError
- Sass::Tree
- Sass::Tree::CharsetNode
- Sass::Tree::CommentNode
- Sass::Tree::ContentNode
- Sass::Tree::CssImportNode
- Sass::Tree::DebugNode
- Sass::Tree::DirectiveNode
- Sass::Tree::EachNode
- Sass::Tree::ExtendNode
- Sass::Tree::ForNode
- Sass::Tree::FunctionNode
- Sass::Tree::IfNode
- Sass::Tree::ImportNode
- 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::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::MultibyteStringScanner
- Sass::Util::StaticConditionalContext
- Sass::Util::SubsetMap
- Sass::Util::Test
- Sass::Version
- ActionController
- ActionController::Base
- Object

No matching classes.

# Sass::Tree::Visitors::ToCss

A visitor for converting a Sass tree into CSS.

### Public Class Methods

new() click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 5
    def initialize
      @tabs = 0
    end

### Protected Instance Methods

visit(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 9
    def visit(node)
      super
    rescue Sass::SyntaxError => e
      e.modify_backtrace(:filename => node.filename, :line => node.line)
      raise e
    end

visit_charset(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 54
    def visit_charset(node)
      "@charset \"#{node.name}\";"
    end

visit_comment(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 58
    def visit_comment(node)
      return if node.invisible?
      spaces = ('  ' * [@tabs - node.resolved_value[/^ */].size, 0].max)

      content = node.resolved_value.gsub(/^/, spaces)
      content.gsub!(%{^(\s*)//(.*)$}) {|md| "#{$1}/*#{$2} */"} if node.type == :silent
      content.gsub!(/\n +(\* *(?!\/))?/, ' ') if (node.style == :compact || node.style == :compressed) && node.type != :loud
      content
    end

visit_cssimport(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 120
    def visit_cssimport(node)
      visit_directive(node)
    end

visit_directive(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 68
    def visit_directive(node)
      was_in_directive = @in_directive
      tab_str = '  ' * @tabs
      return tab_str + node.resolved_value + ";" unless node.has_children
      return tab_str + node.resolved_value + " {}" if node.children.empty?
      @in_directive = @in_directive || !node.is_a?(Sass::Tree::MediaNode)
      result = if node.style == :compressed
                 "#{node.resolved_value}{"
               else
                 "#{tab_str}#{node.resolved_value} {" + (node.style == :compact ? ' ' : "\n")
               end
      was_prop = false
      first = true
      node.children.each do |child|
        next if child.invisible?
        if node.style == :compact
          if child.is_a?(Sass::Tree::PropNode)
            with_tabs(first || was_prop ? 0 : @tabs + 1) {result << visit(child) << ' '}
          else
            result[-1] = "\n" if was_prop
            rendered = with_tabs(@tabs + 1) {visit(child).dup}
            rendered = rendered.lstrip if first
            result << rendered.rstrip + "\n"
          end
          was_prop = child.is_a?(Sass::Tree::PropNode)
          first = false
        elsif node.style == :compressed
          result << (was_prop ? ";" : "") << with_tabs(0) {visit(child)}
          was_prop = child.is_a?(Sass::Tree::PropNode)
        else
          result << with_tabs(@tabs + 1) {visit(child)} + "\n"
        end
      end
      result.rstrip + if node.style == :compressed
                        "}"
                      else
                        (node.style == :expanded ? "\n" : " ") + "}\n"
                      end
    ensure
      @in_directive = was_in_directive
    end

visit_media(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 110
    def visit_media(node)
      str = with_tabs(@tabs + node.tabs) {visit_directive(node)}
      str.gsub!(/\n\Z/, '') unless node.style == :compressed || node.group_end
      str
    end

visit_prop(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 124
    def visit_prop(node)
      return if node.resolved_value.empty?
      tab_str = '  ' * (@tabs + node.tabs)
      if node.style == :compressed
        "#{tab_str}#{node.resolved_name}:#{node.resolved_value}"
      else
        "#{tab_str}#{node.resolved_name}: #{node.resolved_value};"
      end
    end

visit_root(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 23
    def visit_root(node)
      result = String.new
      node.children.each do |child|
        next if child.invisible?
        child_str = visit(child)
        result << child_str + (node.style == :compressed ? '' : "\n")
      end
      result.rstrip!
      return "" if result.empty?
      result << "\n"
      unless Sass::Util.ruby1_8? || result.ascii_only?
        if node.children.first.is_a?(Sass::Tree::CharsetNode)
          begin
            encoding = node.children.first.name
            # Default to big-endian encoding, because we have to decide somehow
            encoding << 'BE' if encoding =~ /\Autf-(16|32)\Z/
            result = result.encode(Encoding.find(encoding))
          rescue EncodingError
          end
        end

        result = "@charset \"#{result.encoding.name}\";#{
          node.style == :compressed ? '' : "\n"
        }".encode(result.encoding) + result
      end
      result
    rescue Sass::SyntaxError => e
      e.sass_template ||= node.template
      raise e
    end

visit_rule(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 134
    def visit_rule(node)
      with_tabs(@tabs + node.tabs) do
        rule_separator = node.style == :compressed ? ',' : ', '
        line_separator =
          case node.style
            when :nested, :expanded; "\n"
            when :compressed; ""
            else; " "
          end
        rule_indent = '  ' * @tabs
        per_rule_indent, total_indent = [:nested, :expanded].include?(node.style) ? [rule_indent, ''] : ['', rule_indent]

        joined_rules = node.resolved_rules.members.map do |seq|
          next if seq.has_placeholder?
          rule_part = seq.to_a.join
          if node.style == :compressed
            rule_part.gsub!(/([^,])\s*\n\s*/, '\1 ')
            rule_part.gsub!(/\s*([,+>])\s*/, '\1')
            rule_part.strip!
          end
          rule_part
        end.compact.join(rule_separator)

        joined_rules.sub!(/\A\s*/, per_rule_indent)
        joined_rules.gsub!(/\s*\n\s*/, "#{line_separator}#{per_rule_indent}")
        total_rule = total_indent << joined_rules

        to_return = ''
        old_spaces = '  ' * @tabs
        spaces = '  ' * (@tabs + 1)
        if node.style != :compressed
          if node.options[:debug_info] && !@in_directive
            to_return << visit(debug_info_rule(node.debug_info, node.options)) << "\n"
          elsif node.options[:trace_selectors]
            to_return << "#{old_spaces}/* "
            to_return << node.stack_trace.join("\n   #{old_spaces}")
            to_return << " */\n"
          elsif node.options[:line_comments]
            to_return << "#{old_spaces}/* line #{node.line}"

            if node.filename
              relative_filename = if node.options[:css_filename]
                begin
                  Pathname.new(node.filename).relative_path_from(
                    Pathname.new(File.dirname(node.options[:css_filename]))).to_s
                rescue ArgumentError
                  nil
                end
              end
              relative_filename ||= node.filename
              to_return << ", #{relative_filename}"
            end

            to_return << " */\n"
          end
        end

        if node.style == :compact
          properties = with_tabs(0) {node.children.map {|a| visit(a)}.join(' ')}
          to_return << "#{total_rule} { #{properties} }#{"\n" if node.group_end}"
        elsif node.style == :compressed
          properties = with_tabs(0) {node.children.map {|a| visit(a)}.join(';')}
          to_return << "#{total_rule}{#{properties}}"
        else
          properties = with_tabs(@tabs + 1) {node.children.map {|a| visit(a)}.join("\n")}
          end_props = (node.style == :expanded ? "\n" + old_spaces : ' ')
          to_return << "#{total_rule} {\n#{properties}#{end_props}}#{"\n" if node.group_end}"
        end

        to_return
      end
    end

visit_supports(node) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 116
    def visit_supports(node)
      visit_media(node)
    end

with_tabs(tabs) click to toggle source

    # File lib/sass/tree/visitors/to_css.rb, line 16
    def with_tabs(tabs)
      old_tabs, @tabs = @tabs, tabs
      yield
    ensure
      @tabs = old_tabs
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.