/* **************************************************************************** * * Mnemonic: FMspace * Abstract: This routine processes the .SP command when entered. * Parms: None. * Returns: Nothing. * Date: 15 November 1988 * Author: E. Scott Daniels * Modified: 29 Jun 1994 - To support rfm conversion * 18 Jul 1994 - To allow listitems in boxes * 6 Dec 1996 - To convert for hfm * 15 Jan 2012 - pulled into tfm * 05 Jul 2013 - to handle .5 pfm style skipping -- defaults to 1 * 17 Jul 2016 - Bring prototypes into modern era. *************************************************************************** */ extern void FMspace( void ) { char *buf; /* pointer at the token */ int len = 1; /* number of lines to skip */ FMflush( ); /* flush out the current line */ if( FMgetparm( &buf ) > 0 ) /* number of lines supplied */ len = atoi( buf ); if( len > 55 ) /* enforce some sanity */ len = 55; else if( len <= 0 ) /* default to 1 for partial line spacing suppored in pfm */ len = 1; FMflush( ); *obuf = 0; optr = 0; for( len; len > 0; len-- ) /* skip lines */ { strcat( obuf, " " ); optr += 1; FMflush( ); *obuf = 0; optr = 0; } }
/* **************************************************************************** * * Mnemonic: FMspace * Abstract: This routine processes the .SP command when entered. * Parms: None. * Returns: Nothing. * Date: 15 November 1988 * Author: E. Scott Daniels * Modified: 29 Jun 1994 - To support rfm conversion * 18 Jul 1994 - To allow listitems in boxes * 6 Dec 1996 - To convert for hfm * 18 Jul 2016 - Add consistent, and sometimes modern, prototypes. *************************************************************************** */ extern void FMspace( void ) { char *buf; /* pointer at the token */ int len; FMflush( ); /* flush out the current line */ len = FMgetparm( &buf ); /* is there a length? */ if( len <= 0 ) /* no parameter entered */ len = 1; /* defalut to one space */ else len = atoi( buf ); /* convert parameter entered */ if( len > 55 ) len = 55; /* no more than 55 please */ for( len++; len > 0; len-- ) /* skip lines */ { strcat( obuf, "<br />" ); optr += 5; } FMflush( ); *obuf = 0; optr = 0; }
/* ***************************************************************************** * * Mnemonic: FMcenter * Abstract: This routine will put the rest of the line of text entered with * this command (.ce) in the center of the current column using * the cen macro defined in the postscript output file. * If the first two tokens are numbers then the text is centered * between these points. * Parms: None. * Returns: Nothing. * Date: 2 November 1992 * Author: E. Scott Daniels * * .ce [x1 x2] <text to center> <eos> * * Modified: 25 Mar 1993 - To accept points between which text is centered * 28 Apr 1993 - To set same y flag if move to not necessary * 6 Dec 1996 - To convert to hfm (ignore x1, x2 if there) * 18 Jul 2016 - Add consistent, and sometimes modern, prototypes. ***************************************************************************** */ extern void FMcenter( void ) { char *buf; /* pointer at parameters */ int i; /* length of the token */ FMflush( ); /* write what ever might be there */ strcat( obuf, "<center>" ); /* add tag to output */ optr += 8; flags2 |= F2_CENTER; /* make flush center rather than show */ if( (i = FMgetparm( &buf )) > 0 && isdigit( buf[0] ) ) { if( !(FMgetparm( &buf ) > 0 && isdigit( buf[0] )) ) { FMmsg( E_MISSINGPARM, inbuf ); /* missing parameter error */ return; } i = FMgetparm( &buf ); /* get first text parm to center */ } while( i > 0 ) /* until all parameters gone */ { FMaddtok( buf, i ); /* add it to the output buffer */ i = FMgetparm( &buf ); } /* end while */ FMflush( ); /* send user line on the way */ flags2 &= ~(F2_CENTER | F2_SAMEY); /* turn off flags */ } /* fmcenter */
/* ***************************************************************************** * * Mnemonic: FMcenter * Abstract: This routine will put the rest of the line of text entered with * this command (.ce) in the center of the current column using * the cen macro defined in the postscript output file. * If the first two tokens are numbers then the text is centered * between these points. * Parms: None. * Returns: Nothing. * Date: 2 November 1992 * Author: E. Scott Daniels * * .ce [x1=p1 x2=p2] <text to center> <eos> * * p1 and p2 are values in points from left column edge. If p2 is negative * then the distance is from the right edge of the current column. * * Modified: 25 Mar 1993 - To accept points between which text is centered * 28 Apr 1993 - To set same y flag if move to not necessary * 08 Feb 2002 - To ditch the x1 x2 parms as it seems to always cause * issues. now accepts x1= x2= parameters if user really * wants to do this. Should cause less headaches * 06 Jul 2013 - negative p2 value now supported. * 17 Jul 2016 - Changes for better prototype generation. ***************************************************************************** */ extern void FMcenter( void ) { char *buf; /* pointer at parameters */ int i; /* length of the token */ FMflush( ); /* write what ever might be there */ flags2 |= F2_CENTER; /* make flush center rather than show */ if( (i = FMgetparm( &buf )) > 0 && strncmp( buf, "x1=", 3 ) == 0 ) { flags2 |= F2_SAMEY; /* indicate same y value */ cenx1 = cur_col->lmar + atoi( buf+3 ); /* convert first point to integer */ if( FMgetparm( &buf ) > 0 && strncmp( buf, "x2=", 3 ) == 0 ) { cenx2 = cur_col->lmar + atoi( buf+3 ); /* convert second digit */ if( cenx2 < 0 ) /* assume neg value is distance from the right edge rather than left */ cenx2 += cur_col->width; } else { FMmsg( E_MISSINGPARM, inbuf ); /* missing parameter error */ return; } if( cenx2 <= cenx1 ) /* cannot have this */ { FMmsg( E_PARMOOR, inbuf ); /* send error and exit from here */ return; } i = FMgetparm( &buf ); /* get first text parm to center */ } else /* no columns defined - center between margins */ { cenx1 = cur_col->lmar; cenx2 = cur_col->lmar + cur_col->width; /* defalult center */ } TRACE( 2, "center: x1=%d x2=%d\n", cenx1, cenx2 ); while( i > 0 ) /* until all parameters gone */ { FMaddtok( buf, i ); /* add it to the output buffer */ i = FMgetparm( &buf ); } /* end while */ FMflush( ); /* send user line on the way */ flags2 &= ~(F2_CENTER | F2_SAMEY); /* turn off flags */ } /* fmcenter */
/* **************************************************************************** * * 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. * 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 */ }
/* **************************************************************************** * * 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 * 19 Nov 2001 - Conversion to use FMrun() * 18 Jul 2016 - Add consistent, and sometimes modern, prototypes. ************************************************************************** */ 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" ); AFIclose( tocfile ); /* close the toc file */ } flags2 &= ~F2_SETFONT; /* dont start a new span on final flush */ FMflush(); /* final flush */ FMele_stack( ES_POP, ET_DOC ); /* final pop of all stacked closer tags */ //sprintf( obuf, "%s</body></HTML>", need_div ? "</div>" : "" ); /* end document stuff */ AFIwrite( ofile, obuf ); AFIclose( ofile ); /* close the output file */ sprintf( obuf, "%ld\n", words ); FMmsg( I_WORDCNT, obuf ); /* write number of words message */ return 0; }
/* ****************************************************************************** * * Mnemonic: FMlisti * Abstract: This routine will setup for a list item in the current text. * Parms: None. * Returns: Nothing. * Date: 1 July 1994 * Author: E. Scott Daniels * * Modified: 19 Jul 1994 - To allow list items in boxes * 8 Dec 1995 - To use font in list item block * 17 Jul 2016 - Changes for better prototype generation. ****************************************************************************** */ extern void FMlisti( void ) { struct li_blk *lptr; /* pointer into listitem list */ char buf[81]; /* output buffer */ int right; /* right indention value */ lptr = lilist; /* point at the list */ FMflush( ); if( rflags & RF_PAR ) /* if a par has been issued */ AFIwrite( ofile, "\\pard" ); /* just terminate settings */ else { AFIwrite( ofile, "\\par\\pard" ); /* terminate previous setup */ } if( flags2 & F2_BOX ) FMbxstart( FALSE, 0, 0, 0, 0 ); rflags &= ~RF_PAR; /* reset flag */ FMccol( 1 ); /* ensure at least one line remains on page */ right = cur_col->width - ((lmar-cur_col->lmar) + linelen); sprintf( buf, "\\plain\\li%d\\fi-200\\qj{\\pnlvlblt\\pn%s\\pntxtb \\'%02x\\pnindent200}", lmar * 20, lptr->font, lptr->ch & 0xff ); AFIwrite( ofile, buf ); sprintf( buf, "\\ri%d\\%s\\fs%d", right * 20, curfont, textsize * 2 ); AFIwrite( ofile, buf ); } /* FMlisti */
/* ***************************************************************************** * * Mnemonic: FMjustify * Abstract: This routine is responsible for sending out the current buffer * with the proper justification command and related parameters. * Parms: None. * Returns: Nothing. * Date: 12 November 1992 * Author: E. Scott Daniels * * Modified: 04 Dec 1992 - To call flush if spaces are 0 * 10 Dec 1992 - To use AFI routines for ansi compatability * 6 Apr 1994 - To take advantage of linelen being points now * 17 Jul 2016 - Changes for better prototype generation. ***************************************************************************** */ extern void FMjustify( void ) { int spaces; /* number of blank spaces */ int i; /* loop index */ int len; /* length of the string for write */ char jbuf[256]; /* buffer for write */ for( i = 0; obuf[i] != EOS; i++ ); /* find end of the string */ for( i--; obuf[i] == BLANK; i-- ); /* find last non blank */ obuf[i+1] = EOS; /* ensure no blanks at end of str */ for( spaces = 0, i = 0; obuf[i] != EOS; i++ ) if( obuf[i] == BLANK ) spaces++; /* bump up the count */ if( spaces == 0 ) { FMflush( ); /* dont call just with a 0 parameter */ return; } if( optr == 0 ) /* need to do a move to? */ { cury += textsize + textspace; /* move to the next y position */ if( flags & DOUBLESPACE ) /* if in double space mode ... */ cury += textsize + textspace; /* then skip down one more */ if( cury > boty ) /* are we out of bounds? */ { FMceject( 0 ); /* move to next column */ } sprintf( jbuf, "%d -%d moveto\n", lmar, cury ); /* create moveto */ AFIwrite( ofile, jbuf ); /* write the move to command or x,y for cen */ } /* end need to do a move to */ if( flags2 & F2_SETFONT ) /* need to reset font to text font? */ { FMsetfont( curfont, textsize ); /* set the font */ flags2 &= ~F2_SETFONT; /* turnoff setfont flag */ } sprintf( jbuf , "%d (%s) %d just\n", spaces, obuf, lmar + linelen ); /* cur_col->lmar + cur_col->width ); */ AFIwrite( ofile, jbuf ); /* write the buffer to output file */ if( flags2 & F2_BOX && box.hconst == TRUE ) /* in box and horz lines */ { sprintf( jbuf, "%d -%d moveto %d -%d lineto stroke\n", box.lmar, cury + 2, box.rmar, cury + 2 ); AFIwrite( ofile, jbuf ); /* output the information */ } } /* FMjustify */
/* ***************************************************************************** * * Mnemonic: FMnofmt * Abstract: This routine is called when the noformat flag is set. It * reads in lines from the input file and if there is not a * command in the first column then it places the line of * text as is out to the page buffer. If a command is on the * input line control is returned to the caller to process the * command. * Parms: None. * Returns: Nothing. * Date: 8 December 1988 * Author: E. Scott Daniels * * Modified: 7 Jul 1994 - To convert to rfm * 4 Oct 1994 - To reduce amount skipped in y direction. * 6 Dec 1996 - To convert for hfm * 4 Apr 1997 - To use the new tokenizer in AFIleio! * 15 Apr 1997 - To return if vardelim is in first col too ******************************************************************************* */ void FMnofmt( ) { char *buf; /* work buffer */ int status; /* status of the read */ int i; /* loop index */ status = FMread( inbuf ); /* get the next buffer */ while( status >= 0 && inbuf[0] != CMDSYM && *inbuf != vardelim ) { for( i = 0; i < MAX_READ-1 && inbuf[i] != EOS; i++, optr++ ) { switch( inbuf[i] ) /* properly escape html special chars */ { case '>': obuf[optr] = EOS; /* terminate for strcat */ strcat( obuf, ">" ); /* copy in the character */ optr += 3; /* incr past the html esc string */ osize += 3; /* incr number of chars in output */ break; case '<': obuf[optr] = EOS; /* terminate for strcat */ strcat( obuf, "<" ); /* copy in the character */ optr += 3; /* incr past the html esc string */ osize += 3; /* incr number of chars in output */ break; case '&': obuf[optr] = EOS; /* terminate for strcat */ strcat( obuf, "&" ); /* copy in the character */ optr += 4; /* incr past the html esce string */ osize += 4; /* incr number of chars in output */ break; default: /* not a special character - just copy in */ obuf[optr] = inbuf[i]; obuf[optr+1] = EOS; /* terminate incase of strcat on next loop */ break; } } /* end while stuff in input buffer to copy */ if( optr == 0 ) /* if this was a blank line */ obuf[optr++] = ' '; /* give flush a blank to write */ obuf[optr] = EOS; /* terminate buffer for flush */ FMflush( ); /* send the line on its way */ status = FMread( inbuf ); /* get the next line and loop back */ } /* end while */ AFIpushtoken( fptr->file, inbuf ); /* put command back into input stack */ iptr = optr = 0; /* return pointing at beginning */ } /* FMnofmt */
/* show the col notes by closing the file and pushing an imbed command onto the stack. the last command in the file is a .cn command to unlink the file (we'll leave droppings in the file system if the user causes us to crash, but thats low risk). returns true if something was pushed -- needed for the end; */ extern int FMcolnotes_show( int end ) { char buf[1024]; FILE *target = NULL; char *fname = NULL; int status = 0; char *end_cmd = ""; if( bfile != NULL ) // target is always the b file if it's there { target = bfile; bfile = NULL; fname = bfname; } if( end ) /* end of doc (atclose) */ { FMflush( ); if( target == NULL ) { // end and no bfile; try end file now target = efile; efile = NULL; fname = efname; } end_cmd = ".qu"; // needed to force end processing after our embed (might bring us back to do efile if bfile exists } if( target == NULL ) return 0; TRACE( 2, "colnotes: showing at: %s cury=%d boty=%d page=%d\n", end ? "end of doc" : "bottom of col", cury, boty, page ); if( cn_space > 0 ) if( boty - cn_space > cury ) cury = boty - cn_space; TRACE( 2, "colnotes: cury set to=%d\n", cury ); fprintf( target, ".br\n.po\n" ); // add the ending commands to the file (force flush and pop) if( ! end ) fprintf( target, ".cb\n" ) ; // new col only if not at end; causes extra page eject if at end if( flags & JUSTIFY ) fprintf( target, ".ju on\n" ); // justify back on if needed fprintf( target, ".cn unlink %s\n%s\n", fname, end_cmd ); fclose( target ); snprintf( buf, sizeof( buf ), "\n.im %s", fname ); /* must have a guarding newline as lead (prevent accidents with .sp without optional parm etc.) */ status = AFIpushtoken( fptr->file, buf ); /* push to imbed the file */ TRACE( 2, "colnotes: pushing: stat=%d (%s)\n", status, buf ); *fname = 0; return 1; }
/* **************************************************************************** * 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 */
/* ***************************************************************************** * * Mnemonic: FMline * Abstract: This routine is responsible for putting a line into the output * file. * Parms: None. * Returns: Nothing. * Date: 1 November 1992 * Author: E. Scott Daniels * * Modified: 6 Jul 1994 - To convert for rfm. * 11 Apr 1994 - To check for box to see what margins to use. * 17 Jul 2016 - Changes for better prototype generation. ***************************************************************************** */ extern void FMline( void ) { char out[100]; /* output buffer */ int len; /* lenght of output string */ FMflush( ); /* put out what ever is currently cached */ AFIwrite( ofile, "\\pard" ); sprintf( out, "\\brdrb\\brdrs\\brdrw%d\\brsp20", linesize * 20 ); AFIwrite( ofile, out ); /* write the command to draw the line out */ FMpara( 0, TRUE ); /* terminate the line and define next paragraph */ /*cury += textsize + linesize; */ /* bump the current spot up some */ rflags |= RF_PAR; } /* FMline */
/* ****************************************************************************** * * Mnemonic: FMlisti * Abstract: This routine will setup for a list item in the current text. * Parms: None. * Returns: Nothing. * Date: 1 July 1994 * Author: E. Scott Daniels * * Modified: 19 Jul 1994 - To allow list items in boxes * 8 Dec 1995 - To use font in list item block * 6 Dec 1996 - To convert to hfm ****************************************************************************** */ void FMlisti( ) { struct li_blk *lptr; /* pointer into listitem list */ char buf[81]; /* output buffer */ int right; /* right indention value */ lptr = lilist; /* point at the list */ FMflush( ); if( lptr != NULL ) { strcat( obuf, "<li>" ); optr += 4; /* add tag and scoot past it */ } } /* FMlisti */
/* **************************************************************************** * * *** WARNING: With the additon of the fmt blocks, this is likely broken!!! * * Mnemonic: FMsetx * Abstract: This routine is responsible for adjusting the current x position * on the output page. The value entered may be specified in pts or * inches. A + or - prefix to the value indicates a relitive move, * and a value without + or - indicates an absolute position in * relation to the current column's left margin value. * Params: None. * Returns: Nothing. * Date: 3 December 1992 * Author: E. Scott Daniels * * Modified: 10 Dec 1992 - To use AFI routines for ansi compatability * 25 Mar 1992 - To accept a + for relative moves * 22 Apr 1993 - To set relmove flag initially to false * 7 Apr 1994 - To use the getpts routine allowing user to enter * x value in inches or points. * 11 Apr 1994 - To take value relative to curcol's left margin * 31 Jan 2016 - To actually allow negative relative moves. * 17 Jul 2016 - Bring decls into the modern world. ****************************************************************************** */ extern void FMsetx( void ) { char *buf; /* pointer at the parameter user has entered */ int len; /* length of parameter entered */ int i; /* new x position */ int relmove = FALSE; /* new x is relative to current x position */ char wbuf[50]; /* buffer to build string in to write to file */ if( (len = FMgetparm( &buf )) > 0 ) /* if user entered a parameter */ { if( buf[0] == '+' || buf[0] == '-' ) /* relative move? */ relmove = TRUE; /* then set local flag */ i = FMgetpts( buf, len ); if( i < cur_col->width ) /* ensure its in the column */ { if( optr == 0 ) /* if nothing currently in the buffer */ { optr = 1; obuf[0] = ' '; /* force flush to setup the current y */ obuf[1] = EOS; osize = 0; /* reset output size */ } FMflush( ); /* put out what is already there */ if( relmove == TRUE ) /* if relative move */ { osize += i; /* indicate number of points skipped over */ sprintf( wbuf, "%d 0 rmoveto\n", i ); /* ps to relative move */ } else { osize = i; /* indicate position in obuf in terms of pts */ sprintf( wbuf, "%d %d moveto\n", cur_col->lmar + i, -cury ); } AFIwrite( ofile, wbuf ); /* write to file */ } /* end if in range */ else /* generate an error message */ FMmsg( E_PARMOOR, ".sx" ); } /* end if parm entered */ } /* FMsetx */
/* ****************************************************************************** * * TFM * Mnemonic: FMlisti * Abstract: This routine will setup for a list item in the current text. * Parms: None. * Returns: Nothing. * Date: 1 July 1994 * Author: E. Scott Daniels * * Modified: 19 Jul 1994 - To allow list items in boxes * 8 Dec 1995 - To use font in list item block * 6 Dec 1996 - To convert to hfm * 21 Mar 2001 - Rebirth of the original; TFM ****************************************************************************** */ void FMlisti( ) { struct li_blk *lptr; /* pointer into listitem list */ char buf[81]; /* output buffer */ int right; /* right indention value */ lptr = lilist; /* point at the list */ FMflush( ); if( lptr != NULL ) { /*sprintf( buf, "%c ", lptr->ch ); strcat( obuf, buf ); optr += 2; */ /* add tag and scoot past it */ lptr->xpos = 0; } } /* FMlisti */
extern void FMccol( int skip ) { char *buf = NULL; /* pointer at the token */ int len; FMflush( ); /* put out what may be there */ if( skip == 0 ) /* calling routine did not pass parameter to use */ { if( (len = FMgetparm( &buf )) ) /* then assume user command and get it */ skip = FMgetpts( buf, len ); /* convert to integer */ else skip = 2 * (textsize + textspace); /* otherwise default to 2 lines */ } TRACE( 2, "ccol: buf=%s skip=%d cnspace=%d size+space=%d cury=%d boty=%d eject=%d(%s)\n", buf ? buf : "", skip, cn_space, textsize+textspace, cury, boty, skip + cn_space + cury, skip + cn_space + cury >= boty ? "true" : "false" ); if( skip + cn_space + cury >= boty ) PFMceject( ); /* eject col if not enough there */ } /* FMccol */
/* **************************************************************************** * * Mnemonic: FMpara * Abstract: This does nothing but flush for tfm; significant in hfm/rfm * Parms: None. * Returns: nothing. * Author: E. Scott Daniels * * Modified: 19 Jul 1994 - To allow list items in boxes * 6 Dec 1996 - Converted for hfm * 21 Mar 2001 - Maybe you can go home - TFM mods. * 17 Jul 2016 - Bring prototypes into modern era. **************************************************************************** */ extern void FMpara( int i, int j ) { strcat( obuf, " " ); /* add tag to output buffer */ optr++; FMflush( ); } /* FMpara */
/* **************************************************************************** * *** this routine needs to be rewritten to get parms in any order *** and not to require n to be supplied if right/font supplied *** * Mnemonic: FMbd * Abstract: This routine parses the .bd command to start a definition list * Parms: None. * Returns: Nothing. * Date: 1 January 1989 (Happy New Year!) * Author: E. Scott Daniels * * Modified: 5 May 1992 - To support postscript conversion * 12 Jul 1993 - To support right justification of terms and * setting of a different font for terms. * 21 Feb 1994 - To correct two col problem by keeping the amount * indented in the stack and not the left marg value. * 6 Apr 1994 - To call getpts to get point value of term size * 10 Feb 2002 - To add auto skip option * 14 May 2016 - Corrected seg fault if font name not given. * 17 Jul 2016 - Bring decls into the modern world. * * .bd <termsize[p|i]> [right] [font name] [s=n] * right - indicates that terms are to be right justified in the field * font - name of the font to show terms in * s=n - skip a line before each di. * Copyright (c) 1989 E. Scott Daniels. All rights reserved. *************************************************************************** */ extern void FMbd( void ) { char *buf; /* pointer at the token */ int len; /* len of parameter entered */ int skip = 0; /* set to true if user wants automatic .sp with each .di */ int tsize = 0; /* requested term size - default is 1 inch = 72pts */ int j = 0; int anumflag = 0; int astart = 1; char title[255]; /* buffer to use to space over on write */ FMflush( ); /* sweep the floor before we start */ if( dlstackp >= MAX_DEFLIST ) /* too deep */ { while( FMgetparm( &buf ) ); fprintf( stderr, "fmbd: too deep - bailing out \n" ); return; } dlstackp++; /* increase the definition list stack pointer */ memset( &dlstack[dlstackp], 0, sizeof( dlstack[0] ) ); while( (len = FMgetparm( &buf )) > 0 ) // process to end of line or : { if( ! j++ ) // first parm is positional; term size { tsize = FMgetpts( buf, len ); dlstack[dlstackp].indent = tsize; lmar += tsize; /* set the new indented left margin */ linelen -= tsize; /* shrink ll as to not shift the line any */ } else { if( strncmp( buf, "right", len ) == 0 ) /* right just? */ { flags2 |= F2_DIRIGHT; /* turn on the flag */ } else { if( strchr( buf, '=' ) ) /* something = something */ { switch( *buf ) { case 'a': if( isdigit( *(buf+2) ) ) { dlstack[dlstackp].anum = DI_ANUMI; /* integer numbering */ dlstack[dlstackp].aidx = atoi( buf+2 ); /* where to start */ } else { dlstack[dlstackp].anum = DI_ANUMA; /* integer numbering */ dlstack[dlstackp].aidx = *(buf+2); /* where to start */ } break; case 'F': if( buf+2 ) { if( difont ) free( difont ); difont = strdup( buf+2 ); } break; case 'f': /* format string */ dlstack[dlstackp].fmt = strdup( buf+2 ); break; case 's': dlstack[dlstackp].skip = atoi( buf + 2 ); break; default: break; } } else { if( difont != NULL ) /* free the font buffer if there */ free( difont ); difont = strdup( buf ); } } } } if( difont == NULL ) { difont = strdup( curfont ); } if( ! tsize ) /* no parms supplied, or bad parm */ { tsize = 72; dlstack[dlstackp].indent = tsize; lmar += tsize; /* set the new indented left margin */ linelen -= tsize; /* shrink ll as to not shift the line any */ } } /* FMbd */
extern void FMtable( void ) { struct table_mgt_blk *t; struct col_blk *col; char colour[50]; /* spot to build colour string in */ char align[50]; char valign[50]; char space[50]; int do_cell = 1; /* n option turns off */ int len; char *ptr; int border = 0; /* border size */ char wstr[50]; /* spot to build width stirng in */ int w = 100; space[0] = 0; align[0] = 0; wstr[0] = 0; sprintf( valign, "valign=top" ); /* default to vert as brows def is cent*/ FMflush( ); /* terminate the line in progress */ if( ts_index >= MAX_TABLES ) { fprintf( stderr, "abort: too many tables max = %d\n", MAX_TABLES ); exit( 1 ); } t = table_stack[ts_index++] = (struct table_mgt_blk *) malloc( sizeof( struct table_mgt_blk) ); memset( t, 0, sizeof( struct table_mgt_blk ) ); t->col_list = firstcol; /* hold things that need to be restored when done */ t->cur_col = cur_col; t->topy = cury; t->old_topy = topy; t->old_linelen = linelen; t->lmar = lmar; t->hlmar = hlmar; t->padding = 5; /* padding inside of cell */ t->maxy = cury; t->edge_borders = 0; // default to no edges for table in table firstcol = NULL; cur_col = NULL; curcell = 1; /* tableinfo[0] has cell count */ colour[0] = (char) 0; while( (len = FMgetparm( &ptr )) != 0 ) switch( *ptr ) { case 'a': sprintf( align, "align=%.13s", ptr + 2 ); break; case 'B': t->edge_borders = 1;; break; case 'b': if( *(ptr+1) == '=' ) border = atoi( ptr + 2 ); else border++; break; case 'c': if( strncmp( ptr, "class=", 6 ) == 0 ) /* ignore hfm class= */ break; /* t->bgcolour = strdup( ptr + 2 ); sprintf( colour, "bgcolor=%.13s", t->bgcolour ); */ break; case 'l': // line weight t->weight = atoi( ptr+2 ); break; case 'n': do_cell = 0; /* dont auto do a cell */ break; case 'p': t->padding = atoi( ptr + 2 ); break; case 's': sprintf( space, "cellspacing=%.13s", ptr +2 ); //t->spacing = atoi( ptr+2 ); break; case 't': /* t->fgcolour = strdup( ptr + 2 ); textcolour = t->fgcolour; flags2 |= F2_SETFONT; */ break; case 'v': sprintf( valign, "valign=%.13s", ptr + 2 ); break; case 'w': /* w=xxx percent of width to use for table */ memcpy( wstr, ptr+2, len - 2 ); wstr[len-2] = 0; w = atoi( wstr ); sprintf( wstr, "width=%d%%", w ); break; default: /* assume column width definition */ if( curcell < MAX_CELLS ) { col = (struct col_blk *) malloc( sizeof( struct col_blk ) ); memset( col, 0, sizeof( *col ) ); col->next = NULL; col->width = FMgetpts( ptr, len ) - 4; /*t->border_width += col->width + (2 * t->padding );*/ t->border_width += col->width + ( t->padding ) + 2; if( cur_col ) { col->lmar = cur_col->lmar + cur_col->width + t->padding; cur_col->next = col; cur_col = col; } else { col->lmar = lmar + t->padding; cur_col = firstcol = col; } curcell++; /* cell counter */ } break; } firstcol->anchor = t->col_list->anchor; /* cary the anchor over for running head/feet */ t->border = border; t->width = (linelen * w)/100; cur_col = firstcol; if( do_cell ) linelen = cur_col->width - t->padding; else for( cur_col = firstcol; cur_col->next; cur_col = cur_col->next ); lmar = firstcol->lmar + t->padding; if( t->edge_borders == 0 && ts_index > 1 ) /* if this is a table in a table w/o edge borders */ { t->topy -= t->padding; topy = cury; /* columns bounce back to here now */ } else { topy = cury + t->padding; /* columns bounce back to here now */ if( border ) /* dont do outside for table in a table */ { sprintf( obuf, "%d setlinewidth ", t->weight ); AFIwrite( ofile, obuf ); sprintf( obuf, "%d %d moveto %d %d rlineto stroke\n", t->lmar+t->padding, -cury, t->border_width-t->padding, 0 ); AFIwrite( ofile, obuf ); } } cury += t->padding; /* allow a bit of room for the line */ if( trace > 1 ) { struct col_blk *cp; int i = 0; fprintf( stderr, "table: lmar=%d cury=%d borarder_width=%dp right_edge%dp\n", t->lmar, cury, t->border_width, t->lmar+ t->border_width ); for( cp = firstcol; cp; cp = cp->next ) fprintf( stderr, "table: cell=%d lmar=%dp width=%dp\n", i++, cp->lmar, cp->width ); } }
/* *************************************************************************** * * 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 {
/* ************************************************************************* * * Mnemonic: FMheader * Abstract: This routine is responsible for putting a paragraph header * into the output buffer based on the information in the * header options buffer that is passed in. * Parms: hptr - Pointer to header information we will use * Returns: Nothing. * Date: 1 December 1988 * Author: E. Scott Daniels * * Modified: 30 Jun 1994 - Conversion to rfm (not much changed) * 15 Dec 1994 - To seperate skip before/after numbers. * 18 Jul 2016 - Add consistent, and sometimes modern, prototypes. ************************************************************************** */ extern void FMheader( struct header_blk *hptr ) { int len; /* len of parm token */ int j; /* index variables */ int i; char buf[80]; /* buffer to build paragraph number in */ char *tbuf; /* pointer at temporary buffer to hold out buf string */ char *ptr; /* pointer to header string */ int oldlmar; /* temp storage for left mar value */ int oldsize; /* temp storage for text size value */ int oldlen; /* temp storage for old line length */ char *oldfont; /* pointer to old font sring */ int skip; /* number of lines to skip before continuing */ TRACE( 2, "header: level=%d saving: len=%d lmar=%d textsize=%d\n", hptr->level, linelen, lmar, textsize ); FMflush( ); /* flush the current line */ pnum[(hptr->level)-1] += 1; /* increase the paragraph number */ for( i = hptr->level; i < MAX_HLEVELS; i++ ) pnum[i] = 0; /* zero out all lower p numbers */ sprintf( buf, "<h%d>", hptr->level ); /* build html tag at runtime */ strcat( obuf, buf ); optr += 4; /* add header tag and scoot past it */ if( hptr->level == 1 && (flags & PARA_NUM) ) fig = 1; /* restart figure numbers */ if( flags & PARA_NUM ) /* number the paragraph if necessary */ { sprintf( buf, "%d.%d.%d.%d", pnum[0], pnum[1], pnum[2], pnum[3] ); for( i = 0, j = 0; j < hptr->level; j++, i++ ) { for( ; buf[i] != '.' && buf[i] != EOS; i++, optr++ ) obuf[optr] = buf[i]; /* copy in the needed part of the number */ if( buf[i] != EOS ) obuf[optr++] = '.'; /* put in the dot */ } /* end for j */ obuf[optr++] = BLANK; /* seperate with a blank */ } while( (len = FMgetparm( &ptr )) > 0 ) /* get next token in string */ { for( i = 0; i < len; i++, optr++ ) { if( hptr->flags & HTOUPPER ) /* xlate to upper flag for this header */ obuf[optr] = toupper( ptr[i] ); else obuf[optr] = ptr[i]; /* copy in the buffer */ } obuf[optr++] = BLANK; /* add an additional blank */ } obuf[optr] = EOS; /* terminate the header string */ /* the call to FMtoc must be made while the header is in obuf */ if( hptr->flags & HTOC ) /* put this in table of contents? */ FMtoc( hptr->level ); /* put entry in the toc file */ #ifdef NOT_IN_HFM oldlen = linelen; /* save the line length */ oldlmar = lmar; /* save left margin */ oldfont = curfont; /* save current text font */ oldsize = textsize; /* save old text size */ textsize = hptr->size / 4; /* set text size to header size for flush */ curfont = hptr->font; /* set font to header font for flush */ #endif sprintf( buf, "</h%d>", hptr->level ); /* end of header */ strcat( obuf, buf ); optr += strlen( buf ); FMflush( ); /* writeout the header line */ #ifdef NOT_IN_HTM linelen = oldlen; /* restore line length */ lmar = oldlmar; /* restore left margin value */ textsize = oldsize; /* restore text size */ curfont = oldfont; /* restore font too */ #endif for( optr = 0, i = 0; i < hptr->indent; i++, optr++ ) /* indent */ obuf[optr] = BLANK; obuf[optr] = EOS; /* terminate incase flush called */ osize = hptr->indent; /* set size of blanks */ }
extern void FMcell( int parms ) { char buf[256]; char buf2[256]; char colour[50]; /* buffers to build various style or parms in */ char span[50]; char rspan[50]; char align[50]; char valign[50]; char width[50]; int len; char *ptr; span[0] = 0; align[0] = 0; buf[0] = 0; buf2[0] = 0; rspan[0] = 0; valign[0] = 0; width[0] = 0; sprintf( valign, "valign=top;" ); /* this is ok in html 4.0 */ if( ! table_stack || ! ts_index ) { while( parms && (len = FMgetparm( &ptr )) != 0 ); return; } if( table_stack[ts_index-1]->bgcolour ) sprintf( colour, "bgcolor=%s", table_stack[ts_index-1]->bgcolour ); else colour[0] = 0; colour[0] = 0; FMflush( ); /* flush what was in the buffer first */ FMele_stack( ES_POP, ET_COL ); /* pop the last column marker and other lower priority elements that are below */ if( ++curcell > MAX_CELLS ) curcell = 1; while( parms && (len = FMgetparm( &ptr )) != 0 ) { switch( *ptr ) { case 'a': snprintf( align, sizeof( align ), "align=%s", ptr + 2 ); break; case 'c': //sprintf( colour, "bgcolor=%s", ptr + 2 ); snprintf( colour, sizeof( colour ), "background-color: %s;", ptr+2 ); break; case 'r': snprintf( rspan, sizeof( rspan ), "rowspan=%s", ptr + 2 ); break; case 's': snprintf( span, sizeof( span ), "colspan=%s", ptr + 2 ); break; case 't': /* really does not make sense to support this */ break; case 'v': snprintf( valign, sizeof( valign ), "valign=%s", ptr + 2 ); /* this is ok in html 4.0 */ break; default: break; } } if( tableinfo && tableinfo[curcell] ) sprintf( width, "width: %d%%;", (tableinfo[curcell]*100)/PG_WIDTH_PTS ); //sprintf( buf2, " width=%d%%>", (tableinfo[curcell]*100)/PG_WIDTH_PTS ); //sprintf( buf, "<td %s %s %s %s %s", colour, span, valign, align, rspan ); sprintf( buf, "<td %s %s %s %s style=\"%s; color: %s; %s font-size: %dpx; font-family: %s;\">", align, valign, span, rspan, width, textcolour, colour, textsize, curfont ); FMele_stack( ES_PUSH, ET_COL ); strcat( buf, buf2 ); AFIwrite( ofile, buf ); flags2 &= ~F2_SETFONT; }
/* ************************************************************************** * * Mnemonic: FMfigure * Abstract: This routine places a blank line and then the word "figure" * and figure number into the file. The line following this * line will contain the user input statement if entered on the * command line. This routine should later be modified to contain * the logic if a figure table will ever be generated. Figure * numbers are the section number followed by a sequential number. * Parms: None. * Returns: Nothing. * Date: 9 December 1988 * Author: E. Scott Daniels * * * .fg [n=number] [t=type] <text> * type is either table or figure, default is figure. * * Modified: 30 Oct 1992 - To reduce figure text size by two from current size * 26 May 1993 - To reduce space between figure text lines. * 22 Feb 1994 - To ensure text font is set properly * 04 Mar 2014 - To allow for preallocation of figure numbers and * to support their use on the .fg command * 17 Jul 2016 - Changes for better prototype generation. ***************************************************************************** */ extern void FMfigure( void ) { int i; /* loop index and parameter length */ char *buf; /* pointer at parameter list entered */ int oldspace; /* old text space value */ char *oldfont; /* hold old font to restore at end */ int oldsize; /* hold old text size to restore at end */ int fnum = -1; /* possible number from the command */ int tok_len; char *cp; char *type = "Figure"; int *num_src; /* pointer to source for table or figure number */ num_src = &fig; /* default to using figure number */ FMflush( ); /* end current working line */ osize = 0; /* reset line size */ oldspace = textspace; /* save stuff we need to restore when leaving */ oldfont = curfont; /* save old font for later */ oldsize = textsize; /* save old size for end */ flags2 |= F2_SETFONT; /* force flush to select our figure font */ textsize -= 2; /* set to size for the font string */ curfont = ffont == NULL ? curfont : ffont; /* set figure font if there */ tok_len = FMgetparm( &buf ); while( tok_len >0 && (cp = strchr( buf, '=' )) != NULL ) { switch( *buf ) { case 'n': // use this figure number fnum = atoi( cp+1 ); break; case 't': // set type (figure or table) if( *(cp+1) == 't' ) { type = "Table"; num_src = &table_number; // refrence the correct table number if needed } break; } tok_len = FMgetparm( &buf ); } if( fnum < 0 ) // not set on the command line { fnum = *num_src; // pull from proper spot and bump up (*num_src)++; } if( flags & PARA_NUM ) /* if numbering the paragraphs, add it to the number */ sprintf( obuf, "%s %d-%d: ", type, pnum[0], fig ); else sprintf( obuf, "%s %d: ", type, fig ); /* gen fig number */ optr = strlen( obuf ); /* set pointer to be past the label */ while( tok_len > 0 ) // add tokens, first already in the buffer { FMaddtok( buf, tok_len ); /* add it to the output buffer */ tok_len = FMgetparm( &buf ); } optr = 1; /* this will cause flush to flush figure information */ FMflush( ); /* send user line on the way */ flags2 |= F2_SETFONT; /* next flush will restore the font */ textspace = oldspace; /* restore original text space value */ textsize = oldsize; /* restore the size that was set on entry */ curfont = oldfont; /* restore the font set on entry */ }
/* ***************************************************************************** * * Mnemonic: fmfloat_mar * Abstract: This module contains functions that support the floating margin * capaibilities. * Date: 01 January 2016 * Author: E. Scott Daniels * Mods: * 17 Jul 2016 - Bring decls into the modern world. * * .fm [i=distance] [w=distance] l=distance [y=yvalue] * l = temp left margin indention from current left margin * w = temp column width (-value subtracts from current width) * l = distance before resetting to original values (auto at col end if l > max y) * y = sets the current y position to this value * .fm pop .** pop the current float and set y to the reset value ***************************************************************************** */ extern void FMfloat_mar( void ) { char *ebuf; // input buffer char *buf; // pointer to info in input buffer int length = 0; // length of floating margins (default to end of col) int new_lmar = 0; // temporary left margin value int new_width = 0; // temporary width value int plen; // parameter token length int top_y = 0; // top y if set woth y= FMflush( ); // ensure last bits flushed out new_width = linelen; new_lmar = lmar; while( (plen = FMgetparm( &buf )) > 0 ) { switch( buf[0] ) { case 'l': case 'L': length = FMgetpts( &buf[2], plen-2 ); // get distance break; case 'w': // line length case 'W': if( buf[2] == '+' || buf[2] == '-' ) { new_width += FMgetpts( &buf[2], plen-2 ); } else { new_width = FMgetpts( &buf[2], plen-2 ); } break; case 'i': // indention case 'I': if( buf[2] == '+' || buf[2] == '-' ) { new_lmar += FMgetpts( &buf[2], plen-2 ); } else { new_lmar = FMgetpts( &buf[2], plen-2 ); } break; case 'p': if( strncmp( buf, "pop", 3 ) == 0 ) { if( cur_col->flags & CF_TMP_MAR ) { lmar = cur_col->olmar; linelen = cur_col->olinelen; cur_col->flags &= ~ CF_TMP_MAR; // reset flag, set cury and boogie out cury = cur_col->revert_y; } return; } else { FMmsg( E_UNKNOWNPARM, buf ); FMignore( ); return; } case 'y': case 'Y': top_y = FMgetpts( &buf[2], plen-2 ); if( length == 0 ) // length not set we'll force it length = cury - top_y; cury = top_y; break; default: FMmsg( E_UNKNOWNPARM, buf ); // let them know they buggered something FMignore( ); return; } } if( cur_col->flags & CF_TMP_MAR ) { // cannot be nested FMmsg( E_PARMOOR, "floating margin is already set" ); return; } if( new_width == linelen ) { // width wasn't adjusted if( new_lmar == lmar ) return; // nothing changed, just bail silently new_width -= new_lmar - lmar; // shrink width by indention amount } if( new_width <= 0 ) { char mbuf[1024]; snprintf( mbuf, sizeof( mbuf ), "width is too small: %d", new_width ); FMmsg( E_PARMOOR, mbuf ); return; } TRACE( 1, "floating mar: cury=%d new_lmar=%d new_linelen=%d revert=%d\n", cury, new_lmar, new_width, cury+length ) cur_col->olmar = lmar; cur_col->olinelen = linelen; cur_col->flags |= CF_TMP_MAR; lmar = new_lmar; linelen = new_width; cur_col->revert_y = cury + length; return; }
extern void FMcell( int parms ) { struct table_mgt_blk *t; int span = 1; /* number of defined columns to span */ char buf[256]; char buf2[256]; char colour[50]; /* buffer to build bgcolor= string in */ char rspan[50]; /* buffer to build rowspan= string in */ char align[50]; /* buffer for align= string */ char valign[50]; /* buffer for align= string */ int len; char *ptr; align[0] = 0; buf[0] = 0; buf2[0] = 0; rspan[0] = 0; valign[0] = 0; colour[0] = 0; sprintf( valign, "valign=top" ); if( ts_index <= 0 || (t = table_stack[ts_index-1]) == NULL ) { char *b; while( (len = FMgetparm( &b )) != 0 ); /* just dump the record */ return; } FMflush( ); /* flush what was in the buffer first */ /* at this point we recognise but ignore some hfm things */ while( parms && (len = FMgetparm( &ptr )) != 0 ) switch( *ptr ) { case 'a': sprintf( align, "align=%s", ptr + 2 ); break; case 'c': if( strncmp( ptr, "class=", 6 ) == 0 ) /* ignore hfm class */ break; sprintf( colour, "bgcolor=%s", ptr + 2 ); break; case 'r': sprintf( rspan, "rowspan=%s", ptr + 2 ); break; case 's': span = atoi( ptr+2 ); break; case 't': /* really does not make sense to support this */ break; case 'v': sprintf( valign, "valign=%s", ptr + 2 ); break; default: break; } 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 */ TRACE(2, " table/cell: cury=%d textsize=%d textspace=%d font=%s boty=%d topy=%d maxy=%d\n", cury, textsize, textspace, curfont, boty, topy, table_stack[ts_index-1]->maxy ); if( cury > table_stack[ts_index-1]->maxy ) table_stack[ts_index-1]->maxy = cury; if( cur_col->next != NULL ) /* if this is not the last in the table */ cur_col = cur_col->next; /* then select it */ else cur_col = firstcol; cury = topy; lmar = cur_col->lmar + t->padding; /* set lmar based on difference calculated */ hlmar = cur_col->lmar + t->padding; /* earlier and next columns left edge */ if( lilist != NULL ) /* if list then reset xpos for next col */ lilist->xpos = cur_col->lmar + t->padding; if( span < 1 ) span = 1; linelen = 0; while( span ) { linelen += cur_col->width; if( --span && cur_col->next ) /* still more to span */ { cur_col = cur_col->next; cur_col->flags |= CF_SKIP; } } linelen -= t->padding; }