haml-edge 2.1.41 → 2.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/EDGE_GEM_VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.41
1
+ 2.1.42
data/Rakefile CHANGED
@@ -71,8 +71,9 @@ end
71
71
 
72
72
  desc "Release a new Haml package to Rubyforge. Requires the NAME and VERSION flags."
73
73
  task :release => [:package] do
74
- name, version = ENV['NAME'], ENV['VERSION']
75
- raise "Must supply NAME and VERSION for release task." unless name && version
74
+ name = File.read("VERSION_NAME").strip
75
+ version = File.read("VERSION").strip
76
+ raise "VERSION_NAME must not be 'Bleeding Edge'" if name == "Bleeding Edge"
76
77
  sh %{rubyforge login}
77
78
  sh %{rubyforge add_release haml haml "#{name} (v#{version})" pkg/haml-#{version}.gem}
78
79
  sh %{rubyforge add_file haml haml "#{name} (v#{version})" pkg/haml-#{version}.tar.gz}
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.41
1
+ 2.1.42
data/VERSION_NAME ADDED
@@ -0,0 +1 @@
1
+ Bleeding Edge
data/lib/haml/buffer.rb CHANGED
@@ -90,12 +90,8 @@ module Haml
90
90
  def initialize(upper = nil, options = {})
91
91
  @active = true
92
92
  @upper = upper
93
- @options = {
94
- :attr_wrapper => "'",
95
- :ugly => false,
96
- :format => :xhtml
97
- }.merge options
98
- @buffer = ""
93
+ @options = options
94
+ @buffer = ruby1_8? ? "" : "".encode(Encoding.find(options[:encoding]))
99
95
  @tabulation = 0
100
96
 
101
97
  # The number of tabs that Engine thinks we should have
data/lib/haml/engine.rb CHANGED
@@ -23,11 +23,6 @@ module Haml
23
23
  # @return [Hash<Symbol, Object>]
24
24
  attr_accessor :options
25
25
 
26
- # The source code that is evaluated to produce the Haml document.
27
- #
28
- # @return [String]
29
- attr_accessor :precompiled
30
-
31
26
  # The indentation used in the Haml document,
32
27
  # or `nil` if the indentation is ambiguous
33
28
  # (for example, for a single-level document).
@@ -55,6 +50,17 @@ module Haml
55
50
  @options[:format] == :html5
56
51
  end
57
52
 
53
+ # The source code that is evaluated to produce the Haml document.
54
+ #
55
+ # In Ruby 1.9, this is automatically converted to the correct encoding
56
+ # (see {file:HAML_REFERENCE.md#encoding-option the `:encoding` option}).
57
+ #
58
+ # @return [String]
59
+ def precompiled
60
+ return @precompiled if ruby1_8?
61
+ return @precompiled.encode(Encoding.find(@options[:encoding]))
62
+ end
63
+
58
64
  # Precompiles the Haml template.
59
65
  #
60
66
  # @param template [String] The Haml template
@@ -74,8 +80,11 @@ module Haml
74
80
  :line => 1,
75
81
  :ugly => false,
76
82
  :format => :xhtml,
77
- :escape_html => false
83
+ :escape_html => false,
78
84
  }
85
+ unless ruby1_8?
86
+ @options[:encoding] = Encoding.default_internal || "utf-8"
87
+ end
79
88
  @options.merge! options
80
89
  @index = 0
81
90
 
@@ -83,6 +92,10 @@ module Haml
83
92
  raise Haml::Error, "Invalid format #{@options[:format].inspect}"
84
93
  end
85
94
 
95
+ if @options[:encoding] && @options[:encoding].is_a?(Encoding)
96
+ @options[:encoding] = @options[:encoding].name
97
+ end
98
+
86
99
  # :eod is a special end-of-document marker
87
100
  @template = (template.rstrip).split(/\r\n|\r|\n/) + [:eod, :eod]
88
101
  @template_index = 0
@@ -169,7 +182,7 @@ END
169
182
  @haml_buffer = buffer
170
183
  end
171
184
 
172
- eval(@precompiled, scope, @options[:filename], @options[:line])
185
+ eval(precompiled, scope, @options[:filename], @options[:line])
173
186
 
174
187
  # Get rid of the current buffer
175
188
  scope_object.instance_eval do
@@ -276,7 +289,8 @@ END
276
289
  :preserve => @options[:preserve],
277
290
  :attr_wrapper => @options[:attr_wrapper],
278
291
  :ugly => @options[:ugly],
279
- :format => @options[:format]
292
+ :format => @options[:format],
293
+ :encoding => @options[:encoding],
280
294
  }
