hamlit 2.12.0-java → 2.13.0-java

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.
@@ -1,11 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'strscan'
2
- require 'hamlit/parser/haml_util'
3
- require 'hamlit/parser/haml_error'
4
- require 'hamlit/parser/haml_attribute_builder'
5
4
 
6
5
  module Hamlit
7
6
  class HamlParser
8
- include ::Hamlit::HamlUtil
7
+ include Hamlit::HamlUtil
9
8
 
10
9
  attr_reader :root
11
10
 
@@ -62,7 +61,7 @@ module Hamlit
62
61
  SILENT_SCRIPT,
63
62
  ESCAPE,
64
63
  FILTER
65
- ]
64
+ ].freeze
66
65
 
67
66
  # The value of the character that designates that a line is part
68
67
  # of a multiline string.
@@ -76,8 +75,8 @@ module Hamlit
76
75
  #
77
76
  BLOCK_WITH_SPACES = /do\s*\|\s*[^\|]*\s+\|\z/
78
77
 
79
- MID_BLOCK_KEYWORDS = %w[else elsif rescue ensure end when]
80
- START_BLOCK_KEYWORDS = %w[if begin case unless]
78
+ MID_BLOCK_KEYWORDS = %w[else elsif rescue ensure end when].freeze
79
+ START_BLOCK_KEYWORDS = %w[if begin case unless].freeze
81
80
  # Try to parse assignments to block starters as best as possible
82
81
  START_BLOCK_KEYWORD_REGEX = /(?:\w+(?:,\s*\w+)*\s*=\s*)?(#{START_BLOCK_KEYWORDS.join('|')})/
83
82
  BLOCK_KEYWORD_REGEX = /^-?\s*(?:(#{MID_BLOCK_KEYWORDS.join('|')})|#{START_BLOCK_KEYWORD_REGEX.source})\b/
@@ -91,14 +90,16 @@ module Hamlit
91
90
  ID_KEY = 'id'.freeze
92
91
  CLASS_KEY = 'class'.freeze
93
92
 
94
- def initialize(template, options)
95
- @options = options
93
+ def initialize(options)
94
+ @options = HamlOptions.wrap(options)
96
95
  # Record the indent levels of "if" statements to validate the subsequent
97
96
  # elsif and else statements are indented at the appropriate level.
98
97
  @script_level_stack = []
99
98
  @template_index = 0
100
99
  @template_tabs = 0
100
+ end
101
101
 
102
+ def call(template)
102
103
  match = template.rstrip.scan(/(([ \t]+)?(.*?))(?:\Z|\r\n|\r|\n)/m)
103
104
  # discard the last match which is always blank
104
105
  match.pop
@@ -107,16 +108,14 @@ module Hamlit
107
108
  end
108
109
  # Append special end-of-document marker
109
110
  @template << Line.new(nil, '-#', '-#', @template.size, self, true)
110
- end
111
111
 
112
- def parse
113
112
  @root = @parent = ParseNode.new(:root)
114
113
  @flat = false
115
114
  @filter_buffer = nil
116
115
  @indentation = nil
117
116
  @line = next_line
118
117
 
119
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:indenting_at_start), @line.index) if @line.tabs != 0
118
+ raise HamlSyntaxError.new(HamlError.message(:indenting_at_start), @line.index) if @line.tabs != 0
120
119
 
121
120
  loop do
122
121
  next_line
@@ -139,7 +138,7 @@ module Hamlit
139
138
  end
140
139
 
141
140
  if !flat? && @next_line.tabs - @line.tabs > 1
142
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:deeper_indenting, @next_line.tabs - @line.tabs), @next_line.index)
141
+ raise HamlSyntaxError.new(HamlError.message(:deeper_indenting, @next_line.tabs - @line.tabs), @next_line.index)
143
142
  end
144
143
 
145
144
  @line = @next_line
@@ -147,7 +146,7 @@ module Hamlit
147
146
  # Close all the open tags
148
147
  close until @parent.type == :root
149
148
  @root
