haml-edge 2.1.21 → 2.1.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/EDGE_GEM_VERSION +1 -1
  2. data/FAQ.md +142 -0
  3. data/{README.rdoc → README.md} +141 -141
  4. data/Rakefile +29 -17
  5. data/VERSION +1 -1
  6. data/lib/haml/buffer.rb +63 -27
  7. data/lib/haml/engine.rb +103 -80
  8. data/lib/haml/error.rb +7 -7
  9. data/lib/haml/exec.rb +80 -26
  10. data/lib/haml/filters.rb +106 -40
  11. data/lib/haml/helpers/action_view_extensions.rb +34 -39
  12. data/lib/haml/helpers/action_view_mods.rb +132 -139
  13. data/lib/haml/helpers.rb +207 -153
  14. data/lib/haml/html.rb +40 -21
  15. data/lib/haml/precompiler.rb +2 -0
  16. data/lib/haml/shared.rb +34 -3
  17. data/lib/haml/template/patch.rb +1 -1
  18. data/lib/haml/template/plugin.rb +0 -2
  19. data/lib/haml/template.rb +5 -0
  20. data/lib/haml/util.rb +136 -1
  21. data/lib/haml/version.rb +16 -4
  22. data/lib/haml.rb +502 -481
  23. data/lib/sass/css.rb +106 -68
  24. data/lib/sass/engine.rb +55 -22
  25. data/lib/sass/environment.rb +52 -21
  26. data/lib/sass/error.rb +23 -12
  27. data/lib/sass/files.rb +27 -0
  28. data/lib/sass/plugin/merb.rb +2 -2
  29. data/lib/sass/plugin/rails.rb +0 -2
  30. data/lib/sass/plugin.rb +32 -23
  31. data/lib/sass/repl.rb +7 -0
  32. data/lib/sass/script/bool.rb +9 -5
  33. data/lib/sass/script/color.rb +87 -1
  34. data/lib/sass/script/funcall.rb +23 -2
  35. data/lib/sass/script/functions.rb +93 -44
  36. data/lib/sass/script/lexer.rb +33 -3
  37. data/lib/sass/script/literal.rb +93 -1
  38. data/lib/sass/script/node.rb +14 -0
  39. data/lib/sass/script/number.rb +128 -4
  40. data/lib/sass/script/operation.rb +16 -1
  41. data/lib/sass/script/parser.rb +51 -21
  42. data/lib/sass/script/string.rb +7 -4
  43. data/lib/sass/script/unary_operation.rb +14 -1
  44. data/lib/sass/script/variable.rb +12 -1
  45. data/lib/sass/script.rb +26 -5
  46. data/lib/sass/tree/attr_node.rb +46 -9
  47. data/lib/sass/tree/comment_node.rb +41 -1
  48. data/lib/sass/tree/debug_node.rb +8 -0
  49. data/lib/sass/tree/directive_node.rb +20 -0
  50. data/lib/sass/tree/file_node.rb +12 -0
  51. data/lib/sass/tree/for_node.rb +15 -0
  52. data/lib/sass/tree/if_node.rb +22 -0
  53. data/lib/sass/tree/mixin_def_node.rb +12 -1
  54. data/lib/sass/tree/mixin_node.rb +13 -0
  55. data/lib/sass/tree/node.rb +136 -6
  56. data/lib/sass/tree/rule_node.rb +66 -7
  57. data/lib/sass/tree/variable_node.rb +10 -0
  58. data/lib/sass/tree/while_node.rb +11 -1
  59. data/lib/sass.rb +544 -534
  60. metadata +7 -6
  61. data/FAQ +0 -138
data/lib/sass/script.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'strscan'
2
+ require 'sass/script/node'
2
3
  require 'sass/script/variable'
3
4
  require 'sass/script/funcall'
4
5
  require 'sass/script/operation'
@@ -6,22 +7,43 @@ require 'sass/script/literal'
6
7
  require 'sass/script/parser'
7
8
 
8
9
  module Sass
9
- # This module contains various SassScript-related functionality.
10
+ # SassScript is code that's embedded in Sass documents
11
+ # to allow for property values to be computed from variables.
12
+ #
13
+ # This module contains code that handles the parsing and evaluation of SassScript.
10
14
  module Script
11
- # :stopdoc:
12
15
  # The character that begins a variable.
