hamlit 2.11.0 → 2.13.0

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +17 -11
  4. data/CHANGELOG.md +29 -1
  5. data/Gemfile +1 -7
  6. data/LICENSE.txt +26 -23
  7. data/REFERENCE.md +4 -4
  8. data/bin/update-haml +125 -0
  9. data/ext/hamlit/hamlit.c +0 -1
  10. data/lib/hamlit/attribute_builder.rb +2 -2
  11. data/lib/hamlit/attribute_compiler.rb +3 -3
  12. data/lib/hamlit/compiler/children_compiler.rb +18 -4
  13. data/lib/hamlit/compiler/comment_compiler.rb +1 -0
  14. data/lib/hamlit/filters/escaped.rb +1 -1
  15. data/lib/hamlit/filters/markdown.rb +1 -0
  16. data/lib/hamlit/filters/preserve.rb +1 -1
  17. data/lib/hamlit/filters/text_base.rb +1 -1
  18. data/lib/hamlit/filters/tilt_base.rb +1 -1
  19. data/lib/hamlit/parser.rb +6 -2
  20. data/lib/hamlit/parser/haml_attribute_builder.rb +164 -0
  21. data/lib/hamlit/parser/haml_buffer.rb +20 -130
  22. data/lib/hamlit/parser/haml_compiler.rb +1 -553
  23. data/lib/hamlit/parser/haml_error.rb +29 -25
  24. data/lib/hamlit/parser/haml_escapable.rb +1 -0
  25. data/lib/hamlit/parser/haml_generator.rb +1 -0
  26. data/lib/hamlit/parser/haml_helpers.rb +41 -59
  27. data/lib/hamlit/parser/{haml_xss_mods.rb → haml_helpers/xss_mods.rb} +20 -15
  28. data/lib/hamlit/parser/haml_options.rb +53 -66
  29. data/lib/hamlit/parser/haml_parser.rb +103 -71
  30. data/lib/hamlit/parser/haml_temple_engine.rb +123 -0
  31. data/lib/hamlit/parser/haml_util.rb +10 -40
  32. data/lib/hamlit/rails_template.rb +1 -1
  33. data/lib/hamlit/string_splitter.rb +1 -0
  34. data/lib/hamlit/temple_line_counter.rb +31 -0
  35. data/lib/hamlit/version.rb +1 -1
  36. metadata +10 -6
  37. data/lib/hamlit/parser/MIT-LICENSE +0 -20
  38. data/lib/hamlit/parser/README.md +0 -30
@@ -1,10 +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
4
 
5
5
  module Hamlit
6
6
  class HamlParser
7
- include ::Hamlit::HamlUtil
7
+ include Hamlit::HamlUtil
8
8
 
9
9
  attr_reader :root
10
10
 
@@ -61,7 +61,7 @@ module Hamlit
61
61
  SILENT_SCRIPT,
62
62
  ESCAPE,
63
63
  FILTER
64
- ]
64
+ ].freeze
65
65
 
66
66
  # The value of the character that designates that a line is part
67
67
  # of a multiline string.
@@ -75,8 +75,8 @@ module Hamlit
75
75
  #
76
76
  BLOCK_WITH_SPACES = /do\s*\|\s*[^\|]*\s+\|\z/
77
77
 
78
- MID_BLOCK_KEYWORDS = %w[else elsif rescue ensure end when]
79
- 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
80
80
  # Try to parse assignments to block starters as best as possible
