haml 1.8.1 → 1.8.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of haml might be problematic. Click here for more details.

data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.1
1
+ 1.8.2
@@ -20,6 +20,10 @@ module Haml
20
20
  # Allow reading and writing of the options hash
21
21
  attr :options, true
22
22
 
23
+ # This string contains the source code that is evaluated
24
+ # to produce the Haml document.
25
+ attr :precompiled, true
26
+
23
27
  # Creates a new instace of Haml::Engine that will compile the given
24
28
  # template string when <tt>render</tt> is called.
25
29
  # See README for available options.
@@ -153,7 +153,7 @@ module Haml
153
153
  # <strong>baz</strong>
154
154
  #
155
155
  def tab_up(i = 1)
156
- buffer.tabulation += i
156
+ haml_buffer.tabulation += i
157
157
  end
158
158
 
159
159
  # Increments the number of tabs the buffer automatically adds
@@ -161,7 +161,7 @@ module Haml
161
161
  #
162
162
  # See tab_up.
163
163
  def tab_down(i = 1)
164
- buffer.tabulation -= i
164
+ haml_buffer.tabulation -= i
165
165
  end
166
166
 
167
167
  # Surrounds the given block of Haml code with the given characters,
@@ -235,12 +235,12 @@ module Haml
235
235
  # the local variable <tt>foo</tt> would be assigned to "<p>13</p>\n".
236
236
  #
237
237
  def capture_haml(*args, &block)
238
- capture_haml_with_buffer(buffer.buffer, *args, &block)
238
+ capture_haml_with_buffer(haml_buffer.buffer, *args, &block)
239
239
  end
240
240
 
241
241
  # Outputs text directly to the Haml buffer, with the proper tabulation
242
242
  def puts(text = "")
243
- buffer.buffer << (' ' * buffer.tabulation) << text.to_s << "\n"
243
+ haml_buffer.buffer << (' ' * haml_buffer.tabulation) << text.to_s << "\n"
244
244
  nil
245
245
  end
246
246
 
@@ -285,7 +285,7 @@ module Haml
285
285
  # </tr>
286
286
  # </table>
287
287
  #
288
- def open(name, attributes = {}, alt_atts = {}, &block)
288
+ def haml_tag(name, attributes = {}, alt_atts = {}, &block)
289
289
  text = nil
290
290
  if attributes.is_a? String
291
291
  text = attributes
@@ -293,11 +293,11 @@ module Haml
293
293
  end
294
294
 
295
295
  if text.nil? && block.nil?
296
- puts "<#{name}#{Haml::Precompiler.build_attributes(buffer.options[:attr_wrapper], attributes)} />"
296
+ puts "<#{name}#{Haml::Precompiler.build_attributes(haml_buffer.options[:attr_wrapper], attributes)} />"
297
297
  return nil
298
298
  end
299
299
 
300
- puts "<#{name}#{Haml::Precompiler.build_attributes(buffer.options[:attr_wrapper], attributes)}>"
300
+ puts "<#{name}#{Haml::Precompiler.build_attributes(haml_buffer.options[:attr_wrapper], attributes)}>"
301
301
  unless text && text.empty?
302
302
  tab_up
303
303
  # Print out either the text (using push_text) or call the block and add an endline
@@ -311,18 +311,27 @@ module Haml
311
311
  puts "</#{name}>"
312
312
  nil
313
313
  end
314
+
315
+ def open(*args, &block)
316
+ warn <<END
317
+ DEPRECATION WARNING:
318
+ The Haml #open helper is deprecated and will be removed in version 2.0.
319
+ Use the #haml_tag method instead.
320
+ END
321
+ haml_tag(*args, &block)
322
+ end
314
323
 
315
324
  private
316
325
 
317
326
  # Gets a reference to the current Haml::Buffer object.
318
- def buffer
327
+ def haml_buffer
319
328
  @haml_stack[-1]
320
329
  end
321
330
 
322
331
  # Gives a proc the same local "_hamlout" and "_erbout" variables
323
332
  # that the current template has.
324
- def bind_proc(&proc)
325
- _hamlout = buffer
333
+ def haml_bind_proc(&proc)
334
+ _hamlout = haml_buffer
326
335
  _erbout = _hamlout.buffer
327
336
  proc { |*args| proc.call(*args) }
328
337
  end
@@ -31,7 +31,7 @@ if defined?(ActionView) and not defined?(Merb::Plugins)
31
31
  module TextHelper
32
32
  def concat_with_haml(string, binding = nil)
33
33
  if is_haml?
