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/plugin.rb CHANGED
@@ -1,9 +1,13 @@
1
1
  require 'sass/engine'
2
2
 
3
3
  module Sass
4
- # This module contains methods to aid in using Sass
5
- # as a stylesheet-rendering plugin for various systems.
6
- # Currently Rails/ActionController and Merb are supported out of the box.
4
+ # This module handles the compilation of Sass files.
5
+ # It provides global options and checks whether CSS files
6
+ # need to be updated.
7
+ #
8
+ # This module is used as the primary interface with Sass
9
+ # when it's used as a plugin for various frameworks.
10
+ # Currently Rails and Merb are supported out of the box.
7
11
  module Plugin
8
12
  extend self
9
13
 
@@ -15,37 +19,42 @@ module Sass
15
19
  }
16
20
  @checked_for_updates = false
17
21
 
18
- # Whether or not Sass has *ever* checked if the stylesheets need updates
22
+ # Whether or not Sass has **ever** checked if the stylesheets need to be updated
19
23
  # (in this Ruby instance).
20
- def checked_for_updates
21
- @checked_for_updates
22
- end
23
-
24
- # Gets various options for Sass. See README.rdoc for details.
25
- #--
26
- # TODO: *DOCUMENT OPTIONS*
27
- #++
28
- def options
29
- @options
30
- end
31
-
32
- # Sets various options for Sass.
24
+ #
25
+ # @return [Boolean]
26
+ attr_reader :checked_for_updates
27
+
28
+ # An options hash.
29
+ # See [the Sass options documentation](../Sass.html#sass_options).
30
+ #
31
+ # @return [Hash<Symbol, Object>]
32
+ attr_reader :options
33
+
34
+ # Sets the options hash.
35
+ # See [the Sass options documentation](../Sass.html#sass_options).
36
+ #
37
+ # @param value [Hash<Symbol, Object>] The options hash
33
38
  def options=(value)
34
39
  @options.merge!(value)
35
40
  end
36
41
 
37
- # Get the options ready to be passed to the Sass::Engine
42
+ # Non-destructively modifies \{#options} so that default values are properly set.
43
+ #
44
+ # @param additional_options [Hash<Symbol, Object>] An options hash with which to merge \{#options}
45
+ # @return [Hash<Symbol, Object>] The modified options hash
38
46
  def engine_options(additional_options = {})
39
47
  opts = options.dup.merge(additional_options)
40
48
  opts[:load_paths] = load_paths(opts)
41
49
  opts
42
50
  end
43
51
 
44
- # Checks each stylesheet in <tt>options[:css_location]</tt>
45
- # to see if it needs updating,
46
- # and updates it using the corresponding template
47
- # from <tt>options[:templates]</tt>
48
- # if it does.
52
+ # Updates out-of-date stylesheets.
53
+ #
54
+ # Checks each Sass file in [`:template_location`](../Sass.html#template_location-option)
55
+ # to see if it's been modified more recently than the corresponding CSS file
56
+ # in [`:css_location`](../Sass.html#css_location-option).
57
+ # If it has, it updates the CSS file.
49
58
  def update_stylesheets
50
59
  return if options[:never_update]
51
60
 
data/lib/sass/repl.rb CHANGED
@@ -1,11 +1,18 @@
1
1
  require 'readline'
2
2
 
3
3
  module Sass
4
+ # Runs a SassScript read-eval-print loop.
5
+ # It presents a prompt on the terminal,
6
+ # reads in SassScript expressions,
7
+ # evaluates them,
8
+ # and prints the result.
4
9
  class Repl
10
+ # @param options [Hash<Symbol, Object>] An options hash.
5
11
  def initialize(options = {})
6
12
  @options = options
7
13
  end
8
14
 
15
+ # Starts the read-eval-print loop.
9
16
  def run
10
17
  environment = Environment.new
11
18
  environment.set_var('important', Script::String.new('!important'))
@@ -1,13 +1,17 @@
1
1
  require 'sass/script/literal'
