home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
ENTERPRS
/
CPM
/
UTILS
/
S
/
TUTOR.ARC
/
CHAPTER7.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-11-30
|
9KB
|
443 lines
{chapter7.pas}
{
copyright (c) 1981
by: bell telephone laboratories, inc. and
whitesmith's ltd.,
this software is derived from the book
"software tools in pascal", by
brian w. kernighan and p. j. plauger
addison-wesley, 1981
isbn 0-201-10342-7
right is hereby granted to freely distribute or duplicate this
software, providing distribution or duplication is not for profit
or other commercial gain and that this copyright notice remains
intact.
}
procedure format;
const
cmd=period;
pagenum=sharp;
pagewidth=60;
pagelen=66;
huge=10000;
type
cmdtype=(bp,br,ce,fi,fo,he,ind,ls,nf,pl,
rm,sp,ti,ul,unknown);
var
curpage,newpage,lineno:integer;
plval,m1val,m2val,m3val,m4val:integer;
bottom:integer;
header,footer:xstring;
fill:boolean;
lsval,spval,inval,rmval,tival,ceval,ulval:integer;
outp,outw,outwds:integer;
outbuf:xstring;
dir:0..1;
inbuf:xstring;
procedure skipbl(var s:xstring;var i:integer);
begin
while(s[i]=blank) or(s[i]=tab)do
i:=i+1
end;
function getval(var buf:xstring;var argtype:integer):integer;
var
i:integer;
begin
i:=1;
while(not(buf[i]in[blank,tab,newline]))do
i:=i+1;
skipbl(buf,i);
argtype:=buf[i];
if(argtype=plus) or (argtype=minus) then
i:=i+1;
getval:=ctoi(buf,i)
end;
procedure setparam(var param:integer;val,argtype,defval,minval,maxval:
integer);
begin
if(argtype=newline)then
param:=defval
else if (argtype=plus)then
param:=param+val
else if(argtype=minus) then
param:=param-val
else param:=val;
param:=min(param,maxval);
param:=max(param,minval)
end;
procedure skip(n:integer);
var i:integer;
begin
for i:=1 to n do
putc(newline)
end;
procedure puttl(var buf:xstring;pageno:integer);
var i:integer;
begin
for i:=1 to xlength(buf) do
if(buf[i]=pagenum) then
putdec(pageno,1)
else
putc(buf[i])
end;
procedure putfoot;
begin
skip(m3val);
if(m4val>0) then begin
puttl(footer,curpage);
skip(m4val-1)
end
end;
procedure puthead;
begin
curpage:=newpage;
newpage:=newpage+1;
if(m1val>0)then begin
skip(m1val-1);
puttl(header,curpage)
end;
skip(m2val);
lineno:=m1val+m2val+1
end;
procedure put(var buf:xstring);
var
i:integer;
begin
if(lineno<=0) or(lineno>bottom) then
puthead;
for i:=1 to inval+tival do
putc(blank);
tival:=0;
putstr(buf,stdout);
skip(min(lsval-1,bottom-lineno));
lineno:=lineno+lsval;
if(lineno>bottom)then putfoot
end;
procedure break;
begin
if(outp>0) then begin
outbuf[outp]:=newline;
outbuf[outp+1]:=endstr;
put(outbuf)
end;
outp:=0;
outw:=0;
outwds:=0
end;
function getword(var s:xstring;i:integer;
var out:xstring):integer;
var
j:integer;
begin
while(s[i] in [blank,tab,newline]) do
i:=i+1;
j:=1;
while(not (s[i] in [endstr,blank,tab,newline])) do begin
out[j]:=s[i];
i:=i+1;
j:=j+1
end;
out[j]:=endstr;
if(s[i]=endstr) then
getword:=0
else
getword:=i
end;
procedure leadbl(var buf:xstring);
var i,j:integer;
begin
break;
i:=1;
while(buf[i]=blank) do
i:=i+1;
if(buf[i]<>newline) then
tival:=tival+i-1;
for j:=i to xlength(buf)+1 do
buf[j-i+1]:=buf[j]
end;
procedure gettl(var buf,ttl:xstring);
var
i:integer;
begin
i:=1;
while(not(buf[i]in[blank,tab,newline]))do
i:=i+1;
skipbl(buf,i);
if(buf[i]=squote) or(buf[i]=dquote)then
i:=i+1;
scopy(buf,i,ttl,1)
end;
procedure space(n:integer);
begin
break;
if (lineno<=bottom) then begin
if(lineno<=0)then
puthead;
skip(min(n,bottom+1-lineno));
lineno:=lineno+n;
if(lineno>bottom) then
putfoot
end
end;
procedure page;
begin
break;
if(lineno>0) and (lineno<=bottom) then begin
skip(bottom+1-lineno);putfoot
end;
lineno:=0
end;
function width(var buf:xstring):integer;
var
i,w:integer;
begin
w:=0;
i:=1;
while(buf[i]<>endstr) do begin
if (buf[i] = backspace) then
w:=w-1
else if (buf[i]<>newline) then
w:=w+1;i:=i+1
end;
width:=w
end;
procedure spread(var buf:xstring;
outp,nextra,outwds:integer);
var
i,j,nb,nholes:integer;
begin
if(nextra>0) and (outwds>1) then begin
dir:=1-dir;
nholes:=outwds-1;
i:=outp-1;
j:=min(maxstr-2,i+nextra);
while(i<j) do begin
buf[j]:=buf[i];
if(buf[i]=blank) then begin
if(dir=0) then
nb:=(nextra-1) div nholes +1
else nb:=nextra div nholes;
nextra:=nextra - nb;
nholes:=nholes-1;
while(nb>0) do begin
j:=j-1;
buf[j]:=blank;
nb:=nb-1
end
end;
i:=i-1;
j:=j-1
end
end
end;
procedure putword(var wordbuf:xstring);
var
last,llval,nextra,w:integer;
begin
w:=width(wordbuf);
last:=xlength(wordbuf)+outp+1;
llval:=rmval-tival-inval;
if(outp>0)
and ((outw+w>llval) or (last >=maxstr)) then begin
last:=last-outp;
nextra:=llval-outw+1;
if(nextra >0) and(outwds>1) then begin
spread(outbuf,outp,nextra,outwds);
outp:=outp+nextra
end;
break
end;
scopy(wordbuf,1,outbuf,outp+1);
outp:=last;
outbuf[outp]:=blank;
outw:=outw+w+1;
outwds:=outwds+1
end;
procedure center(var buf:xstring);
begin
tival:=max((rmval+tival-width(buf)) div 2,0)
end;
procedure underln (var buf:xstring;size:integer);
var
i,j:integer;
tbuf:xstring;
begin
j:=1;
i:=1;
while(buf[i]<>newline) and (j<size-1)do begin
if(isalphanum(buf[i])) then begin
tbuf[j]:=underline;
tbuf[j+1]:=backspace;
j:=j+2
end;
tbuf[j]:=buf[i];
j:=j+1;
i:=i+1
end;
tbuf[j]:=newline;
tbuf[j+1]:=endstr;
scopy(tbuf,1,buf,1)
end;
procedure text(var inbuf:xstring);
var
wordbuf:xstring;
i:integer;
begin
if(inbuf[1]=blank) or (inbuf[1]=newline) then
leadbl(inbuf);
if(ulval>0) then begin
underln(inbuf,maxstr);
ulval:=ulval-1
end;
if(ceval>0)then begin
center(inbuf);
put(inbuf);
ceval:=ceval-1
end
else if (inbuf[1]=newline)then
put(inbuf)
else if(not fill) then
put(inbuf)
else begin
i:=1;
repeat
i:=getword(inbuf,i,wordbuf);
if(i>0)then
putword(wordbuf)
until(i=0)
end
end;
procedure initfmt;
begin
fill:=true;
dir:=0;
inval:=0;
rmval:=pagewidth;
tival:=0;
lsval:=1;
spval:=0;
ceval:=0;
ulval:=0;
lineno:=0;
curpage:=0;
newpage:=1;
plval:=pagelen;
m1val:=3;m2val:=2;m3val:=2;m4val:=3;
bottom:=plval-m3val-m4val;
header[1]:=newline;
header[2]:=endstr;
footer[1]:=newline;
footer[2]:=endstr;
outp:=0;
outw:=0;
outwds:=0
end;
function getcmd(var buf:xstring):cmdtype;
var
cmd:packed array[1..2] of char;
begin
cmd[1]:=chr(buf[2]);
cmd[2]:=chr(buf[3]);
if(cmd='fi')then getcmd:=fi
else if (cmd='nf')then getcmd:=nf
else if (cmd='br')then getcmd:=br
else if (cmd='ls')then getcmd:=ls
else if (cmd='bp')then getcmd:=bp
else if (cmd='sp')then getcmd:=sp
else if (cmd='in')then getcmd:=ind
else if (cmd='rm')then getcmd:=rm
else if (cmd='ce')then getcmd:=ce
else if (cmd='ti')then getcmd:=ti
else if (cmd='ul')then getcmd:=ul
else if (cmd='he') then getcmd:=he
else if (cmd='fo') then getcmd:=fo
else if (cmd='pl') then getcmd:=pl
else getcmd:=unknown
end;
procedure command(var buf:xstring);
var cmd:cmdtype;
argtype,spval,val:integer;
begin
cmd:=getcmd(buf);
if(cmd<>unknown)then
val:=getval(buf,argtype);
case cmd of
fi:begin
break;
fill:=true end;
nf:begin break;
fill:=false end;
br:break;
ls:setparam(lsval,val,argtype,1,1,huge);
ce:begin break;
setparam(ceval,val,argtype,1,0,huge) end;
ul:setparam(ulval,val,argtype,1,0,huge);
he:gettl(buf,header);
fo:gettl(buf,footer);
bp:begin page;
setparam(curpage,val,argtype,curpage+1,-huge,huge);
newpage:=curpage end;
sp:begin
setparam(spval,val,argtype,1,0,huge);
space(spval)
end;
ind:setparam(inval,val,argtype,0,0,rmval-1);
rm:setparam(inval,val,argtype,pagewidth,
inval+tival+1,huge);
ti:begin break;
setparam(tival,val,argtype,0,-huge,rmval) end;
pl:begin
setparam(plval,val,argtype,pagelen,
m1val+m2val+m3val+m4val+1,huge);
bottom:=plval-m3val-m4val end;
unknown:
end
end;
begin
initfmt;
while(getline(inbuf,stdin,maxstr))do
if(inbuf[1]=cmd) then
command(inbuf)
else
text(inbuf);
page
end;