Class: Stylish::Generate::Description

Inherits:
Object
  • Object
show all
Includes:
ElementMethods
Defined in:
lib/stylish/generate.rb

Overview

Description objects are the core of the stylesheet generation DSL. Blocks passed into the +Stylish#generate_ method are executed in the context of a Description object. All the DSL methods, rule, comment, and all the HTML element methods are all methods on instances of the Description class.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context = nil) ⇒ Description

Description instances are associated with a particular node in a selector tree; if no node is assigned to them on creation, they associate with a new root, i.e. a Stylesheet object.



205
206
207
# File 'lib/stylish/generate.rb', line 205

def initialize(context = nil)
  @node = context || Stylesheet.new
end

Instance Attribute Details

#nodeObject (readonly)

Returns the value of attribute node.



200
201
202
# File 'lib/stylish/generate.rb', line 200

def node
  @node
end

Instance Method Details

#comment(*args) ⇒ Object

Adds a Comment object to the current node. This method simply hands its arguments off to the Comment initialiser, and hence implements its API precisely.



283
284
285
# File 'lib/stylish/generate.rb', line 283

def comment(*args)
  @node << Comment.new(*args)
end

#rule(selectors, declarations = nil, &block) ⇒ Object

The rule method is the most general and powerful part of the DSL. It can be used to add a single Rule, with attendant declarations, or to create a selector namespace within which further rules or namespaces can be added.

The nested structure created is precisely that of a selector tree; the rule method adds Rule leaves and SelectorScope nodes to the tree, whose root is a Stylesheet object.

Either a set of declarations or a block must be passed to the method; failing to do so will result in an early return which creates no additional objects. The following example demonstrates the various ways in which the method can be used:

Stylish.generate do
  rule ".section", :margin_bottom => "10px"

  rule "form" do
    rule ".notice", :color => "#00f"
    rule "input[type=submit]", :font_weight => "normal"
  end

  rule "body", :padding => "0.5em" do
    rule "div", :margin => "2px"
  end
end

This would produce a stylesheet with the following rules:

.section {margin-bottom:10px;}

form .notice {color:#00f;}
form input[type=submit] {font-weight:normal;}

body {padding:0.5em;}
body div {margin:2px;}

Usefully, a call to #rule which passes in both declarations and a block will produce a single Rule with the declarations attached, then create a new SelectorScope node with the same selectors and execute the block in that context.

If several selectors and a block are passed to rule, new SelectorScope nodes will be created for each selector and the block will be executed in all the contexts created, not just one.



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/stylish/generate.rb', line 254

def rule(selectors, declarations = nil, &block)
  return unless declarations || block
  
  selectors = [selectors] unless selectors.is_a?(Array)
  selectors.map! do |s|
    s.is_a?(Symbol) ? Variable.new(s, Selector) : Selector.new(s)
  end
  
  declarations = Generate.parse_declarations(declarations)
  
  unless block
    @node << Rule.new(selectors, declarations)
  else
    selectors.each do |selector|
      unless declarations.empty?
        @node << Rule.new([selector], declarations)
      end
      
      new_node = Tree::SelectorScope.new(selector)
      @node << new_node
      
      self.class.new(new_node).instance_eval(&block)
    end
  end
end