/* **************************************************************************** * * Mnemonic: FMimbed * Abstract: This routine is responsible for parsing the imbed string and * calling FMopen to open a file to process. * Parms: None. * Returns: Nothing. * Date: 15 November 1988 * Author: E. Scott Daniels * Modified: 25 Aug 2000 - to add NF option * 13 Nov 207 - Added run/stop command to stream to mark pop of * the fmrun() command and return to this function. Allows * this rouitine to drive the imbed which is needed * for things like oneject that imbed files and push/pop the * environment before/after the file. Basically negates the * AFIchain() feature where the imbed file was pushed onto * the stack of open files. c'est la vie! * 17 Jul 2016 - Bring decls into the modern world. * * .im [nf] filename *************************************************************************** */ extern void FMimbed( void ) { char *fp = 0; char *buf; /* pointer into the imput buffer of the fname token */ int len; /* length of the token */ len = FMgetparm( &buf ); if( strcmp( buf, "nf" ) == 0 ) { len = FMgetparm( &buf ); /* point to the next token in the buffer */ FMflush( ); /* send last formatted line on its way */ flags = flags | NOFORMAT; /* turn no format flag on */ } if( len <= 0 ) { FMmsg( E_MISSINGNAME, ".IM" ); return; } FMmsg( I_IMBED, buf ); fp = strdup( buf ); AFIpushtoken( fptr->file, ".sr" ); /* push the special runstop command to mark end of imbed file */ TRACE( 2, "imbed: starting with file %s (pushed .sr token) \n", fp ); FMopen( buf ); /* open the imbed file */ FMrun( ); /* run until we hit the end of the file */ TRACE( 2, "imbed: finished with file %s lmar=%d\n", fp, lmar ); free( fp ); } /* FMimbed */
/* **************************************************************************** * * 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. ************************************************************************** */ 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 */ #ifdef KEEP len = sprintf( inbuf, ".im %s", tocname ); /* create imbed command */ FMopen( inbuf ); FMrun( ); #endif } /* 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 */ }
/* **************************************************************************** * * Mnemonic: FMinit * Abstract: This routine opens the initial input file and the output file * and does other necessary house keeping chores. * Parms: argc - Number of arguments passed to fm from command line * argv - Argument vector list passed from command line * Returns: Valid if all is well, ERROR if system could not be initialized. * Date: 17 November 1988 * Author: E. Scott Daniels * * Modified: 22 Apr 1991 - To remove need to have dedicated page num buffer * 3 May 1991 - To initialize flags2 variable * 3 May 1992 - To convert for post script output * 7 Nov 1992 - To alloc header font buffers * 12 Nov 1992 - To add justify PS proc * 13 Nov 1992 - To allocate current font buffer before use * 10 Dec 1992 - To use AFIwrite for ansi compat on sun * 6 Apr 1993 - To create a dummy variable block for psuedo * commands generated by .gm and .gd commands. * 26 May 1993 - To add stroke command to box routine. * 13 Jun 1993 - To set the psfm variable by placing a dv command * into the initial input buffer. * 12 Jul 1993 - To set the def item list font ptr to null * 21 Feb 1994 - To open output file just "w" * To put out the PS routine rightxy for header/footer * 22 Feb 1994 - To init figure font (ffont) * 7 Apr 1994 - To seup for TOC now that linelen is points related * 7 Oct 2000 - To use new AFI tokeniser * 10 Oct 2001 - To add new justification PS functions * 13 Jan 2001 - Added sym table support * 08 Nov 2006 - Some cleanup and now allow default input from stdin. * 10 Apr 2007 - Memory leak cleanup * 16 Sep 2007 - added page geometry argument support * 13 Nov 2007 - Changed the imbed/run() mechanism to better support the * oneject processing. * 22 Mar 2011 - Correctly set boty when geometry (-g) is given. * 07 Jul 2013 - Changed initialisation of text colour to use setcolour. * 17 Jul 2016 - Bring decls into the modern world. ***************************************************************************** */ extern int FMinit( int argc, char **argv ) { int i; /* loop index */ char buf[1024]; char *ptr; /* pointer to argument */ char *ifname = "stdin"; char *ofname = "stdout"; int geomh = 0; /* geometry from -g hxw */ int geomw = 0; argc--; argv++; while( argc > 0 && argv[0][0] == '-' ) { switch( argv[0][1] ) { case 'g': geomh = atoi( argv[1] ) * 72; if( (ptr = strchr( argv[1], 'x' )) != NULL ) geomw = atoi( ptr + 1 ) * 72; argv++; argc--; break; case 't': trace = atoi( argv[1] ); argv++; argc--; break; case 'v': flags2 |= F2_NOISY; break; case '?': FMmsg( ERROR, "Usage: tfm [input-file [output-file [inital command tokens]]]" ); exit( 1 ); default: fprintf( stderr, "unrecognised option: %s\n", argv[0] ); exit( 1 ); } argv++; argc--; } if( argc >= 1 ) { if( *argv[0] != '-' ) /* allow - to default to stdin */ ifname = argv[0]; } if( argc > 1 ) { if( *argv[1] != '-' ) /* allow - to default to stdout */ ofname = argv[1]; } if( strcmp( ifname, ofname ) == 0 ) { FMmsg( ERROR, "input name cannot be same as output; this is just wrong"); return ERROR; } if( FMopen( ifname ) < VALID ) /* open the initial input file */ return ERROR; symtab = sym_alloc( 4999 ); /* symtab for variables */ AFIsettoken( fptr->file, symtab, " \t", '&', '^', ":" ); AFIsetflag( fptr->file, AFI_F_EOBSIG, AFI_SET ); /* end of buffer notifications */ #ifdef KEEP this is dropped because imbed now puts a run/stop command into the stream to pop the call to fmrun() at end of file AFIsetflag( fptr->file, AFI_F_EOFSIG, AFI_SET ); /* end of file notifications -- must have so .im file .cmd works */ #endif ofile = AFIopen( ofname, "w" ); /* open output file */ if( ofile < VALID ) { FMmsg( E_CANTOPEN, ofname ); FMclose( ); return ERROR; } version = "pfm V2.8/17243"; /* returned by .gv v command */ snprintf( buf, sizeof( buf ), "+PFM text formatter (%s) started", version ); FMmsg( -1, buf ); /* write out our postscript routines that make life easier */ snprintf( buf, sizeof( buf ), "%%! %s generated this postscript file\n", version ); AFIwrite( ofile, buf ); /*AFIwrite( ofile, "%! PFM 1.1-02282 PostScript output\n" );*/ /*AFIwrite( ofile, "% Copyright (c) 1994-2002 by E. Scott Daniels. All Rights Reserved!\n" );*/ AFIwrite( ofile, "% A happy programme is one that generates other programmes;\n" ); AFIwrite( ofile, "% This was generated by a happy programme!\n" ); boty = (10 * 71); /* default to 11" page with a 1" bottom margin */ if( cury <= 0 ) cury = topy = 71; /* default to 1" top margin */ if( top_gutter <= 0 ) top_gutter = cury/2; // space above first line for running matter pagew = MAX_X; pageh = MAX_Y; AFIwrite( ofile, "%these functions are Copyright (c) 2001-2013 by E. Scott Daniels. All Rights Reserved!\n" ); /* new page macro to showpage and set the origion of the 0,0 */ if( geomh ) { pagew = geomw; /* override defaults with user setting */ pageh = geomh; AFIwrite( ofile, "%%BeginSetup\n" ); AFIwrite( ofile, "mark {\n" ); AFIwrite( ofile, "%BeginFeature: *PageRegion C\n" ); snprintf( buf, sizeof( buf ), "<</PageSize [%d %d]>> setpagedevice\n", pagew, pageh ); AFIwrite( ofile, buf ); AFIwrite( ofile, "%EndFeature\n" ); AFIwrite( ofile, "} stopped cleartomark\n" ); AFIwrite( ofile, "%%EndSetup\n" ); snprintf( buf, sizeof( buf ), "/xlate {0 %d translate} def\n/newp {showpage xlate} def\n", pageh ); AFIwrite( ofile, buf ); boty = pageh - 42; /* adjust botom y based on geometry */ } else AFIwrite( ofile, "/xlate {0 792 translate} def\n/newp {showpage xlate} def\n" ); /* the remainder of the native ps that we dump on initialisation is in init.ps which is parsed and compressed by a mk rule and put into init_ps.c */ #include "init_ps.c" /* easier to manage postscript functions we need */ /* now initialize from a C point of view */ difont = NULL; /* initially no def list item font string defined */ ffont = NULL; /* no figure font defined */ //textcolour = strdup( "000000" ); FMsetcolour( "#000000" ); /* default to black */ curfont = strdup( DEF_TEXTFONT ); runfont = strdup( DEF_RUNFONT ); FMfmt_add( ); textspace = 2; iptr = 0; optr = 0; /* start at beginning of the output buffer */ obuf = (char *) malloc( sizeof( char ) * 2048 ); inbuf = (char *) malloc( sizeof( char ) * 2048 ); if( ! obuf || ! inbuf ) { fprintf( stderr, "malloc of obuffer failed\n" ); return ERROR; } *obuf = (char) 0; sprintf( inbuf, ".dv pfm 1 : " ); /* simulate a user command - define compiler name */ AFIpushtoken( fptr->file, inbuf ); /* and push onto the input stack */ if( (path = getenv( "PFM_PATH" )) == NULL ) path = getenv( "XFM_PATH" ); cur_col = firstcol = (struct col_blk *) malloc( sizeof( struct col_blk ) ); if( cur_col == NULL ) return ERROR; cur_col->lmar = DEF_LMAR; cur_col->width = 550 - DEF_LMAR; /* set single column width */ cur_col->next = NULL; /* by default we are in single column mode */ flags = PARA_NUM; /* turn on paragraph numbering */ memset( tocname, 0, sizeof(tocname ) ); snprintf( tocname, sizeof( tocname )-5, "%s", ifname ); if( (ptr = strrchr( tocname, '.' )) != NULL ) *ptr = 0; strcat( tocname, ".toc" ); /* same filename with .toc extension */ memset( pnum, 0, sizeof( pnum ) ); for( i = argc - 1; i > 2; i-- ) AFIpushtoken( fptr->file, argv[i] ); /* whatever is after output file we use as input */ for( i = 0; i < MAX_HLEVELS; i++ ) /* allocate and init header blks */ { headers[i] = (struct header_blk *) malloc( sizeof( struct header_blk ) ); if( headers[i] == NULL ) return ERROR; headers[i]->font = (char *) malloc( (strlen( DEF_HEADFONT )) + 1 ); strcpy( headers[i]->font, DEF_HEADFONT ); /* move in default string */ headers[i]->flags = HTOC; /* initially only TOC flag set */ headers[i]->indent = DEF_HEADINDENT; /* set default indention */ headers[i]->level = i+1; /* set the level */ headers[i]->skip = 21; /* skip down 2 lines before/1after */ } headers[0]->size = DEF_H1SIZE; /* set default header text sizes */ headers[1]->size = DEF_H2SIZE; headers[2]->size = DEF_H3SIZE; headers[3]->size = DEF_H4SIZE; headers[0]->flags |= HEJECTC+HTOUPPER; /* header level 1 defaults */ return VALID; }