13
16
  VARIABLE_CHAR = ?!
14
17
 
15
- # The regular expression used to parse variables
18
+ # The regular expression used to parse variables.
16
19
  MATCH = /^!([a-zA-Z_]\w*)\s*((?:\|\|)?=)\s*(.+)/
17
20
 
18
- # The regular expression used to validate variables without matching
21
+ # The regular expression used to validate variables without matching.
19
22
  VALIDATE = /^![a-zA-Z_]\w*$/
20
23
 
24
+ # Parses and evaluates a string of SassScript.
25
+ #
26
+ # @param value [String] The SassScript
27
+ # @param line [Fixnum] The number of the line on which the SassScript appeared.
28
+ # Used for error reporting
29
+ # @param offset [Fixnum] The number of characters in on `line` that the SassScript started.
30
+ # Used for error reporting
31
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
32
+ # @return [String] The string result of evaluating the SassScript
21
33
  def self.resolve(value, line, offset, environment)
22
34
  parse(value, line, offset).perform(environment).to_s
23
35
  end
24
36
 
37
+ # Parses a string of SassScript
38
+ #
39
+ # @param value [String] The SassScript
40
+ # @param line [Fixnum] The number of the line on which the SassScript appeared.
41
+ # Used for error reporting
42
+ # @param offset [Fixnum] The number of characters in on `line` that the SassScript started.
43
+ # Used for error reporting
44
+ # @param filename [String] The path to the file in which the SassScript appeared.
45
+ # Used for error reporting
46
+ # @return [Script::Node] The root node of the parse tree
25
47
  def self.parse(value, line, offset, filename = nil)
26
48
  Parser.parse(value, line, offset, filename)
27
49
  rescue Sass::SyntaxError => e
@@ -33,6 +55,5 @@ module Sass
33
55
  e.sass_line = line
34
56
  raise e
35
57
  end
36
- # :startdoc:
37
58
  end
38
59
  end
@@ -1,7 +1,23 @@
1
1
  module Sass::Tree
2
+ # A static node reprenting a CSS property.
3
+ #
4
+ # @see Sass::Tree
2
5
  class AttrNode < Node
3
- attr_accessor :name, :value
4
-
6
+ # The name of the property.
7
+ #
8
+ # @return [String]
9
+ attr_accessor :name
10
+
11
+ # The value of the property,
12
+ # either a plain string or a SassScript parse tree.
13
+ #
14
+ # @return [String, Script::Node]
15
+ attr_accessor :value
16
+
17
+ # @param name [String] See \{#name}
18
+ # @param value [String] See \{#value}
19
+ # @param attr_syntax [Symbol] `:new` if this property uses `a: b`-style syntax,
20
+ # `:old` if it uses `:a b`-style syntax
5
21
  def initialize(name, value, attr_syntax)
6
22
  @name = name
7
23
  @value = value
@@ -9,10 +25,21 @@ module Sass::Tree
9
25
  super()
10
26
  end
11
27
 
28
+ # Compares the names and values of two properties.
29
+ #
30
+ # @param other [Object] The object to compare with
31
+ # @return [Boolean] Whether or not this node and the other object
32
+ # are the same
12
33
  def ==(other)
13
34
  self.class == other.class && name == other.name && value == other.value && super
14
35
  end
15
36
 
37
+ # Computes the CSS for the property.
38
+ #
39
+ # @param tabs [Fixnum] The level of indentation for the CSS
40
+ # @param parent_name [String] The name of the parent property (e.g. `text`) or nil
41
+ # @return [String] The resulting CSS
42
+ # @raise [Sass::SyntaxError] if the attribute uses invalid syntax
16
43
  def to_s(tabs, parent_name = nil)
17
44
  if @options[:attribute_syntax] == :normal && @attr_syntax == :new
18
45
  raise Sass::SyntaxError.new("Illegal attribute syntax: can't use alternate syntax when :attribute_syntax => :normal is set.")
@@ -50,23 +77,33 @@ module Sass::Tree
50
77
  end
51
78
 
52
79
  protected
53
-
80
+
81
+ # Runs any SassScript that may be embedded in the property.
82
+ #
83
+ # @param environment [Sass::Environment] The lexical environment containing
84
+ # variable and mixin values
54
85
  def perform!(environment)