281
295
  end
282
296
 
@@ -101,7 +101,7 @@ END
101
101
  @haml_buffer = @haml_buffer.upper
102
102
  _erbout
103
103
  END
104
- preamble + locals_code(local_names) + @precompiled + postamble
104
+ preamble + locals_code(local_names) + precompiled + postamble
105
105
  end
106
106
 
107
107
  def locals_code(names)
data/lib/haml/version.rb CHANGED
@@ -10,27 +10,33 @@ module Haml
10
10
 
11
11
  # Returns a hash representing the version of Haml.
12
12
  # The `:major`, `:minor`, and `:teeny` keys have their respective numbers as Fixnums.
13
+ # The `:name` key has the name of the version.
13
14
  # The `:string` key contains a human-readable string representation of the version.
15
+ # The `:number` key is the major, minor, and teeny keys separated by periods.
14
16
  # If Haml is checked out from Git, the `:rev` key will have the revision hash.
15
17
  # For example:
16
18
  #
17
19
  # {
18
- # :string=>"2.1.0.9616393",
19
- # :rev => "9616393b8924ef36639c7e82aa88a51a24d16949",
20
- # :major => 2, :minor => 1, :teeny => 0
20
+ # :string => "2.1.0.9616393",
21
+ # :rev => "9616393b8924ef36639c7e82aa88a51a24d16949",
22
+ # :number => "2.1.0",
23
+ # :major => 2, :minor => 1, :teeny => 0
21
24
  # }
22
25
  #
23
- # @return [Hash<Symbol, String/Symbol>] The version hash
26
+ # @return [Hash<Symbol, String/Fixnum>] The version hash
24
27
  def version
25
28
  return @@version if defined?(@@version)
26
29
 
27
30
  numbers = File.read(scope('VERSION')).strip.split('.').map { |n| n.to_i }
31
+ name = File.read(scope('VERSION_NAME')).strip
28
32
  @@version = {
29
33
  :major => numbers[0],
30
34
  :minor => numbers[1],
31
- :teeny => numbers[2]
35
+ :teeny => numbers[2],
36
+ :name => name
32
37
  }
33
- @@version[:string] = [:major, :minor, :teeny].map { |comp| @@version[comp] }.compact.join('.')
38
+ @@version[:number] = [:major, :minor, :teeny].map { |comp| @@version[comp] }.compact.join('.')
39
+ @@version[:string] = @@version[:number].dup
34
40
 
35
41
  if File.exists?(scope('REVISION'))
36
42
  rev = File.read(scope('REVISION')).strip
@@ -47,9 +53,9 @@ module Haml
47
53
  if rev
48
54
  @@version[:rev] = rev