2
2
 
3
3
  module Sass::Script
4
- class Bool < Literal # :nodoc:
4
+ # A SassScript object representing a boolean (true or false) value.
5
+ class Bool < Literal
6
+ # The Ruby value of the boolean.
7
+ #
8
+ # @return [Boolean]
9
+ attr_reader :value
10
+ alias_method :to_bool, :value
11
+
12
+ # @return [String] "true" or "false"
5
13
  def to_s
6
14
  @value.to_s
7
15
  end
8
-
9
- def to_bool
10
- @value
11
- end
12
16
  end
13
17
  end
@@ -1,9 +1,11 @@
1
1
  require 'sass/script/literal'
2
2
 
3
3
  module Sass::Script
4
- class Color < Literal # :nodoc:
4
+ # A SassScript object representing a CSS color.
5
+ class Color < Literal
5
6
  class << self; include Haml::Util; end
6
7
 
8
+ # A hash from color names to [red, green, blue] value arrays.
7
9
  HTML4_COLORS = map_vals({
8
10
  'black' => 0x000000,
9
11
  'silver' => 0xc0c0c0,
@@ -22,14 +24,33 @@ module Sass::Script
22
24
  'teal' => 0x008080,
23
25
  'aqua' => 0x00ffff
24
26
  }) {|color| (0..2).map {|n| color >> (n << 3) & 0xff}.reverse}
27
+ # A hash from [red, green, blue] value arrays to color names.
25
28
  HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}
26
29
 
30
+ # @param rgb [Array<Fixnum>] A three-element array of the red, green, and blue values (respectively)
31
+ # of the color
32
+ # @raise [Sass::SyntaxError] if any color value isn't between 0 and 255
27
33
  def initialize(rgb)
28
34
  rgb = rgb.map {|c| c.to_i}
29
35
  raise Sass::SyntaxError.new("Color values must be between 0 and 255") if rgb.any? {|c| c < 0 || c > 255}
30
36
  super(rgb)
31
37
  end
32
38
 
39
+ # The SassScript `+` operation.
40
+ # Its functionality depends on the type of its argument:
41
+ #
42
+ # {Number}
43
+ # : Adds the number to each of the RGB color channels.
44
+ #
45
+ # {Color}
46
+ # : Adds each of the RGB color channels together.
47
+ #
48
+ # {Literal}
49
+ # : See {Literal#plus}.
50
+ #
51
+ # @param other [Literal] The right-hand side of the operator
52
+ # @return [Color] The resulting color
53
+ # @raise [Sass::SyntaxError] if `other` is a number with units
33
54
  def plus(other)
34
55
  if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
35
56
  piecewise(other, :+)
@@ -38,6 +59,21 @@ module Sass::Script
38
59
  end
39
60
  end
40
61
 
62
+ # The SassScript `-` operation.
63
+ # Its functionality depends on the type of its argument:
64
+ #
65
+ # {Number}
66
+ # : Subtracts the number from each of the RGB color channels.
67
+ #
68
+ # {Color}
69
+ # : Subtracts each of the other color's RGB color channels from this color's.
70
+ #
71
+ # {Literal}
72
+ # : See {Literal#minus}.
73
+ #
74
+ # @param other [Literal] The right-hand side of the operator
75
+ # @return [Color] The resulting color
76
+ # @raise [Sass::SyntaxError] if `other` is a number with units
41
77
  def minus(other)
42
78
  if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
43
79
  piecewise(other, :-)
@@ -46,6 +82,21 @@ module Sass::Script
46
82
  end
47
83
  end
48
84
 
85
+ # The SassScript `*` operation.
86
+ # Its functionality depends on the type of its argument:
87
+ #
88
+ # {Number}
89
+ # : Multiplies the number by each of the RGB color channels.
90
+ #
91
+ # {Color}
92
+ # : Multiplies each of the RGB color channels together.
93
+ #
94
+ # {Literal}
95
+ # : See {Literal#times}.
96
+ #
97
+ # @param other [Literal] The right-hand side of the operator
98
+ # @return [Color] The resulting color
99
+ # @raise [Sass::SyntaxError] if `other` is a number with units
49
100
  def times(other)
