hamlit 2.12.0-java → 2.13.0-java

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