Class: Erubi::Engine

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

Direct Known Subclasses

CaptureEndEngine

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input, properties = {}) ⇒ Engine

Initialize a new Erubi::Engine. Options:

:bufval

The value to use for the buffer variable, as a string.

:bufvar

The variable name to use for the buffer variable, as a string.

:ensure

Wrap the template in a begin/ensure block restoring the previous value of bufvar.

:escapefunc

The function to use for escaping, as a string (default: ::Erubi.h).

:escape

Whether to make <%= escape by default, and <%== not escape by default.

:escape_html

Same as :escape, with lower priority.

:filename

The filename for the template.

:freeze

Whether to enable frozen string literals in the resulting source code.

:outvar

Same as bufvar, with lower priority.

:postamble

The postamble for the template, by default returns the resulting source code.

:preamble

The preamble for the template, by default initializes up the buffer variable.

:regexp

The regexp to use for scanning.

:src

The initial value to use for the source code

:trim

Whether to trim leading and trailing whitespace, true by default.


67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/erubi.rb', line 67

def initialize(input, properties={})
  @escape = escape = properties.fetch(:escape){properties.fetch(:escape_html, false)}
  trim       = properties[:trim] != false
  @filename  = properties[:filename]
  @bufvar = bufvar = properties[:bufvar] || properties[:outvar] || "_buf"
  bufval = properties[:bufval] || 'String.new'
  regexp = properties[:regexp] || /<%(={1,2}|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m
  preamble   = properties[:preamble] || "#{bufvar} = #{bufval};"
  postamble  = properties[:postamble] || "#{bufvar}.to_s\n"

  @src = src = properties[:src] || String.new
  src << "# frozen_string_literal: true\n" if properties[:freeze]
  src << "begin; __original_outvar = #{bufvar} if defined?(#{bufvar}); " if properties[:ensure]

  unless @escapefunc = properties[:escapefunc]
    if escape
      @escapefunc = '__erubi.h'
      src << "__erubi = ::Erubi;"
    else
      @escapefunc = '::Erubi.h'
    end
  end

  src << preamble

  pos = 0
  is_bol = true
  input.scan(regexp) do |indicator, code, tailch, rspace|
    match = Regexp.last_match
    len  = match.begin(0) - pos
    text = input[pos, len]
    pos  = match.end(0)
    ch   = indicator ? indicator[RANGE_FIRST] : nil

    lspace = nil

    unless ch == '='
      if text.empty?
        lspace = "" if is_bol
      elsif text[RANGE_LAST] == "\n"
        lspace = ""
      else
        rindex = text.rindex("\n")
        if rindex
          range = rindex+1..-1
          s = text[range]
          if s =~ /\A[ \t]*\z/
            lspace = s
            text[range] = ''
          end
        else
          if is_bol && text =~ /\A[ \t]*\z/
            lspace = text.dup
            text[RANGE_ALL] = ''
          end
        end
      end
    end

    is_bol = rspace ? true : false
    add_text(text) if text && !text.empty?
    case ch
    when '='
      rspace = nil if tailch && !tailch.empty?
      add_text(lspace) if lspace
      add_expression(indicator, code)
      add_text(rspace) if rspace
    when '#'
      n = code.count("\n") + (rspace ? 1 : 0)
      if trim
        add_code("\n" * n)
      else
        add_text(lspace) if lspace
        add_code("\n" * n)
        add_text(rspace) if rspace
      end
    when '%'
      add_text("#{lspace}#{prefix||='<%'}#{code}#{tailch}#{postfix||='%>'}#{rspace}")
    when nil, '-'
      if trim && lspace && rspace
        add_code("#{lspace}#{code}#{rspace}")
      else
        add_text(lspace) if lspace
        add_code(code)
        add_text(rspace) if rspace
      end
    else
      handle(indicator, code, tailch, rspace, lspace)
    end
  end
  rest = pos == 0 ? input : input[pos..-1]
  add_text(rest)

  src << "\n" unless src[RANGE_LAST] == "\n"
  add_postamble(postamble)
  src << "; ensure\n  #{bufvar} = __original_outvar\nend\n" if properties[:ensure]
  src.freeze
  freeze
end

Instance Attribute Details

#bufvarObject (readonly)

The variable name used for the buffer variable.


50
51
52
# File 'lib/erubi.rb', line 50

def bufvar
  @bufvar
end

#filenameObject (readonly)

The filename of the template, if one was given.


47
48
49
# File 'lib/erubi.rb', line 47

def filename
  @filename
end

#srcObject (readonly)

The frozen ruby source code generated from the template, which can be evaled.


44
45
46
# File 'lib/erubi.rb', line 44

def src
  @src
end