81
81
  START_BLOCK_KEYWORD_REGEX = /(?:\w+(?:,\s*\w+)*\s*=\s*)?(#{START_BLOCK_KEYWORDS.join('|')})/
82
82
  BLOCK_KEYWORD_REGEX = /^-?\s*(?:(#{MID_BLOCK_KEYWORDS.join('|')})|#{START_BLOCK_KEYWORD_REGEX.source})\b/
@@ -90,14 +90,16 @@ module Hamlit
90
90
  ID_KEY = 'id'.freeze
91
91
  CLASS_KEY = 'class'.freeze
92
92
 
93
- def initialize(template, options)
94
- @options = options
93
+ def initialize(options)
94
+ @options = HamlOptions.wrap(options)
95
95
  # Record the indent levels of "if" statements to validate the subsequent
96
96
  # elsif and else statements are indented at the appropriate level.
97
97
  @script_level_stack = []
98
98
  @template_index = 0
99
99
  @template_tabs = 0
100
+ end
100
101
 
102
+ def call(template)
101
103
  match = template.rstrip.scan(/(([ \t]+)?(.*?))(?:\Z|\r\n|\r|\n)/m)
102
104
  # discard the last match which is always blank
103
105
  match.pop
@@ -106,16 +108,14 @@ module Hamlit
106
108
  end
107
109
  # Append special end-of-document marker
108
110
  @template << Line.new(nil, '-#', '-#', @template.size, self, true)
109
- end
110
111
 
111
- def parse
112
112
  @root = @parent = ParseNode.new(:root)
113
113
  @flat = false
114
114
  @filter_buffer = nil
115
115
  @indentation = nil
116
116
  @line = next_line
117
117
 
118
- 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
119
119
 
120
120
  loop do
121
121
  next_line
@@ -138,7 +138,7 @@ module Hamlit
138
138
  end
139
139
 
140
140
  if !flat? && @next_line.tabs - @line.tabs > 1
141
- 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)
142
142
  end
143
143
 
144
144
  @line = @next_line
@@ -146,7 +146,7 @@ module Hamlit
146
146
  # Close all the open tags
147
147
  close until @parent.type == :root
148
148
  @root
149
- rescue ::Hamlit::HamlError => e
149
+ rescue Hamlit::HamlError => e
150
150
  e.backtrace.unshift "#{@options.filename}:#{(e.line ? e.line + 1 : @line.index + 1) + @options.line - 1}"
151
151
  raise
152
152
  end
@@ -158,7 +158,7 @@ module Hamlit
158
158
  @indentation = line.whitespace
159
159
 
160
160
  if @indentation.include?(?\s) && @indentation.include?(?\t)
161
- 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)
162
162
  end
163
163
 
164
164
  @flat_spaces = @indentation * (@template_tabs+1) if flat?
@@ -169,17 +169,17 @@ module Hamlit
169
169
  return tabs if line.whitespace == @indentation * tabs
170
170
  return @template_tabs + 1 if flat? && line.whitespace =~ /^#{@flat_spaces}/
171
171
 
172
- message = ::Hamlit::HamlError.message(:inconsistent_indentation,
172
+ message = HamlError.message(:inconsistent_indentation,
173
173
  human_indentation(line.whitespace),
174
174
  human_indentation(@indentation)
175
175
  )
176
- raise ::Hamlit::HamlSyntaxError.new(message, line.index)
176
+ raise HamlSyntaxError.new(message, line.index)
177
177
  end
178
178
 
179
179
  private
180
180
 
181
181
  # @private
182
- class Line < Struct.new(:whitespace, :text, :full, :index, :parser, :eod)
182
+ Line = Struct.new(:whitespace, :text, :full, :index, :parser, :eod) do
183
183
  alias_method :eod?, :eod
184
184
 
185
185
  # @private
@@ -195,14 +195,39 @@ module Hamlit
195
195
  end
196
196
 
197
197
  # @private
198
- class ParseNode < Struct.new(:type, :line, :value, :parent, :children)
198
+ ParseNode = Struct.new(:type, :line, :value, :parent, :children) do
199
199
  def initialize(*args)
200
200
  super
201
201
  self.children ||= []
202
202
  end
203
203
 
204
204
  def inspect
205
- %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
206
+ end
207
+ end
208
+
209
+ # @param [String] new - Hash literal including dynamic values.
210
+ # @param [String] old - Hash literal including dynamic values or Ruby literal of multiple Hashes which MUST be interpreted as method's last arguments.
211
+ DynamicAttributes = Struct.new(:new, :old) do
212
+ undef :old=
213
+ def old=(value)
214
+ unless value =~ /\A{.*}\z/m
215
+ raise ArgumentError.new('Old attributes must start with "{" and end with "}"')
216
+ end
217
+ self[:old] = value
218
+ end
219
+
220
+ # This will be a literal for Hamlit::HamlBuffer#attributes's last argument, `attributes_hashes`.
221
+ def to_literal
222
+ [new, stripped_old].compact.join(', ')
223
+ end
224
+
225
+ private
226
+
227
+ # For `%foo{ { foo: 1 }, bar: 2 }`, :old is "{ { foo: 1 }, bar: 2 }" and this method returns " { foo: 1 }, bar: 2 " for last argument.
228
+ def stripped_old
229
+ return nil if old.nil?
230
+ old.sub!(/\A{/, '').sub!(/}\z/m, '')
206
231
  end
207
232
  end
208
233
 
@@ -264,7 +289,7 @@ module Hamlit
264
289
  end
265
290
 
266
291
  def block_keyword(text)
267
- return unless keyword = text.scan(BLOCK_KEYWORD_REGEX)[0]
292
+ return unless (keyword = text.scan(BLOCK_KEYWORD_REGEX)[0])
268
293
  keyword[0] || keyword[1]
269
294
  end
270
295
 
@@ -275,20 +300,20 @@ module Hamlit
275
300
 
276
301
  def plain(line, escape_html = nil)
277
302
  if block_opened?
278
- 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)
279
304
  end
280
305
 
281
306
  unless contains_interpolation?(line.text)
282
307
  return ParseNode.new(:plain, line.index + 1, :text => line.text)
283
308
  end
284
309
 
285
- escape_html = @options.escape_html if escape_html.nil?
286
- 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)
287
312
  script(line, false).tap { |n| n.value[:escape_interpolation] = true if escape_html }
