ftp.nice.ch/pub/next/text/framemaker/filters/la2mml.tar.gz#/la2mml.c

This is la2mml.c in view mode; [Download] [Up]

/* la2mml.c */

/*
 * Copyright (c) 1991  R. Nigel Horspool.
 * All rights reserved.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <stdio.h>
#include <ctype.h>
#ifdef THINK_C
#include <stdlib.h>
#endif

#include "tables.h"
#include "lexer.h"
#include "output.h"
#include "auxprocs.h"
#include "la2mml.h"



FILE *outputfile;		/* descriptor for output */
char *outputfilename;

int numreports = 0;
BOOL unknowns = FALSE;		/* if true, report "\xxx" commands
				   that are not in the tables (really
				   a debugging option) */

TEXTMODE curr_matching_mode = PARA;
char *paratag = NULL;

#ifndef THINK_C
/*  definitions for non-int external functions  */
extern char *malloc(), *strcpy(), *strcat();
#endif



void OOPS( char *msg ) {
    if (msg != NULL) perror( msg );
    abort();
}


/* Print the current filename and linenumber --
   used just before printing an error message.	*/
void LN() {
    if (!filenameprinted) {
	FPR(stderr, "File %s:\n", filename );
	filenameprinted = TRUE;
    }
    FPR(stderr, "%4d:\t", linenum );
    numreports++;
}


/*  Returns the name of the current text processing mode  */
char *modename( TEXTMODE mode ) {
    switch( mode ) {
    case MATH:		return "math";
    case PARA:		return "para or lr";
    case MATHARRAY:	return "math array";
    case TABLE:		return "table";
    case VERBATIM:	return "verbatim";
    }
    return "??";
}


void match_opt_arg() {
    SKIPWSPACE();
    if (ch == '[') {
	readch();
	match_grouping( RSQ );
    }
}


void handle_environment( ENVPTR newenv, TOKEN terminator ) {
    ENVPTR prev_env = curr_env;
    TEXTMODE prev_mode = curr_matching_mode;
    BOOL save_first = firstitem;
    ACTIONPTR meptr;
    int ln = linenum;
    char *savedfamily = nextfamily;
    short savedfont = nextfont;
    int savedsize = nextsize;

    curr_env = newenv;
    GProc(newenv->startcmd);
    curr_matching_mode = newenv->kind;
    if ( newenv->kind == VERBATIM ) {
	for( ; ; ) {
	    readch();
	    while ( ch == '\\') {
		static char *endtext = "\\end{verbatim}";
		register int i, j;

		for( i = 0;  ch == endtext[i];  i++ )
		    readch();
		if (i >= strlen(endtext)) goto EXIT; 
		for( j = 0;  j < i;  j++ )
		    copychar( endtext[j] );
	    }
	    if (ch == EOF) {
		linenum = ln;
		LN();
		FPR(stderr, "unclosed \\begin{verbatim} command\n" );
		goto EXIT;
	    }
	    if (ch == '\n')
		newline();
	    else if (ch != ' ')
		copychar(ch);
	    else
		appendstring( "\\x11  " );
	}
    } else {
	if (terminator == RBRACE) {	/* special case! */
	    meptr = get_token();
	    if (GProc(meptr->code) != LBRACE) goto EXIT;
	}
	match_grouping( terminator );
    }

EXIT:
    firstitem = save_first;
    GProc( newenv->endcmd );
    nextfamily = savedfamily;  nextfont = savedfont;  nextsize = savedsize;
    if (newenv->conttag != NULL)
	register_tag( prev_env->conttag );
    curr_matching_mode = prev_mode;
    curr_env = prev_env;
}


void report_bad_usage( char *text ) {
    LN();
    FPR(stderr, "inappropriate use of %s inside %s mode text\n",
	text, modename(curr_matching_mode) );
}


void match_one_unit() {
    ACTIONPTR meptr;

    meptr = get_token();
    if (GProc(meptr->code) == LBRACE)
	match_grouping( RBRACE );   
}


void skip_arg() {
    ACTIONPTR meptr;
    register int nesting = 0;
    register char *cp;

    do {
	meptr = get_token();
	cp = meptr->cmd;
	if (cp[0] == '{' && cp[1] == '\0')
	    nesting++;
	else if (cp[0] == '}' && cp[1] == '\0')
	    nesting--;
    } while( nesting > 0 );
}



void match_grouping( TOKEN terminator ) {
    TOKEN cmd;
    int ln = linenum;
    ACTIONPTR meptr;
    ENVPTR ep;
    short savefont = nextfont;
    short savesize = nextsize;
    char *savefamily = nextfamily;

    for( ; ; ) {
	meptr = (ACTIONPTR)get_token();
	cmd = GProc(meptr->code) ;

	switch( cmd ) {

	case LSQCMD:
	    handle_environment( displaymath_env, RSQCMD );
	    continue;

	case LPARCMD:
	    handle_environment( math_env, RPARCMD );
	    continue;

	case LBRACE:
	    match_grouping( RBRACE );
	    continue;

	case DOLLAR_START:
	    handle_environment( math_env, DOLLAR_END );
	    continue;

	case DOLLARDOLLAR_START:
	    handle_environment( math_env, DOLLARDOLLAR_END );
	    continue;

	case OTHER:
	    continue;

	}

	if (cmd == terminator)
	    goto EXIT;
	
	if (cmd == RSQ) {
	    copychar( ']' );
	    continue;
	}

	/*  all correct tokens have been handled and
	    control returned to the top of the loop
	    via a continue.  If control reaches here,
	    there is an error.  */
	if (cmd == EOFCMD) {
	    linenum = ln;
	    LN();
	    FPR(stderr, "construct unclosed when end-of-file reached\n" );
	    goto EXIT;
	}
	switch( cmd ) {
	case EOFCMD:
	case RSQCMD:
	case RPARCMD:
	case ENDCMD:
	case RBRACE:
	case DOLLAR_END:
	case DOLLARDOLLAR_END:
	case RSQ:
	    LN();
	    FPR(stderr, "%s mismatched with construct started on line %d\n",
		meptr->cmd, ln );
	    return;
	}
	report_bad_usage( meptr->cmd );
    }
EXIT:
    nextfont = savefont;  nextfamily = savefamily;  nextsize = savesize;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.