50
101
  if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
51
102
  piecewise(other, :*)
@@ -54,6 +105,21 @@ module Sass::Script
54
105
  end
55
106
  end
56
107
 
108
+ # The SassScript `/` operation.
109
+ # Its functionality depends on the type of its argument:
110
+ #
111
+ # {Number}
112
+ # : Divides each of the RGB color channels by the number.
113
+ #
114
+ # {Color}
115
+ # : Divides each of this color's RGB color channels by the other color's.
116
+ #
117
+ # {Literal}
118
+ # : See {Literal#div}.
119
+ #
120
+ # @param other [Literal] The right-hand side of the operator
121
+ # @return [Color] The resulting color
122
+ # @raise [Sass::SyntaxError] if `other` is a number with units
57
123
  def div(other)
58
124
  if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
59
125
  piecewise(other, :/)
@@ -62,6 +128,21 @@ module Sass::Script
62
128
  end
63
129
  end
64
130
 
131
+ # The SassScript `%` operation.
132
+ # Its functionality depends on the type of its argument:
133
+ #
134
+ # {Number}
135
+ # : Takes each of the RGB color channels module the number.
136
+ #
137
+ # {Color}
138
+ # : Takes each of this color's RGB color channels modulo the other color's.
139
+ #
140
+ # {Literal}
141
+ # : See {Literal#mod}.
142
+ #
143
+ # @param other [Literal] The right-hand side of the operator
144
+ # @return [Color] The resulting color
145
+ # @raise [Sass::SyntaxError] if `other` is a number with units
65
146
  def mod(other)
66
147
  if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
67
148
  piecewise(other, :%)
@@ -70,6 +151,11 @@ module Sass::Script
70
151
  end
71
152
  end
72
153
 
154
+ # Returns a string representation of the color.
155
+ # This is usually the color's hex value,
156
+ # but if the color has a name that's used instead.
157
+ #
158
+ # @return [String] The string representation
73
159
  def to_s
74
160
  return HTML4_COLORS_REVERSE[@value] if HTML4_COLORS_REVERSE[@value]
75
161
  red, green, blue = @value.map { |num| num.to_s(16).rjust(2, '0') }
@@ -1,18 +1,39 @@
1
1
  require File.join(File.dirname(__FILE__), 'functions')
2
2
  module Sass
3
3
  module Script
4
- class Funcall # :nodoc:
5
- attr_reader :name, :args
4
+ # A SassScript parse node representing a function call.
5
+ #
6
+ # A function call either calls one of the functions in {Script::Functions},
7
+ # or if no function with the given name exists
8
+ # it returns a string representation of the function call.
9
+ class Funcall < Node
10
+ # The name of the function.
11
+ #
12
+ # @return [String]
13
+ attr_reader :name
6
14
 
15
+ # The arguments to the function.
16
+ #
17
+ # @return [Array<Script::Node>]
18
+ attr_reader :args
19
+
20
+ # @param name [String] See \{#name}
21
+ # @param name [Array<Script::Node>] See \{#args}
7
22
  def initialize(name, args)
8
23
  @name = name
9
24
  @args = args
10
25
  end
11
26
 
27
+ # @return [String] A string representation of the function call
12
28
  def inspect
13
29
  "#{name}(#{args.map {|a| a.inspect}.join(', ')})"
14
30
  end
15
31
 
32
+ # Evaluates the function call.
33
+ #
34
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
35
+ # @return [Literal] The SassScript object that is the value of the function call
36
+ # @raise [Sass::SyntaxError] if the function call raises an ArgumentError
16
37
  def perform(environment)
17
38
  args = self.args.map {|a| a.perform(environment)}