49
55
  unless rev[0] == ?(
50
- @@version[:string] << "."
51
- @@version[:string] << rev[0...7]
56
+ @@version[:string] << "." << rev[0...7]
52
57
  end
58
+ @@version[:string] << " (#{name})"
53
59
  end
54
60
 
55
61
  @@version
data/lib/sass/error.rb CHANGED
@@ -50,4 +50,8 @@ module Sass
50
50
  @message
51
51
  end
52
52
  end
53
+
54
+ # The class for Sass errors that are raised due to invalid unit conversions
55
+ # in SassScript.
56
+ class UnitConversionError < SyntaxError; end
53
57
  end
@@ -61,6 +61,21 @@ module Sass::Script
61
61
 
62
62
  instance_methods.each { |m| undef_method m unless m.to_s =~ /^__/ }
63
63
 
64
+
65
+ # Creates a {Color} object from red, green, and blue values.
66
+ # @param red
67
+ # A number between 0 and 255 inclusive
68
+ # @param green
69
+ # A number between 0 and 255 inclusive
70
+ # @param blue
71
+ # A number between 0 and 255 inclusive
72
+ def rgb(red, green, blue)
73
+ [red.value, green.value, blue.value].each do |v|
74
+ raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive") if v <= 0 || v >= 255
75
+ end
76
+ Color.new([red.value, green.value, blue.value])
77
+ end
78
+
64
79
  # Creates a {Color} object from hue, saturation, and lightness
65
80
  # as per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsl-color).
66
81
  #
@@ -170,5 +170,8 @@ module Sass::Script
170
170
  def to_i
171
171
  raise Sass::SyntaxError.new("#{self.inspect} is not an integer.")
172
172
  end
173
+
174
+ # @raise [Sass::SyntaxError] if this literal isn't an integer
175
+ def assert_int!; to_i; end
173
176
  end
174
177
  end
@@ -54,7 +54,7 @@ module Sass::Script
54
54
  #
55
55
  # @param other [Literal] The right-hand side of the operator
56
56
  # @return [Literal] The result of the operation
57
- # @raise [Sass::SyntaxError] if `other` is a number with incompatible units
57
+ # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
58
58
  def plus(other)
59
59
  if other.is_a? Number
60
60
  operate(other, :+)
@@ -76,7 +76,7 @@ module Sass::Script
76
76
  #
77
77
  # @param other [Literal] The right-hand side of the operator
78
78
  # @return [Literal] The result of the operation
79
- # @raise [Sass::SyntaxError] if `other` is a number with incompatible units
79
+ # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
80
80
  def minus(other)
81
81
  if other.is_a? Number
82
82
  operate(other, :-)
@@ -138,11 +138,11 @@ module Sass::Script
138
138
  # @param other [Number] The right-hand side of the operator
139
139
  # @return [Number] This number modulo the other
140
140
  # @raise [NoMethodError] if `other` is an invalid type
141
- # @raise [Sass::SyntaxError] if `other` has any units
141
+ # @raise [Sass::UnitConversionError] if `other` has any units
142
142
  def mod(other)
143
143
  if other.is_a?(Number)
144
144
  unless other.unitless?
145
- raise Sass::SyntaxError.new("Cannot modulo by a number with units: #{other.inspect}.")
145
+ raise Sass::UnitConversionError.new("Cannot modulo by a number with units: #{other.inspect}.")
146
146
  end
147
147
  operate(other, :%)
148
148
  else
@@ -155,9 +155,19 @@ module Sass::Script
155
155
  # @param other [Literal] The right-hand side of the operator
156
156
  # @return [Boolean] Whether this number is equal to the other object
157
157
  def eq(other)
158
- Sass::Script::Bool.new(super.to_bool &&
159
- self.numerator_units.sort == other.numerator_units.sort &&
160
- self.denominator_units.sort == other.denominator_units.sort)
158
+ return Sass::Script::Bool.new(false) unless other.is_a?(Sass::Script::Number)
159
+ this = self
160
+ begin
161
+ if unitless?
162
+ this = this.coerce(other.numerator_units, other.denominator_units)
163
+ else
164
+ other = other.coerce(numerator_units, denominator_units)
165
+ end
166
+ rescue Sass::UnitConversionError
167
+ return Sass::Script::Bool.new(false)
168
+ end
169
+
170
+ Sass::Script::Bool.new(this.value == other.value)
161
171
  end
162
172
 
163
173
  # The SassScript `>` operation.
@@ -249,11 +259,36 @@ module Sass::Script
249
259
  (numerator_units.empty? || numerator_units.size == 1) && denominator_units.empty?
250
260
  end
251
261
 
262
+ # Returns this number converted to other units.
263
+ # The conversion takes into account the relationship between e.g. mm and cm,
264
+ # as well as between e.g. in and cm.
265
+ #
266
+ # If this number has no units, it will simply return itself
267
+ # with the given units.
268
+ #
269
+ # An incompatible coercion, e.g. between px and cm, will raise an error.
270
+ #
271
+ # @param num_units [Array<String>] The numerator units to coerce this number into.
272
+ # See {#numerator\_units}
273
+ # @param den_units [Array<String>] The denominator units to coerce this number into.
274
+ # See {#denominator\_units}
275
+ # @return [Number] The number with the new units
276
+ # @raise [Sass::UnitConversionError] if the given units are incompatible with the number's
277
+ # current units
278
+ def coerce(num_units, den_units)
279
+ Number.new(if unitless?
280
+ self.value
281
+ else
282
+ self.value * coercion_factor(self.numerator_units, num_units) /
283
+ coercion_factor(self.denominator_units, den_units)
284
+ end, num_units, den_units)
285
+ end
286
+
252
287
  protected
253
288
 
254
289
  def operate(other, operation)
255
290
  this = self
256
- if [:+, :-].include?(operation)
291
+ if [:+, :-, :<=, :<, :>, :>=].include?(operation)
257
292
  if unitless?
258
293
  this = this.coerce(other.numerator_units, other.denominator_units)
259
294
  else
@@ -271,21 +306,12 @@ module Sass::Script
271
306
  end
272
307
  end
273
308
 
274
- def coerce(num_units, den_units)
275
- Number.new(if unitless?
276
- self.value
277
- else
278
- self.value * coercion_factor(self.numerator_units, num_units) /
279
- coercion_factor(self.denominator_units, den_units)
280
- end, num_units, den_units)
281
- end
282
-
283
309
  def coercion_factor(from_units, to_units)
284
310
  # get a list of unmatched units
285
311
  from_units, to_units = sans_common_units(from_units, to_units)
286
312
 
287
313
  if from_units.size != to_units.size || !convertable?(from_units | to_units)
288
- raise Sass::SyntaxError.new("Incompatible units: '#{from_units.join('*')}' and '#{to_units.join('*')}'.")
314
+ raise Sass::UnitConversionError.new("Incompatible units: '#{from_units.join('*')}' and '#{to_units.join('*')}'.")
289
315
  end
290
316
 
291
317
  from_units.zip(to_units).inject(1) {|m,p| m * conversion_factor(p[0], p[1]) }
@@ -28,14 +28,18 @@ module Sass::Tree
28
28
  # @return [Array<Tree::Node>] The resulting static nodes
29
29
  # @see Sass::Tree
30
30
  def _perform(environment)
31
- from = @from.perform(environment).to_i
32
- to = @to.perform(environment).to_i
33
- range = Range.new(from, to, @exclusive)
31
+ from = @from.perform(environment)
32
+ to = @to.perform(environment)
33
+ from.assert_int!
34
+ to.assert_int!
35
+
36
+ to = to.coerce(from.numerator_units, from.denominator_units)
37
+ range = Range.new(from.to_i, to.to_i, @exclusive)
34
38
 
35
39
  children = []
36
40
  environment = Sass::Environment.new(environment)
37
41
  range.each do |i|
38
- environment.set_local_var(@var, Sass::Script::Number.new(i))
42
+ environment.set_local_var(@var, Sass::Script::Number.new(i, from.numerator_units, from.denominator_units))
39
43
  children += perform_children(environment)
40
44
  end
41
45
  children
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
2
3
  require File.dirname(__FILE__) + '/../test_helper'
3
4
 
4
5
  class EngineTest < Test::Unit::TestCase
@@ -803,4 +804,55 @@ END
803
804
  def test_html5_doctype
804
805
  assert_equal %{<!DOCTYPE html>\n}, render('!!!', :format => :html5)
805
806
  end
807
+
808
+ # Encodings
809
+
810
+ unless Haml::Util.ruby1_8?
811
+ def test_default_encoding
812
+ assert_equal(Encoding.find("utf-8"), render(<<HAML.encode("us-ascii")).encoding)
813
+ HTML
814
+ %p bar
815
+ %p foo
816
+ HAML
817
+ end
818
+
819
+ def test_convert_template_render
820
+ assert_equal(<<HTML, render(<<HAML.encode("iso-8859-1"), :encoding => "utf-8"))
821
+ <p>bâr</p>
822
+ <p>föö</p>
823
+ HTML
824
+ %p bâr
825
+ %p föö
826
+ HAML
827
+ end
828
+
829
+ def test_convert_template_render_proc
830
+ assert_converts_template_properly {|e| e.render_proc.call}
831
+ end
832
+
833
+ def test_convert_template_render
834
+ assert_converts_template_properly {|e| e.render}
835
+ end
836
+
837
+ def test_convert_template_def_method
838
+ assert_converts_template_properly do |e|
839
+ o = Object.new
840
+ e.def_method(o, :render)
841
+ o.render
842
+ end
843
+ end
844
+ end
845
+
846
+ private
847
+
848
+ def assert_converts_template_properly
849
+ engine = Haml::Engine.new(<<HAML.encode("iso-8859-1"), :encoding => "utf-8")
850
+ %p bâr
851
+ %p föö
852
+ HAML
853
+ assert_equal(<<HTML, yield(engine))
854
+ <p>bâr</p>
855
+ <p>föö</p>
856
+ HTML
857
+ end
806
858
  end
@@ -33,6 +33,10 @@ class SassEngineTest < Test::Unit::TestCase
33
33
  "! a" => 'Invalid variable: "! a".',
34
34
  "!a b" => 'Invalid variable: "!a b".',
35
35
  "!a = 1b + 2c" => "Incompatible units: 'c' and 'b'.",
36
+ "!a = 1b < 2c" => "Incompatible units: 'c' and 'b'.",
37
+ "!a = 1b > 2c" => "Incompatible units: 'c' and 'b'.",
38
+ "!a = 1b <= 2c" => "Incompatible units: 'c' and 'b'.",
39
+ "!a = 1b >= 2c" => "Incompatible units: 'c' and 'b'.",
36
40
  "a\n :b= 1b * 2c" => "2b*c isn't a valid CSS value.",
37
41
  "a\n :b= 1b % 2c" => "Cannot modulo by a number with units: 2c.",
38
42
  "!a = 2px + #ccc" => "Cannot add a number with units (2px) to a color (#cccccc).",
@@ -76,8 +80,11 @@ class SassEngineTest < Test::Unit::TestCase
76
80
  "@if false\n@else if " => "Invalid else directive '@else if': expected 'if <expr>'.",
77
81
  "a\n !b = 12\nc\n d = !b" => 'Undefined variable: "!b".',
78
82
  "=foo\n !b = 12\nc\n +foo\n d = !b" => 'Undefined variable: "!b".',
83
+ '@for !a from "foo" to 1' => '"foo" is not an integer.',
84
+ '@for !a from 1 to "2"' => '"2" is not an integer.',
79
85
  '@for !a from 1 to "foo"' => '"foo" is not an integer.',
80
86
  '@for !a from 1 to 1.232323' => '1.232 is not an integer.',
87
+ '@for !a from 1px to 3em' => "Incompatible units: 'em' and 'px'.",
81
88
  '@if' => "Invalid if directive '@if': expected expression.",
82
89
  '@while' => "Invalid while directive '@while': expected expression.",
83
90
  '@debug' => "Invalid debug directive '@debug': expected expression.",
@@ -88,6 +88,22 @@ class SassFunctionTest < Test::Unit::TestCase
88
88
  assert_error_message("#aaaaaa is not a number for `abs'", "abs(#aaa)")
89
89
  end
90
90
 
91
+ def test_rgb
92
+ assert_equal("#123456", evaluate("rgb(18, 52, 86)"))
93
+ assert_equal("#beaded", evaluate("rgb(190, 173, 237)"))
94
+
95
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
96
+ "rgb(256, 1, 1)")
97
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
98
+ "rgb(1, 256, 1)")
99
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
100
+ "rgb(1, 1, 256)")
101
+ assert_error_message("Color value 256 must be between 0 and 255 inclusive for `rgb'",
102
+ "rgb(1, 256, 257)")
103
+ assert_error_message("Color value -1 must be between 0 and 255 inclusive for `rgb'",
104
+ "rgb(-1, 1, 1)")
105
+ end
106
+
91
107
  private