288
313
  end
289
314
 
290
315
  def script(line, escape_html = nil, preserve = false)
291
- 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?
292
317
  line = handle_ruby_multiline(line)
293
318
  escape_html = @options.escape_html if escape_html.nil?
294
319
 
@@ -300,12 +325,12 @@ module Hamlit
300
325
  end
301
326
 
302
327
  def flat_script(line, escape_html = nil)
303
- 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?
304
329
  script(line, escape_html, :preserve)
305
330
  end
306
331
 
307
332
  def silent_script(line)
308
- 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'
309
334
 
310
335
  line = handle_ruby_multiline(line)
311
336
  keyword = block_keyword(line.text)
@@ -314,7 +339,7 @@ module Hamlit
314
339
 
315
340
  if ["else", "elsif", "when"].include?(keyword)
316
341
  if @script_level_stack.empty?
317
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:missing_if, keyword), @line.index)
342
+ raise Hamlit::HamlSyntaxError.new(HamlError.message(:missing_if, keyword), @line.index)
318
343
  end
319
344
 
320
345
  if keyword == 'when' and !@script_level_stack.last[2]
@@ -325,8 +350,8 @@ module Hamlit
325
350
  end
326
351
 
327
352
  if @script_level_stack.last[1] != @line.tabs
328
- message = ::Hamlit::HamlError.message(:bad_script_indent, keyword, @script_level_stack.last[1], @line.tabs)
329
- 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)
330
355
  end
331
356
  end
332
357
 
@@ -363,7 +388,6 @@ module Hamlit
363
388
 
364
389
  preserve_tag = @options.preserve.include?(tag_name)
365
390
  nuke_inner_whitespace ||= preserve_tag
366
- preserve_tag = false if @options.ugly
367
391
  escape_html = (action == '&' || (action != '!' && @options.escape_html))
