class Erubi::Engine
def initialize(input, properties={})
+:src+ :: The initial value to use for the source code, an empty string by default.
+:regexp+ :: The regexp to use for scanning.
+:preamble+ :: The preamble for the template, by default initializes the buffer variable.
+:postamble+ :: The postamble for the template, by default returns the resulting source code.
+:outvar+ :: Same as +:bufvar+, with lower priority.
+:literal_postfix+ :: The postfix to output when using escaped tag delimiters (default '%>').
+:literal_prefix+ :: The prefix to output when using escaped tag delimiters (default '<%').
in order to improve performance.
Can be set to +false+ on Ruby 2.3+ when frozen string literals are enabled
(default: +true+ on Ruby 2.1+, +false+ on Ruby 2.0 and older).
+:freeze_template_literals+ :: Whether to suffix all literal strings for template code with .freeze
the file, and having the magic comment later in the file can trigger warnings.
source code in other code, because the magic comment only has an effect at the beginning of
the resulting source code. Note this may cause problems if you are wrapping the resulting
+:freeze+ :: Whether to enable add a frozen_string_literal: true magic comment at the top of
+:filename+ :: The filename for the template.
+:escape_html+ :: Same as +:escape+, with lower priority.
+:escape+ :: Whether to make <%= escape by default, and <%== not escape by default.
+:escapefunc+ :: The function to use for escaping, as a string (default: '::Erubi.h').
+:ensure+ :: Wrap the template in a begin/ensure block restoring the previous value of bufvar.
template rendering (default +false+).
performance, but can cause issues when the buffer variable is reassigned during
+:chain_appends+ :: Whether to chain << calls to the buffer variable. Offers better
+:bufvar+ :: The variable name to use for the buffer variable, as a string.
+:bufval+ :: The value to use for the buffer variable, as a string (default '::String.new').
Initialize a new Erubi::Engine. Options:
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] || DEFAULT_REGEXP literal_prefix = properties[:literal_prefix] || '<%' literal_postfix = properties[:literal_postfix] || '%>' preamble = properties[:preamble] || "#{bufvar} = #{bufval};" postamble = properties[:postamble] || "#{bufvar}.to_s\n" @chain_appends = properties[:chain_appends] @text_end = if properties.fetch(:freeze_template_literals, FREEZE_TEMPLATE_LITERALS) "'.freeze" else "'" end @buffer_on_stack = false @src = src = properties[:src] || String.new src << "# frozen_string_literal: true\n" if properties[:freeze] if properties[:ensure] src << "begin; __original_outvar = #{bufvar}" if SKIP_DEFINED_FOR_INSTANCE_VARIABLE && /\A@[^@]/ =~ bufvar src << "; " else src << " if defined?(#{bufvar}); " end end 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 /\A[ \t]*\z/.send(MATCH_METHOD, s) lspace = s text[range] = '' end else if is_bol && /\A[ \t]*\z/.send(MATCH_METHOD, text) lspace = text text = '' end end end end is_bol = rspace add_text(text) case ch when '=' rspace = nil if tailch && !tailch.empty? add_expression(indicator, code) add_text(rspace) if 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 when '#' n = code.count("\n") + (rspace ? 1 : 0) if trim && lspace && rspace add_code("\n" * n) else add_text(lspace) if lspace add_code("\n" * n) add_text(rspace) if rspace end when '%' add_text("#{lspace}#{literal_prefix}#{code}#{tailch}#{literal_postfix}#{rspace}") 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