55
86
  @name = interpolate(@name, environment)
56
87
  @value = @value.is_a?(String) ? interpolate(@value, environment) : @value.perform(environment).to_s
57
88
  super
58
89
  end
59
90
 
60
- private
61
-
62
- def declaration
63
- @attr_syntax == :new ? "#{name}: #{value}" : ":#{name} #{value}"
64
- end
65
-
91
+ # Returns an error message if the given child node is invalid,
92
+ # and false otherwise.
93
+ #
94
+ # {AttrNode} only allows other {AttrNode}s and {CommentNode}s as children.
95
+ # @param child [Tree::Node] A potential child node
96
+ # @return [String] An error message if the child is invalid, or nil otherwise
66
97
  def invalid_child?(child)
67
98
  if !child.is_a?(AttrNode) && !child.is_a?(CommentNode)
68
99
  "Illegal nesting: Only attributes may be nested beneath attributes."
69
100
  end
70
101
  end
102
+
103
+ private
104
+
105
+ def declaration
106
+ @attr_syntax == :new ? "#{name}: #{value}" : ":#{name} #{value}"
107
+ end
71
108
  end
72
109
  end
@@ -1,11 +1,27 @@
1
1
  require 'sass/tree/node'
2
2
 
3
3
  module Sass::Tree
4
+ # A static node representing a Sass comment (silent or loud).
5
+ #
6
+ # @see Sass::Tree
4
7
  class CommentNode < Node
8
+ # The lines of text nested beneath the comment.
9
+ #
10
+ # @return [Array<Sass::Engine::Line>]
5
11
  attr_accessor :lines
12
+
13
+ # The text on the same line as the comment starter.
14
+ #
15
+ # @return [String]
6
16
  attr_accessor :value
17
+
18
+ # Whether or not the comment is silent (that is, doesn't output to CSS).
19
+ #
20
+ # @return [Boolean]
7
21
  attr_accessor :silent
8
22
 
23
+ # @param value [String] See \{#value}
24
+ # @param silent [Boolean] See \{#silent}
9
25
  def initialize(value, silent)
10
26
  @lines = []
11
27
  @value = value[2..-1].strip
@@ -13,11 +29,25 @@ module Sass::Tree
13
29
  super()
14
30
  end
15
31
 
32
+ # Compares the contents of two comments.
33
+ #
34
+ # @param other [Object] The object to compare with
35
+ # @return [Boolean] Whether or not this node and the other object
36
+ # are the same
16
37
  def ==(other)
17
38
  self.class == other.class && value == other.value && silent == other.silent && lines == other.lines
18
39
  end
19
40
 
20
- def to_s(tabs = 0, parent_name = nil)
41
+ # Computes the CSS for the comment.
42
+ #
43
+ # Returns `nil` if this is a silent comment
44
+ # or the current style doesn't render comments.
45
+ #
46
+ # @overload to_s(tabs = 0)
47
+ # @param tabs [Fixnum] The level of indentation for the CSS
48
+ # @return [String, nil] The resulting CSS
49
+ # @see #invisible?
50
+ def to_s(tabs = 0, _ = nil)
21
51
  return if invisible?
22
52
 
23
53
  spaces = ' ' * (tabs - 1)
@@ -25,12 +55,22 @@ module Sass::Tree
25
55
  map{|l| l.sub(%r{ ?\*/ *$},'')}.join(style == :compact ? ' ' : "\n#{spaces} * ") + " */"
26
56
  end
27
57
 
58
+ # Returns `true` if this is a silent comment
59
+ # or the current style doesn't render comments.
60
+ #
61
+ # @return [Boolean]
28
62
  def invisible?
29
63
  style == :compressed || @silent
30
64
  end
31
65
 
32
66
  protected
33
67
 
68
+ # Removes this node from the tree if it's a silent comment.
69
+ #
70
+ # @param environment [Sass::Environment] The lexical environment containing
71
+ # variable and mixin values
72
+ # @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
73
+ # @see Sass::Tree
34
74
  def _perform(environment)
35
75
  return [] if @silent
36
76
  self
@@ -1,6 +1,10 @@
1
1
  module Sass
2
2
  module Tree
3
+ # A dynamic node representing a Sass `@debug` statement.
4
+ #
5
+ # @see Sass::Tree
3
6
  class DebugNode < Node
