Class: Erbse::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/erbse/parser.rb

Constant Summary collapse

ERB_EXPR =

ERB_EXPR = /(n)|<%(=|#)?(.*?)%>(n)*/m # this is the desired pattern.

/(\n)|<=|<%(=+|-|\#|@\s|%)?(.*?)[-=]?%>/m
BLOCK_EXPR =

BLOCK_EXPR = /s*((s+|))do|{)(s*|*|)?s*Z/

/\sdo\s*\z|\sdo\s+\|[^|]*\|\s*\z/
BLOCK_EXEC =
/\A\s*(if|unless)\b|#{BLOCK_EXPR}/

Instance Method Summary collapse

Constructor Details

#initializeParser

Parsing patterns

Blocks will be recognized when written: <% … do %> or <% … do |…| %>



14
15
# File 'lib/erbse/parser.rb', line 14

def initialize(*)
end

Instance Method Details

#call(str) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/erbse/parser.rb', line 17

def call(str)
  pos = 0
  buffers = []
  result = [:multi]
  buffers << result
  match = nil

  str.scan(ERB_EXPR) do |newline, indicator, code|
    match = Regexp.last_match
    len  = match.begin(0) - pos

    text = str[pos, len]
    pos  = match.end(0)
    ch   = indicator ? indicator[0] : nil

    if newline
      buffers.last << [:static, "#{text}\n"] << [:newline]
      next
    end

    if text and !text.empty? # text
      buffers.last << [:static, text]
    end

    if ch == ?= # <%= %>
      if code =~ BLOCK_EXPR
        buffers.last << [:erb, :block, code, block = [:multi]] # picked up by our own BlockFilter.
        buffers << block
      else
        buffers.last << [:dynamic, code]
      end
    elsif ch =~ /#/ # DISCUSS: doesn't catch <% # this %>
      newlines = code.count("\n")
      buffers.last.concat  [[:newline]] * newlines if newlines > 0
    elsif code =~ /\bend\b/ # <% end %>
      buffers.pop
    elsif ch == ?@
      buffers.last << [:capture, :block, code, block = [:multi]] # picked up by our own BlockFilter. # TODO: merge with %= ?
      buffers << block
    else # <% %>
      if code =~ BLOCK_EXEC
        buffers.last << [:block, code, block = [:multi]] # picked up by Temple's ControlFlow filter.
        buffers << block
      else
        buffers.last << [:code, code]
      end
    end
  end

  # add text after last/none ERB tag.
  buffers.last << [:static, str[pos..str.length]] if pos < str.length

  buffers.last
end