368
392
 
369
393
  case action
@@ -372,7 +396,7 @@ module Hamlit
372
396
  when '='
373
397
  parse = true
374
398
  if value[0] == ?=
375
- value = ::Hamlit::HamlUtil.unescape_interpolation(value[1..-1].strip)
399
+ value = unescape_interpolation(value[1..-1].strip)
376
400
  escape_interpolation = true if escape_html
377
401
  escape_html = false
378
402
  end
@@ -381,50 +405,47 @@ module Hamlit
381
405
  parse = true
382
406
  preserve_script = (value[0] == ?~)
383
407
  if value[1] == ?=
384
- value = ::Hamlit::HamlUtil.unescape_interpolation(value[2..-1].strip)
408
+ value = unescape_interpolation(value[2..-1].strip)
385
409
  escape_interpolation = true if escape_html
386
410
  escape_html = false
387
411
  else
388
412
  value = value[1..-1].strip
389
413
  end
390
414
  elsif contains_interpolation?(value)
391
- value = ::Hamlit::HamlUtil.unescape_interpolation(value)
415
+ value = unescape_interpolation(value)
392
416
  escape_interpolation = true if escape_html
393
417
  parse = true
394
418
  escape_html = false
395
419
  end
396
420
  else
397
421
  if contains_interpolation?(value)
398
- value = ::Hamlit::HamlUtil.unescape_interpolation(value)
399
- escape_interpolation = true if escape_html
422
+ value = unescape_interpolation(value, escape_html)
400
423
  parse = true
401
424
  escape_html = false
402
425
  end
403
426
  end
404
427
 
405
- attributes = ::Hamlit::HamlParser.parse_class_and_id(attributes)
406
- attributes_list = []
428
+ attributes = HamlParser.parse_class_and_id(attributes)
429
+ dynamic_attributes = DynamicAttributes.new
407
430
 
408
431
  if attributes_hashes[:new]
409
432
  static_attributes, attributes_hash = attributes_hashes[:new]
410
- ::Hamlit::HamlBuffer.merge_attrs(attributes, static_attributes) if static_attributes
411
- attributes_list << attributes_hash
433
+ HamlAttributeBuilder.merge_attributes!(attributes, static_attributes) if static_attributes
434
+ dynamic_attributes.new = attributes_hash
412
435
  end
413
436
 
414
437
  if attributes_hashes[:old]
415
438
  static_attributes = parse_static_hash(attributes_hashes[:old])
416
- ::Hamlit::HamlBuffer.merge_attrs(attributes, static_attributes) if static_attributes
417
- attributes_list << attributes_hashes[:old] unless static_attributes || @options.suppress_eval
439
+ HamlAttributeBuilder.merge_attributes!(attributes, static_attributes) if static_attributes
440
+ dynamic_attributes.old = attributes_hashes[:old] unless static_attributes || @options.suppress_eval
418
441
  end
419
442
 
420
- attributes_list.compact!
421
-
422
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_nesting_self_closing), @next_line.index) if block_opened? && self_closing
423
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:no_ruby_code, action), last_line - 1) if parse && value.empty?
424
- 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?
425
446
 
426
447
  if block_opened? && !value.empty? && !is_ruby_multiline?(value)
427
- 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)
428
449
  end
429
450
 
430
451
  self_closing ||= !!(!block_opened? && value.empty? && @options.autoclose.any? {|t| t === tag_name})
@@ -433,7 +454,7 @@ module Hamlit
433
454
  line = handle_ruby_multiline(line) if parse
434
455
 
