Sha256: 934897192fb8b9ac014986ecf7f58c33fccaaa2857cee0eee466ffa8e16cc99f

Contents?: true

Size: 1.93 KB

Versions: 8

Compression:

Stored size: 1.93 KB

Contents

# frozen_string_literal: true
module Slim
  # In Slim you don't need to close any blocks:
  #
  #   - if Slim.awesome?
  #     | But of course it is!
  #
  # However, the parser is not smart enough (and that's a good thing) to
  # automatically insert end's where they are needed. Luckily, this filter
  # does *exactly* that (and it does it well!)
  #
  # @api private
  class EndInserter < Filter
    IF_RE = /\A(if|begin|unless|else|elsif|when|in|rescue|ensure)\b|\bdo\s*(\|[^\|]*\|)?\s*$/
    ELSE_RE = /\A(else|elsif|when|in|rescue|ensure)\b/
    END_RE = /\Aend\b/

    # Handle multi expression `[:multi, *exps]`
    #
    # @return [Array] Corrected Temple expression with ends inserted
    def on_multi(*exps)
      result = [:multi]
      # This variable is true if the previous line was
      # (1) a control code and (2) contained indented content.
      prev_indent = false

      exps.each do |exp|
        if control?(exp)
          raise(Temple::FilterError, 'Explicit end statements are forbidden') if exp[2] =~ END_RE

          # Two control code in a row. If this one is *not*
          # an else block, we should close the previous one.
          append_end(result) if prev_indent && exp[2] !~ ELSE_RE

          # Indent if the control code starts a block.
          prev_indent = exp[2] =~ IF_RE
        elsif exp[0] != :newline && prev_indent
          # This is *not* a control code, so we should close the previous one.
          # Ignores newlines because they will be inserted after each line.
          append_end(result)
          prev_indent = false
        end

        result << compile(exp)
      end

      # The last line can be a control code too.
      prev_indent ? append_end(result) : result
    end

    private

    # Appends an end
    def append_end(result)
      result << [:code, 'end']
    end

    # Checks if an expression is a Slim control code
    def control?(exp)
      exp[0] == :slim && exp[1] == :control
    end
  end
end

Version data entries

8 entries across 8 versions & 2 rubygems

Version Path
brakeman-7.0.0 bundle/ruby/3.1.0/gems/slim-5.2.1/lib/slim/end_inserter.rb
brakeman-6.2.2 bundle/ruby/3.1.0/gems/slim-5.2.1/lib/slim/end_inserter.rb
brakeman-6.2.2.rc1 bundle/ruby/3.3.0/gems/slim-5.2.1/lib/slim/end_inserter.rb
brakeman-6.2.1 bundle/ruby/3.1.0/gems/slim-5.2.1/lib/slim/end_inserter.rb
brakeman-6.2.0 bundle/ruby/3.1.0/gems/slim-5.2.1/lib/slim/end_inserter.rb
slim-5.2.1 lib/slim/end_inserter.rb
slim-5.2.0 lib/slim/end_inserter.rb
slim-5.1.1 lib/slim/end_inserter.rb