150
- rescue ::Hamlit::HamlError => e
149
+ rescue Hamlit::HamlError => e
151
150
  e.backtrace.unshift "#{@options.filename}:#{(e.line ? e.line + 1 : @line.index + 1) + @options.line - 1}"
152
151
  raise
153
152
  end
@@ -159,7 +158,7 @@ module Hamlit
159
158
  @indentation = line.whitespace
160
159
 
161
160
  if @indentation.include?(?\s) && @indentation.include?(?\t)
162
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:cant_use_tabs_and_spaces), line.index)
161
+ raise HamlSyntaxError.new(HamlError.message(:cant_use_tabs_and_spaces), line.index)
163
162
  end
164
163
 
165
164
  @flat_spaces = @indentation * (@template_tabs+1) if flat?
@@ -170,17 +169,17 @@ module Hamlit
170
169
  return tabs if line.whitespace == @indentation * tabs
171
170
  return @template_tabs + 1 if flat? && line.whitespace =~ /^#{@flat_spaces}/
172
171
 
173
- message = ::Hamlit::HamlError.message(:inconsistent_indentation,
172
+ message = HamlError.message(:inconsistent_indentation,
174
173
  human_indentation(line.whitespace),
175
174
  human_indentation(@indentation)
176
175
  )
177
- raise ::Hamlit::HamlSyntaxError.new(message, line.index)
176
+ raise HamlSyntaxError.new(message, line.index)
178
177
  end
179
178
 
180
179
  private
181
180
 
182
181
  # @private
183
- class Line < Struct.new(:whitespace, :text, :full, :index, :parser, :eod)
182
+ Line = Struct.new(:whitespace, :text, :full, :index, :parser, :eod) do
184
183
  alias_method :eod?, :eod
185
184
 
186
185
  # @private
@@ -196,14 +195,14 @@ module Hamlit
196
195
  end
197
196
 
198
197
  # @private
199
- class ParseNode < Struct.new(:type, :line, :value, :parent, :children)
198
+ ParseNode = Struct.new(:type, :line, :value, :parent, :children) do
200
199
  def initialize(*args)
201
200
  super
202
201
  self.children ||= []
203
202
  end
204
203
 
205
204
  def inspect
206
- %Q[(#{type} #{value.inspect}#{children.each_with_object('') {|c, s| s << "\n#{c.inspect.gsub!(/^/, ' ')}"}})]
205
+ %Q[(#{type} #{value.inspect}#{children.each_with_object(''.dup) {|c, s| s << "\n#{c.inspect.gsub!(/^/, ' ')}"}})].dup
207
206
  end
208
207
  end
209
208
 
@@ -218,7 +217,7 @@ module Hamlit
218
217
  self[:old] = value
219
218
  end
220
219
 
221
- # This will be a literal for Haml::Buffer#attributes's last argument, `attributes_hashes`.
220
+ # This will be a literal for Hamlit::HamlBuffer#attributes's last argument, `attributes_hashes`.
222
221
  def to_literal
223
222
  [new, stripped_old].compact.join(', ')
224
223
  end
@@ -290,7 +289,7 @@ module Hamlit
290
289
  end
291
290
 
292
291
  def block_keyword(text)
293
- return unless keyword = text.scan(BLOCK_KEYWORD_REGEX)[0]
292
+ return unless (keyword = text.scan(BLOCK_KEYWORD_REGEX)[0])
294
293
  keyword[0] || keyword[1]
295
294
  end
296
295
 
@@ -301,20 +300,20 @@ module Hamlit
301
300
 
302
301
  def plain(line, escape_html = nil)
303
302
  if block_opened?
304
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_nesting_plain), @next_line.index)
303
+ raise HamlSyntaxError.new(HamlError.message(:illegal_nesting_plain), @next_line.index)
305
304
  end
306
305
 
307
306
  unless contains_interpolation?(line.text)
308
307
  return ParseNode.new(:plain, line.index + 1, :text => line.text)
309
308
  end
310
309
 
311
- escape_html = @options.escape_html if escape_html.nil?
312
- line.text = ::Hamlit::HamlUtil.unescape_interpolation(line.text)
310
+ escape_html = @options.escape_html && @options.mime_type != 'text/plain' if escape_html.nil?
311
+ line.text = unescape_interpolation(line.text)
313
312
  script(line, false).tap { |n| n.value[:escape_interpolation] = true if escape_html }
314
313
  end
315
314
 
316
315
  def script(line, escape_html = nil, preserve = false)
317
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:no_ruby_code, '=')) if line.text.empty?
316
+ raise HamlSyntaxError.new(HamlError.message(:no_ruby_code, '=')) if line.text.empty?
318
317
  line = handle_ruby_multiline(line)
319
318
  escape_html = @options.escape_html if escape_html.nil?
320
319
 
@@ -326,12 +325,12 @@ module Hamlit
326
325
  end
327
326
 
328
327
  def flat_script(line, escape_html = nil)
329
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:no_ruby_code, '~')) if line.text.empty?
328
+ raise HamlSyntaxError.new(HamlError.message(:no_ruby_code, '~')) if line.text.empty?
330
329
  script(line, escape_html, :preserve)
