program multcol; { converts a single column of text to multi-column output} {$iglobdefs.pas} {$istdutil.pas} {$istdio.pas} {$R+} const ncdefault = 2; { default number of columns } csdefault = 4; { default space between columns } cwdefault = 38; { default column width } lppdefault = 56; { default lines per page } ppdefault = 66; { default physical page size } PBSIZE = 8000; { size of page buffer (chars.) } MAXLINES = 80; { max. no. of lines/page } var gotfile,gotfile2 :boolean; name,prompt :textline; infile,outfile :filedesc; badinput :boolean; linesperpage, colwidth, colspace, physpage, numcols, linewidth :integer; procedure getparams(var numcols,colwidth,colspace,linesperpage,linewidth: integer; var badinput:boolean); { get parameters from console} var prompt :textline; maxbuf :integer; procedure getnum(var prompt:textline;var x:integer;xdefault:integer); {get a number from the console} var gotline :boolean; numstring :textline; i,junk :integer; begin putstr(prompt,TRMOUT); putc(LESS); write(xdefault); putc(GREATER); putc(SPACE); if getline(numstring,TRMIN,MAXSTR) then begin i:=1; if skipsp(numstring,i) in [NEWLINE,EOS] then x := xdefault else x := ctoi(numstring,i); end else x := xdefault; end; { getnum } begin { getparams } setstring(prompt,'Number of columns? '); getnum(prompt,numcols,ncdefault); setstring(prompt,'Column width? '); getnum(prompt,colwidth,cwdefault); setstring(prompt,'Space between columns? '); getnum(prompt,colspace,csdefault); setstring(prompt,'Lines per page? '); getnum(prompt,linesperpage,lppdefault); setstring(prompt,'Physical page size (lines)? '); getnum(prompt,physpage,ppdefault); linewidth := (numcols*colwidth) + (numcols-1)*colspace; maxbuf := linesperpage*(linewidth+1) + 5; badinput := false; if maxbuf>PBSIZE then begin writeln; writeln('Not enough memory to store an output page.'); writeln; badinput := true; end; if (linesperpage>MAXLINES) or (physpage>MAXLINES) then begin writeln; writeln('Too many lines specified -- ',MAXLINES,' maximum.'); writeln; badinput := true; end; end; { getparams } procedure convert(var infile,outfile:filedesc); type pagebuftype = array[1..PBSIZE] of character; cwarray = array[1..MAXLINES] of integer; var s :textline; pagebuf :pagebuftype; colswritten :cwarray; pagenum, line, column :integer; procedure initpage; { initialize page buffer } var i :integer; begin for i:=1 to PBSIZE do pagebuf[i] := SPACE; for i:=1 to MAXLINES do colswritten[i] := 0; end; procedure writeline(var s:textline;column,line:integer); { write a line into the proper place on the page} var i,j :integer; eol :boolean; begin i := 1; j := (linewidth+1)*(line-1) + 1 + (column-1)*(colwidth+colspace); eol := false; while (i<=colwidth) and (not eol) do begin eol := (s[i] = NEWLINE) or (s[i]=EOS); if not eol then begin pagebuf[j] := s[i]; i := i + 1; j := j + 1; end; end; colswritten[line] := colswritten[line] + 1; end; {writeline} procedure writepage(var colswritten: cwarray); { write contents of page buffer to file } var i,j,k:integer; c :character; begin pagenum := pagenum + 1; for i:=1 to linesperpage do begin j := (i-1)*(linewidth+1) + 1 + (colswritten[i]*colwidth); if colswritten[i]>0 then j:=j+(colswritten[i]-1)*colspace; pagebuf[j] := NEWLINE; end; for i:=1 to linesperpage do begin j := (i-1)*(linewidth+1)+1; k := 0; repeat c := pagebuf[j]; {putc(c);} putcf(c,outfile); j := j + 1; k := k + 1; until (c=NEWLINE) or (k>linewidth); end; for i:=linesperpage+1 to physpage do putcf(NEWLINE,outfile); end; { writepage } begin { convert } column := 1; line := 1; pagenum := 0; initpage; while getline(s,infile,MAXSTR) do begin {putstr(s,TRMOUT);} if (line>1) or (not (s[1] in [EOS,NEWLINE])) then begin writeline(s,column,line); line := line + 1; end; if line > linesperpage then begin column := column + 1; line := 1; if column > numcols then begin writepage(colswritten); initpage; column := 1; end; end; end; { while } if (line>1) or (column>1) then {output last partial page} writepage(colswritten); writeln; writeln(pagenum, ' page(s) written.'); writeln; end; { convert } begin { main program } lowvideo; ioinit(2); writeln; writeln('This program converts a single-column input file to'); writeln('multi-column output.'); writeln; writeln('by Jon Dart ... Version 1.3 (31-Mar-85)'); writeln; repeat setstring(prompt,'Input file name? '); gotfile := getfile(infile,prompt,name,IOREAD); if gotfile then begin setstring(prompt,'Output file name? '); repeat gotfile2 := getfile(outfile,prompt,name,IOWRITE); until gotfile2; getparams(numcols,colwidth,colspace,linesperpage,linewidth, badinput); if not badinput then convert(infile,outfile); pclose(infile); pclose(outfile); end; until not gotfile; end.