3 # (c) 2008 B. Crowell, GPL v 2
5 # This is designed to be more or less a drop-in replacement for eruby. It supports a subset
6 # of eruby, and has better error handling.
8 # fruby infile >outfile
10 # - Better error handling.
11 # - Parses and evaluates the input file on the fly, rather than
12 # translating it into a .rb file.
13 # - Supports <% %>, <%= %>, and <%# %>, but not % at beginning of line. This makes
14 # it compatible with TeX.
15 # - Doesn't support this kind of thing:
16 # <% 3.times do %> rah <% end %>
17 # <% if foo %> foo <% end %>
18 # Every block has to be a syntactically self-contained piece of ruby code.
19 # Variables assigned to in one piece of code *are* available in later pieces of code.
20 # This type of thing has to be accomplished by using a single block of ruby code,
21 # with print statements inside it.
23 # - Doesn't check if <% and %> are properly matched.
25 # Will happily run any code in the file.
28 $stderr.print
"fruby: " + message
+ "\n"
32 # The following dummy subroutine is the environment in which we evaluate the code.
33 # see pickaxe book, pp. 296, 419
34 # This accomplishes two things for us:
35 # - If we change a variable in one <% %> block, the change persists in later blocks.
36 # - Local variables in <% %> blocks are separate from local variables in this program.
37 def binding_for_eval()
41 if ARGV.empty
? then die("Usage: fruby infile >outfile") end
43 if ! File
.exist
?(infile
) then die("File #{infile} does not exist.") end
45 File
.open(infile
,'r') { |f
|
46 t
= f
.gets(nil) # nil means read whole file
49 b
= binding_for_eval()
50 inside
= false # even if there is a ruby expression at the very beginning of the string, split() gives us a null string as our first string
52 t
.split(/(?:\<\%|\%\>)/).each
{ |x
|
55 if x
=~
/\A=/ then what
='evaluate' end
56 if x
=~
/\A#/ then what
='comment' end
58 if what
!= 'comment' then
59 y
= eval(x
,b
,infile
,line
)
60 if what
== 'evaluate' then print y
end
65 x
.scan(/\n/) {line
+= 1}