예제 #1
0
파일: fmmain.c 프로젝트: ScottDaniels/xfm
/*
****************************************************************************
*
*   Mnemonic:  FMmain
*   Abstract:  This routine is the driver for the FM formatter
*   Parms:     argc - Number of parameters passed to the routine
*              argv - Argument vectors
*                  [1] - input file name
*                  [2] - Output file name
*   Returns:   Nothing.
*   Date:      15 November 1988
*   Author:    E. Scott Daniels
*   Modified:   5 May 1992 - To support conversion to postscript
*              29 Oct 1992 - To call command only if .xx is followed by a
*                            blank so that token starting with a . can be
*                            included in the text (as long as they are more
*                            than 2 characters long.)
*              27 Nov 1992 - To support as is postscript commands
*              10 Dec 1992 - To use AFI routines for ansi compatability
*              15 Dec 1992 - To output a newline to stdout at end of run
*              21 Dec 1992 - To process the .toc file generated
*              13 Apr 1992 - To no longer break when blank as first char
*				18 Nov 2001 - To rewrite to allow for immediate ex of .im 
*				18 Dec 2015 - Call pflush at end only if cury not at top.
*			17 Jul 2016 - Bring decls into the modern world.
**************************************************************************
*/
extern int main( int argc, char **argv ) {
 int len;          /* length of token */
 char *buf;        /* buffer pointer to token */

 if( FMinit( argc, argv ) < VALID )
	  return 1;

	FMrun( );							/* run the open file */

	if( tocfile >= OK )		/* if the toc file is still open */
	{				/* then close it, and simulate .im command on it */
		len = sprintf( inbuf, ".et\n" );
		AFIwrite( tocfile, inbuf );
		flags &= ~PAGE_NUM;	/* turn off page numbering */
		rhead = rfoot = NULL;	/* no headers or footer either */

		AFIclose( tocfile );	/* close the toc file */
	}                      /* end if toc file open */

	FMflush( );            		 /* flush the current line to page buffer */
	if( cury != topy ) {
		TRACE( 3, "main flushing: %d %d\n", cury, topy );
		FMpflush( );			// flush the page out of the printer with headers
	}

	AFIclose( ofile );      /* close the output file */
	sprintf( obuf, "%ld\n", words );

	FMmsg( I_WORDCNT, obuf );     /* write number of words message */
	return 0;                     /* assume end of file reached */
}
예제 #2
0
파일: fmcpage.c 프로젝트: ScottDaniels/xfm
/*
****************************************************************************
*   Mnemonic:  FMcpage
*   Abstract:  This routine conditionally causes a page eject depending
*              on the parameter entered by the user and the remaining
*              space in the current column.
*   Parms:     None.
*   Returns:   Nothing.
*   Date:      3 December 1988
*   Author:    E. Scott Daniels
*   Modified:  5 May 1992 - To support postscript conversion
*				17 Jul 2016 - Changes for better prototype generation.
*
***************************************************************************
*/
extern void FMcpage(  void )
{
 char *buf;          /* pointer at the token */
 int len;

 len = FMgetparm( &buf );    /* is there a length? */

 if( len > 0 )     /* no parameter entered */
  if( (((textsize + textspace) * atoi( buf )) + cury) > boty ) /* & no room */
   {
    FMflush( );              /* terminate the current line */
    FMpflush( );
   }
}               /* FMcpage */
예제 #3
0
파일: fmceject.c 프로젝트: ScottDaniels/xfm
/*
****************************************************************************
*
*  Mnemonic: FMceject
*  Abstract: This rotine ejects the current column such that the next tokin
*            is placed at the top of the next column on the page. If the
*            current column is the last defined column then pflush is
*            called to flush the page and then the first column is selected.
*            FMflush MUST be called prior to this routine... This routine
*            cannot call FMflush as it is called by FMflush and a loop might
*            occur.
*  Parms:    force - forces hard eject if true
*  Date:     6 May 1992
*  Returns:  Nothing.
*  Author:   E. Scott Daniels
*
*  Modified: 13 Jul 1994 - To convert t rfm
*             8 Dec 1994 - To write par mark at top only if not in def list.
*            27 Jan 2000 - To not put hard page if in single col mode to
*                          prevent small # words with large spaces on last ln
*				17 Jul 2016 - Changes for better prototype generation.
****************************************************************************
*/
extern void FMceject( int force )
{
 int diff;     /* difference between lmar in col block and current lmar */
 int diffh;    /* difference betweeh header lmar in col block and current */
 int diffx;    /* diff between x value in list blk and curcol lmar */

 if( flags2 & F2_BOX )    /* if a box is inprogress */
  FMbxend( );             /* then end the box right here */

 FMendlist( FALSE );         /* putout listitem mark characters if in list */

 diffh = hlmar - cur_col->lmar;  /* figure difference between col left mar */
 diff = lmar - cur_col->lmar;   /* and what has been set using .in and .hm */
 if( lilist != NULL )                               /* if list in progress */
  diffx = lilist->xpos - cur_col->lmar;            /* then calc difference */

 if( cur_col->next != NULL )       /* if this is not the last on the page */
  {
   cur_col = cur_col->next;                              /* then select it */
   if( ((rflags & RF_PAR) == 0) && (lilist == NULL) )
    AFIwrite( ofile, "\\par" );                         /* need a par mark */
   FMsetcol( col_gutter );                /* write out col def information */
  }
 else
  {
   if( force || firstcol->next ) /* only do a hard page if in multi col mode */
    FMpflush( );                 /* force a page eject with headers etc */
   cur_col = firstcol;           /* select the first column */
  }

 lmar = cur_col->lmar + diff;   /* set lmar based on difference calculated */
 hlmar = cur_col->lmar + diffh;      /* earlier and next columns left edge */
 if( lilist != NULL )              /* if list then reset xpos for next col */
  lilist->xpos = cur_col->lmar + diffx;

 cury = topy;                           /* make sure were at the top */
 if( rtopy > 0  &&  rtopcount > 0 )     /* reset real topy if needed */
   if( (--rtopcount) == 0 )             /* need to reset */
    {
     topy = rtopy;
     rtopy = 0;
    }

 if( flags2 & F2_BOX )    /* if a box is inprogress */
	FMbxstart( FALSE, 0, 0, 0, 0 );
}                         /* FMceject */
예제 #4
0
파일: fmcmd.c 프로젝트: dhanunjaya/xfm
/*
***************************************************************************
*
*   Mnemonic: FMcmd
*   Abstract: This routine is responsible for dispatching the proper
*             routine to handle the command that was input by the user.
*             Commands are those tokins that begin with a period and are 2
*             characters long.
*   Parms:    buf - Pointer to the command. (.aa)
*   Returns:  Nothing.
*   Date:     17 November 1988
*   Author:   E. Scott Daniels
*
*   Modified: 	1-1-89 - To support normal and definition lists
*             	4-30-98- To support user defined list item characters
*             	5-05-89- To support boxes
*             	6-10-89- To add .** as a comment line in the input file
*             	3 May 1991 - To support .ts (two sided) command
*             	4 May 1991 - To support page shifting
*             	5 May 1992 - To support postscript
*             	1 Oct 1992 - To support punctuation space command
*             	2 Nov 1992 - To add center command
*            	13 Nov 1992 - To free/malloc current font buffer
*             	3 Dec 1992 - To flush before setting font size or font
*             	6 Jun 1993 - To set y position for list item bullets higher
*            	21 Feb 1994 - To handle shift value in dlstack rather than old
*                          left margin; correct multi column problem
*                          and to call setstr for running strings
*	 			21 Oct 2007 - Added index interface
*				26 Jun 2013 - Prevents 0 text size from being set on .st command (happening
*							when .st &var and var not defined. 
*				03 Jan 2016 - Removed errant flush before FMll() and indent
*							calls.
**************************************************************************
*/
int FMcmd( char *buf )
{
	int cmd;                  /* command converted to integer for switch */
	int i;                    /* temp integer */
	struct li_blk *liptr;     /* pointer to head to delete on a .el cmd */
	char *ptr;                /* dummy pointer to skip parameters */
	int len;                  /* length of parameter returned */
	int rc = 1;		/* return code indicating command or not */
	char 	wbuf[512];
	char	*tok;

	cmd = toupper( buf[1] );
	i = toupper( buf[2] );       /* pick off and translate indiv characters */
	cmd = (cmd << 8) + i;        /* combine the characters */

	switch( cmd )
	{
	
		case C_ABORT:	exit( 1 ); break;	/* get out w/o end housekeeping */

		case C_ASIS:	flags2 |= F2_ASIS; break;

		case C_BEGDEFLST:        FMbd( ); break; 	/* definition list */

		case C_BEGLIST:          FMbeglst( ); break;

		case C_BLOCKCTR:		/* .bc {start|end} */
				if( FMgetparm( &buf ) != 0 )
				{
					FMflush( );		/* need to put out last one */
					cenx1 = cur_col->lmar;
					cenx2 = cur_col->lmar + cur_col->width;  /* defalult center */
					if( *buf == 's' || *buf == 'S' )
						flags2 |= F2_CENTER;
					else
						flags2 &= ~F2_CENTER;
				}
				break;

		case C_BOTY:	/* .by [-]x[ip] if - (neg) then thats how far UP from bottom */
				len = FMgetparm( &ptr );
				boty = FMgetpts( ptr, len );
				if( boty <= 0 )
					boty += (11 * 72)-10;
				break;
	
		case C_BREAK:           FMflush( ); break;

		case C_BOX:             FMbox( ); break;

		case C_CAPTURE:		FMcapture( ); break;

		case C_CCOL:            FMccol( 0 ); break;

		case C_COLNOTES:	FMcolnotes( ); break;

		case C_TABLECELL:	FMcell( 1 ); break;

		case C_CENTER:          FMcenter( ); break;

		case C_COLOUR:  	
				if( FMgetparm( &ptr ) > 0 )
				{
					if( strcmp( ptr, "text" ) != 0 || FMgetparm( &ptr ) > 0  )		/* hfm compatable format since it allows bg, link colours to be set */
					{
						if( textcolour )
							free( textcolour );
						FMsetcolour( ptr );			
					}
				}
				break;


		case C_COMMA:		FMcomma( ); break;

		case C_COMMENT:         FMskip( ); break;		/* skip to real end of buffer not : */

		case C_DEFHEADER:       FMdefheader( ); break;

		case C_CDEFINE:		FMcd( ); break;

		case C_EP:              FMep( ); break;

		case C_CEJECT:           
				PFMceject( );            /* eject column, flush page if in last column */
				break;

		case C_CPAGE:            FMcpage( ); break;

		case C_CSS:				/* html cascading style sheet -- meaningless here */
				FMignore( );
				break;

		case C_DEFDELIM:         /* define the variable definition delimiter */
				if( FMgetparm( &ptr ) != 0 )
					vardelim = ptr[0];    /* set the new pointer */
				break;

		case C_DEFITEM:         FMditem( ); break;

		case C_DEFVAR:          FMdv( ); break;

		case C_DOUBLESPACE:	flags = flags | DOUBLESPACE; break;

		case C_ELSE:		FMelse( ); break;

		case C_ENDDEFLST:        /* end definition list */
				if( dlstackp >= 0 )     /* valid stack pointer? */
				{
					flags2 &= ~F2_DIRIGHT;  /* turn off the right justify flag for di's */
					FMflush( );             
					i = dlstack[dlstackp].indent / PTWIDTH;     /* calc line len shift */
					lmar -= dlstack[dlstackp].indent;           /* shift margin back to left */
					linelen += dlstack[dlstackp].indent;        /* reset line len */
					dlstackp--;                          /* "pop" from the stack */
				}
				break;

		case C_ENDIF:            break; /* .fi encountered - ignore it */

		case C_ENDLIST:          /* end a list */
				if( lilist != NULL )    /* if inside of a list */
				{
					FMflush( );           /* clear anything that is there */
					FMendlist( TRUE );      /* terminate the list and delete the block */
				}
				break;


		case C_ENDTABLE: 	FMendtable( ); break;

   		case C_EVAL:                  /* evaluate expression and push result */
    				if( FMgetparm( &buf ) > 0 )  /* get parameter entered */
     					AFIpushtoken( fptr->file, buf );
    				break;

		case C_FIGURE:           FMfigure( ); break;

		case C_FLOATMAR:
					FMfloat_mar( );
					break;

		case C_FORMAT:           FMformat( ); break;

		case C_GETVALUE:         FMgetval( ); break;

		case C_GREY:             /* set grey scale for fills */
				if( FMgetparm( &buf ) > 0 )  /* get parameter entered */
				fillgrey = atoi( buf );   /* convert it to integer */
				break;

		case C_HDMARG:           FMindent( &hlmar );    break;

		case C_HLINE:			FMcline( ); break;

		case C_HN:               FMhn( );   break;

		case C_H1:              FMheader( headers[0] ); break;

		case C_H2:               FMheader( headers[1] ); break;

		case C_H3:               FMheader( headers[2] ); break;

		case C_H4:               FMheader( headers[3] ); break;

		case C_HYPHEN:		
				if( FMgetparm( &buf ) > 0 )  /* get parameter entered */
				{
					if( *(buf+1) == 'n' )	/* assume on */
						flags3 |= F3_HYPHEN;
					else
						flags3 &= ~F3_HYPHEN;
				}
				else
					flags3 |= F3_HYPHEN;
				break;

		case C_IF:               FMif( ); break;

		case C_IMBED:            FMimbed( ); break;

		case C_INDENT:           /* user indention of next line */
				FMindent( &lmar );      /* indent the left margin value */
				break;

		case C_INDEX:
				fmindex( );
				break;

		case C_JUMP: 	FMjump( ); break;

		case C_JUSTIFY:         FMsetjust( ); break;

		
		case C_LINESIZE:        /* set line size for line command */
				if( FMgetparm( &buf ) > 0 )   /* get the parameter */
				{
					linesize = atoi( buf );   /* convert to integer */
					if( linesize > 10 )
						linesize = 2;        /* dont allow them to be crazy */
				}
				break;

		case C_LISTITEM:        /* list item entered */
				if( lilist != NULL && lilist->yindex < 60 )
				{
					FMflush( );          /* output what we have so far */
					if( cury + textspace + textsize  > boty )  /* flush before marking */
					PFMceject( );
					lilist->ypos[lilist->yindex] =  (cury + textsize);
					lilist->yindex++;     /* point at next index */
				}
				break;

		case C_LL:                      /* reset line length */
				FMll( );
				break;

		case C_LINE:            FMline( );   break;

		case C_ONPAGEEJECT:	FMoneject( ); break;	/* on all eject commands */

		case C_OUTLINE:          /* use true charpath and fill instead of stroke */
				if( FMgetparm( &buf ) > 0 )  /* get the parameter on | off */
				{
					if( toupper( buf[1] ) == 'N' )
						flags2 |= F2_TRUECHAR;        /* turn on the flag */
					else
						flags2 &= ~F2_TRUECHAR;       /* turn off the flag */
				}
				break;

		case C_NOFORMAT:                /* turn formatting off */
				FMflush( );                    /* send last formatted line on its way */
				flags = flags | NOFORMAT;      /* turn no format flag on */
				break;

		case C_PAGE:            /* eject the page now */
				FMflush( );            /* terminate the line in progress */
				FMpflush();            /* and do the flush */
				break;

		case C_PAGENUM:		FMpgnum( ); break;

		case C_PAGEMAR:		FMindent( &pageshift );  break;

		case C_POP:			FMpop_state( ); break;

		case C_PUNSPACE:	flags2 ^= F2_PUNSPACE; break;
	
		case C_PUSH:		FMpush_state( ); break;

		case C_QUIT:		 
						if( !FMcolnotes_show( 1 ) )			/* push command(s) to show end notes which MUST contain another .qu! */
							AFIclose( fptr->file ); 		/* if there wasn't end commands, then safe to close and exit now */
						break;

		case C_RFOOT:		FMsetstr( &rfoot, HEADFOOT_SIZE ); break;

		case C_RHEAD:		FMsetstr( &rhead, HEADFOOT_SIZE ); break;

		case C_RESTARTTAB:	
				TRACE( 1, ">>>++++ calling restart\n" )
				FMrestart_table(); 
				break;

		case C_SECTION:		FMsection( ); break;

		case C_SETX:		FMsetx( ); break;

		case C_SETY:		FMsety( ); break;

   		case C_SHOWV:
				if( (len = FMgetparm( &buf )) > 0 )
				{
					if( strcmp( buf, "all" ) == 0 )
						FMshowvars( );
					else
					{
						if( (ptr = sym_get( symtab, buf, 0 )) )
							fprintf( stderr, "(%s @ %ld) %s = (%s)\n", fptr->name, AFIstat( fptr->file, AFI_OPS, NULL), buf, ptr );
						else
							fprintf( stderr, "(%s @ %ld) %s = UNDEFINED\n", fptr->name, AFIstat( fptr->file, AFI_OPS, NULL), buf );
					}
				}
				break;

		case C_SINGLESPACE:        /* turn off double space */
				if( flags & DOUBLESPACE )
					flags = flags & (255-DOUBLESPACE);
				break;

		case C_SKIP:            
				if( cury == topy )
					break;                 /* if not at top fall into space */

		case C_SPACE:            /* user wants blank lines */
				FMspace( );
				break;

		case C_SETFONT:           								/* set font for text (font name only parm) */
				if( (len = FMgetparm( &ptr )) != 0 )     		/* if a parameter was entered */
				{
					*wbuf = 0;

					for( tok = ptr; *tok && (isalpha( *tok ) || *tok == '-'); tok++ );
					if(  *tok != 0 )								/* found non-alpha, assume closing . or ) or somesuch */
					{
						strcpy( wbuf, tok );
						*tok = 0;
					}

					TRACE( 2, "setfont old=%s  new=%s\n", curfont, ptr );
					free( curfont );          
					curfont = strdup( ptr );
					FMfmt_add( );		/* add a format block to the list */

					//if( *wbuf )
     				//	AFIpushtoken( fptr->file, wbuf );
				}
				else
					TRACE( 2, "setfont MISSING parameter!\n" );
				break;

		case C_SETTXTSIZE:        					/* set text font size */
				if( FMgetparm( &ptr ) )     		/* must have parameter */
				{
					if( (i = atoi( ptr )) > 5 )    /* if number is ok */
					{
						TRACE( 2, "textsize set to: %d\n", i );
						textsize = i; 
						FMfmt_add( );
					}
					else
						TRACE( 2, "textsize NOT set to: %d", i );
				}
				else
					TRACE( 2, "textsize NOT, no parm" );
				break;

		case C_SMASH:	 flags2 |= F2_SMASH; break;

		case C_TABLE:	 FMtable( ); break;

		case C_TABLEHEADER:	 FMth( ); break;

		case C_TABLEROW:	 FMtr( 0 ); break;

		case C_TMPFONT:	 FMtmpfont( ); break;

		case C_TMPTOP:            FMtmpy( cmd ); break;

		case C_TOC:	 FMtc( ); break;

		case C_TOPGUT:								// set the top gutter
				if( (len = FMgetparm( &ptr )) ) 
				{
					i = FMgetpts( ptr, len );
					if( i > 0 && i < topy )
					{
						TRACE( 2, "top gutter set to: %d\n", i );
						top_gutter = i; 
					} else {
						TRACE( 2, "top gutter not set, not in range: %d  topy=%d\n", i, topy )
					}
				} else {