18
39
  unless Haml::Util.has?(:public_instance_method, Functions, name) && name !~ /^__/
@@ -1,15 +1,35 @@
1
1
  module Sass::Script
2
- # Methods in this module are accessible from the Sass script context.
2
+ # Methods in this module are accessible from the SassScript context.
3
3
  # For example, you can write
4
4
  #
5
- # color = hsl(120, 100%, 50%)
5
+ # !color = hsl(120, 100%, 50%)
6
6
  #
7
- # and it will call Sass::Script::Functions#hsl.
7
+ # and it will call {Sass::Script::Functions#hsl}.
8
+ #
9
+ # The following functions are provided:
10
+ #
11
+ # \{#hsl}
12
+ # : Converts an `hsl(hue, saturation, lightness)` triplet into a color.
13
+ #
14
+ # \{#percentage}
15
+ # : Converts a unitless number to a percentage.
16
+ #
17
+ # \{#round}
18
+ # : Rounds a number to the nearest whole number.
19
+ #
20
+ # \{#ceil}
21
+ # : Rounds a number up to the nearest whole number.
22
+ #
23
+ # \{#floor}
24
+ # : Rounds a number down to the nearest whole number.
25
+ #
26
+ # \{#abs}
27
+ # : Returns the absolute value of a number.
8
28
  #
9
29
  # You can add your own functions to this module,
10
30
  # but there are a few things to keep in mind.
11
- # First of all, the arguments passed are (currently undocumented) Sass::Script::Literal objects,
12
- # Literal objects are also the expected return values.
31
+ # First of all, the arguments passed are {Sass::Script::Literal} objects.
32
+ # Literal objects are also expected to be returned.
13
33
  #
14
34
  # Second, making Ruby functions accessible from Sass introduces the temptation
15
35
  # to do things like database access within stylesheets.
@@ -17,38 +37,23 @@ module Sass::Script
17
37
  # Keep in mind that Sass stylesheets are only compiled once
18
38
  # at a somewhat indeterminate time
19
39
  # and then left as static CSS files.
20
- # Any dynamic CSS should be left in <style> tags in the HTML.
21
- #
22
- # Within a sass function you can call the options method to gain access to the
23
- # options hash that was used to create the Sass::Engine that is processing the function call.
24
- #
25
- # The following functions are provided:
26
- # * +hsl+ - converts an <tt>hsl(hue, saturation, lightness)</tt> triplet into a color.
27
- #
28
- # The +hue+ value should be between 0 and 360 inclusive,
29
- # saturation and lightness must be between <tt>0%</tt> to <tt>100%</tt> inclusive.
30
- # The percent sign is optional.
31
- # * +percentage+ - converts a unitless number to a css percentage.
32
- #
33
- # Example: <tt>percentage(14px / 7px) => 200%</tt>
34
- # * +round+ - Rounds a number to the nearest whole number.
35
- #
36
- # Example: <tt>round(10.4px) => 10px</tt>
37
- # * +ceil+ - Rounds a number up to the nearest whole number.
38
- #
39
- # Example: <tt>ceil(10.4px) => 11px</tt>
40
- # * +floor+ - Rounds a number down to the nearest whole number.
41
- #
42
- # Example: <tt>floor(10.6px) => 10px</tt>
43
- # * +abs+ - Returns the absolute value of a number.
40
+ # Any dynamic CSS should be left in `<style>` tags in the HTML.
44
41
  #
45
- # Example: <tt>abs(-10px) => 10px</tt>
42
+ # Within one of the functions in this module,
43
+ # methods of {EvaluationContext} can be used.
46
44
  module Functions
47
- class EvaluationContext # :nodoc:
45
+ # The context in which methods in {Script::Functions} are evaluated.
46
+ # That means that all instance methods of {EvaluationContext}
47
+ # are available to use in functions.
48
+ class EvaluationContext
48
49
  include Sass::Script::Functions
49
50
 