34
- buffer.buffer.concat(string)
34
+ haml_buffer.buffer.concat(string)
35
35
  else
36
36
  concat_without_haml(string, binding)
37
37
  end
@@ -45,7 +45,7 @@ if defined?(ActionView) and not defined?(Merb::Plugins)
45
45
  if is_haml?
46
46
  if block_given?
47
47
  oldproc = proc
48
- proc = bind_proc do |*args|
48
+ proc = haml_bind_proc do |*args|
49
49
  concat "\n"
50
50
  tab_up
51
51
  oldproc.call(*args)
@@ -67,7 +67,7 @@ if defined?(ActionView) and not defined?(Merb::Plugins)
67
67
  def form_for_with_haml(object_name, *args, &proc)
68
68
  if block_given? && is_haml?
69
69
  oldproc = proc
70
- proc = bind_proc do |*args|
70
+ proc = haml_bind_proc do |*args|
71
71
  tab_up
72
72
  oldproc.call(*args)
73
73
  tab_down
@@ -122,7 +122,7 @@ END
122
122
  @tab_change = 0
123
123
 
124
124
  old_line = Line.new
125
- (@template + "\n-#\n-#").split("\n").each_with_index do |text, index|
125
+ (@template + "\n-#\n-#").split(/\n?\r|\r?\n/).each_with_index do |text, index|
126
126
  line = Line.new text.strip, text.lstrip.chomp, index
127
127
  line.spaces, line.tabs = count_soft_tabs(text)
128
128
 
@@ -473,15 +473,29 @@ END
473
473
  def prerender_tag(name, atomic, attributes)
474
474
  "<#{name}#{Precompiler.build_attributes(@options[:attr_wrapper], attributes)}#{atomic ? ' />' : '>'}"
475
475
  end