7
+ # @param expr [Script::Node] The expression to print
4
8
  def initialize(expr)
5
9
  @expr = expr
6
10
  super()
@@ -8,6 +12,10 @@ module Sass
8
12
 
9
13
  protected
10
14
 
15
+ # Prints the expression to STDERR.
16
+ #
17
+ # @param environment [Sass::Environment] The lexical environment containing
18
+ # variable and mixin values
11
19
  def _perform(environment)
12
20
  res = @expr.perform(environment)
13
21
  if filename
@@ -1,12 +1,32 @@
1
1
  module Sass::Tree
2
+ # A static node representing an unproccessed Sass `@`-directive.
3
+ # Directives known to Sass, like `@for` and `@debug`,
4
+ # are handled by their own nodes;
5
+ # only CSS directives like `@media` and `@font-face` become {DirectiveNode}s.
6
+ #
7
+ # `@import` is a bit of a weird case;
8
+ # if it's importing a Sass file,
9
+ # it becomes a {FileNode},
10
+ # but if it's importing a plain CSS file,
11
+ # it becomes a {DirectiveNode}.
12
+ #
13
+ # @see Sass::Tree
2
14
  class DirectiveNode < Node
15
+ # The text of the directive, `@` and all.
16
+ #
17
+ # @return [String]
3
18
  attr_accessor :value
4
19
 
20
+ # @param value [String] See \{#value}
5
21
  def initialize(value)
6
22
  @value = value
7
23
  super()
8
24
  end
9
25
 
26
+ # Computes the CSS for the directive.
27
+ #
28
+ # @param tabs [Fixnum] The level of indentation for the CSS
29
+ # @return [String] The resulting CSS
10
30
  def to_s(tabs)
11
31
  if children.empty?
12
32
  value + ";"
@@ -1,11 +1,18 @@
1
1
  module Sass
2
2
  module Tree
3
+ # A static node that wraps the {Sass::Tree} for an `@import`ed file.
4
+ # It doesn't have a functional purpose other than to add the `@import`ed file
5
+ # to the backtrace if an error occurs.
3
6
  class FileNode < Node
7
+ # @param filename [String] The name of the imported file
4
8
  def initialize(filename)
5
9
  @filename = filename
6
10
  super()
7
11
  end
8
12
 
13
+ # Computes the CSS for the imported file.
14
+ #
15
+ # @param args [Array] Ignored
9
16
  def to_s(*args)
10
17
  @to_s ||= (style == :compressed ? super().strip : super())
11
18
  rescue Sass::SyntaxError => e
@@ -17,6 +24,11 @@ module Sass
17
24
 
18
25
  protected
19
26
 
27
+ # Parses the imported file
28
+ # and runs the dynamic Sass for it.
29
+ #
30
+ # @param environment [Sass::Environment] The lexical environment containing
31
+ # variable and mixin values
20
32
  def perform!(environment)
21
33
  self.children = Sass::Files.tree_for(filename, @options).children
22
34
  self.children = perform_children(environment)
@@ -1,7 +1,15 @@
1
1
  require 'sass/tree/node'
2
2
 
3
3
  module Sass::Tree
4
+ # A dynamic node representing a Sass `@for` loop.
5
+ #
6
+ # @see Sass::Tree
4
7
  class ForNode < Node
8
+ # @param var [String] The name of the loop variable
9
+ # @param from [Script::Node] The parse tree for the initial expression
10
+ # @param to [Script::Node] The parse tree for the final expression
11
+ # @param exclusive [Boolean] Whether to include `to` in the loop
12
+ # or stop just before
5
13
  def initialize(var, from, to, exclusive)
6
14
  @var = var
7
15
  @from = from
@@ -12,6 +20,13 @@ module Sass::Tree
12
20
 
13
21
  protected
14
22
 
23
+ # Runs the child nodes once for each time through the loop,
24
+ # varying the variable each time.
25
+ #
26
+ # @param environment [Sass::Environment] The lexical environment containing
27
+ # variable and mixin values
28
+ # @return [Array<Tree::Node>] The resulting static nodes
29
+ # @see Sass::Tree
15
30
  def _perform(environment)
16
31
  from = @from.perform(environment).to_i
17
32
  to = @to.perform(environment).to_i