331
330
  end
332
331
 
333
332
  def silent_script(line)
334
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:no_end), line.index) if line.text[1..-1].strip == 'end'
333
+ raise HamlSyntaxError.new(HamlError.message(:no_end), line.index) if line.text[1..-1].strip == 'end'
335
334
 
336
335
  line = handle_ruby_multiline(line)
337
336
  keyword = block_keyword(line.text)
@@ -340,7 +339,7 @@ module Hamlit
340
339
 
341
340
  if ["else", "elsif", "when"].include?(keyword)
342
341
  if @script_level_stack.empty?
343
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:missing_if, keyword), @line.index)
342
+ raise Hamlit::HamlSyntaxError.new(HamlError.message(:missing_if, keyword), @line.index)
344
343
  end
345
344
 
346
345
  if keyword == 'when' and !@script_level_stack.last[2]
@@ -351,8 +350,8 @@ module Hamlit
351
350
  end
352
351
 
353
352
  if @script_level_stack.last[1] != @line.tabs
354
- message = ::Hamlit::HamlError.message(:bad_script_indent, keyword, @script_level_stack.last[1], @line.tabs)
355
- raise ::Hamlit::HamlSyntaxError.new(message, @line.index)
353
+ message = HamlError.message(:bad_script_indent, keyword, @script_level_stack.last[1], @line.tabs)
354
+ raise Hamlit::HamlSyntaxError.new(message, @line.index)
356
355
  end
357
356
  end
358
357
 
@@ -389,7 +388,6 @@ module Hamlit
389
388
 
390
389
  preserve_tag = @options.preserve.include?(tag_name)
391
390
  nuke_inner_whitespace ||= preserve_tag
392
- preserve_tag = false if @options.ugly
393
391
  escape_html = (action == '&' || (action != '!' && @options.escape_html))
394
392
 
395
393
  case action
@@ -398,7 +396,7 @@ module Hamlit
398
396
  when '='
399
397
  parse = true
400
398
  if value[0] == ?=
401
- value = ::Hamlit::HamlUtil.unescape_interpolation(value[1..-1].strip)
399
+ value = unescape_interpolation(value[1..-1].strip)
402
400
  escape_interpolation = true if escape_html
403
401
  escape_html = false
404
402
  end
@@ -407,28 +405,27 @@ module Hamlit
407
405
  parse = true
408
406
  preserve_script = (value[0] == ?~)
409
407
  if value[1] == ?=
410
- value = ::Hamlit::HamlUtil.unescape_interpolation(value[2..-1].strip)
408
+ value = unescape_interpolation(value[2..-1].strip)
411
409
  escape_interpolation = true if escape_html
412
410
  escape_html = false
413
411
  else
414
412
  value = value[1..-1].strip
415
413
  end
416
414
  elsif contains_interpolation?(value)
