haml 2.0.0 → 2.0.1
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/REVISION +1 -0
- data/Rakefile +6 -2
- data/VERSION +1 -1
- data/lib/haml.rb +12 -4
- data/lib/haml/buffer.rb +2 -2
- data/lib/haml/engine.rb +12 -5
- data/lib/haml/error.rb +4 -5
- data/lib/haml/exec.rb +4 -2
- data/lib/haml/helpers.rb +39 -22
- data/lib/haml/helpers/action_view_mods.rb +72 -35
- data/lib/haml/precompiler.rb +17 -26
- data/lib/haml/template.rb +11 -3
- data/lib/haml/template/patch.rb +1 -1
- data/lib/sass.rb +26 -3
- data/lib/sass/constant.rb +26 -57
- data/lib/sass/constant/literal.rb +1 -0
- data/lib/sass/constant/nil.rb +9 -0
- data/lib/sass/engine.rb +10 -4
- data/test/haml/engine_test.rb +20 -1
- data/test/haml/helper_test.rb +18 -2
- data/test/haml/html2haml_test.rb +1 -3
- data/test/haml/results/helpers.xhtml +2 -5
- data/test/haml/results/just_stuff.xhtml +0 -1
- data/test/haml/results/nuke_inner_whitespace.xhtml +6 -0
- data/test/haml/results/whitespace_handling.xhtml +1 -1
- data/test/haml/template_test.rb +29 -46
- data/test/haml/templates/helpers.haml +1 -1
- data/test/haml/templates/just_stuff.haml +0 -1
- data/test/haml/templates/nuke_inner_whitespace.haml +6 -0
- data/test/haml/templates/partials.haml +1 -1
- data/test/haml/templates/whitespace_handling.haml +10 -10
- data/test/sass/engine_test.rb +11 -5
- data/test/sass/plugin_test.rb +2 -6
- data/test/sass/results/constants.css +2 -0
- data/test/sass/templates/constants.sass +3 -0
- data/test/{haml/test_helper.rb → test_helper.rb} +4 -3
- metadata +102 -99
data/REVISION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
(release)
|
data/Rakefile
CHANGED
@@ -19,7 +19,9 @@ require 'rake/testtask'
|
|
19
19
|
|
20
20
|
Rake::TestTask.new do |t|
|
21
21
|
t.libs << 'lib'
|
22
|
-
|
22
|
+
test_files = FileList['test/**/*_test.rb']
|
23
|
+
test_files.exclude('test/rails/*')
|
24
|
+
t.test_files = test_files
|
23
25
|
t.verbose = true
|
24
26
|
end
|
25
27
|
Rake::Task[:test].send(:add_comment, <<END)
|
@@ -53,13 +55,15 @@ end
|
|
53
55
|
Rake::Task[:package].prerequisites.insert(0, :revision_file)
|
54
56
|
|
55
57
|
# We also need to get rid of this file after packaging.
|
56
|
-
|
58
|
+
at_exit { File.delete('REVISION') rescue nil }
|
57
59
|
|
60
|
+
desc "Install Haml as a gem."
|
58
61
|
task :install => [:package] do
|
59
62
|
sudo = RUBY_PLATFORM =~ /win32/ ? '' : 'sudo'
|
60
63
|
sh %{#{sudo} gem install --no-ri pkg/haml-#{File.read('VERSION').strip}}
|
61
64
|
end
|
62
65
|
|
66
|
+
desc "Release a new Haml package to Rubyforge. Requires the NAME and VERSION flags."
|
63
67
|
task :release => [:package] do
|
64
68
|
name, version = ENV['NAME'], ENV['VERSION']
|
65
69
|
raise "Must supply NAME and VERSION for release task." unless name && version
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.
|
1
|
+
2.0.1
|
data/lib/haml.rb
CHANGED
@@ -914,9 +914,16 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
914
914
|
#
|
915
915
|
# === Haml Options
|
916
916
|
#
|
917
|
-
# Options can be set by setting the
|
918
|
-
#
|
919
|
-
#
|
917
|
+
# Options can be set by setting the <tt>Haml::Template.options</tt> hash
|
918
|
+
# in <tt>environment.rb</tt> in Rails...
|
919
|
+
#
|
920
|
+
# Haml::Template.options[:output] = :html5
|
921
|
+
#
|
922
|
+
# ...or by setting the <tt>Merb::Config[:haml]</tt> hash in <tt>init.rb</tt> in Merb...
|
923
|
+
#
|
924
|
+
# Merb::Config[:haml][:output] = :html5
|
925
|
+
#
|
926
|
+
# ...or by passing an options hash to Haml::Engine.new.
|
920
927
|
# Available options are:
|
921
928
|
#
|
922
929
|
# [<tt>:output</tt>] Determines the output format. The default is :xhtml.
|
@@ -927,7 +934,8 @@ $LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
|
927
934
|
# [<tt>:escape_html</tt>] Sets whether or not to escape HTML-sensitive characters in script.
|
928
935
|
# If this is true, = behaves like &=;
|
929
936
|
# otherwise, it behaves like !=.
|
930
|
-
#
|
937
|
+
# Note that if this is set, != should be used for yielding to subtemplates
|
938
|
+
# and rendering partials.
|
931
939
|
# Defaults to false.
|
932
940
|
#
|
933
941
|
# [<tt>:suppress_eval</tt>] Whether or not attribute hashes and Ruby scripts
|
data/lib/haml/buffer.rb
CHANGED
@@ -114,7 +114,7 @@ module Haml
|
|
114
114
|
result = html_escape(result) if escape_html
|
115
115
|
|
116
116
|
has_newline = result.include?("\n")
|
117
|
-
if in_tag && (@options[:ugly] || !has_newline || preserve_tag)
|
117
|
+
if in_tag && !nuke_inner_whitespace && (@options[:ugly] || !has_newline || preserve_tag)
|
118
118
|
@buffer << result
|
119
119
|
@real_tabs -= 1
|
120
120
|
return
|
@@ -199,7 +199,7 @@ module Haml
|
|
199
199
|
@@tab_cache = {}
|
200
200
|
# Gets <tt>count</tt> tabs. Mostly for internal use.
|
201
201
|
def tabs(count = 0)
|
202
|
-
tabs = count + @tabulation
|
202
|
+
tabs = [count + @tabulation, 0].max
|
203
203
|
@@tab_cache[tabs] ||= ' ' * tabs
|
204
204
|
end
|
205
205
|
|
data/lib/haml/engine.rb
CHANGED
@@ -45,11 +45,11 @@ module Haml
|
|
45
45
|
|
46
46
|
# Creates a new instace of Haml::Engine that will compile the given
|
47
47
|
# template string when <tt>render</tt> is called.
|
48
|
-
# See
|
48
|
+
# See the Haml module documentation for available options.
|
49
49
|
#
|
50
50
|
#--
|
51
51
|
# When adding options, remember to add information about them
|
52
|
-
# to
|
52
|
+
# to lib/haml.rb!
|
53
53
|
#++
|
54
54
|
#
|
55
55
|
def initialize(template, options = {})
|
@@ -73,13 +73,20 @@ module Haml
|
|
73
73
|
raise Haml::Error, "Invalid format #{@options[:format].inspect}"
|
74
74
|
end
|
75
75
|
|
76
|
-
@template = template.rstrip
|
76
|
+
@template = template.rstrip + "\n-#\n-#"
|
77
77
|
@to_close_stack = []
|
78
78
|
@output_tabs = 0
|
79
79
|
@template_tabs = 0
|
80
80
|
@index = 0
|
81
81
|
@flat_spaces = -1
|
82
82
|
@newlines = 0
|
83
|
+
@precompiled = ''
|
84
|
+
@merged_text = ''
|
85
|
+
@tab_change = 0
|
86
|
+
|
87
|
+
if @template =~ /\A(\s*\n)*[ \t]+\S/
|
88
|
+
raise SyntaxError.new("Indenting at the beginning of the document is illegal.", ($1 || "").count("\n"))
|
89
|
+
end
|
83
90
|
|
84
91
|
if @options[:filters]
|
85
92
|
warn <<END
|
@@ -90,8 +97,8 @@ END
|
|
90
97
|
end
|
91
98
|
|
92
99
|
precompile
|
93
|
-
rescue Haml::Error
|
94
|
-
|
100
|
+
rescue Haml::Error => e
|
101
|
+
e.backtrace.unshift "#{@options[:filename]}:#{(e.line ? e.line + 1 : @index) + @options[:line] - 1}" if @index
|
95
102
|
raise
|
96
103
|
end
|
97
104
|
|
data/lib/haml/error.rb
CHANGED
@@ -5,13 +5,12 @@ module Haml
|
|
5
5
|
|
6
6
|
# By default, an error is taken to refer to the line of the template
|
7
7
|
# that was being processed when the exception was raised.
|
8
|
-
# However, if
|
9
|
-
|
10
|
-
attr_reader :line_offset
|
8
|
+
# However, if line is non-nil, it + 1 is used instead.
|
9
|
+
attr_reader :line
|
11
10
|
|
12
|
-
def initialize(message = nil,
|
11
|
+
def initialize(message = nil, line = nil)
|
13
12
|
super(message)
|
14
|
-
@
|
13
|
+
@line = line
|
15
14
|
end
|
16
15
|
# :startdoc:
|
17
16
|
end
|
data/lib/haml/exec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../haml'
|
2
2
|
require 'optparse'
|
3
|
+
require 'fileutils'
|
3
4
|
|
4
5
|
module Haml
|
5
6
|
# This module contains code for working with the
|
@@ -128,8 +129,9 @@ END
|
|
128
129
|
dir = File.join(dir, 'haml')
|
129
130
|
|
130
131
|
if File.exists?(dir)
|
131
|
-
|
132
|
-
exit
|
132
|
+
print "Directory #{dir} already exists, overwrite [y/N]? "
|
133
|
+
exit if gets !~ /y/i
|
134
|
+
FileUtils.rm_rf(dir)
|
133
135
|
end
|
134
136
|
|
135
137
|
begin
|
data/lib/haml/helpers.rb
CHANGED
@@ -265,8 +265,8 @@ module Haml
|
|
265
265
|
|
266
266
|
#
|
267
267
|
# call-seq:
|
268
|
-
# haml_tag(name, attributes = {}) {...}
|
269
|
-
# haml_tag(name, text, attributes = {}) {...}
|
268
|
+
# haml_tag(name, *flags, attributes = {}) {...}
|
269
|
+
# haml_tag(name, text, *flags, attributes = {}) {...}
|
270
270
|
#
|
271
271
|
# Creates an HTML tag with the given name and optionally text and attributes.
|
272
272
|
# Can take a block that will be executed
|
@@ -274,6 +274,11 @@ module Haml
|
|
274
274
|
# If the block is a Haml block or outputs text using puts,
|
275
275
|
# the text will be properly indented.
|
276
276
|
#
|
277
|
+
# <tt>flags</tt> is a list of symbol flags
|
278
|
+
# like those that can be put at the end of a Haml tag
|
279
|
+
# (<tt>:/</tt>, <tt>:<</tt>, and <tt>:></tt>).
|
280
|
+
# Currently, only <tt>:/</tt> and <tt>:<</tt> are supported.
|
281
|
+
#
|
277
282
|
# For example,
|
278
283
|
#
|
279
284
|
# haml_tag :table do
|
@@ -304,34 +309,46 @@ module Haml
|
|
304
309
|
# </tr>
|
305
310
|
# </table>
|
306
311
|
#
|
307
|
-
def haml_tag(name,
|
312
|
+
def haml_tag(name, *rest, &block)
|
308
313
|
name = name.to_s
|
314
|
+
text = rest.shift if rest.first.is_a? String
|
315
|
+
flags = []
|
316
|
+
flags << rest.shift while rest.first.is_a? Symbol
|
317
|
+
attributes = Haml::Precompiler.build_attributes(haml_buffer.html?,
|
318
|
+
haml_buffer.options[:attr_wrapper],
|
319
|
+
rest.shift || {})
|
320
|
+
|
321
|
+
if text.nil? && block.nil? && (haml_buffer.options[:autoclose].include?(name) || flags.include?(:/))
|
322
|
+
puts "<#{name}#{attributes} />"
|
323
|
+
return nil
|
324
|
+
end
|
309
325
|
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
attributes = alt_atts
|
326
|
+
if flags.include?(:/)
|
327
|
+
raise Error.new("Self-closing tags can't have content.") if text
|
328
|
+
raise Error.new("Illegal nesting: nesting within a self-closing tag is illegal.") if block
|
314
329
|
end
|
315
330
|
|
316
|
-
|
317
|
-
|
331
|
+
tag = "<#{name}#{attributes}>"
|
332
|
+
if block.nil?
|
333
|
+
tag << text.to_s << "</#{name}>"
|
334
|
+
puts tag
|
335
|
+
return
|
336
|
+
end
|
318
337
|
|
319
|
-
if text
|
320
|
-
|
321
|
-
return nil
|
338
|
+
if text
|
339
|
+
raise Error.new("Illegal nesting: content can't be both given to haml_tag :#{name} and nested within it.")
|
322
340
|
end
|
323
341
|
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
if text
|
329
|
-
puts(text)
|
330
|
-
elsif block
|
331
|
-
block.call
|
332
|
-
end
|
333
|
-
tab_down
|
342
|
+
if flags.include?(:<)
|
343
|
+
tag << capture_haml(&block).strip << "</#{name}>"
|
344
|
+
puts tag
|
345
|
+
return
|
334
346
|
end
|
347
|
+
|
348
|
+
puts tag
|
349
|
+
tab_up
|
350
|
+
block.call
|
351
|
+
tab_down
|
335
352
|
puts "</#{name}>"
|
336
353
|
nil
|
337
354
|
end
|
@@ -7,56 +7,93 @@ if defined?(ActionView) and not defined?(Merb::Plugins)
|
|
7
7
|
end
|
8
8
|
alias_method :render_without_haml, :render
|
9
9
|
alias_method :render, :render_with_haml
|
10
|
+
|
11
|
+
# Rails >2.1
|
12
|
+
if instance_methods.include?('output_buffer')
|
13
|
+
def output_buffer_with_haml
|
14
|
+
return haml_buffer.buffer if is_haml?
|
15
|
+
output_buffer_without_haml
|
16
|
+
end
|
17
|
+
alias_method :output_buffer_without_haml, :output_buffer
|
18
|
+
alias_method :output_buffer, :output_buffer_with_haml
|
19
|
+
|
20
|
+
def set_output_buffer_with_haml(new)
|
21
|
+
if is_haml?
|
22
|
+
haml_buffer.buffer = new
|
23
|
+
else
|
24
|
+
set_output_buffer_without_haml new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
alias_method :set_output_buffer_without_haml, :output_buffer=
|
28
|
+
alias_method :output_buffer=, :set_output_buffer_with_haml
|
29
|
+
end
|
10
30
|
end
|
11
31
|
|
12
32
|
# This overrides various helpers in ActionView
|
13
33
|
# to make them work more effectively with Haml.
|
14
34
|
module Helpers
|
15
35
|
# :stopdoc:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
36
|
+
# In Rails <=2.1, we've got to override considerable capturing infrastructure.
|
37
|
+
# In Rails >2.1, we can make do with only overriding #capture
|
38
|
+
# (which no longer behaves differently in helper contexts).
|
39
|
+
unless ActionView::Base.instance_methods.include?('output_buffer')
|
40
|
+
module CaptureHelper
|
41
|
+
def capture_with_haml(*args, &block)
|
42
|
+
# Rails' #capture helper will just return the value of the block
|
43
|
+
# if it's not actually in the template context,
|
44
|
+
# as detected by the existance of an _erbout variable.
|
45
|
+
# We've got to do the same thing for compatibility.
|
46
|
+
block_is_haml =
|
47
|
+
begin
|
48
|
+
eval('_hamlout', block)
|
49
|
+
true
|
50
|
+
rescue
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
if block_is_haml && is_haml?
|
55
|
+
capture_haml(*args, &block)
|
56
|
+
else
|
57
|
+
capture_without_haml(*args, &block)
|
28
58
|
end
|
59
|
+
end
|
60
|
+
alias_method :capture_without_haml, :capture
|
61
|
+
alias_method :capture, :capture_with_haml
|
29
62
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
63
|
+
def capture_erb_with_buffer_with_haml(*args, &block)
|
64
|
+
if is_haml?
|
65
|
+
capture_haml_with_buffer(*args, &block)
|
66
|
+
else
|
67
|
+
capture_erb_with_buffer_without_haml(*args, &block)
|
68
|
+
end
|
34
69
|
end
|
70
|
+
alias_method :capture_erb_with_buffer_without_haml, :capture_erb_with_buffer
|
71
|
+
alias_method :capture_erb_with_buffer, :capture_erb_with_buffer_with_haml
|
35
72
|
end
|
36
|
-
alias_method :capture_without_haml, :capture
|
37
|
-
alias_method :capture, :capture_with_haml
|
38
73
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
74
|
+
module TextHelper
|
75
|
+
def concat_with_haml(string, binding = nil)
|
76
|
+
if is_haml?
|
77
|
+
haml_buffer.buffer.concat(string)
|
78
|
+
else
|
79
|
+
concat_without_haml(string, binding)
|
80
|
+
end
|
44
81
|
end
|
82
|
+
alias_method :concat_without_haml, :concat
|
83
|
+
alias_method :concat, :concat_with_haml
|
45
84
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
concat_without_haml(string, binding)
|
85
|
+
else
|
86
|
+
module CaptureHelper
|
87
|
+
def capture_with_haml(*args, &block)
|
88
|
+
if is_haml?
|
89
|
+
capture_haml(*args, &block)
|
90
|
+
else
|
91
|
+
capture_without_haml(*args, &block)
|
92
|
+
end
|
56
93
|
end
|
94
|
+
alias_method :capture_without_haml, :capture
|
95
|
+
alias_method :capture, :capture_with_haml
|
57
96
|
end
|
58
|
-
alias_method :concat_without_haml, :concat
|
59
|
-
alias_method :concat, :concat_with_haml
|
60
97
|
end
|
61
98
|
|
62
99
|
module TagHelper
|
data/lib/haml/precompiler.rb
CHANGED
@@ -109,28 +109,15 @@ END
|
|
109
109
|
end.join(';') + ';'
|
110
110
|
end
|
111
111
|
|
112
|
-
Line = Struct.new(
|
112
|
+
Line = Struct.new(:text, :unstripped, :index, :spaces, :tabs)
|
113
113
|
|
114
114
|
def precompile
|
115
|
-
@precompiled = ''
|
116
|
-
@merged_text = ''
|
117
|
-
@tab_change = 0
|
118
|
-
|
119
115
|
old_line = Line.new
|
120
|
-
|
121
|
-
line = Line.new
|
116
|
+
@template.split(/\r\n|\r|\n/).each_with_index do |text, index|
|
117
|
+
@next_line = line = Line.new(text.strip, text.lstrip.chomp, index)
|
122
118
|
line.spaces, line.tabs = count_soft_tabs(text)
|
123
119
|
|
124
|
-
if line.text.empty?
|
125
|
-
process_indent(old_line) if flat? && !old_line.text.empty?
|
126
|
-
|
127
|
-
unless flat?
|
128
|
-
newline
|
129
|
-
next
|
130
|
-
end
|
131
|
-
|
132
|
-
push_flat(old_line)
|
133
|
-
old_line.text, old_line.unstripped, old_line.spaces = '', '', 0
|
120
|
+
if line.text.empty? && !flat?
|
134
121
|
newline
|
135
122
|
next
|
136
123
|
end
|
@@ -154,7 +141,7 @@ END
|
|
154
141
|
end
|
155
142
|
|
156
143
|
if old_line.spaces != old_line.tabs * 2
|
157
|
-
raise SyntaxError.new(<<END.strip,
|
144
|
+
raise SyntaxError.new(<<END.strip, old_line.index)
|
158
145
|
#{old_line.spaces} space#{old_line.spaces == 1 ? ' was' : 's were'} used for indentation. Haml must be indented using two spaces.
|
159
146
|
END
|
160
147
|
end
|
@@ -165,7 +152,7 @@ END
|
|
165
152
|
resolve_newlines
|
166
153
|
|
167
154
|
if !flat? && line.tabs - old_line.tabs > 1
|
168
|
-
raise SyntaxError.new(<<END.strip,
|
155
|
+
raise SyntaxError.new(<<END.strip, line.index)
|
169
156
|
#{line.spaces} spaces were used for indentation. Haml must be indented using two spaces.
|
170
157
|
END
|
171
158
|
end
|
@@ -307,7 +294,10 @@ END
|
|
307
294
|
# Renders a block of text as plain text.
|
308
295
|
# Also checks for an illegally opened block.
|
309
296
|
def push_plain(text)
|
310
|
-
|
297
|
+
if @block_opened
|
298
|
+
raise SyntaxError.new("Illegal nesting: nesting within plain text is illegal.", @next_line.index)
|
299
|
+
end
|
300
|
+
|
311
301
|
push_text text
|
312
302
|
end
|
313
303
|
|
@@ -545,6 +535,7 @@ END
|
|
545
535
|
|
546
536
|
preserve_tag = options[:preserve].include?(tag_name)
|
547
537
|
nuke_inner_whitespace ||= preserve_tag
|
538
|
+
preserve_tag &&= !options[:ugly]
|
548
539
|
|
549
540
|
case action
|
550
541
|
when '/'; self_closing = xhtml?
|
@@ -573,8 +564,8 @@ END
|
|
573
564
|
attributes = parse_class_and_id(attributes)
|
574
565
|
Buffer.merge_attrs(attributes, static_attributes) if static_attributes
|
575
566
|
|
576
|
-
raise SyntaxError.new("Illegal nesting: nesting within a self-closing tag is illegal.",
|
577
|
-
raise SyntaxError.new("Illegal nesting: content can't be both given on the same line as %#{tag_name} and nested within it.",
|
567
|
+
raise SyntaxError.new("Illegal nesting: nesting within a self-closing tag is illegal.", @next_line.index) if @block_opened && self_closing
|
568
|
+
raise SyntaxError.new("Illegal nesting: content can't be both given on the same line as %#{tag_name} and nested within it.", @next_line.index) if @block_opened && !value.empty?
|
578
569
|
raise SyntaxError.new("There's no Ruby code for #{action} to evaluate.") if parse && value.empty?
|
579
570
|
raise SyntaxError.new("Self-closing tags can't have content.") if self_closing && !value.empty?
|
580
571
|
|
@@ -641,7 +632,7 @@ END
|
|
641
632
|
conditional << ">" if conditional
|
642
633
|
|
643
634
|
if @block_opened && !line.empty?
|
644
|
-
raise SyntaxError.new('Illegal nesting: nesting within a tag that already has content is illegal.',
|
635
|
+
raise SyntaxError.new('Illegal nesting: nesting within a tag that already has content is illegal.', @next_line.index)
|
645
636
|
end
|
646
637
|
|
647
638
|
open = "<!--#{conditional} "
|
@@ -662,7 +653,7 @@ END
|
|
662
653
|
|
663
654
|
# Renders an XHTML doctype or XML shebang.
|
664
655
|
def render_doctype(line)
|
665
|
-
raise SyntaxError.new("Illegal nesting: nesting within a header command is illegal.",
|
656
|
+
raise SyntaxError.new("Illegal nesting: nesting within a header command is illegal.", @next_line.index) if @block_opened
|
666
657
|
doctype = text_for_doctype(line)
|
667
658
|
push_text doctype if doctype
|
668
659
|
end
|
@@ -758,8 +749,8 @@ END
|
|
758
749
|
def count_soft_tabs(line)
|
759
750
|
spaces = line.index(/([^ ]|$)/)
|
760
751
|
if line[spaces] == ?\t
|
761
|
-
return
|
762
|
-
raise SyntaxError.new(<<END.strip,
|
752
|
+
return 0, 0 if line.strip.empty?
|
753
|
+
raise SyntaxError.new(<<END.strip, @next_line.index)
|
763
754
|
A tab character was used for indentation. Haml must be indented using two spaces.
|
764
755
|
Are you sure you have soft tabs enabled in your editor?
|
765
756
|
END
|