Using Ruby as a preprocessor for another language

I have the misfortune of being stuck programming in a very bad
scripting language that has poor support for functions, variable
substitutions, loops, etc. etc. (It's a proprietary language called
Aegis scripting language, for scripting NPCs in a game.)

I've been using Ruby as a macro pre-processor so that I can write more
maintainable scripts without violating the DRY (Don't Repeat Yourself)
principle. Presently, I have the following functionality:

1. #{...} strings are evaluated by Ruby
2. lines starting with @ are evaluated by Ruby

Thanks to Ruby's power and simplicity, the ENTIRE pre-processor is
just these few lines:

while line = gets
        line.chomp!
        if line =~ /^\s*\@(.*)$/
                # Line starts with a @; it is Ruby code
                puts $1
        else
                # Line should be printed, with #{} substitution
available
                puts "puts \"#{line.gsub('"', '\"')}\""
        end
end

This allows me to "compile" a template like this:

        http://theanimaro.com/debbie/ruby/template.sc

into a script like this:

        http://theanimaro.com/debbie/ruby/test.sc

Now my question is, am I reinventing the wheel here in that
pre-processor code I wrote---is there already an existing module in
the RAA that does this? I didn't want to use ERuby because I find that
those <% %> <%= %> tags everywhere make the script unreadable (ERuby
is more for HTML IMO).

Are you aware that you can set ERuby (and ERb, the little brother library included standard with Ruby) to treat any line beginning with a simple % as code?

Example:

% npcs.each do |thug|
     The thug's name is: <%= thug.name %>
% end

Just wanted to point that out. It's covered in the documentation for the library, if you want to learn more.

James Edward Gray II

···

On Sep 9, 2005, at 7:11 PM, debbie@theanimaro.com wrote:

I didn't want to use ERuby because I find that
those <% %> <%= %> tags everywhere make the script unreadable (ERuby
is more for HTML IMO).

debbie@theanimaro.com wrote:

I've been using Ruby as a macro pre-processor so that I can write more
maintainable scripts without violating the DRY (Don't Repeat Yourself)
principle. Presently, I have the following functionality:

1. #{...} strings are evaluated by Ruby
2. lines starting with @ are evaluated by Ruby

Thanks to Ruby's power and simplicity, the ENTIRE pre-processor is
just these few lines:

while line = gets
        line.chomp!
        if line =~ /^\s*\@(.*)$/
                # Line starts with a @; it is Ruby code
                puts $1
        else
                # Line should be printed, with #{} substitution
available
                puts "puts \"#{line.gsub('"', '\"')}\""
        end
end

/^\s*\@(.*)$/

could be changed to

/^\s*@(.*)$/

Looks like your template's distilled your business logic pretty well,
but maybe you can locate a copy of Herrington's book on eRB for code
generation. i've seen it at Borders in the past (doesn't talk about
avoiding the '<%' '%>' and '<%' '=%>', except to say that you can use
'<%%' etc for ASP, JSP.) Actually, i find that if those tags aren't
set off by themselves and surrounded by blank lines, they're hard to
pick out of HTML templates.

http://www.manning.com/books/herrington

debbie@theanimaro.com wrote:

···

I have the misfortune of being stuck programming in a very bad
scripting language that has poor support for functions, variable
substitutions, loops, etc. etc. (It's a proprietary language called
Aegis scripting language, for scripting NPCs in a game.)

I've been using Ruby as a macro pre-processor so that I can write more
maintainable scripts without violating the DRY (Don't Repeat Yourself)
principle. Presently, I have the following functionality:

1. #{...} strings are evaluated by Ruby
2. lines starting with @ are evaluated by Ruby

Thanks to Ruby's power and simplicity, the ENTIRE pre-processor is
just these few lines:

while line = gets
        line.chomp!
        if line =~ /^\s*\@(.*)$/
                # Line starts with a @; it is Ruby code
                puts $1
        else
                # Line should be printed, with #{} substitution
available
                puts "puts \"#{line.gsub('"', '\"')}\""
        end
end

This allows me to "compile" a template like this:

        http://theanimaro.com/debbie/ruby/template.sc

into a script like this:

        http://theanimaro.com/debbie/ruby/test.sc

Now my question is, am I reinventing the wheel here in that
pre-processor code I wrote---is there already an existing module in
the RAA that does this? I didn't want to use ERuby because I find that
those <% %> <%= %> tags everywhere make the script unreadable (ERuby
is more for HTML IMO).

Are you aware that you can set ERuby (and ERb, the little brother library included standard with Ruby) to treat any line beginning with a simple % as code?

And further, than you don't have to use <%=...%> if you don't want:

Example:

% npcs.each do |thug|
    The thug's name is: <%= thug.name %>
% end

% nps.each do |thug|
% _erbout << "The thug's name is: #{thug.name}"
% end

···

On Sep 9, 2005, at 6:21 PM, James Edward Gray II wrote:

% npcs.each do |thug|
     The thug's name is: <%= thug.name %>
% end

It looks like the % only works if it's at the beginning of the line. It
won't work if there's tab characters before it. Is there a way to
change this?

Gavin Kistner wrote:
[erb]

% nps.each do |thug|
% _erbout << "The thug's name is: #{thug.name}"
% end

Furthermore, if erb is supposed to send its output to STDOUT, there's no
problem to simply use "puts" here.

Malte

debbie@theanimaro.com wrote:

% npcs.each do |thug|
     The thug's name is: <%= thug.name %>
% end

It looks like the % only works if it's at the beginning of the line.
It won't work if there's tab characters before it. Is there a way to
change this?

Preprocess the file. SCNR :slight_smile:

    robert

I don't believe so, no.

James Edward Gray II

···

On Sep 10, 2005, at 12:36 AM, debbie@theanimaro.com wrote:

% npcs.each do |thug|
     The thug's name is: <%= thug.name %>
% end

It looks like the % only works if it's at the beginning of the line. It
won't work if there's tab characters before it. Is there a way to
change this?

There is if you have any literal text in your ERB file. (And if you don't have ANY literal text, then there's not much point in using ERB, is there?) For example:

require 'erb'

template1 = <<'ENDTEMPLATE'
Hello
% puts "you crazy"
World
ENDTEMPLATE

ERB.new( template1, nil, '%' ).run
#=> you crazy
#=> Hello
#=> World

template2 = <<'ENDTEMPLATE'
Hello
% _erbout << "you crazy\n"
World
ENDTEMPLATE

ERB.new( template2, nil, '%' ).run
#=> Hello
#=> you crazy
#=> World

However, you can use my patch to ERB which makes puts behave as might be expected/desired in the above situation. See http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/152909 for more information.

···

On Sep 10, 2005, at 3:26 AM, Malte Milatz wrote:

Gavin Kistner wrote:
[erb]

% nps.each do |thug|
% _erbout << "The thug's name is: #{thug.name}"
% end

Furthermore, if erb is supposed to send its output to STDOUT, there's no
problem to simply use "puts" here.

Yes there is. A call to puts() would be resolved when it is interpreted, while the rest of the template output would come out once the whole thing has been generated. The output would be out of order. Avoid puts() in ERb, or use the patch floating around that makes it work as expected there.

James Edward Gray II

···

On Sep 10, 2005, at 4:26 AM, Malte Milatz wrote:

Gavin Kistner wrote:
[erb]

% nps.each do |thug|
% _erbout << "The thug's name is: #{thug.name}"
% end

Furthermore, if erb is supposed to send its output to STDOUT, there's no
problem to simply use "puts" here.