51
+ # The options hash for the {Sass::Engine} that is processing the function call
52
+ #
53
+ # @return [Hash<Symbol, Object>]
50
54
  attr_reader :options
51
55
 
56
+ # @param options [Hash<Symbol, Object>] See \{#options}
52
57
  def initialize(options)
53
58
  @options = options
54
59
  end
@@ -56,15 +61,22 @@ module Sass::Script
56
61
 
57
62
  instance_methods.each { |m| undef_method m unless m.to_s =~ /^__/ }
58
63
 
59
- # Creates a Sass::Script::Color object from hue, saturation, and lightness.
60
- # As per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsl-color),
61
- # hue is in degrees,
62
- # and saturation and lightness are percentages.
63
- def hsl(h, s, l)
64
- original_s = s
65
- original_l = l
64
+ # Creates a {Color} object from hue, saturation, and lightness
65
+ # as per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsl-color).
66
+ #
67
+ # @param hue [Number] The hue of the color.
68
+ # Should be between 0 and 360 degrees, inclusive
69
+ # @param saturation [Number] The saturation of the color.
70
+ # Must be between `0%` and `100%`, inclusive
71
+ # @param lightness [Number] The lightness of the color.
72
+ # Must be between `0%` and `100%`, inclusive
73
+ # @return [Color] The resulting color
74
+ # @raise [ArgumentError] if `saturation` or `lightness` are out of bounds
75
+ def hsl(hue, saturation, lightness)
76
+ original_s = saturation
77
+ original_l = lightness
66
78
  # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
67
- h, s, l = [h, s, l].map { |a| a.value }
79
+ h, s, l = [hue, saturation, lightness].map { |a| a.value }
68
80
  raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") if s < 0 || s > 100
69
81
  raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") if l < 0 || l > 100
70
82
 
@@ -79,9 +91,14 @@ module Sass::Script
79
91
  hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round })
80
92
  end
81
93
 
82
- # Converts a unitless number into a percent and multiplies the number by 100.
83
- # E.g. percentage(100px / 50px) => 200%
84
- # Some may find this more natural than: 100% * 100px / 50px
94
+ # Converts a decimal number to a percentage.
95
+ # For example:
96
+ #
97
+ # percentage(100px / 50px) => 200%
98
+ #
99
+ # @param value [Number] The decimal number to convert to a percentage
100
+ # @return [Number] The percentage
101
+ # @raise [ArgumentError] If `value` isn't a unitless number
85
102
  def percentage(value)
86
103
  unless value.is_a?(Sass::Script::Number) && value.unitless?
87
104
  raise ArgumentError.new("#{value} is not a unitless number")
@@ -90,21 +107,53 @@ module Sass::Script
90
107
  end
91
108
 
92
109
  # Rounds a number to the nearest whole number.
110
+ # For example:
111
+ #
112
+ # round(10.4px) => 10px
113
+ # round(10.6px) => 11px
114
+ #
115
+ # @param value [Number] The number
116
+ # @return [Number] The rounded number
117
+ # @raise [Sass::SyntaxError] if `value` isn't a number
93
118
  def round(value)
94
119
  numeric_transformation(value) {|n| n.round}
95
120
  end
96
121
 
97
- # Rounds up to the nearest whole number.
122
+ # Rounds a number up to the nearest whole number.
123
+ # For example:
124
+ #
125
+ # ciel(10.4px) => 11px
126
+ # ciel(10.6px) => 11px
127
+ #
128
+ # @param value [Number] The number
129
+ # @return [Number] The rounded number
130
+ # @raise [Sass::SyntaxError] if `value` isn't a number
98
131
  def ceil(value)
99
132
  numeric_transformation(value) {|n| n.ceil}
100
133
  end
101
134
 
102
135
  # Rounds down to the nearest whole number.
136
+ # For example:
137
+ #
138
+ # floor(10.4px) => 10px
139
+ # floor(10.6px) => 10px
140
+ #
141
+ # @param value [Number] The number
142
+ # @return [Number] The rounded number
143
+ # @raise [Sass::SyntaxError] if `value` isn't a number
103
144
  def floor(value)
