# A visitor for converting a Sass tree into CSS. class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base protected def initialize @tabs = 0 end def visit(node) super rescue Sass::SyntaxError => e e.modify_backtrace(:filename => node.filename, :line => node.line) raise e end def with_tabs(tabs) old_tabs, @tabs = @tabs, tabs yield ensure @tabs = old_tabs end 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/i 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 def visit_charset(node) "@charset \"#{node.name}\";" end def visit_comment(node) return if node.invisible? spaces = (' ' * [@tabs - node.value[/^ */].size, 0].max) content = node.value.gsub(/^/, spaces).gsub(%r{^(\s*)//(.*)$}) do |md| "#{$1}/*#{$2} */" end if content =~ /[^\\]\#\{.*\}/ Sass::Util.sass_warn < false, :line_comments => false, :style => :compressed) node end end