/* Screen editor:  output format module
*
* Source: ed5.c
* Version: May 15, 1981.
*/

/* define globals */

#include ed1.h

/* variables global to this module -----

int fmttab;             maximal tab length
int fmtdev;             device flag -- YES/NO = LIST/CONSOLE
int fmtwidth;           devide width.  LISTW/SCRNW1

fmtcol[i] is the first column at which buf[i] is printed.
fmtsub() and fmtlen() assume fmtcol[] is valid on entry.

int fmtcol[MAXLEN1];

----- */

/* direct output from this module to either the console or
* the list device.
*/

fmtassn(listflag) int listflag;
{
       if (listflag==YES) {
               fmtdev=YES;
               fmtwidth=LISTW;
       }
       else {
               fmtdev=NO;
               fmtwidth=SCRNW1;
       }
}

/* adjust fmtcol[] to prepare for calls on
* fmtout() and fmtlen()
*
* NOTE:  this routine is needed as an efficiency
*        measure.  Without fmtadj(), calls on
*        fmtlen() become too slow.
*/

fmtadj(buf,minind,maxind) char *buf; int minind,maxind;
{
int k;
       /* line always starts at left margin */
       fmtcol[0]=0;
       /* start scanning at minind */
       k=minind;
       while (k<maxind) {
               if (buf[k]==CR) {
                       break;
               }
               fmtcol[k+1]=fmtcol[k]+fmtlench(buf[k],fmtcol[k]);
               k++;
       }
}

/* return column at which at which buf[i] will be printed */

fmtlen(buf,i) char *buf; int i;
{
       return(fmtcol[i]);
}

/* print buf[i] ... buf[j-1] on current device so long as
* characters will not be printed in last column.
*/

fmtsubs(buf,i,j) char *buf; int i, j;
{
int k;
       if (fmtcol[i]>=fmtwidth) {
               return;
       }
       outxy(fmtcol[i],outgety());     /* position cursor */
       while (i<j) {
               if (buf[i]==CR) {
                       break;
               }
               if (fmtcol[i+1]>fmtwidth) {
                       break;
               }
               fmtoutch(buf[i],fmtcol[i]);
               i++;
       }
       outdeol();      /* clear rest of line */
}

/* print string which ends with CR or EOS to current device.
* truncate the string if it is too long.
*/

fmtsout(buf,offset) char *buf; int offset;
{
char c;
int col,k;
       col=0;
       while (c= *buf++) {
               if (c==CR) {
                       break;
               }
               k=fmtlench(c,col);
               if ((col+k+offset)>fmtwidth) {
                       break;
               }
               fmtoutch(c,col);
               col=col+k;
       }
}

/* return length of char c at column col */

fmtlench(c,col) char c; int col;
{
       if (c==TAB) {
               /* tab every fmttab columns */
               return(fmttab-(col%fmttab));
       }
       else if (c<32) {
               /* control char */
               return(2);
       }
       else {
               return(1);
       }
}

/* output one character to current device.
* convert tabs to blanks.
*/

fmtoutch(c,col) char c; int col;
{
int k;
       if (c==TAB) {
               k=fmtlench(TAB,col);
               while ((k--)>0) {
                       fmtdevch(' ');
               }
       }
       else if (c<32) {
               fmtdevch('^');
               fmtdevch(c+64);
       }
       else {
               fmtdevch(c);
       }
}

/* output character to current device */

fmtdevch(c) char c;
{
       if (fmtdev==YES) {
               syslout(c);
       }
       else {
               outchar(c);
       }
}

/* output a CR and LF to the current device */

fmtcrlf()
{
       if (fmtdev==YES) {
               syslout(CR);
               syslout(LF);
       }
       else {
               /* kludge: this should be in out module */
               /* make sure out module knows position */
               outxy(0,SCRNL1);
               syscout(CR);
               syscout(LF);
       }
}

/* set tabs at every n columns */

fmtset(n) int n;
{
       fmttab=max(1,n);
}