435
456
  ParseNode.new(:tag, line.index + 1, :name => tag_name, :attributes => attributes,
436
- :attributes_hashes => attributes_list, :self_closing => self_closing,
457
+ :dynamic_attributes => dynamic_attributes, :self_closing => self_closing,
437
458
  :nuke_inner_whitespace => nuke_inner_whitespace,
438
459
  :nuke_outer_whitespace => nuke_outer_whitespace, :object_ref => object_ref,
439
460
  :escape_html => escape_html, :preserve_tag => preserve_tag,
@@ -462,13 +483,13 @@ module Hamlit
462
483
 
463
484
  if contains_interpolation?(text)
464
485
  parse = true
465
- text = slow_unescape_interpolation(text)
486
+ text = unescape_interpolation(text)
466
487
  else
467
488
  parse = false
468
489
  end
469
490
 
470
491
  if block_opened? && !text.empty?
471
- 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)
472
493
  end
473
494
 
474
495
  ParseNode.new(:comment, @line.index + 1, :conditional => conditional, :text => text, :revealed => revealed, :parse => parse)
@@ -476,13 +497,13 @@ module Hamlit
476
497
 
477
498
  # Renders an XHTML doctype or XML shebang.
478
499
  def doctype(text)
479
- 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?
480
501
  version, type, encoding = text[3..-1].strip.downcase.scan(DOCTYPE_REGEX)[0]
481
502
  ParseNode.new(:doctype, @line.index + 1, :version => version, :type => type, :encoding => encoding)
482
503
  end
483
504
 
484
505
  def filter(name)
485
- 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+$/
486
507
 
487
508
  if filter_opened?
488
509
  @flat = true
@@ -519,7 +540,7 @@ module Hamlit
519
540
 
520
541
  # Post-process case statements to normalize the nesting of "when" clauses
521
542
  return unless node.value[:keyword] == "case"
522
- return unless first = node.children.first
543
+ return unless (first = node.children.first)
523
544
  return unless first.type == :silent_script && first.value[:keyword] == "when"
524
545
  return if first.children.empty?
525
546
  # If the case node has a "when" child with children, it's the
@@ -531,7 +552,7 @@ module Hamlit
531
552
 
532
553
  alias :close_script :close_silent_script
533
554
 
534
- # 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}.
535
556
  #
536
557
  # Iterates through the classes and ids supplied through `.`
537
558
  # and `#` syntax, and returns a hash with them as attributes,
@@ -540,7 +561,7 @@ module Hamlit
540
561
  attributes = {}
541
562
  return attributes if list.empty?
542
563
 
