class ERB::Compiler

:nodoc:
Good! See also ERB#def_method, ERB#def_module, and ERB#def_class.
klass.new(‘It’).get_it
}
end
#{code}
def get_it
end
@obj = obj
def initialize(obj)
attr_accessor :obj
klass.class_eval %{
klass = Class.new Object
Evaluate using an accessor:
get(‘It’)
extend mod
}
end
#{code}
def get(obj)
mod.module_eval %{
mod = Module.new
Evaluate using an input:
eval code
obj = ‘It’
Evaluate using a variable:
correctly resolve. Using the last example, each of these print ‘Got It!’
The compiled code can be used in any context where the names in the code
== Evaluation
print “Got ”.freeze; print(( obj ).to_s); print “!n”.freeze
#coding:UTF-8
Generates:
puts code
code, enc = compiler.compile(“Got <%= obj %>!n”)
compiler = ERB::Compiler.new(‘<>’)
By default the output is sent to the print method. For example:
_erbout=+”; _erbout.<< “Got ”.freeze; _erbout.<<(( obj ).to_s); _erbout.<< “!n”.freeze; _erbout
#coding:UTF-8
Generates:
puts code
code, enc = compiler.compile(“Got <%= obj %>!n”)
compiler.post_cmd = [“_erbout”]
compiler.insert_cmd = “_erbout.<<”
compiler.put_cmd = “_erbout.<<”
compiler.pre_cmd = [“_erbout=+””]
compiler = ERB::Compiler.new(‘<>’)
ERB#src:
Internally ERB does something like this to generate the code returned by
generated output is handled.
template result when evaluated. ERB::Compiler provides hooks to define how
Compiles ERB templates into Ruby code; the compiled code produces the
ERB::Compiler

frozen_string_literal: true

def add_insert_cmd(out, content)

def add_insert_cmd(out, content)
  out.push("#{@insert_cmd}((#{content}).to_s)")
end

def add_put_cmd(out, content)

def add_put_cmd(out, content)
  out.push("#{@put_cmd} #{content.dump}.freeze#{"\n" * content.count("\n")}")
end

def compile(s)

and encoding like ["code", Encoding].
Compiles an ERB template into Ruby code. Returns an array of the code
def compile(s)
  enc = s.encoding
  raise ArgumentError, "#{enc} is not ASCII compatible" if enc.dummy?
  s = s.b # see String#b
  magic_comment = detect_magic_comment(s, enc)
  out = Buffer.new(self, *magic_comment)
  self.content = +''
  scanner = make_scanner(s)
  scanner.scan do |token|
    next if token.nil?
    next if token == ''
    if scanner.stag.nil?
      compile_stag(token, out, scanner)
    else
      compile_etag(token, out, scanner)
    end
  end
  add_put_cmd(out, content) if content.size > 0
  out.close
  return out.script, *magic_comment
end

def compile_content(stag, out)

def compile_content(stag, out)
  case stag
  when '<%'
    if content[-1] == ?\n
      content.chop!
      out.push(content)
      out.cr
    else
      out.push(content)
    end
  when '<%='
    add_insert_cmd(out, content)
  when '<%#'
    out.push("\n" * content.count("\n")) # only adjust lineno
  end
end

def compile_etag(etag, out, scanner)

def compile_etag(etag, out, scanner)
  case etag
  when '%>'
    compile_content(scanner.stag, out)
    scanner.stag = nil
    self.content = +''
  when '%%>'
    content << '%>'
  else
    content << etag
  end
end

def compile_stag(stag, out, scanner)

def compile_stag(stag, out, scanner)
  case stag
  when PercentLine
    add_put_cmd(out, content) if content.size > 0
    self.content = +''
    out.push(stag.to_s)
    out.cr
  when :cr
    out.cr
  when '<%', '<%=', '<%#'
    scanner.stag = stag
    add_put_cmd(out, content) if content.size > 0
    self.content = +''
  when "\n"
    content << "\n"
    add_put_cmd(out, content)
    self.content = +''
  when '<%%'
    content << '<%'
  else
    content << stag
  end
end

def detect_magic_comment(s, enc = nil)

def detect_magic_comment(s, enc = nil)
  re = @percent ? /\G(?:<%#(.*)%>|%#(.*)\n)/ : /\G<%#(.*)%>/
  frozen = nil
  s.scan(re) do
    comment = $+
    comment = $1 if comment[/-\*-\s*([^\s].*?)\s*-\*-$/]
    case comment
    when %r"coding\s*[=:]\s*([[:alnum:]\-_]+)"
      enc = Encoding.find($1.sub(/-(?:mac|dos|unix)/i, ''))
    when %r"frozen[-_]string[-_]literal\s*:\s*([[:alnum:]]+)"
      frozen = $1
    end
  end
  return enc, frozen
end

def initialize(trim_mode)

trim modes.
Construct a new compiler using the trim_mode. See ERB::new for available
def initialize(trim_mode)
  @percent, @trim_mode = prepare_trim_mode(trim_mode)
  @put_cmd = 'print'
  @insert_cmd = @put_cmd
  @pre_cmd = []
  @post_cmd = []
end

def make_scanner(src) # :nodoc:

:nodoc:
def make_scanner(src) # :nodoc:
  Scanner.make_scanner(src, @trim_mode, @percent)
end

def prepare_trim_mode(mode) # :nodoc:

:nodoc:
def prepare_trim_mode(mode) # :nodoc:
  case mode
  when 1
    return [false, '>']
  when 2
    return [false, '<>']
  when 0, nil
    return [false, nil]
  when String
    unless mode.match?(/\A(%|-|>|<>){1,2}\z/)
      warn_invalid_trim_mode(mode, uplevel: 5)
    end
    perc = mode.include?('%')
    if mode.include?('-')
      return [perc, '-']
    elsif mode.include?('<>')
      return [perc, '<>']
    elsif mode.include?('>')
      return [perc, '>']
    else
      [perc, nil]
    end
  else
    warn_invalid_trim_mode(mode, uplevel: 5)
    return [false, nil]
  end
end

def warn_invalid_trim_mode(mode, uplevel:)

def warn_invalid_trim_mode(mode, uplevel:)
  warn "Invalid ERB trim mode: #{mode.inspect} (trim_mode: nil, 0, 1, 2, or String composed of '%' and/or '-', '>', '<>')", uplevel: uplevel + WARNING_UPLEVEL
end