haml-edge 2.1.41 → 2.1.42

Sign up to get free protection for your applications and to get access to all the features.
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