@Section
   @Title { Reading and selecting program text from separate files }
   @Tag { pipes }
@Begin
@PP
We have said that program text within @Code "@CP { ... }" and the other
programs. @RawIndex { programs }
programs.include @SubIndex { @Code "@Include" within }
include.programs @Index { @Code "@Include" within programs }
symbols is passed directly to @Code prg2lout for analysis.  However,
there is an exception.  The program text may contain an
@Code "@Include" or @Code "@SysInclude" command, which, as for the
@Code "@Verbatim" symbol (Section {@NumberOf verbatim}), causes Lout
to take the program text from a file:
@ID @OneRow @Code {
"@Eiffel"
"{"
"    @Include { \"/usr/staff/jeff/Eiffel/hash.e\" }"
"}"
}
The included file is not examined for balanced braces or @Code "@End" or
{@Code "@Include"}; it is treated entirely verbatim and passed straight
on to {@Code prg2lout}.  There may be several @Code "@Include" commands,
and any amount of program text as well, within @Code "@CP { ... }" and
the rest.
@PP
When including files in this way it often happens that only part of an
actual program file is wanted for display.  Rather than placing the
wanted part in a separate file, which is error-prone and tedious when
the program is changing, Unix users can use the @Code "pipe" option
programs. @RawIndex { programs }
programs.pipe @SubIndex { @Code "pipe" option }
pipe.programs @Index { @Code "pipe" option (programs) }
to pipe the entire file through an arbitrary sequence of Unix commands,
which may be used to make the wanted selection before the program text
is passed to {@Code prg2lout}.
@PP
For example, suppose that all your Eiffel routines begin with the
routine name one tab stop from the left margin and end at the first
following @Eiffel { end } indented two tab stops.  Then
@ID @OneRow @Code {
"@Eiffel"
"    pipe { \"sed -n /^.insert/,/^..end/p\" }"
"{"
"    @Include { \"/usr/staff/jeff/Eiffel/hash.e\" }"
"}"
}
will select just the @Eiffel { insert } routine from the @Code { hash.e }
file.  Assuming that your program text has been laid out in a
disciplined manner, every line of the selection will begin with a
tab character that is not wanted in this display, so an even better
pipe is
@ID @OneRow @Code {
"@Eiffel"
"    pipe { \"sed -n /^.insert/,/^..end/p | cut -c2-\" }"
"{"
"    @Include { \"/usr/staff/jeff/Eiffel/hash.e\" }"
"}"
}
since it cuts away the unwanted tab characters.  Unfortunately, we
can't show the result of this on an actual example, since that would
prevent this manual from being formatted on a non-Unix system.
@PP
When using @Code "pipe" it is also possible to omit {@Code "@Include"}
and use the pipe to get the file as well as select from it:
@ID @OneRow @Code {
"@Eiffel pipe { \"cat /usr/staff/jeff/Eiffel/hash.e | sed -n /^.insert/,/^..end/p | cut -c2-\" } {}"
}
This pipes nothing into the {@Code cat} command, which does no harm.
@End @Section