476
+
477
+ # Parses a line into tag_name, attributes, attributes_hash, object_ref, action, value
478
+ def parse_tag(line)
479
+ raise SyntaxError.new("Invalid tag: \"#{line}\"") unless match = line.scan(/[%]([-:\w]+)([-\w\.\#]*)(.*)/)[0]
480
+ tag_name, attributes, rest = match
481
+ if rest[0] == ?{
482
+ scanner = StringScanner.new(rest)
483
+ attributes_hash, rest = balance(scanner, ?{, ?})
484
+ attributes_hash = attributes_hash[1, attributes_hash.length - 2] if attributes_hash
485
+ end
486
+ if rest
487
+ object_ref, rest = balance(rest, ?[, ?]) if rest[0] == ?[
488
+ action, value = rest.scan(/([=\/\~]?)?(.*)?/)[0]
489
+ end
490
+ value = value.to_s.strip
491
+ [tag_name, attributes, attributes_hash, object_ref, action, value]
492
+ end
476
493
 
477
494
  # Parses a line that will render as an XHTML tag, and adds the code that will
478
495
  # render that tag to <tt>@precompiled</tt>.
479
496
  def render_tag(line)
480
- raise SyntaxError.new("Invalid tag: \"#{line}\"") unless match = line.scan(TAG_REGEX)[0]
481
- tag_name, attributes, attributes_hash, object_ref, action, value = match
482
- value = value.to_s.strip
483
- attributes_hash = attributes_hash[1...-1] if attributes_hash
484
-
497
+ tag_name, attributes, attributes_hash, object_ref, action, value = parse_tag(line)
498
+
485
499
  raise SyntaxError.new("Illegal element: classes and ids must have values.") if attributes =~ /[\.#](\.|#|\z)/
486
500
 
487
501
  case action
@@ -505,7 +519,7 @@ END
505
519
  Buffer.merge_attrs(attributes, static_attributes) if static_attributes
506
520
 
507
521
  raise SyntaxError.new("Illegal Nesting: Nesting within an atomic tag is illegal.") if @block_opened && atomic
508
- raise SyntaxError.new("Illegal Nesting: Nesting within a tag that already has content is illegal.") if @block_opened && !value.empty?
522
+ raise SyntaxError.new("Illegal Nesting: Content can't be both given on the same line as %#{tag_name} and nested within it.") if @block_opened && !value.empty?
509
523
  raise SyntaxError.new("Tag has no content.") if parse && value.empty?
510
524
  raise SyntaxError.new("Atomic tags can't have content.") if atomic && !value.empty?
511
525
 
@@ -621,25 +635,26 @@ END
621
635
 
622
636
  while scan.scan(/(.*?)\\\#\{/)
623
637
  str << scan.matched[0...-3]
624
- str << eval("\"\\\#{#{balance_brackets(scan)}}\"")
638
+ str << eval("\"\\\#{#{balance(scan, ?{, ?}, 1)[0][0...-1]}}\"")
625
639
  end
626
640
 
627
641
  str + scan.rest
628
642
  end
629
643
 
630
- def balance_brackets(scanner)
644
+ def balance(scanner, start, finish, count = 0)
631
645
  str = ''
632
- count = 1
633
-
634
- while scanner.scan(/(.*?)[\{\}]/)
646
+ scanner = StringScanner.new(scanner) unless scanner.is_a? StringScanner
647
+ regexp = Regexp.new("(.*?)[\\#{start.chr}\\#{finish.chr}]")
648
+ while scanner.scan(regexp)
635
649
  str << scanner.matched
636
- count += 1 if scanner.matched[-1] == ?{
637
- count -= 1 if scanner.matched[-1] == ?}
638
- return str[0...-1] if count == 0
650
+ count += 1 if scanner.matched[-1] == start
651
+ count -= 1 if scanner.matched[-1] == finish
652
+ return [str.strip, scanner.rest] if count == 0
639
653
  end
640
654
 
641
655
  raise SyntaxError.new("Unbalanced brackets.")
642
656
  end
657
+
643
658
 
644
659
  # Counts the tabulation of a line.
645
660
  def count_soft_tabs(line)
@@ -26,6 +26,16 @@ module Haml
26
26
  options = Haml::Template.options.dup
27
27
  Haml::Engine.new(template, options).send(:precompiled_with_ambles, [])
28
28
  end
29
+
30
+ def cache_fragment(block, name = {}, options = nil)
31
+ @view.fragment_for(block, name, options) do
32
+ eval("_hamlout.buffer", block.binding)
33
+ end
34
+ end
35
+
36
+ def read_template_file(template_path, extension)
37
+ File.read(template_path)
38
+ end
29
39
  end
30
40
  end
31
41
 
@@ -71,7 +71,7 @@ module Sass
71
71
  :style => :nested,
72
72
  :load_paths => ['.']
73
73
  }.merge! options
74
- @template = template.split(/\n\r|\n/)
74
+ @template = template.split(/\n?\r|\r?\n/)
75
75
  @lines = []
76
76
  @constants = {"important" => "!important"}
77
77
  end
@@ -13,6 +13,13 @@ module Sass
13
13
  :always_check => true,
14
14
  :full_exception => true
15
15
  }
16
+ @@checked_for_updates = false
17
+
18
+ # Whether or not Sass has *ever* checked if the stylesheets need updates
19
+ # (in this Ruby instance).
20
+ def checked_for_updates
21
+ @@checked_for_updates
22
+ end
16
23
 
17
24
  # Gets various options for Sass. See README for details.
18
25
  #--
@@ -35,6 +42,7 @@ module Sass
35
42
  def update_stylesheets
36
43
  return if options[:never_update]
37
44
 
45
+ @@checked_for_updates = true
38
46
  Dir.glob(File.join(options[:template_location], "**", "*.sass")).entries.each do |file|
39
47
 
40
48
  # Get the relative path to the file with no extension
@@ -18,12 +18,35 @@ unless defined?(Sass::MERB_LOADED)
18
18
  config.symbolize_keys!
19
19
  Sass::Plugin.options.merge!(config)
20
20
 
21
- class MerbHandler # :nodoc:
22
- def process_with_sass(request, response)
23
- Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
24
- process_without_sass(request, response)
21
+ if version[0] > 0 || version[1] >= 9
22
+
23
+ class Merb::Rack::Application # :nodoc:
24
+ def call_with_sass(env)
25
+ if !Sass::Plugin.checked_for_updates ||
26
+ Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
27
+ Sass::Plugin.update_stylesheets
28
+ end
29
+
30
+ call_without_sass(env)
31
+ end
32
+ alias_method :call_without_sass, :call
33
+ alias_method :call, :call_with_sass
34
+ end
35
+
36
+ else
37
+
38
+ class MerbHandler # :nodoc:
39
+ def process_with_sass(request, response)
40
+ if !Sass::Plugin.checked_for_updates ||
41
+ Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
42
+ Sass::Plugin.update_stylesheets
43
+ end
44
+
45
+ process_without_sass(request, response)
46
+ end
47
+ alias_method :process_without_sass, :process
48
+ alias_method :process, :process_with_sass
25
49
  end
26
- alias_method :process_without_sass, :process
27
- alias_method :process, :process_with_sass
50
+
28
51
  end
29
52
  end
@@ -11,7 +11,11 @@ unless defined?(Sass::RAILS_LOADED)
11
11
  class Base
12
12
  alias_method :sass_old_process, :process
13
13
  def process(*args)
14
- Sass::Plugin.update_stylesheets if Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
14
+ if !Sass::Plugin.checked_for_updates ||
15
+ Sass::Plugin.options[:always_update] || Sass::Plugin.options[:always_check]
16
+ Sass::Plugin.update_stylesheets
17
+ end
18
+
15
19
  sass_old_process(*args)
16
20
  end
17
21
  end
@@ -97,6 +97,10 @@ class EngineTest < Test::Unit::TestCase
97
97
  assert_equal("<p>0</p>\n<p>1</p>\n<p>2</p>\n", render("- for i in (0...3)\n %p= |\n i |"))
98
98
  end
99
99
 
100
+ def test_cr_newline
101
+ assert_equal("<p>foo</p>\n<p>bar</p>\n<p>baz</p>\n<p>boom</p>\n", render("%p foo\r%p bar\r\n%p baz\n\r%p boom"))
102
+ end
103
+
100
104
  # Options tests
101
105
 
102
106
  def test_stop_eval
@@ -129,6 +133,18 @@ class EngineTest < Test::Unit::TestCase
129
133
  assert_equal("<p escaped='quo4te'>\n</p>\n", render("%p{ :escaped => \"quo\#{2 + 2}te\"}"))
130
134
  end
131
135
 
136
+ def test_correct_parsing_with_brackets
137
+ assert_equal("<p class='foo'>{tada} foo</p>\n", render("%p{:class => 'foo'} {tada} foo"))
138
+ assert_equal("<p class='foo'>deep {nested { things }}</p>\n", render("%p{:class => 'foo'} deep {nested { things }}"))
139
+ assert_equal("<p class='bar foo'>{a { d</p>\n", render("%p{{:class => 'foo'}, :class => 'bar'} {a { d"))
140
+ assert_equal("<p foo='bar'>a}</p>\n", render("%p{:foo => 'bar'} a}"))
141
+
142
+ foo = []
143
+ foo[0] = Struct.new('Foo', :id).new
144
+ assert_equal("<p class='struct_foo' id='struct_foo_new'>New User]</p>\n",
145
+ render("%p[foo[0]] New User]", :locals => {:foo => foo}))
146
+ end
147
+
132
148
  def test_empty_attrs
133
149
  assert_equal("<p attr=''>empty</p>\n", render("%p{ :attr => '' } empty"))
134
150
  assert_equal("<p attr=''>empty</p>\n", render("%p{ :attr => x } empty", :locals => {:x => ''}))
@@ -140,7 +140,7 @@ class HelperTest < Test::Unit::TestCase
140
140
  context.init_haml_helpers
141
141
 
142
142
  result = context.capture_haml do
143
- context.open :p, :attr => "val" do
143
+ context.haml_tag :p, :attr => "val" do
144
144
  context.puts "Blah"
145
145
  end
146
146
  end
@@ -31,10 +31,10 @@ click
31
31
  = succeed '.' do
32
32
  %a{:href=>"thing"} here
33
33
  %p baz
34
- - buffer.tabulation = 10
34
+ - haml_buffer.tabulation = 10
35
35
  %p boom
36
36
  - concat "foo\n"
37
- - buffer.tabulation = 0
37
+ - haml_buffer.tabulation = 0
38
38
  - def url_for(*stuff); stuff.join(' '); end
39
39
  -# The form URLs must be empty
40
40
  -# because of a weird bug that causes url_for to misbehave.
@@ -58,12 +58,12 @@ click
58
58
  - puts "boom"
59
59
  baz
60
60
  - puts "boom, again"
61
- - open :table do
62
- - open :tr do
63
- - open :td, {:class => 'cell'} do
64
- - open :strong, "strong!"
61
+ - haml_tag :table do
62
+ - haml_tag :tr do
63
+ - haml_tag :td, {:class => 'cell'} do
64
+ - haml_tag :strong, "strong!"
65
65
  - puts "data"
66
- - open :td do
66
+ - haml_tag :td do
67
67
  - puts "more_data"
68
- - open :hr
69
- - open :div, ''
68
+ - haml_tag :hr
69
+ - haml_tag :div, ''
@@ -204,6 +204,10 @@ END
204
204
  assert_equal(":focus {\n a: b; }\n", render("\\:focus\n a: b"))
205
205
  assert_equal("a {\n b: c; }\n a :focus {\n d: e; }\n", render("\\a\n b: c\n \\:focus\n d: e"))
206
206
  end
207
+
208
+ def test_cr_newline
209
+ assert_equal("foo {\n a: b;\n c: d;\n e: f; }\n", render("foo\r a: b\r\n c: d\n\r e: f"))
210
+ end
207
211
 
208
212
  private
209
213
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: haml
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.8.1
7
- date: 2008-01-28 00:00:00 -08:00
6
+ version: 1.8.2
7
+ date: 2008-02-24 00:00:00 -08:00
8
8
  summary: An elegant, structured XHTML/XML templating engine. Comes with Sass, a similar CSS templating engine.
9
9
  require_paths:
10
10
  - lib
@@ -36,7 +36,6 @@ files:
36
36
  - lib/sass/plugin
37
37
  - lib/sass/plugin/rails.rb
38
38
  - lib/sass/plugin/merb.rb
39
- - lib/sass/constant.rb.rej
40
39
  - lib/sass/error.rb
41
40
  - lib/sass/tree
42
41
  - lib/sass/tree/value_node.rb
@@ -71,7 +70,6 @@ files:
71
70
  - lib/haml/precompiler.rb
72
71
  - lib/haml/helpers
73
72
  - lib/haml/helpers/action_view_extensions.rb
74
- - lib/haml/helpers/action_view_mods.rb.rej
75
73
  - lib/haml/helpers/action_view_mods.rb
76
74
  - lib/haml.rb
77
75
  - bin/css2sass
@@ -114,7 +112,6 @@ files:
114
112
  - test/sass/results/compressed.css
115
113
  - test/sass/results/parent_ref.css
116
114
  - test/sass/results/basic.css
117
- - test/sass/engine_test.rb.rej
118
115
  - test/sass/engine_test.rb
119
116
  - test/haml
120
117
  - test/haml/mocks
@@ -1,30 +0,0 @@
1
- ***************
2
- *** 1,11 ****
3
- - begin
4
- - require 'rubygems'
5
- - require 'active_support'
6
- - require 'action_controller'
7
- - require 'action_view'
8
- - action_view_included = true
9
- - rescue LoadError
10
- - action_view_included = false
11
- end
12
-
13
-
14
- --- 1,16 ----
15
- +
16
- + # This obviously requires that ActiveSupport be present prior to Haml
17
- + # being loaded.
18
- + action_view_included = false
19
- + if defined?(ActiveSupport)
20
- + begin
21
- + require 'rubygems'
22
- + require 'active_support'
23
- + require 'action_controller'
24
- + require 'action_view'
25
- + action_view_included = true
26
- + rescue LoadError
27
- + end
28
- end
29
-
30
-
@@ -1,42 +0,0 @@
1
- ***************
2
- *** 106,121 ****
3
- end
4
-
5
- # Time for a unary minus!
6
- - if negative_okay && symbol == :minus
7
- - negative_okay = true
8
- to_return << :neg
9
- next
10
- end
11
-
12
- # Are we looking at an operator?
13
- if symbol && (str.empty? || symbol != :mod)
14
- str = reset_str.call
15
- - negative_okay = true
16
- to_return << symbol
17
- next
18
- end
19
- --- 107,129 ----
20
- end
21
-
22
- # Time for a unary minus!
23
- + if beginning_of_token && symbol == :minus
24
- + beginning_of_token = true
25
- to_return << :neg
26
- next
27
- end
28
-
29
- + # Is this a constant?
30
- + if beginning_of_token && symbol == :const
31
- + beginning_of_token = true
32
- + to_return << :const
33
- + next
34
- + end
35
- +
36
- # Are we looking at an operator?
37
- if symbol && (str.empty? || symbol != :mod)
38
- str = reset_str.call
39
- + beginning_of_token = true
40
- to_return << symbol
41
- next
42
- end
@@ -1,18 +0,0 @@
1
- ***************
2
- *** 44,49 ****
3
- "@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
4
- "foo\n @import templates/basic" => "Import directives may only be used at the root of a document.",
5
- "@foo bar boom" => "Unknown compiler directive: \"@foo bar boom\"",
6
- }
7
-
8
- def test_basic_render
9
- --- 44,52 ----
10
- "@import templates/basic\n foo" => "Illegal nesting: Nothing may be nested beneath import directives.",
11
- "foo\n @import templates/basic" => "Import directives may only be used at the root of a document.",
12
- "@foo bar boom" => "Unknown compiler directive: \"@foo bar boom\"",
13
- + "!foo = bar baz -" => "Unterminated unary minus.",
14
- + "!foo = bar baz !" => "Unterminated constant.",
15
- + "!foo = !(foo)" => "Invalid constant.",
16
- }
17
-
18
- def test_basic_render