EXTERNAL KFORMAT::DOTEXT; {+++++++++++++++++++++++++++++++++++++++++++++++++++} {+ DOTEXT MODULE FOR KFORMAT Text Output Processor +} {+++++++++++++++++++++++++++++++++++++++++++++++++++} { compiler options for Pascal/Z compiler. } {$C-}{ control-c checking OFF } {$M-}{ integer mult & divd error checking OFF } {$F-}{ floating point error checking OFF } { process text } PROCEDURE DOTEXT(inbuf:BUFFER); VAR i :int; wordbuf :BUFFER; { delete leading blanks & set tival } PROCEDURE LEADBL(VAR lbbuf:BUFFER); VAR i :int; BEGIN DOBREAK; i := 1; WHILE ((lbbuf[i]=SPACE) and (i < LENGTH(lbbuf))) DO i := i + 1; IF (lbbuf[i] <> NEWLINE) THEN tival := tival + i - 1; IF ( i<>1 ) THEN DELETE(lbbuf,1,i-1); { *** 3-81 *** } END; { width of a printed line } FUNCTION WIDTH(VAR w:BUFFER):int; VAR i,wdth :int; BEGIN wdth := 0; FOR i := 1 TO LENGTH(w) DO IF (w[i]=BACKSPACE) THEN wdth := wdth - 1 ELSE IF (w[i] <> NEWLINE) THEN wdth := wdth + 1; WIDTH := wdth; END; { centers by setting temporary indent } PROCEDURE CENTER(VAR cebuf:BUFFER); var k: int; BEGIN k := ( rmval + tival - WIDTH(cebuf) ) DIV 2; tival := IMAX( k,0 ); END; { replace non-white space chars with bksp, "_" } PROCEDURE UNDERLINE(VAR inbuf:BUFFER); VAR u :int; ulstr :DSTRING; BEGIN ulstr := ' '; ulstr[1] := BACKSPACE; ulstr[2] := '_'; u := 1; WHILE (u <= LENGTH(inbuf)) DO begin IF ( (inbuf[u] <> SPACE) AND (inbuf[u] <> TAB) AND (inbuf[u] <> BACKSPACE) AND (inbuf[u] <> NEWLINE) ) THEN BEGIN INSERT(ulstr,inbuf,u+1); u := u + 3 END ELSE u := u + 1; end; END; { spread words to justify right margin } PROCEDURE SPREAD(VAR outbuf:BUFFER; outp, nextra, outwds:int); VAR nb, { number blanks } ne, { number extra } nholes, { number holes } i, j: int; BEGIN IF (nextra > 0) THEN BEGIN{nextra > 0} IF (outwds > 0) and ( spacefill ) THEN BEGIN direction := NOT direction; { tobble bias direction } ne := nextra; nholes := outwds - 1; i := LENGTH(outbuf) - 1; { point at final non-blank } WHILE ( ne > 0 ) DO BEGIN WHILE ( outbuf[i] <> SPACE ) DO i := i - 1; IF ( direction ) THEN nb := (ne-1) DIV nholes + 1 { rounded } ELSE nb := ne DIV nholes; { truncated } ne := ne - nb; nholes := nholes - 1; WHILE ( nb > 0 ) DO { insert extra blanks } BEGIN INSERT(' ',outbuf,i+1); nb := nb - 1; END; i := i - 1 END {while ne > 0} END END {IF nextra > 0} END; { put a word in outbuf including margin justification } PROCEDURE PUTWORD(VAR pwbuf:BUFFER); VAR w, last, llval, nextra: int; BEGIN w := WIDTH(pwbuf); { printable width of pwbuf } last := LENGTH(pwbuf) + outp + 1; { new end of outbuf } llval := rmval - tival; { printable line length } IF ((outp > 0) AND ( ((outw + w) > llval) OR (last > MAXBUF) ) ) THEN{ too big } BEGIN last := last - outp; { remember end of wrdbuf } nextra := llval - outw + 1; { # blanks needed to pad } IF ( spacefill ) THEN SPREAD(outbuf,outp,nextra,outwds); IF ((nextra > 0) AND (outwds > 1)) THEN outp := outp + nextra; DOBREAK { flush previous line } END; outp := last; { * outbuf := CONCAT(outbuf,pwbuf,space); * } append(outbuf,pwbuf); { add new word to outbuf } append(outbuf,space); { add a blank } outw := outw + w + 1; { update output width } outwds := outwds + 1; { increment the word count } END; { get a non-blank word from inbuf[] to wdbuf[] and advance g. Returns length of wdbuf. } FUNCTION GETWORD(VAR inbuf: BUFFER; VAR g: int; VAR wdbuf: BUFFER):int; VAR st: int; BEGIN WHILE (((inbuf[g]=SPACE) OR (inbuf[g]=TAB)) AND (g < LENGTH(inbuf))) DO g := g + 1; st := g; SKIPCHARS(inbuf,g); wdbuf := COPY(inbuf,st,g-st); GETWORD := LENGTH(wdbuf); END; BEGIN {dotext} IF ((inbuf[1]=SPACE) OR (inbuf[1]=NEWLINE)) THEN LEADBL(inbuf); { * move left, set tival * } IF ( ulval > 0 ) THEN { * underlining * } BEGIN UNDERLINE(inbuf); ulval := ulval - 1 END; IF ( ceval > 0 ) THEN { * centering in effect * } BEGIN CENTER(inbuf); PUTTEXT(inbuf); ceval := ceval - 1; END ELSE IF (inbuf[1]=NEWLINE) THEN { * all blank line * } PUTTEXT(inbuf) ELSE IF ( NOT fill ) THEN { * un-filled text passes * } PUTTEXT(inbuf) { * text "as is" * } ELSE { * filled text * } BEGIN i := 1; WHILE ( GETWORD(inbuf,i,wordbuf) > 0 ) DO PUTWORD(wordbuf); END; END; {dotext} {END EXTERNAL}. .