@@ -1,15 +1,30 @@
1
1
  require 'sass/tree/node'
2
2
 
3
3
  module Sass::Tree
4
+ # A dynamic node representing a Sass `@if` statement.
5
+ #
6
+ # {IfNode}s are a little odd, in that they also represent `@else` and `@else if`s.
7
+ # This is done as a linked list:
8
+ # each {IfNode} has a link (\{#else}) to the next {IfNode}.
9
+ #
10
+ # @see Sass::Tree
4
11
  class IfNode < Node
12
+ # The next {IfNode} in the if-else list, or `nil`.
13
+ #
14
+ # @return [IfNode]
5
15
  attr_accessor :else
6
16
 
17
+ # @param expr [Script::Expr] The conditional expression.
18
+ # If this is nil, this is an `@else` node, not an `@else if`
7
19
  def initialize(expr)
8
20
  @expr = expr
9
21
  @last_else = self
10
22
  super()
11
23
  end
12
24
 
25
+ # Append an `@else` node to the end of the list.
26
+ #
27
+ # @param node [IfNode] The `@else` node to append
13
28
  def add_else(node)
14
29
  @last_else.else = node
15
30
  @last_else = node
@@ -22,6 +37,13 @@ module Sass::Tree
22
37
 
23
38
  protected
24
39
 
40
+ # Runs the child nodes if the conditional expression is true;
41
+ # otherwise, tries the \{#else} nodes.
42
+ #
43
+ # @param environment [Sass::Environment] The lexical environment containing
44
+ # variable and mixin values
45
+ # @return [Array<Tree::Node>] The resulting static nodes
46
+ # @see Sass::Tree
25
47
  def _perform(environment)
26
48
  environment = Sass::Environment.new(environment)
27
49
  return perform_children(environment) if @expr.nil? || @expr.perform(environment).to_bool
@@ -1,14 +1,25 @@
1
1
  module Sass
2
2
  module Tree
3
+ # A dynamic node representing a mixin definition.
4
+ #
5
+ # @see Sass::Tree
3
6
  class MixinDefNode < Node
7
+ # @param name [String] The mixin name
8
+ # @param args [Array<(String, Script::Node)>] The arguments for the mixin.
9
+ # Each element is a tuple containing the name of the argument
10
+ # and the parse tree for the default value of the argument
4
11
  def initialize(name, args)
5
12
  @name = name
6
13
  @args = args
7
14
  super()
8
15
  end
9
16
 
10
- private
17
+ protected
11
18
 
19
+ # Loads the mixin into the environment.
20
+ #
21
+ # @param environment [Sass::Environment] The lexical environment containing
22
+ # variable and mixin values
12
23
  def _perform(environment)
13
24
  environment.set_mixin(@name, Sass::Mixin.new(@name, @args, environment, children))
14
25
  []
@@ -1,7 +1,12 @@
1
1
  require 'sass/tree/node'
2
2
 
3
3
  module Sass::Tree
4
+ # A dynamic node representing a mixin include.
5
+ #
6
+ # @see Sass::Tree
4
7
  class MixinNode < Node
8
+ # @param name [String] The name of the mixin
9
+ # @param args [Array<Script::Node>] The arguments to the mixin
5
10
  def initialize(name, args)
6
11
  @name = name
7
12
  @args = args
@@ -10,6 +15,14 @@ module Sass::Tree
10
15
 
11
16
  protected
12
17
 
18
+ # Runs the mixin.
19
+ #
20
+ # @param environment [Sass::Environment] The lexical environment containing
21
+ # variable and mixin values
22
+ # @return [Array<Tree::Node>] The resulting static nodes
23
+ # @raise [Sass::SyntaxError] if there is no mixin with the given name
24
+ # @raise [Sass::SyntaxError] if an incorrect number of arguments was passed
25
+ # @see Sass::Tree
13
26
  def _perform(environment)
14
27
  raise Sass::SyntaxError.new("Undefined mixin '#{@name}'.", @line) unless mixin = environment.mixin(@name)
15
28
 
@@ -1,24 +1,69 @@
1
1
  module Sass
