StructuredStreams.Mesa
Mike Spreitzer July 30, 1986 9:26:25 pm PDT
DIRECTORY IO, Rope, TiogaAccess, UnparserBuffer;
Greg Nelson has implemented a package called UnparserBuffer for his use in formatting Juno programs. StructuredStreams is a streams interface to it. A StructuredStream is an output stream, layered on another stream (or TiogaAccess.Writer) which recieves the formatted characters. A StructuredStream takes in a stream of characters, delimited into nested objects, each of which has a beginning, an end, and some breakpoints. The StructuredStream delivers to its understream the characters, interspersed with various white space characters (carriage returns and spaces) according to the formatting rules (described in UnparserBuffer.Mesa). The rules are such that characters sent to a StructuredStream outside of any object delimiters will not get any white space inserted among them. Also, StructuredStreams has been defined so that an ordinary stream used in place of a StructuredStream gives no ill effects.
StructuredStreams: CEDAR DEFINITIONS = {
ROPE: TYPE = Rope.ROPE;
BreakCondition: TYPE = UnparserBuffer.BreakCondition;
Create:
PROC [onTopOf: UnparserBuffer.Handle]
RETURNS [ss:
IO.
STREAM];
If onTopOf.output is a stream, it will be ss's backingStream.
IsAnSS: PROC [s: IO.STREAM] RETURNS [BOOLEAN];
GetHandle:
PROC [ss:
IO.
STREAM]
RETURNS [UnparserBuffer.Handle];
Returns what the StructuredStream is layered on top of.
Returns NIL if ss is a non-structured stream.
Strip:
PROC [ss:
IO.
STREAM]
RETURNS [
IO.
STREAM];
If ss is a non-structured stream, returns ss, else
if ss's UnparserBuffer.Handle.output is a stream, returns that, else
returns NIL
CloseThrough:
PROC [self:
IO.
STREAM];
Closes both self and the stream (if any) it is on top of.
For non-structured streams, = IO.Close[self].
IO.Close on a StructuredStream does not close the understream (if any).
Although StructuredStreams have some buffering (between the earliest undecideable breakpoint and the current position), StructuredStreams pass on characters as soon as possible. Thus, IO.Flush on a StructuredStream is a no-op (except that it is called on the backingStream (if any)).
Structured streams implement the following formatted conversions:
%l [rope[dlooks]] as usual;
%p [refAny[charProps]] applies the given props to the following chars;
%n [refAny[nodeProps]] applies the props to nodes that end later;
%n [atom[format]] sets format of nodes that end later;
%n [boolean[comment]] sets comment property of nodes that end later.
The following proc's, peculiar to StructuredStreams, are almost no-ops on non-structured streams:
Begin,
End:
PROC [ss:
IO.
STREAM];
Setb and Enb of UnparserBuffer
Bp:
PROC [ss:
IO.
STREAM, cond: UnparserBuffer.BreakCondition, offset:
INTEGER, sep:
ROPE ←
NIL];
On a non-structured stream, this is just PutRope[sep].
Newlineb:
PROC [ss:
IO.
STREAM, offset:
INTEGER]
= INLINE {Bp[ss, always, offset, NIL]};
A carriage-return sent to a StructuredStream becomes a call on Newlineb in UnparserBuffer with offset = 0.
ChangeMargin:
PROC [ss:
IO.
STREAM, newMargin:
INTEGER ← 69];
Should only be called immediately after a carriage-return.
}.