TSDumperImpl.mesa
Dumps boxes and glue, for debugging
Michael Plass, November 2, 1982 10:35 am
Last Edited by: Beach, May 24, 1983 9:11 am
DIRECTORY Ascii, IO, Rope, TSObject, TSGlue, TSTypes, TSDumper, JaMFnsDefs;
TSDumperImpl: CEDAR PROGRAM IMPORTS TSObject, IO, TSTypes, JaMFnsDefs EXPORTS TSDumper =
BEGIN OPEN TSTypes, TSGlue;
ROPE: TYPE = Rope.ROPE;
stream: IO.STREAMNIL;
Stream: PROC RETURNS [IO.STREAM] = {IF stream=NIL THEN [out:stream]←IO.CreateViewerStreams["Boxes.log"]; RETURN[stream]};
oneLine: NAT ← 0; -- non-zero puts stuff on one line
SameLine: PROC = {oneLine←oneLine+1};
Indent: PROC [i: NAT] = {IF oneLine=0 THEN THROUGH [0..i) DO Pc['.]; Pc[Ascii.TAB] ENDLOOP};
DumpList: PUBLIC PROC [list: TSObject.ItemList, indent: NAT ← 0] = {
oldOneLine: NAT ← oneLine;
lastThingWasCharBox: BOOLEANFALSE;
source: TSObject.ListReader;
FinishCharBox: PROC = {
IF lastThingWasCharBox THEN {Pc['"]; Pl[" Chars"]; lastThingWasCharBox ← FALSE}
};
DumpException: PROC[x: REF ANY] = {
FinishCharBox[];
Indent[indent];
SELECT TRUE FROM
ISTYPE[x, TSObject.Glue] => {
glue: TSObject.Glue ← NARROW[x];
Pd[glue.space]; Pr["plus"]; Pd[glue.stretch]; Pr["minus"]; Pd[glue.shrink]; Pl["glue"];
};
ISTYPE[x, TSObject.Box] => TRUSTED {
box: TSObject.Box ← NARROW[x];
Pd[box.extent[left]]; Pr["+"];
Pd[box.extent[right]]; Pr["wide"];
Pd[box.extent[up]]; Pr["high"];
Pd[box.extent[down]]; Pr["deep"];
WITH b: box SELECT FROM
char => {
Pc['"]; Pc[source.CurrentChar[]]; Pc['"]; Pl[" CharBox"];
};
list => {
IF b.direction = down THEN Pr["vbox"] ELSE Pr["hbox"];
Stream[].Put[IO.real[b.glueset.value]];
Pl[" glueset"];
DumpList[b.items, indent+1];
Indent[indent+1];
Pl["endbox"];
};
rule => Pl["rule"];
ENDCASE => Pl["box"];
};
ISTYPE[x, TSObject.Kerf] => {
k: TSObject.Kerf ← NARROW[x];
p: LIST OF REF ANY ← k.prebreak;
SameLine[];
WHILE p # NIL DO
DumpException[p.first];
p ← p.rest;
ENDLOOP;
Pl["pre"];
p ← k.join;
WHILE p # NIL DO
DumpException[p.first];
p ← p.rest;
ENDLOOP;
Pl["join"];
p ← k.postbreak;
WHILE p # NIL DO
DumpException[p.first];
p ← p.rest;
ENDLOOP;
Pl["post"];
oneLine ← oldOneLine;
Stream[].Put[IO.real[k.penalty]];
Pl[" penalty"];
};
ISTYPE[x, TSObject.Kern] => {
Pd[NARROW[x, TSObject.Kern]^];
Pl["kern"];
};
ENDCASE => {Pl["Unknown list entry"]};
};
source ← list.CreateReader[];
UNTIL source.End[] DO
SELECT source.CurrentTag[] FROM
char => {
IF NOT lastThingWasCharBox THEN {Indent[indent]; Pc['"]};
Pc[source.CurrentChar[]]; lastThingWasCharBox ← TRUE
};
space => {
IF NOT lastThingWasCharBox THEN {Indent[indent]; Pc['"]};
Pc['\\];Pc[' ]; lastThingWasCharBox ← TRUE
};
hyphen => {
IF NOT lastThingWasCharBox THEN {Indent[indent]; Pc['"]};
Pc['\\];Pc['-]; lastThingWasCharBox ← TRUE
};
exception => DumpException[source.CurrentItem[]];
ENDCASE => ERROR;
source.Next[];
ENDLOOP;
FinishCharBox[];
oneLine ← oldOneLine;
IF indent = 0 THEN Pl[""];
};
Pc: PROC[c: CHAR] = {IO.PutChar[Stream[],c]};
Pr: PROC[r: ROPE] = {IO.PutRope[Stream[],r]; Pc[' ]};
Pl: PROC[r: ROPE] = TRUSTED {IO.PutRope[Stream[],r]; IF JaMFnsDefs.GetJaMBreak[] THEN ERROR ABORTED; IF oneLine=0 THEN IO.PutRope[Stream[],"
"] ELSE Pc[' ]};
Pd: PROC[d: Dimn] = {OPEN IO; Put[Stream[],real[DimnRatio[d,pt]], rope[" pt "]]};
DumpReset: PUBLIC PROC [] = {stream ← NIL};
DumpText: PUBLIC PROC [t: REF READONLY TEXT] = {
{OPEN IO; Put[Stream[],text[t],char[CR]]};
};
END.