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_cssimport(node) protected
- #visit_directive(node) protected
- #visit_media(node) protected
- #visit_prop(node) protected
- #visit_root(node) protected
- #visit_rule(node) protected
- #visit_supports(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 |
# 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!(%r{^(\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) (protected)
120 121 122 |
# File 'lib/sass/tree/visitors/to_css.rb', line 120
def visit_cssimport(node)
visit_directive(node)
end
|
#visit_directive(node) (protected)
68 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 105 106 107 108 |
# 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) (protected)
110 111 112 113 114 |
# 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) (protected)
124 125 126 127 128 129 130 131 132 |
# 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) (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)
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 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# 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*/m, '\1 ')
rule_part.gsub!(/\s*([,+>])\s*/m, '\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
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) (protected)
116 117 118 |
# File 'lib/sass/tree/visitors/to_css.rb', line 116
def visit_supports(node)
visit_media(node)
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
|