417
- value = ::Hamlit::HamlUtil.unescape_interpolation(value)
415
+ value = unescape_interpolation(value)
418
416
  escape_interpolation = true if escape_html
419
417
  parse = true
420
418
  escape_html = false
421
419
  end
422
420
  else
423
421
  if contains_interpolation?(value)
424
- value = ::Hamlit::HamlUtil.unescape_interpolation(value)
425
- escape_interpolation = true if escape_html
422
+ value = unescape_interpolation(value, escape_html)
426
423
  parse = true
427
424
  escape_html = false
428
425
  end
429
426
  end
430
427
 
431
- attributes = ::Hamlit::HamlParser.parse_class_and_id(attributes)
428
+ attributes = HamlParser.parse_class_and_id(attributes)
432
429
  dynamic_attributes = DynamicAttributes.new
433
430
 
434
431
  if attributes_hashes[:new]
@@ -443,12 +440,12 @@ module Hamlit
443
440
  dynamic_attributes.old = attributes_hashes[:old] unless static_attributes || @options.suppress_eval
444
441
  end
445
442
 
446
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_nesting_self_closing), @next_line.index) if block_opened? && self_closing
447
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:no_ruby_code, action), last_line - 1) if parse && value.empty?
448
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:self_closing_content), last_line - 1) if self_closing && !value.empty?
443
+ raise HamlSyntaxError.new(HamlError.message(:illegal_nesting_self_closing), @next_line.index) if block_opened? && self_closing
444
+ raise HamlSyntaxError.new(HamlError.message(:no_ruby_code, action), last_line - 1) if parse && value.empty?
445
+ raise HamlSyntaxError.new(HamlError.message(:self_closing_content), last_line - 1) if self_closing && !value.empty?
449
446
 
450
447
  if block_opened? && !value.empty? && !is_ruby_multiline?(value)
451
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_nesting_line, tag_name), @next_line.index)
448
+ raise HamlSyntaxError.new(HamlError.message(:illegal_nesting_line, tag_name), @next_line.index)
452
449
  end
453
450
 
454
451
  self_closing ||= !!(!block_opened? && value.empty? && @options.autoclose.any? {|t| t === tag_name})
@@ -486,13 +483,13 @@ module Hamlit
486
483
 
487
484
  if contains_interpolation?(text)
488
485
  parse = true
489
- text = slow_unescape_interpolation(text)
486
+ text = unescape_interpolation(text)
490
487
  else
491
488
  parse = false
492
489
  end
493
490
 
494
491
  if block_opened? && !text.empty?
495
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_nesting_content), @next_line.index)
492
+ raise HamlSyntaxError.new(Hamlit::HamlError.message(:illegal_nesting_content), @next_line.index)
496
493
  end
497
494
 
498
495
  ParseNode.new(:comment, @line.index + 1, :conditional => conditional, :text => text, :revealed => revealed, :parse => parse)
@@ -500,13 +497,13 @@ module Hamlit
500
497
 
501
498
  # Renders an XHTML doctype or XML shebang.
502
499
  def doctype(text)
503
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_nesting_header), @next_line.index) if block_opened?
500
+ raise HamlSyntaxError.new(HamlError.message(:illegal_nesting_header), @next_line.index) if block_opened?
504
501
  version, type, encoding = text[3..-1].strip.downcase.scan(DOCTYPE_REGEX)[0]
505
502
  ParseNode.new(:doctype, @line.index + 1, :version => version, :type => type, :encoding => encoding)
506
503
  end
507
504
 
508
505
  def filter(name)
509
- raise ::Hamlit::HamlError.new(::Hamlit::HamlError.message(:invalid_filter_name, name)) unless name =~ /^\w+$/
506
+ raise HamlError.new(HamlError.message(:invalid_filter_name, name)) unless name =~ /^\w+$/
510
507
 
511
508
  if filter_opened?
512
509
  @flat = true
@@ -543,7 +540,7 @@ module Hamlit
543
540
 
544
541
  # Post-process case statements to normalize the nesting of "when" clauses
