class RGen::TemplateLanguage::TemplateContainer

Constants

LOCAL_TEMPLATE_REGEX
TemplateDesc

Public Class Methods

const_missing(name) click to toggle source
Calls superclass method
# File lib/rgen/template_language/template_container.rb, line 64
def self.const_missing(name)
  super unless @@metamodels
  @@metamodels.each do |mm|
    return mm.const_get(name) rescue NameError
  end
  super
end
new(metamodels, output_path, parent, filename) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 16
def initialize(metamodels, output_path, parent, filename)
  @templates = {}
  @parent = parent
  @filename = filename
  @indent = 0
  @output_path = output_path
          @metamodels = metamodels
          @metamodels = [ @metamodels ] unless @metamodels.is_a?(Array)
end

Public Instance Methods

evaluate(template, *all_args) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 50
def evaluate(template, *all_args)
  args, params = _splitArgsAndOptions(all_args)
  raise StandardError.new(":foreach can not be used with evaluate") if params[:foreach]
  _expand(template, args, params.merge({:_evalOnly => true}))
end
expand(template, *all_args) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 39
def expand(template, *all_args)
  args, params = _splitArgsAndOptions(all_args)
          if params.has_key?(:foreach)
          raise StandardError.new("expand :foreach argument is not enumerable") \
                  unless params[:foreach].is_a?(Enumerable)
    _expand_foreach(template, args, params)
  else
    _expand(template, args, params)
  end
end
load() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 26
def load
          File.open(@filename,"rb") do |f|
    begin
               @@metamodels = @metamodels
             fileContent = f.read
           _detectNewLinePattern(fileContent)
                  ERB.new(fileContent,nil,nil,'@output').result(binding)
    rescue Exception => e
      processAndRaise(e)
    end
          end
end
method_missing(name, *args) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 60
def method_missing(name, *args)
  @context.send(name, *args)
end
this() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 56
def this
  @context
end

Private Instance Methods

_call_template(tpl, context, args, localCall) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 183
def _call_template(tpl, context, args, localCall)
  found = false
  @templates[tpl].each_pair do |key, value| 
    if context.is_a?(key)
      templateDesc = @templates[tpl][key]
      proc = templateDesc.block
      arity = proc.arity
      arity = 0 if arity == -1    # if no args are given
      raise StandardError.new("Wrong number of arguments calling template #{tpl}: #{args.size} for #{arity} "+
        "(Beware: Hashes as last arguments are taken as options and are ignored)") \
        if arity != args.size
      raise StandardError.new("Template can only be called locally: #{tpl}") \
        if templateDesc.local && !localCall
      begin
          @@metamodels = @metamodels
        proc.call(*args) 
      rescue Exception => e
        processAndRaise(e, tpl)
      end
      found = true
    end
  end
  raise StandardError.new("Template class not matching: #{tpl} for #{context.class.name}") unless found
end
_define(template, params={}, &block) click to toggle source

private private

# File lib/rgen/template_language/template_container.rb, line 127
def _define(template, params={}, &block)
  @templates[template] ||= {}
  cls = params[:for] || Object
  @templates[template][cls] = TemplateDesc.new(block, params[:local])
end
_detectNewLinePattern(text) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 215
def _detectNewLinePattern(text)
  tests = 0
  rnOccurances = 0
  text.scan(/(\r?)\n/) do |groups|
    tests += 1
    rnOccurances += 1 if groups[0] == "\r"
    break if tests >= 10
  end
  if rnOccurances > (tests / 2)
    @newLinePattern = "\r\n"
  else
    @newLinePattern = "\n"
  end
end
_direct_concat(s) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 208
def _direct_concat(s)
  if @output.is_a? OutputHandler
    @output.direct_concat(s)
  else
    @output << s
  end
end
_expand(template, args, params) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 143
def _expand(template, args, params)
  raise StandardError.new("expand :for argument evaluates to nil") if params.has_key?(:for) && params[:for].nil?
  context = params[:for]
  old_indent = @indent
  @indent = params[:indent] || @indent
  noIndentNextLine = params[:_noIndentNextLine] || 
    (@output.is_a?(OutputHandler) && @output.noIndentNextLine) || 
    (@output.to_s.size > 0 && @output.to_s[-1] != "\n"[0]) 
  caller = params[:_caller] || self
  old_context, @context = @context, context if context
  local_output = nil
  if template =~ LOCAL_TEMPLATE_REGEX
    tplname = $1
    raise StandardError.new("Template not found: #{$1}") unless @templates[tplname]
    old_output, @output = @output, OutputHandler.new(@indent, @parent.indentString)
    @output.noIndentNextLine = noIndentNextLine
    _call_template(tplname, @context, args, caller == self)
    old_output.noIndentNextLine = false if old_output.is_a?(OutputHandler) && !old_output.noIndentNextLine
    local_output, @output = @output, old_output
  else
    local_output = @parent.expand(template, *(args.dup << {:for => @context, :indent => @indent, :_noIndentNextLine => noIndentNextLine, :_evalOnly => true, :_caller => caller}))
  end
  _direct_concat(local_output) unless params[:_evalOnly]
  @context = old_context if old_context
  @indent = old_indent
  local_output.to_s
end
_expand_foreach(template, args, params) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 133
def _expand_foreach(template, args, params)
  sep = params[:separator]
  params[:foreach].each_with_index {|e,i|
    _direct_concat(sep.to_s) if sep && i > 0 
    output = _expand(template, args, params.merge({:for => e}))
  }
end
define(template, params={}, &block) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 102
def define(template, params={}, &block)
  _define(template, params, &block)
end
define_local(template, params={}, &block) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 106
def define_local(template, params={}, &block)
  _define(template, params.merge({:local => true}), &block)
end
file(name, indentString=nil) { || ... } click to toggle source
# File lib/rgen/template_language/template_container.rb, line 110
def file(name, indentString=nil)
  old_output, @output = @output, OutputHandler.new(@indent, indentString || @parent.indentString)
  begin
    yield
  rescue Exception => e
    processAndRaise(e)
  end
  path = ""
  path += @output_path+"/" if @output_path
  dirname = File.dirname(path+name)
  FileUtils.makedirs(dirname) unless File.exist?(dirname)
          File.open(path+name,"wb") { |f| f.write(@output) }
  @output = old_output
end
idec() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 95
def idec
  @indent -= 1 if @indent > 0
  @output.indent = @indent
end
iinc() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 90
def iinc
  @indent += 1
  @output.indent = @indent
end
nl() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 82
def nl
          _direct_concat(@newLinePattern)
end
nonl() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 74
def nonl
  @output.ignoreNextNL
end
nows() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 78
def nows
  @output.ignoreNextWS
end
processAndRaise(e, tpl=nil) click to toggle source
# File lib/rgen/template_language/template_container.rb, line 171
def processAndRaise(e, tpl=nil)
  bt = e.backtrace.dup
  e.backtrace.each_with_index do |t,i|
    if t =~ /\(erb\):(\d+):/
      bt[i] = "#{@filename}:#{$1}"
      bt[i] += ":in '#{tpl}'" if tpl
      break
    end
  end
  raise e, e.to_s, bt
end
ws() click to toggle source
# File lib/rgen/template_language/template_container.rb, line 86
def ws
  _direct_concat(" ")
end