From: ptkwt@...1.aracnet.com (Phil Tomson) Date: 2001-10-30T09:51:10+09:00 Subject: [ruby-talk:23788] Re: Simple templating system (fixed - I hope:) In article , Phil Tomson wrote: > >I'll fix these bugs and repost... maybe I'll put it on the RAA or >cookbook. Here's the updated code with some bug fixes: class String def interpolate(bind) eval (self.inspect,bind) end end class TemplateFile def initialize(file,bind) @file = file @bind = bind @stateArray = Array.new @stateArray << true #default read state end def interpolate(b = @bind) fileString = "" File.foreach(@file) {|line| case line.strip when /^#>IF/ #check condition expression = line.gsub(/#>IF/,"").strip condition = expression.interpolate(b) if condition.type == String condition = eval condition end unless(condition.type == TrueClass || condition.type == FalseClass) raise TypeError, "#>IF #{expression} does not result in boolean, it is: #{condition.type}:file:#@file, line:#$.!",caller end @stateArray << condition puts "#{line} : #{@stateArray.to_s}" if $DEBUG puts "condition is: "+condition if $DEBUG when /^#>ELSE/ #invert condition @stateArray[-1] = !@stateArray[-1] puts "#{line} : #{@stateArray.to_s}" if $DEBUG when /^#>END/ @stateArray.pop puts "#{line} : #{@stateArray.to_s}" if $DEBUG when /^#>INCLUDE/ fields = line.split file = fields[1].strip puts "file to include is: #{file}" if $DEBUG fileString << include(fields[1].strip) if allTrue? else fileString << line if allTrue? end } fileString.interpolate(b) end private def include(file) tf = TemplateFile.new(file,@bind) tf.interpolate end def allTrue? bool = true @stateArray.each {|entry| bool = bool && entry } return bool end end #test it: if $0 == __FILE__ var = "string" i = 0 tf = TemplateFile.new("tests/vhdl",binding) 5.times do |i| puts "for i==#{i}:" puts tf.interpolate(binding) end end #End of template.rb Here's the file I used for testing, call it "vhdl" and put it in a subdir called 'tests', then you can run: ruby template.rb: --vhdl #>INCLUDE license.txt entity vector_#{i} is port( data_in:in STD_LOGIC_VECTOR(#{i} downto 0); data_out:out STD_LOGIC_VECTOR(#{i} downto 0); ); end architecture arch_vector_#{i} of vector_#{i} is begin signal vector(0 to #{i}) = "#{"X"*(i+1)}"; #>IF #{i<2} --this comment means that i is less than 2 #>IF #{true} --you shouldn't be printing this if i is >= 2 #>IF #{i>0} --You'll see this if i is greater than 0 and i < 2 #>ELSE --You'll see this only if i == 0 #>END #>END #>ELSE --this comment means that i is greater than or equal to 2 #>IF #{i==2} --this comment means that i is equal to 2 #>END #>IF #{i} #>END #>END end --end of vhdl file Oh, and here's the file included, license.txt: #license.txtB -------------------------------------- --this file is covered by the GPL --creation time: #{Time.now.to_s} --created by: #{$0} --author: pt -------------------------------------- Phil