[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
For Oliver Bandel [re @Filter] -- long post.
From: |
Graham Douglas |
Subject: |
For Oliver Bandel [re @Filter] -- long post. |
Date: |
Sun, 15 Jul 2001 16:31:27 +0100 |
The Trials and Tribulations of @Filter
==========================
Hi Oliver
Here's what I did to understand the way @Filter works.
It summarises my own efforts plus the invaluable help from
Uwe and a great Lua example (e-mailed privately)
from Peter Shook, to whom I am very grateful.
If there are errors of fact I'm sure Uwe will jump in to
correct me -- please do -- because I do not want to give
out misleading or incorrect information.
[I don't want to ignore Oliver's request either.]
I was utterly confused by @Filter but,
like you, did not want to ignore it (due to
lack of understanding) because it was just
too useful.
The basic idea:
---------------
I was experimenting with my favourite
scripting language, called Lua -- see www.lua.org
because I wanted to be able to create
EPS files with Lua scripts. This was basically
an experiment to explore @Filter.
NOTE
-------------------------------------------
To understand this example, you need to
know that Lua has a command called "dofile"
which runs a Lua script file -- i.e. Lua code.
So, to run foo.lua you execute dofile("foo.lua")
-------------------------------------------
To use Lua I wrote
def @Lua
right x
{
def @Filter {Lua @FilterIn > @FilterOut}
@IncludeGraphic { x }
}
so that Lua would run a script file and
generate an EPS for inclusion via @IncludeGraphic.
Here is an example of using @Lua
@Lua {
dofile("c:\\lua\\syscall.lua")
}
The Lua command
dofile("c:\\lua\\syscall.lua")
tells Lua to run a file called
syscall.lua
-- the name "syscall.lua" is not important, it
could be anything; the important
point is that the Lua code in
syscall.lua
creates an EPS graphic AND tells Lout the name
of the EPS file so that @IncludeGraphic can import it.
Stay with me, I'll put the pieces together below.
What actually happens is that Lout "converts" (expands?)
@FilterIn and @FilterOut to create *temporary* files.
So, in my definition of @Lua I have
Lua @FilterIn > @FilterOut
but what actually gets executed via the system
command is
Lua louti1 > lout1
The two files "louti1" and "lout1" are *temporary*
files created by Lout.
BE CAREFUL TO NOTE THE VERY
SUBTLE DIFFERENCE IN
THESE NAMES -- a lowercase i
louti1 corresponds to @FilterIn
lout1 corresponds @FilterOut
What Lout does is to write the
parameter of
@Lua {
dofile("c:\\lua\\syscall.lua")
}
-- i.e.
dofile("c:\\lua\\syscall.lua")
into the file louti1.
To better understand this, I need to add a bit
about the Lout C source.
=========================
Looking into Lout's C source
=========================
To understand what was going on I
searched the Lout C source for the
"system" command -- because that's
how Lout executes other programs,
via a call to the "shell" [which translates
to calling c:\windows\command.com
under Windows 98 -- via CreateProcess()]
I compiled a debug version of Lout
(under Visual C++) and set a breakpoint on
line 152 in z40.c which is the C code:
status = system( (char *) command);
Once the above breakpoint was
reached, and execution paused,
the string pointed to [by (char*)command]
was
Lua louti1 > lout1
At this point, Lua is about to be called
so I did a disk search for file "louti1".
I found it and it contained the following text:
dofile("c:\\lua\\syscall.lua")
============================
End of Looking into Lout's c source
============================
So, in summary, Lout takes the parameter of @Lua{...}
[dofile("c:\\lua\\syscall.lua") in the example here]
and WRITES it into a TEMPORARY file -- called louti1.
So, Lua is given the NAME of the file louti1 as
its first argument
Lua louti1 > lout1
which it runs and sees the code
dofile("c:\\lua\\syscall.lua")
which Lout has already written into louti1.
Now, here is the bit which I found most confusing.
HOW does Lout get to know the NAME of the file
to input via @IncludeGraphic. This caused me
no end of frustration...
=============================
Let's review things.
1. We defined @Lua to contain Lua @FilterIn > @FilterOut
2. We use this with the example
@Lua {
dofile("c:\\lua\\syscall.lua")
}
3. We've seen that Lout has written
dofile("c:\\lua\\syscall.lua")
into the temporary file lout1
which Lua is told to run via
Lua louti1 > lout1
==================================
OK, so what does the " > lout1" bit do?
In essence, it is telling Lua to run the file louti1
and redirect the output into a file called lout1.
And here comes the *key concept* which
finally enabled my "Eureka moment"
What I had to do (THANKS to Peter Shook)
was to tell Lua to output the NAME of the
EPS file it had just created. What? Well,
I had to instruct Lua to print the name of the EPS file
-- which is then redirected into lout1 by
> lout1
[remember: Lua louti1 > lout1]
OK, we have told Lua to execute the script
syscall.lua via
dofile("c:\\lua\\syscall.lua")
Suppose that the script syscall.lua has some
Lua source which creates a simple EPS graphic called
eureka.eps
Well, inside the file syscall.lua I have to tell Lua to output the
name of the file AS A LOUT *STRING*;
to do this I need the Lua instruction
print("\"eureka.eps\"")
Normally, this would be output on the screen
(And this is the ONLY thing that should be
output) but because we redirected the output via
> @FilterOut
which translates to
> lout1
we have told Lua (rather, the operating system)
to send the output to the file lout1
RATHER THAN stdout WHICH IS
USUALLY THE SCREEN.
We're nearly there...
So the file lout1 will contain the result of
the Lua command
print("\"eureka.eps\"")
Here is an important point. Whatever
utility you are using, the EPS file name
written to lout1 must be A LOUT STRING
-- enclosed in quotes "".
Remember that @IncludeGraphic
needs the file name as a string -- hence the quotes.
In the example here
\"
tells Lua to output a quote so our command
print("\"eureka.eps\"")
outputs
"eureka.eps"
INCLUDING THE QUOTES
which is the name of the EPS file
our Lua code (syscall.lua) has created.
To Quote the Expert's Guide:
"@FilterOut is the name of a file
of Lout text whose contents Lout
will read after the system command has
finished, as a replacement for what
was put into @FilterIn"
What I take this to mean, in the example
studied here, is that Lout then arranges
for @IncludeGraphic to import the file
name written into lout1 -- "eureka.eps".
Phew.
I hope I've got this right + hope it helps.
Regards
Graham Douglas
- For Oliver Bandel [re @Filter] -- long post.,
Graham Douglas <=