(* Read a text and produce a copy with flushed left and right margins.
  Place a fixed number of characters (say, length = 72) in each line,
  and distribute blanks as word separators accordingly. *)

MODULE chedit;

FROM InOut IMPORT Write, WriteLn, OpenInput, Done, Read;

CONST length = 72;

VAR ch: CHAR;
   i,m,k,lim: CARDINAL;
   line: ARRAY [1..136] OF CHAR;
   index: ARRAY [1..68] OF CARDINAL;

PROCEDURE setline;
VAR i,j,h,s,spaces,q,l,r: CARDINAL;

BEGIN
 IF m = 0 THEN m := 1; index[m] := lim END;
 j := 0; Write(' '); (* printer control *)
 IF m > 1 THEN
   spaces := lim - index[m];
   q := spaces DIV (m-1);
   r := spaces - (m-1)*q;
   l := (m-r) DIV 2;
   r := l + r;  (* distribute spaces *)
   i := 0;
   REPEAT
     INC(i);
     s := index[i];
     REPEAT
       INC(j);
       Write(line[j]);
     UNTIL j = s;
     FOR h := 1 TO q DO Write(' ') END;
     IF (l <= i) AND (i < r) THEN Write(' ') END;
   UNTIL i = m-1;
 END;
 s := index[m]-1;
 REPEAT INC(j); Write(line[j]) UNTIL j = s;
 j := 0; WriteLn;
 FOR h := index[m]+1 TO lim DO
   INC(j);
   line[j] := line[h];
 END;
 k := j; m := 0
END setline;

BEGIN
 OpenInput('TEXT');
 lim := length + 1;
 k := 0;            (* k = # OF characters IN line *)
 m := 0;            (* m = # OF complete words IN line *)
 LOOP
   Read(ch);
   IF NOT Done THEN EXIT END;
   IF ch # ' ' THEN
     REPEAT
       INC(k);
       line[k] := ch;
       Read(ch);
       IF k = lim THEN setline END
     UNTIL (ch = ' ') OR (NOT Done);
     INC(k); line[k] := ' ';
     INC(m); index[m] := k;
     IF k = lim THEN setline END
   END
 END;
 Write(' ');
 FOR i := 1 TO k DO Write(line[i]) END;
 WriteLn;
END chedit.