JunoUnparserBuffer.mesa (was UnparserBuffer.mesa)
Coded December 7, 1982 3:57 pm by Greg Nelson
Last Edited by GNelson, December 6, 1983 2:03 am
Last Edited by Stolfi March 13, 1984 3:47:31 am PST
Formatted output routines. Send a stream of characters through a buffer, delineate the stream into subsequences called objects. The objects can be nested. (Objects are called "groups" in CGN9.) For each object, specify within it a set of breakpoints. The routines will format the text as follows. (1) An object will be printed all on one line if possible. (2) If an object cannot fit on one line, new lines will be started at one or more of the object's breakpoints, so that no text overflows the right margin. (3) With each breakpoint there is associated an integer call the breakpoint's offset. If a new line is started at a breakpoint, then the new line will be indented by the sum of the breakpoint's offset plus the indentation of the first character of the smallest object that contains the breakpoint. (4) Each breakpoint is either united or ununited. If any breakpoint of an object is broken, then all that object's united breakpoints are broken. An ununited breakpoint is broken only if it is necessary to do so to prevent overflowing the right margin.
DIRECTORY IO, Rope, Atom;
JunoUnparserBuffer: DEFINITIONS =
BEGIN
Handle: TYPE = REF HandleRec;
NewHandle: PROC RETURNS [Handle];
Init:
PUBLIC
PROC [h: Handle];
Destroys any information in the internal buffers and makes the buffers all empty.
Almost like allocating a new handle, but does not affect h.margin, h.output, h.width, or h.clientData, which are the feilds that a client may alter.
Setb: PUBLIC PROC [h: Handle]; -- begin an object
Endb: PUBLIC PROC [h: Handle]; -- end an object
Bp:
PUBLIC
PROC[h: Handle,
united:
BOOL,
offset:
INTEGER];
Inserts a breakpoint. If the breakpoint breaks, the next line will be indented by offset from the beginning of the object to which this breakpoint belongs.
Charb: PUBLIC PROC [h: Handle, ch: CHAR]; -- outputs the character
Ropeb: PUBLIC PROC[h: Handle, r: Rope.ROPE]; -- outputs the rope
Atomb: PUBLIC PROC[h: Handle, a: ATOM]; -- outputs the pname of the atom
Newlineb:
PUBLIC
PROC[h: Handle, offset:
INTEGER];
Just like a breakpoit except that it is certain to break, thus the effect is to insert a new line into the output.
HandleRec:
TYPE =
RECORD [
The following four fields may be set by the client if the default values arenot satisfactory. The output field must be set by the client. As all character widthscurrently must be expressed as multiples of the width of the space character, themain purpose of the width array is to set the widths of certain characters to zeroto pass them through the buffer as some kind of code for later processing.
margin:
PUBLIC
INTEGER ← 80,
width:
ARRAY
CHAR
OF
INTEGER ←
ALL [1],
output:
IO.
STREAM,
clientData:
REF ←
NIL,
Client, kindly ignore the remaining fields.
bufferWidth: INTEGER ← 0,
bl, cl, br, cr, sr, srx: INTEGER ← 0,
c: ARRAY [0 .. n) OF CHAR,
b: ARRAY [0 .. n) OF RECORD [
type: {setb, breakpoint},
united: BOOL,
offset: INTEGER,
p: [0 .. n)],
s: ARRAY [0 .. n) OF INTEGER,
indentation: INTEGER ← 0];
n: INT = 256; -- size of various internal buffers; plenty large for reasonable margins.
-- should be a parameter of the module but ....
END.