543
- list.scan(/([#.])([-:_a-zA-Z0-9]+)/) do |type, property|
564
+ list.scan(/([#.])([-:_a-zA-Z0-9\@]+)/) do |type, property|
544
565
  case type
545
566
  when '.'
546
567
  if attributes[CLASS_KEY]
@@ -555,16 +576,22 @@ module Hamlit
555
576
  attributes
556
577
  end
557
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
558
584
  def parse_static_hash(text)
559
585
  attributes = {}
560
586
  return attributes if text.empty?
561
587
 
588
+ text = text[1...-1] # strip brackets
562
589
  scanner = StringScanner.new(text)
563
590
  scanner.scan(/\s+/)
564
591
  until scanner.eos?
565
- return unless key = scanner.scan(LITERAL_VALUE_REGEX)
592
+ return unless (key = scanner.scan(LITERAL_VALUE_REGEX))
566
593
  return unless scanner.scan(/\s*=>\s*/)
567
- return unless value = scanner.scan(LITERAL_VALUE_REGEX)
594
+ return unless (value = scanner.scan(LITERAL_VALUE_REGEX))
568
595
  return unless scanner.scan(/\s*(?:,|$)\s*/)
569
596
  attributes[eval(key).to_s] = eval(value).to_s
570
597
  end
@@ -573,13 +600,13 @@ module Hamlit
573
600
 
574
601
  # Parses a line into tag_name, attributes, attributes_hash, object_ref, action, value
575
602
  def parse_tag(text)
576
- match = text.scan(/%([-:\w]+)([-:\w.#]*)(.+)?/)[0]
577
- 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
578
605
 
579
606
  tag_name, attributes, rest = match
580
607
 
581
608
  if !attributes.empty? && (attributes =~ /[.#](\.|#|\z)/)
582
- raise ::Hamlit::HamlSyntaxError.new(::Hamlit::HamlError.message(:illegal_element))
609
+ raise HamlSyntaxError.new(HamlError.message(:illegal_element))
583
610
  end
584
611
 
585
612
  new_attributes_hash = old_attributes_hash = last_line = nil
@@ -624,14 +651,17 @@ module Hamlit
624
651
  nuke_inner_whitespace, action, value, last_line || @line.index + 1]
625
652
  end
626
653
 
654
+ # @return [String] attributes_hash - Hash literal starting with `{` and ending with `}`
655
+ # @return [String] rest
656
+ # @return [Integer] last_line
627
657
  def parse_old_attributes(text)
628
658
  text = text.dup
629
659
  last_line = @line.index + 1
630
660
 
631
661
  begin
632
662
  attributes_hash, rest = balance(text, ?{, ?})
633
- rescue ::Hamlit::HamlSyntaxError => e
634
- 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)
635
665
  text << "\n#{@next_line.text}"
636
666
  last_line += 1
637
667
  next_line
@@ -641,10 +671,12 @@ module Hamlit
641
671
  raise e
642
672
  end
643
673
 
644
- attributes_hash = attributes_hash[1...-1] if attributes_hash
645
674
  return attributes_hash, rest, last_line
646
675
  end
647
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
648
680
  def parse_new_attributes(text)
649
681
  scanner = StringScanner.new(text)
650
682
  last_line = @line.index + 1
@@ -656,9 +688,9 @@ module Hamlit
656
688
  break if name.nil?
657
689
 
658
690
  if name == false
659
- scanned = ::Hamlit::HamlUtil.balance(text, ?(, ?))
691
+ scanned = Hamlit::HamlUtil.balance(text, ?(, ?))
660
692
  text = scanned ? scanned.first : text
661
- 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)
662
694
  end
663
695
  attributes[name] = value
664
696
  scanner.scan(/\s*/)
@@ -672,7 +704,7 @@ module Hamlit
672
704
  end
673
705
 
674
706
  static_attributes = {}
675
- dynamic_attributes = "{"
707
+ dynamic_attributes = "{".dup
676
708
  attributes.each do |name, (type, val)|
677
709
  if type == :static
678
710
  static_attributes[name] = val
@@ -687,7 +719,7 @@ module Hamlit
687
719
  end
688
720
 
689
721
  def parse_new_attribute(scanner)
690
- unless name = scanner.scan(/[-:\w]+/)
722
+ unless (name = scanner.scan(/[-:\w]+/))
691
723
  return if scanner.scan(/\)/)
692
724
  return false
693
725
  end
@@ -696,8 +728,8 @@ module Hamlit
696
728
  return name, [:static, true] unless scanner.scan(/=/) #/end
697
729
 
698
730
  scanner.scan(/\s*/)
699
- unless quote = scanner.scan(/["']/)
700
- return false unless var = scanner.scan(/(@@?|\$)?\w+/)
731
+ unless (quote = scanner.scan(/["']/))
732
+ return false unless (var = scanner.scan(/(@@?|\$)?\w+/))
701
733
  return name, [:dynamic, var]
702
734
  end
703
735
 
@@ -712,7 +744,7 @@ module Hamlit
712
744
 
713
745
  return name, [:static, content.first[1]] if content.size == 1
714
746
  return name, [:dynamic,
715
- %!"#{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}}")}}"!]
716
748
  end
717
749
 
718
750
  def next_line
@@ -780,7 +812,7 @@ module Hamlit
780
812
  end
781
813
 
782
814
  def balance(*args)
783
- ::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)))
784
816
  end
785
817
 
786
818
  def block_opened?