In Files

Parent

Class Index [+]

Quicksearch

Sass::CSS

This class converts CSS documents into Sass or SCSS templates. It works by parsing the CSS document into a {Sass::Tree} structure, and then applying various transformations to the structure to produce more concise and idiomatic Sass/SCSS.

Example usage:

    Sass::CSS.new("p { color: blue }").render(:sass) #=> "p\n  color: blue"
    Sass::CSS.new("p { color: blue }").render(:scss) #=> "p {\n  color: blue; }"

Public Class Methods

new(template, options = {}) click to toggle source

@param template [String] The CSS stylesheet.

  This stylesheet can be encoded using any encoding
  that can be converted to Unicode.
  If the stylesheet contains an `@charset` declaration,
  that overrides the Ruby encoding
  (see {file:SASS_REFERENCE.md#encodings the encoding documentation})

@option options :old [Boolean] (false)

    Whether or not to output old property syntax
    (`:color blue` as opposed to `color: blue`).
    This is only meaningful when generating Sass code,
    rather than SCSS.
    # File lib/sass/css.rb, line 28
28:     def initialize(template, options = {})
29:       if template.is_a? IO
30:         template = template.read
31:       end
32: 
33:       @options = options.dup
34:       # Backwards compatibility
35:       @options[:old] = true if @options[:alternate] == false
36:       @template = template
37:     end

Public Instance Methods

render(fmt = :sass) click to toggle source

Converts the CSS template into Sass or SCSS code.

@param fmt [Symbol] `:sass` or `:scss`, designating the format to return. @return [String] The resulting Sass or SCSS code @raise [Sass::SyntaxError] if there’s an error parsing the CSS template

    # File lib/sass/css.rb, line 44
44:     def render(fmt = :sass)
45:       check_encoding!
46:       build_tree.send("to_#{fmt}", @options).strip + "\n"
47:     rescue Sass::SyntaxError => err
48:       err.modify_backtrace(:filename => @options[:filename] || '(css)')
49:       raise err
50:     end
source_encoding() click to toggle source

Returns the original encoding of the document, or `nil` under Ruby 1.8.

@return [Encoding, nil] @raise [Encoding::UndefinedConversionError] if the source encoding

  cannot be converted to UTF-8

@raise [ArgumentError] if the document uses an unknown encoding with `@charset`

    # File lib/sass/css.rb, line 59
59:     def source_encoding
60:       check_encoding!
61:       @original_encoding
62:     end

Private Instance Methods

build_tree() click to toggle source

Parses the CSS template and applies various transformations

@return [Tree::Node] The root node of the parsed tree

    # File lib/sass/css.rb, line 77
77:     def build_tree
78:       root = Sass::SCSS::CssParser.new(@template).parse
79:       expand_commas      root
80:       parent_ref_rules   root
81:       remove_parent_refs root
82:       flatten_rules      root
83:       fold_commas        root
84:       root
85:     end
check_encoding!() click to toggle source
    # File lib/sass/css.rb, line 66
66:     def check_encoding!
67:       return if @checked_encoding
68:       @checked_encoding = true
69:       @template, @original_encoding = Haml::Util.check_sass_encoding(@template) do |msg, line|
70:         raise Sass::SyntaxError.new(msg, :line => line)
71:       end
72:     end
expand_commas(root) click to toggle source

Transform

    foo, bar, baz
      color: blue

into

    foo
      color: blue
    bar
      color: blue
    baz
      color: blue

@param root [Tree::Node] The parent node

     # File lib/sass/css.rb, line 102
102:     def expand_commas(root)
103:       root.children.map! do |child|
104:         unless child.is_a?(Tree::RuleNode) && child.rule.first.include?(',')
105:           expand_commas(child) if child.is_a?(Tree::DirectiveNode)
106:           next child
107:         end
108:         child.rule.first.split(',').map do |rule|
109:           node = Tree::RuleNode.new([rule.strip])
110:           node.children = child.children
111:           node
112:         end
113:       end
114:       root.children.flatten!
115:     end
flatten_rule(rule) click to toggle source

Flattens a single rule

@param rule [Tree::RuleNode] The candidate for flattening @see #

     # File lib/sass/css.rb, line 243
243:     def flatten_rule(rule)
244:       while rule.children.size == 1 && rule.children.first.is_a?(Tree::RuleNode)
245:         child = rule.children.first
246: 
247:         if child.rule.first[0] == &&
248:           rule.rule = [child.rule.first.gsub(/^&/, rule.rule.first)]
249:         else
250:           rule.rule = ["#{rule.rule.first} #{child.rule.first}"]
251:         end
252: 
253:         rule.children = child.children
254:       end
255: 
256:       flatten_rules(rule)
257:     end
flatten_rules(root) click to toggle source

Flatten rules so that

    foo
      bar
        color: red

becomes

    foo bar
      color: red

and

    foo
      &.bar
        color: blue

becomes

    foo.bar
      color: blue

@param root [Tree::Node] The parent node

     # File lib/sass/css.rb, line 228
228:     def flatten_rules(root)
229:       root.children.each do |child|
230:         case child
231:         when Tree::RuleNode
232:           flatten_rule(child)
233:         when Tree::DirectiveNode
234:           flatten_rules(child)
235:         end
236:       end
237:     end
fold_commas(root) click to toggle source

Transform

    foo
      bar
        color: blue
      baz
        color: blue

into

    foo
      bar, baz
        color: blue

@param rule [Tree::RuleNode] The candidate for flattening

     # File lib/sass/css.rb, line 274
274:     def fold_commas(root)
275:       prev_rule = nil
276:       root.children.map! do |child|
277:         unless child.is_a?(Tree::RuleNode)
278:           fold_commas(child) if child.is_a?(Tree::DirectiveNode)
279:           next child
280:         end
281: 
282:         if prev_rule && prev_rule.children == child.children
283:           prev_rule.rule.first << ", #{child.rule.first}"
284:           next nil
285:         end
286: 
287:         fold_commas(child)
288:         prev_rule = child
289:         child
290:       end
291:       root.children.compact!
292:     end
parent_ref_rules(root) click to toggle source

Make rules use parent refs so that

    foo
      color: green
    foo.bar
      color: blue

becomes

    foo
      color: green
      &.bar
        color: blue

This has the side effect of nesting rules, so that

    foo
      color: green
    foo bar
      color: red
    foo baz
      color: blue

becomes

    foo
      color: green
      & bar
        color: red
      & baz
        color: blue

@param root [Tree::Node] The parent node

     # File lib/sass/css.rb, line 151
151:     def parent_ref_rules(root)
152:       current_rule = nil
153:       root.children.map! do |child|
154:         unless child.is_a?(Tree::RuleNode)
155:           parent_ref_rules(child) if child.is_a?(Tree::DirectiveNode)
156:           next child
157:         end
158: 
159:         first, rest = child.rule.first.scan(/\A(&?(?: .|[^ ])[^.#: \[]*)([.#: \[].*)?\Z/).first
160: 
161:         if current_rule.nil? || current_rule.rule.first != first
162:           current_rule = Tree::RuleNode.new([first])
163:         end
164: 
165:         if rest
166:           child.rule = ["&" + rest]
167:           current_rule << child
168:         else
169:           current_rule.children += child.children
170:         end
171: 
172:         current_rule
173:       end
174:       root.children.compact!
175:       root.children.uniq!
176: 
177:       root.children.each { |v| parent_ref_rules(v) }
178:     end
remove_parent_refs(root) click to toggle source

Remove useless parent refs so that

    foo
      & bar
        color: blue

becomes

    foo
      bar
        color: blue

@param root [Tree::Node] The parent node

     # File lib/sass/css.rb, line 193
193:     def remove_parent_refs(root)
194:       root.children.each do |child|
195:         case child
196:         when Tree::RuleNode
197:           child.rule.first.gsub! /^& +/, ''
198:           remove_parent_refs child
199:         when Tree::DirectiveNode
200:           remove_parent_refs child
201:         end
202:       end
203:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.