545
542
  return unless node.value[:keyword] == "case"
546
- return unless first = node.children.first
543
+ return unless (first = node.children.first)
547
544
  return unless first.type == :silent_script && first.value[:keyword] == "when"
548
545
  return if first.children.empty?
549
546
  # If the case node has a "when" child with children, it's the
@@ -555,7 +552,7 @@ module Hamlit
555
552
 
556
553
  alias :close_script :close_silent_script
557
554
 
558
- # This is a class method so it can be accessed from {Haml::Helpers}.
555
+ # This is a class method so it can be accessed from {Hamlit::HamlHelpers}.
559
556
  #
560
557
  # Iterates through the classes and ids supplied through `.`
561
558
  # and `#` syntax, and returns a hash with them as attributes,
@@ -564,7 +561,7 @@ module Hamlit
564
561
  attributes = {}
565
562
  return attributes if list.empty?
566
563
 
567
- list.scan(/([#.])([-:_a-zA-Z0-9]+)/) do |type, property|
564
+ list.scan(/([#.])([-:_a-zA-Z0-9\@]+)/) do |type, property|
568
565
  case type
569
566
  when '.'
570
567
  if attributes[CLASS_KEY]
@@ -579,16 +576,22 @@ module Hamlit
579
576
  attributes
580
577
  end
581
578
 
579
+ # This method doesn't use Hamlit::HamlAttributeParser because currently it depends on Ripper and Rubinius doesn't provide it.
580
+ # Ideally this logic should be placed in Hamlit::HamlAttributeParser instead of here and this method should use it.
581
+ #
582
+ # @param [String] text - Hash literal or text inside old attributes
583
+ # @return [Hash,nil] - Return nil if text is not static Hash literal
582
584
  def parse_static_hash(text)
583
585
  attributes = {}
584
586
  return attributes if text.empty?
585
587
 
588
+ text = text[1...-1] # strip brackets
586
589
  scanner = StringScanner.new(text)
587
590
  scanner.scan(/\s+/)
588
591
  until scanner.eos?
589
- return unless key = scanner.scan(LITERAL_VALUE_REGEX)
592
+ return unless (key = scanner.scan(LITERAL_VALUE_REGEX))
590
593
  return unless scanner.scan(/\s*=>\s*/)
591
- return unless value = scanner.scan(LITERAL_VALUE_REGEX)
594
+ return unless (value = scanner.scan(LITERAL_VALUE_REGEX))
592
595
  return unless scanner.scan(/\s*(?:,|$)\s*/)
593
596
  attributes[eval(key).to_s] = eval(value).to_s
594
597
  end
@@ -597,13 +600,13 @@ module Hamlit
597
600
 
598
601
  # Parses a line into tag_name, attributes, attributes_hash, object_ref, action, value
599
602
  def parse_tag(text)
600
- match = text.scan(/%([-:\w]+)([-:\w.#]*)(.+)?/)[0]
601
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:invalid_tag, text)) unless match
603
+ match = text.scan(/%([-:\w]+)([-:\w.#\@]*)(.+)?/)[0]
604
+ raise HamlSyntaxError.new(HamlError.message(:invalid_tag, text)) unless match
602
605
 
603
606
  tag_name, attributes, rest = match
604
607
 
605
608
  if !attributes.empty? && (attributes =~ /[.#](\.|#|\z)/)
606
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_element))
609
+ raise HamlSyntaxError.new(HamlError.message(:illegal_element))
607
610
  end
608
611
 
609
612
  new_attributes_hash = old_attributes_hash = last_line = nil
@@ -648,14 +651,17 @@ module Hamlit
648
651
  nuke_inner_whitespace, action, value, last_line || @line.index + 1]
649
652
  end
650
653
 
654
+ # @return [String] attributes_hash - Hash literal starting with `{` and ending with `}`
655
+ # @return [String] rest
656
+ # @return [Integer] last_line
651
657
  def parse_old_attributes(text)
652
658
  text = text.dup
653
659
  last_line = @line.index + 1
654
660
 
655
661
  begin
656
662
  attributes_hash, rest = balance(text, ?{, ?})
657
- rescue ::Hamlit::HamlSyntaxError => e
658
- if text.strip[-1] == ?, && e.message == ::Hamlit::HamlError.message(:unbalanced_brackets)
663
+ rescue HamlSyntaxError => e
664
+ if text.strip[-1] == ?, && e.message == HamlError.message(:unbalanced_brackets)
659
665
  text << "\n#{@next_line.text}"
660
666
  last_line += 1
661
667
  next_line
@@ -668,6 +674,9 @@ module Hamlit
668
674
  return attributes_hash, rest, last_line
669
675
  end
670
676
 
677
+ # @return [Array<Hash,String,nil>] - [static_attributes (Hash), dynamic_attributes (nil or String starting with `{` and ending with `}`)]
678
+ # @return [String] rest
679
+ # @return [Integer] last_line
671
680
  def parse_new_attributes(text)
672
681
  scanner = StringScanner.new(text)
673
682
  last_line = @line.index + 1
@@ -679,9 +688,9 @@ module Hamlit
679
688
  break if name.nil?
680
689
 
681
690
  if name == false
682
- scanned = ::Hamlit::HamlUtil.balance(text, ?(, ?))
691
+ scanned = Hamlit::HamlUtil.balance(text, ?(, ?))
683
692
  text = scanned ? scanned.first : text
684
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:invalid_attribute_list, text.inspect), last_line - 1)
693
+ raise Hamlit::HamlSyntaxError.new(HamlError.message(:invalid_attribute_list, text.inspect), last_line - 1)
685
694
  end
686
695
  attributes[name] = value
687
696
  scanner.scan(/\s*/)
@@ -695,7 +704,7 @@ module Hamlit
695
704
  end
696
705
 
697
706
  static_attributes = {}
698
- dynamic_attributes = "{"
707
+ dynamic_attributes = "{".dup
699
708
  attributes.each do |name, (type, val)|
700
709
  if type == :static
701
710
  static_attributes[name] = val
@@ -710,7 +719,7 @@ module Hamlit
710
719
  end
711
720
 
712
721
  def parse_new_attribute(scanner)
713
- unless name = scanner.scan(/[-:\w]+/)
722
+ unless (name = scanner.scan(/[-:\w]+/))
714
723
  return if scanner.scan(/\)/)
715
724
  return false
716
725
  end
@@ -719,8 +728,8 @@ module Hamlit
719
728
  return name, [:static, true] unless scanner.scan(/=/) #/end
720
729
 
721
730
  scanner.scan(/\s*/)
722
- unless quote = scanner.scan(/["']/)
723
- return false unless var = scanner.scan(/(@@?|\$)?\w+/)
731
+ unless (quote = scanner.scan(/["']/))
732
+ return false unless (var = scanner.scan(/(@@?|\$)?\w+/))
724
733
  return name, [:dynamic, var]
725
734
  end
726
735
 
@@ -735,7 +744,7 @@ module Hamlit
735
744
 
736
745
  return name, [:static, content.first[1]] if content.size == 1
737
746
  return name, [:dynamic,
738
- %!"#{content.each_with_object('') {|(t, v), s| s << (t == :str ? inspect_obj(v)[1...-1] : "\#{#{v}}")}}"!]
747
+ %!"#{content.each_with_object(''.dup) {|(t, v), s| s << (t == :str ? inspect_obj(v)[1...-1] : "\#{#{v}}")}}"!]
739
748
  end
740
749
 
741
750
  def next_line
@@ -803,7 +812,7 @@ module Hamlit
803
812
  end
804
813
 
805
814
  def balance(*args)
806
- ::Hamlit::HamlUtil.balance(*args) or raise(::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:unbalanced_brackets)))
815
+ Hamlit::HamlUtil.balance(*args) or raise(HamlSyntaxError.new(HamlError.message(:unbalanced_brackets)))
807
816
  end
808
817
 
809
818
  def block_opened?