class Erubi::Engine
Attributes
The variable name used for the buffer variable.
The filename of the template, if one was given.
The frozen ruby source code generated from the template, which can be evaled.
Public Class Methods
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 (default ‘::String.new’)
- :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.
# File lib/erubi.rb 67 def initialize(input, properties={}) 68 @escape = escape = properties.fetch(:escape){properties.fetch(:escape_html, false)} 69 trim = properties[:trim] != false 70 @filename = properties[:filename] 71 @bufvar = bufvar = properties[:bufvar] || properties[:outvar] || "_buf" 72 bufval = properties[:bufval] || '::String.new' 73 regexp = properties[:regexp] || /<%(={1,2}|-|\#|%)?(.*?)([-=])?%>([ \t]*\r?\n)?/m 74 preamble = properties[:preamble] || "#{bufvar} = #{bufval};" 75 postamble = properties[:postamble] || "#{bufvar}.to_s\n" 76 77 @src = src = properties[:src] || String.new 78 src << "# frozen_string_literal: true\n" if properties[:freeze] 79 src << "begin; __original_outvar = #{bufvar} if defined?(#{bufvar}); " if properties[:ensure] 80 81 unless @escapefunc = properties[:escapefunc] 82 if escape 83 @escapefunc = '__erubi.h' 84 src << "__erubi = ::Erubi;" 85 else 86 @escapefunc = '::Erubi.h' 87 end 88 end 89 90 src << preamble 91 92 pos = 0 93 is_bol = true 94 input.scan(regexp) do |indicator, code, tailch, rspace| 95 match = Regexp.last_match 96 len = match.begin(0) - pos 97 text = input[pos, len] 98 pos = match.end(0) 99 ch = indicator ? indicator[RANGE_FIRST] : nil 100 101 lspace = nil 102 103 unless ch == '=' 104 if text.empty? 105 lspace = "" if is_bol 106 elsif text[RANGE_LAST] == "\n" 107 lspace = "" 108 else 109 rindex = text.rindex("\n") 110 if rindex 111 range = rindex+1..-1 112 s = text[range] 113 if s =~ /\A[ \t]*\z/ 114 lspace = s 115 text[range] = '' 116 end 117 else 118 if is_bol && text =~ /\A[ \t]*\z/ 119 lspace = text.dup 120 text[RANGE_ALL] = '' 121 end 122 end 123 end 124 end 125 126 is_bol = rspace 127 add_text(text) if text && !text.empty? 128 case ch 129 when '=' 130 rspace = nil if tailch && !tailch.empty? 131 add_text(lspace) if lspace 132 add_expression(indicator, code) 133 add_text(rspace) if rspace 134 when '#' 135 n = code.count("\n") + (rspace ? 1 : 0) 136 if trim && lspace && rspace 137 add_code("\n" * n) 138 else 139 add_text(lspace) if lspace 140 add_code("\n" * n) 141 add_text(rspace) if rspace 142 end 143 when '%' 144 add_text("#{lspace}#{prefix||='<%'}#{code}#{tailch}#{postfix||='%>'}#{rspace}") 145 when nil, '-' 146 if trim && lspace && rspace 147 add_code("#{lspace}#{code}#{rspace}") 148 else 149 add_text(lspace) if lspace 150 add_code(code) 151 add_text(rspace) if rspace 152 end 153 else 154 handle(indicator, code, tailch, rspace, lspace) 155 end 156 end 157 rest = pos == 0 ? input : input[pos..-1] 158 add_text(rest) 159 160 src << "\n" unless src[RANGE_LAST] == "\n" 161 add_postamble(postamble) 162 src << "; ensure\n #{bufvar} = __original_outvar\nend\n" if properties[:ensure] 163 src.freeze 164 freeze 165 end
Private Instance Methods
Add ruby code to the template
# File lib/erubi.rb 175 def add_code(code) 176 @src << code 177 @src << ';' unless code[RANGE_LAST] == "\n" 178 end
Add the given ruby expression result to the template, escaping it based on the indicator given and escape flag.
# File lib/erubi.rb 182 def add_expression(indicator, code) 183 if ((indicator == '=') ^ @escape) 184 add_expression_result(code) 185 else 186 add_expression_result_escaped(code) 187 end 188 end
Add the result of Ruby expression to the template
# File lib/erubi.rb 191 def add_expression_result(code) 192 @src << " #{@bufvar} << (" << code << ').to_s;' 193 end
Add the escaped result of Ruby expression to the template
# File lib/erubi.rb 196 def add_expression_result_escaped(code) 197 @src << " #{@bufvar} << #{@escapefunc}((" << code << '));' 198 end
Add the given postamble to the src. Can be overridden in subclasses to make additional changes to src that depend on the current state.
# File lib/erubi.rb 202 def add_postamble(postamble) 203 src << postamble 204 end
Add raw text to the template
# File lib/erubi.rb 170 def add_text(text) 171 @src << " #{@bufvar} << '" << text.gsub(/['\\]/, '\\\\\&') << TEXT_END unless text.empty? 172 end
Raise an exception, as the base engine class does not support handling other indicators.
# File lib/erubi.rb 207 def handle(indicator, code, tailch, rspace, lspace) 208 raise ArgumentError, "Invalid indicator: #{indicator}" 209 end