Class: Sass::Tree::Visitors::ToCss
- Defined in:
- lib/sass/tree/visitors/to_css.rb
Overview
A visitor for converting a Sass tree into CSS.
Constant Summary
Constants inherited from Base
Instance Method Summary collapse
-
#initialize ⇒ ToCss
constructor
protected
A new instance of ToCss.
- #visit(node) protected
- #visit_charset(node) protected
- #visit_comment(node) protected
- #visit_directive(node) protected
- #visit_media(node) protected
- #visit_prop(node) protected
- #visit_root(node) protected
- #visit_rule(node) protected
- #with_tabs(tabs) protected
Methods inherited from Base
#node_name, visit, #visit_children, #visit_if
Constructor Details
#initialize ⇒ ToCss (protected)
Returns a new instance of ToCss.
5 6 7 |
# File 'lib/sass/tree/visitors/to_css.rb', line 5
def initialize
@tabs = 0
end
|
Instance Method Details
#visit(node) (protected)
9 10 11 12 13 14 |
# 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) (protected)
54 55 56 |
# File 'lib/sass/tree/visitors/to_css.rb', line 54
def visit_charset(node)
"@charset \"#{node.name}\";"
end
|
#visit_comment(node) (protected)
58 59 60 61 62 63 64 65 66 67 |
# 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).gsub(%r{^(\s*)//(.*)$}) do |md|
"#{$1}/*#{$2} */"
end
content.gsub!(/\n +(\* *(?!\/))?/, ' ') if (node.style == :compact || node.style == :compressed) && !node.loud
content
end
|
#visit_directive(node) (protected)
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/sass/tree/visitors/to_css.rb', line 69
def visit_directive(node)
return node.value + ";" unless node.has_children
return node.value + " {}" if node.children.empty?
result = if node.style == :compressed
"#{node.value}{"
else
"#{' ' * @tabs}#{node.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
end
|
#visit_media(node) (protected)
106 107 108 109 110 |
# File 'lib/sass/tree/visitors/to_css.rb', line 106
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) (protected)
112 113 114 115 116 117 118 119 |
# File 'lib/sass/tree/visitors/to_css.rb', line 112
def visit_prop(node)
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) (protected)
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# 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/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
|
#visit_rule(node) (protected)
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/sass/tree/visitors/to_css.rb', line 121
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|
rule_part = seq.to_a.join
rule_part.gsub!(/\s*([^,])\s*\n\s*/m, '\1 ') if node.style == :compressed
rule_part
end.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]
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
|
#with_tabs(tabs) (protected)
16 17 18 19 20 21 |
# 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
|