104
145
  numeric_transformation(value) {|n| n.floor}
105
146
  end
106
147
 
107
- # Returns the absolute value of a number.
148
+ # Finds the absolute value of a number.
149
+ # For example:
150
+ #
151
+ # abs(10px) => 10px
152
+ # abs(-10px) => 10px
153
+ #
154
+ # @param value [Number] The number
155
+ # @return [Number] The absolute value
156
+ # @raise [Sass::SyntaxError] if `value` isn't a number
108
157
  def abs(value)
109
158
  numeric_transformation(value) {|n| n.abs}
110
159
  end
@@ -2,9 +2,26 @@ require 'strscan'
2
2
 
3
3
  module Sass
4
4
  module Script
5
- class Lexer # :nodoc:
5
+ # The lexical analyzer for SassScript.
6
+ # It takes a raw string and converts it to individual tokens
7
+ # that are easier to parse.
8
+ class Lexer
9
+ # A struct containing information about an individual token.
10
+ #
11
+ # `type`: [{Symbol}]
12
+ # : The type of token.
13
+ #
14
+ # `value`: [{Object}]
15
+ # : The Ruby object corresponding to the value of the token.
16
+ #
17
+ # `line`: [{Fixnum}]
18
+ # : The line of the source file on which the token appears.
19
+ #
20
+ # `offset`: [{Fixnum}]
21
+ # : The number of bytes into the line the SassScript token appeared.
6
22
  Token = Struct.new(:type, :value, :line, :offset)
7
23
 
24
+ # A hash from operator strings to the corresponding token types.
8
25
  OPERATORS = {
9
26
  '+' => :plus,
10
27
  '-' => :minus,
@@ -27,10 +44,11 @@ module Sass
27
44
  '}' => :end_interpolation,
28
45
  }
29
46
 
30
- # We'll want to match longer names first
31
- # so that > and < don't clobber >= and <=
47
+ # A list of operator strings ordered with longer names first
48
+ # so that `>` and `<` don't clobber `>=` and `<=`.
32
49
  OP_NAMES = OPERATORS.keys.sort_by {|o| -o.size}
33
50
 
51
+ # A hash of regular expressions that are used for tokenizing.
34
52
  REGULAR_EXPRESSIONS = {
35
53
  :whitespace => /\s*/,
36
54
  :variable => /!(\w+)/,
@@ -42,6 +60,11 @@ module Sass
42
60
  :op => %r{(#{Regexp.union(*OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + (s =~ /\w$/ ? '(?:\b|$)' : ''))})})}
43
61
  }
44
62
 
63
+ # @param str [String, StringScanner] The source text to lex
64
+ # @param line [Fixnum] The line on which the SassScript appears.
65
+ # Used for error reporting
66
+ # @param offset [Fixnum] The number of characters in on which the SassScript appears.
67
+ # Used for error reporting
45
68
  def initialize(str, line, offset)
46
69
  @scanner = str.is_a?(StringScanner) ? str : StringScanner.new(str)
47
70
  @line = line
@@ -49,6 +72,9 @@ module Sass
49
72
  @prev = nil
50
73
  end
51
74
 
75
+ # Moves the lexer forward one token.
76
+ #
77
+ # @return [Token] The token that was moved past
52
78
  def next
53
79
  @tok ||= read_token
54
80
  @tok, tok = nil, @tok
@@ -56,10 +82,14 @@ module Sass
56
82
  return tok
57
83
  end
58
84
 
85
+ # Returns the next token without moving the lexer forward.
86
+ #
87
+ # @return [Token] The next token
59
88
  def peek
60
89
  @tok ||= read_token
61
90
  end
62
91
 
92
+ # @return [Boolean] Whether or not there's more source text to lex.
63
93
  def done?
64
94
  whitespace unless after_interpolation?
65
95
  @scanner.eos? && @tok.nil?