92
108
 
93
109
  def assert_rgb_hsl(rgb, hsl)
@@ -199,6 +199,14 @@ WARN
199
199
  assert_equal "#81ff81", resolve("hsl(120, 100%, 75%) + #010001")
200
200
  end
201
201
 
202
+ def test_operator_unit_conversion
203
+ assert_equal "1.1cm", resolve("1cm + 1mm")
204
+ assert_equal "true", resolve("2mm < 1cm")
205
+ assert_equal "true", resolve("10mm == 1cm")
206
+ assert_equal "true", resolve("1 == 1cm")
207
+ assert_equal "true", resolve("1.1cm == 11mm")
208
+ end
209
+
202
210
  private
203
211
 
204
212
  def resolve(str, opts = {}, environment = env)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: haml-edge
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.41
4
+ version: 2.1.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Weizenbaum
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-06-28 00:00:00 -04:00
13
+ date: 2009-07-04 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -27,6 +27,7 @@ extra_rdoc_files:
27
27
  - README.md
28
28
  - MIT-LICENSE
29
29
  - VERSION
30
+ - VERSION_NAME
30
31
  - REVISION
31
32
  - EDGE_GEM_VERSION
32
33
  files:
@@ -230,6 +231,7 @@ files:
230
231
  - README.md
231
232
  - MIT-LICENSE
232
233
  - VERSION
234
+ - VERSION_NAME
233
235
  - REVISION
234
236
  - EDGE_GEM_VERSION
235
237
  has_rdoc: true