2
+ # A namespace for nodes in the Sass parse tree.
3
+ #
4
+ # The Sass parse tree has two states.
5
+ # When it's first parsed, it has nodes for mixin definitions
6
+ # and for loops and so forth,
7
+ # in addition to nodes for CSS rules and properties.
8
+ #
9
+ # However, {Tree::Node#perform} returns a different sort of tree.
10
+ # This tree maps more closely to the resulting CSS document
11
+ # than it does to the original Sass document.
12
+ # It still has nodes for CSS rules and properties,
13
+ # but it doesn't have any dynamic-generation-related nodes.
14
+ #
15
+ # Nodes that only appear in the pre-perform state are called **dynamic nodes**;
16
+ # those that appear in both states are called **static nodes**.
2
17
  module Tree
18
+ # This class doubles as the root node of the parse tree
19
+ # and the superclass of all other parse-tree nodes.
3
20
  class Node
21
+ # The child nodes of this node.
22
+ #
23
+ # @return [Array<Tree::Node>]
4
24
  attr_accessor :children
25
+
26
+ # The line of the document on which this node appeared.
27
+ #
28
+ # @return [Fixnum]
5
29
  attr_accessor :line
30
+
31
+ # The name of the document on which this node appeared.
32
+ #
33
+ # @return [String]
6
34
  attr_writer :filename
35
+
36
+ # The options hash for the node.
37
+ # See [the Sass options documentation](../../Sass.html#sass_options).
38
+ #
39
+ # @return [Hash<Symbol, Object>]
7
40
  attr_reader :options
8
41
 
9
42
  def initialize
10
43
  @children = []
11
44
  end
12
45
 
46
+ # Sets the options hash for the node and all its children.
47
+ #
48
+ # @param options [Hash<Symbol, Object>] The options
49
+ # @see #options
13
50
  def options=(options)
14
51
  children.each {|c| c.options = options}
15
52
  @options = options
16
53
  end
17
54
 
55
+ # The name of the document on which this node appeared.
56
+ #
57
+ # @return [String]
18
58
  def filename
19
59
  @filename || @options[:filename]
20
60
  end
21
61
 
62
+ # Appends a child to the node.
63
+ #
64
+ # @param child [Tree::Node] The child node
65
+ # @raise [Sass::SyntaxError] if `child` is invalid
66
+ # @see #invalid_child?
22
67
  def <<(child)
23
68
  if msg = invalid_child?(child)
24
69
  raise Sass::SyntaxError.new(msg, child.line)
@@ -26,21 +71,54 @@ module Sass
26
71
  @children << child
27
72
  end
28
73
 
29
- # We need this because Node duck types as an Array in engine.rb
74
+ # Return the last child node.
75
+ #
76
+ # We need this because {Tree::Node} duck types as an Array for {Sass::Engine}.
77
+ #
78
+ # @return [Tree::Node] The last child node
30
79
  def last
31
80
  children.last
32
81
  end
33
82
 
83
+ # Compares this node and another object (only other {Tree::Node}s will be equal).
84
+ # This does a structural comparison;
85
+ # if the contents of the nodes and all the child nodes are equivalent,
86
+ # then the nodes are as well.
87
+ #
88
+ # Only static nodes need to override this.
89
+ #
90
+ # @param other [Object] The object to compare with
91
+ # @return [Boolean] Whether or not this node and the other object
92
+ # are the same
93
+ # @see Sass::Tree
34
94
  def ==(other)
35
95
  self.class == other.class && other.children == children
36
96
  end
37
97
 
98
+ # Runs the dynamic Sass code *and* computes the CSS for the tree.
99
+ #
100
+ # @see #perform
101
+ # @see #to_s
38
102
  def render
39
103
  perform(Environment.new).to_s
40
104
  end
41
105
 
106
+ # True if \{#to\_s} will return `nil`;
107
+ # that is, if the node shouldn't be rendered.
108
+ # Should only be called in a static tree.
109
+ #
110
+ # @return [Boolean]
42
111
  def invisible?; false; end
43
112
 
113
+ # Computes the CSS corresponding to this Sass tree.
114
+ #
115
+ # Only static-node subclasses need to implement \{#to\_s}.
116
+ #
117
+ # This may return `nil`, but it will only do so if \{#invisible?} is true.
118
+ #
119
+ # @return [String, nil] The resulting CSS
120
+ # @raise [Sass::SyntaxError] if some element of the tree is invalid
121
+ # @see Sass::Tree
44
122
  def to_s
45
123
  result = String.new
46
124
  children.each do |child|
@@ -56,32 +134,77 @@ module Sass
56
134
  rescue Sass::SyntaxError => e; e.add_metadata(filename, line)
57
135
  end
58
136
 
137
+ # Runs the dynamic Sass code:
138
+ # mixins, variables, control structures, and so forth.
139
+ # This doesn't modify this node or any of its children.
140
+ #
141
+ # \{#perform} shouldn't be overridden directly;
142
+ # if you want to return a new node (or list of nodes),
143
+ # override \{#\_perform};
144
+ # if you want to destructively modify this node,
145
+ # override \{#perform!}.
146
+ #
147
+ # @param environment [Sass::Environment] The lexical environment containing
148
+ # variable and mixin values
149
+ # @return [Tree::Node] The resulting tree of static nodes
150
+ # @raise [Sass::SyntaxError] if some element of the tree is invalid
151
+ # @see Sass::Tree
59
152
  def perform(environment)
60
153
  environment.options = @options if self.class == Tree::Node
61
154
  _perform(environment)
62
155
  rescue Sass::SyntaxError => e; e.add_metadata(filename, line)
63
156
  end
64
157
 
158
+ # The output style. See [the Sass options documentation](../../Sass.html#output_style).
159
+ #
160
+ # @return [Symbol]
65
161
  def style
66
162
  @options[:style]
67
163
  end
68
164
 
69
165
  protected
70
166
 
167
+ # Runs any dynamic Sass code in this particular node.
168
+ # This doesn't modify this node or any of its children.
169
+ #
170
+ # @param environment [Sass::Environment] The lexical environment containing
171
+ # variable and mixin values
172
+ # @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
173
+ # @see #perform
174
+ # @see Sass::Tree
71
175
  def _perform(environment)
72
176
  node = dup
73
177
  node.perform!(environment)
74
178
  node
75
179
  end
76
180
 
181
+ # Destructively runs dynamic Sass code in this particular node.
182
+ # This *does* modify this node,
183
+ # but will be run non-destructively by \{#\_perform\}.
184
+ #
185
+ # @param environment [Sass::Environment] The lexical environment containing
186
+ # variable and mixin values
187
+ # @see #perform
77
188
  def perform!(environment)
78
189
  self.children = perform_children(Environment.new(environment))
79
190
  end
80
191
 
192
+ # Non-destructively runs \{#perform} on all children of the current node.
193
+ #
194
+ # @param environment [Sass::Environment] The lexical environment containing
195
+ # variable and mixin values
196
+ # @return [Array<Tree::Node>] The resulting static nodes
81
197
  def perform_children(environment)
82
198
  children.map {|c| c.perform(environment)}.flatten
83
199
  end
84
200
 
201
+ # Replaces SassScript in a chunk of text (via `#{}`)
202
+ # with the resulting value.
203
+ #
204
+ # @param text [String] The text to interpolate
205
+ # @param environment [Sass::Environment] The lexical environment containing
206
+ # variable and mixin values
207
+ # @return [String] The interpolated text
85
208
  def interpolate(text, environment)
86
209
  res = ''
87
210
  rest = Haml::Shared.handle_interpolation text do |scan|
@@ -98,17 +221,24 @@ module Sass
98
221
  res + rest
99
222
  end
100
223
 
224
+ # @see Haml::Shared.balance
225
+ # @raise [Sass::SyntaxError] if the brackets aren't balanced
101
226
  def balance(*args)
102
227
  res = Haml::Shared.balance(*args)
103
228
  return res if res
104
229
  raise Sass::SyntaxError.new("Unbalanced brackets.", line)
105
230
  end
106
231
 
107
- private
108
-
109
- # This method should be overridden by subclasses to return an error message
110
- # if the given child node is invalid,
111
- # and false or nil otherwise.
232
+ # Returns an error message if the given child node is invalid,
233
+ # and false otherwise.
234
+ #
235
+ # By default, all child nodes are valid.
236
+ # This is expected to be overriden by subclasses
237
+ # for which some children are invalid.
238
+ #
239
+ # @param child [Tree::Node] A potential child node
240
+ # @return [Boolean, String] Whether or not the child node is valid,
241
+ # as well as the error message to display if it is invalid
112
242
  def invalid_child?(child)
113
243
  false
114
244
  end