Metropoli BBS
VIEWER: irithlp.c MODE: TEXT (ASCII)
/*****************************************************************************
*   Documentation processor of IRIT- a 3d solid modeller.		     *
******************************************************************************
* Usage:								     *
*   Irit [-t] [-l] [-h] [-o OutFileName] [-z] [InFileName]		     *
*									     *
* Written by:  Gershon Elber				Ver 1.0, Nov. 1991   *
*****************************************************************************/

#ifdef __MSDOS__
#include <stdlib.h>
#endif /* __MSDOS__ */

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define TRUE		1
#define FALSE		0
#define LINE_LEN	128
#define MAX_ARRAY_SIZE	128

typedef enum {
    UNDEFINED_DOC_PROCESS = 0,

    PLAIN_TEXT_DOCS,
    LATEX_DOCS,
    IRIT_HELP_DOCS
} DocProcessType;

void ProcessFiles(FILE *Fin, FILE *Fout, DocProcessType OutputDocType);
void FilterLatexMods(char *Line1, char *Line2);

/*****************************************************************************
*   Main module - process command line optionsd modeller.		     *
*****************************************************************************/
void
#ifdef __MSDOS__
cdecl
#endif /* __MSDOS__ */
main(int argc, char **argv)
{
    FILE
	*Fin = stdin,
	*Fout = stdout;
    DocProcessType
	OutputDocType = UNDEFINED_DOC_PROCESS;

    while (argc > 1) {
	if (strcmp(argv[1], "-t") == 0) {
	    OutputDocType = PLAIN_TEXT_DOCS;
	    argc--;
	    argv++;
	}
	else if (strcmp(argv[1], "-l") == 0) {
	    OutputDocType = LATEX_DOCS;
	    argc--;
	    argv++;
	}
	else if (strcmp(argv[1], "-h") == 0) {
	    OutputDocType = IRIT_HELP_DOCS;
	    argc--;
	    argv++;
	}
	else if (strcmp(argv[1], "-o") == 0) {
	    if ((Fout = fopen(argv[2], "w")) == NULL) {
		fprintf(stderr, "Failed to open \"%s\".\n", argv[2]);
		exit(1);
	    }
	    argc -= 2;
	    argv += 2;
	}
	else if (strcmp(argv[1], "-z") == 0) {
	    fprintf(stderr, "Usage: IritHlp [-t] [-l] [-h] [-o OutFileName] [-z] [InFileName].\n");
	    exit(0);
	}
	else
	    break;
    }

    if (argc > 1) {
	if ((Fin = fopen(argv[1], "r")) == NULL) {
	    fprintf(stderr, "Failed to open \"%s\".\n", argv[2]);
	    exit(1);
	}
    }

    if (OutputDocType == UNDEFINED_DOC_PROCESS) {
	fprintf(stderr, "One of [-t] [-l] [-h] must be specified.\n");
	exit(1);
    }

    ProcessFiles(Fin, Fout, OutputDocType);

    fclose(Fin);
    fclose(Fout);

    exit(0);
}

/*****************************************************************************
*   Reads lines from Fin and dumps them to Fout after the following	     *
* processing take place:						     *
* Allways:						       		     *
*    a. Lines start with ';' are ignored ans skipped (comments).	     *
*    b. Lines start with '#' followed by four ingeters (indentation,         *
*       # elements per line, a Boolean to specify vertical seperator, and    *
*       a Boolean flag on the row (TRUE) or col (FALSE) entries order)	     *
*       signifies an array. All entries, one per line are part of the array  *
*       until another '#' occurs. Each of the method below should do its     *
*       best to create such an array.					     *
* 1. OutputDocType = PLAIN_TEXT_DOCS					     *
*    a. Lines start with '@' are ignored.				     *
*    b. Lines start with '!' are echoed as is with underline.		     *
*    c. Lines start with '$' are ignored.				     *
*    c. Lines start with '&' are echoed as is with underline.		     *
*    d. Other lines are dumped out as is after filtering out of '{\cmd * }'  *
*       latex modifiers.						     *
*    e. all lines are dumped out without their first character.		     *
* 2. OutputDocType = LATEX_DOCS						     *
*    a. Lines start with '@' are echoed as is.				     *
*    b. Lines start with '!' are ignored.				     *
*    c. Lines start with '$' are ignored.				     *
*    d. Lines start with '&' are ignored.				     *
*    e. Other lines are dumped out as is.				     *
*    f. all lines are dumped out without their first character.		     *
* 3. OutputDocType = IRIT_HELP_DOCS					     *
*    a. Lines start with '@' are ignored.				     *
*    b. Lines start with '!' are dumped out as is.			     *
*    c. Lines start with '$' causes echoing of the '$' in a single line.     *
*    d. Lines start with '&' are ignored.				     *
*    e. Other lines are dumped out as is after filtering out of '{\cmd * }'  *
*       latex modifiers.						     *
*    f. all lines are dumped out with their first character as in input.     *
*****************************************************************************/
void ProcessFiles(FILE *Fin, FILE *Fout, DocProcessType OutputDocType)
{
    int i, j,
	LineNum = 0;
    char Line1[LINE_LEN], Line2[LINE_LEN], *p;

    while (fgets(Line1, LINE_LEN - 1, Fin) != NULL) {
	LineNum++;
	if (Line1[0] == ';') continue;

	if (Line1[0] == '#') {             /* Beginning of array definition. */
	    static char ArrayEntries[MAX_ARRAY_SIZE][LINE_LEN];
	    int i, j, k,
		Indentation, NumPerLine, VertSep, NumLines, EntriesRowBased,
		StartLineNum = LineNum,
		NumArrayEntries = 0;

	    if (sscanf(&Line1[1], "%d %d %d %d",
		       &Indentation, &NumPerLine,
		       &VertSep, &EntriesRowBased) != 4) {
		fprintf(stderr, "Four integers expected in line %d\n", LineNum);
		exit(1);
	    }

	    /* Gets all the entries of the array: */
	    while ((p =	fgets(ArrayEntries[NumArrayEntries++],
						LINE_LEN - 1, Fin)) != NULL &&
		   p[0] != '#' &&
		   NumArrayEntries < MAX_ARRAY_SIZE) {
		p += strlen(p);		      /* Remove the EOL from string. */
		while (*--p < ' ');
		p[1] = 0;

		LineNum++;
            }
	    NumArrayEntries--;

	    if (p[0] != '#') {
		fprintf(stderr,
			"Array at line %d too large (max %d) or missing '#'.\n",
			StartLineNum, MAX_ARRAY_SIZE);
		exit(1);
	    }

	    /* Now we have all the array elements. Computes how many lines   */
	    /* need and print the lines in the format this documentation is  */
	    /* suppose to be in.					     */
	    NumLines = (NumArrayEntries + NumPerLine - 1) / NumPerLine;
	    switch (OutputDocType) {
		case PLAIN_TEXT_DOCS:
		    sprintf(Line2, "%%-%ds", Indentation);
		    fprintf(Fout, "\n");
		    for (i = 0; i < NumLines; i++) {
			k = EntriesRowBased ? i * NumPerLine : i;
			fprintf(Fout, "   ");
			for (j = 0; j < NumPerLine; j++) {
			    if (k >= NumArrayEntries)
				fprintf(Fout, Line2, "");
			    else {
				FilterLatexMods(ArrayEntries[k],
						ArrayEntries[k]);
				fprintf(Fout, Line2, &ArrayEntries[k][1]);
			    }
			    k += EntriesRowBased ? 1 : NumLines;
			}
			fprintf(Fout, "\n");
		    }
		    fprintf(Fout, "\n");
		    break;
		case LATEX_DOCS:
		    fprintf(Fout,
			    "\n\n\\smallskip\n\n\\begin{center}\n    \\begin{tabular}{|");
		    if (VertSep)
			for (i = 0; i < NumPerLine; i++)
			    fprintf(Fout, "|l");
		    else {
			fprintf(Fout, "|");
			for (i = 0; i < NumPerLine; i++)
			    fprintf(Fout, "l");
		    }
		    fprintf(Fout,"||} \\hline \\hline\n");

		    for (i = 0; i < NumLines; i++) {
			k = EntriesRowBased ? i * NumPerLine : i;
			fprintf(Fout, "\t");
			for (j = 0; j < NumPerLine; j++) {
			    fprintf(Fout, "%s %s ",
				    k < NumArrayEntries ? &ArrayEntries[k][1] : "",
				    j == NumPerLine - 1 ? "\\\\\n" : "&");
			    k += EntriesRowBased ? 1 : NumLines;
			}
		    }
		    fprintf(Fout,
			    "\t\\hline\n    \\end{tabular}\n\\end{center}\n\n\\smallskip\n\n");
		    break;
		case IRIT_HELP_DOCS:
		    sprintf(Line2, "%%-%ds", Indentation);
		    fprintf(Fout, "\n");
		    for (i = 0; i < NumLines; i++) {
			k = EntriesRowBased ? i * NumPerLine : i;
			fprintf(Fout, "   ");
			for (j = 0; j < NumPerLine; j++) {
			    if (k >= NumArrayEntries)
				fprintf(Fout, Line2, "");
			    else {
				FilterLatexMods(ArrayEntries[k],
						ArrayEntries[k]);
				fprintf(Fout, Line2, &ArrayEntries[k][1]);
			    }
			    k += EntriesRowBased ? 1 : NumLines;
			}
			fprintf(Fout, "\n");
		    }
		    fprintf(Fout, "\n");
		    break;
	    }

	    continue;
	}

	switch (OutputDocType) {
	    case PLAIN_TEXT_DOCS:
		switch (Line1[0]) {
		    case '@':
		    case '$':
			break;
		    case '&':
		    case '!':
		    	j = (78 - (int) strlen(&Line1[1])) / 2;
		    	for (i = 0; i < j; i++) fprintf(Fout, " ");
			fprintf(Fout, "%s", &Line1[1]);
		    	for (i = 0; i < j; i++) fprintf(Fout, " ");
			for (i = 1; i < (int) strlen(&Line1[1]); i++)
			    fprintf(Fout, "-");
			fprintf(Fout, "\n");
			break;
		    default:
			fprintf(stderr,
			    "Undefine first char command at line %d.\n",
			    LineNum);
			/* Let it print without the first char... */
		    case 0:
		    case 10:
		    case 13:
		    case ' ':
			FilterLatexMods(Line1, Line2);
			fprintf(Fout, "%s", &Line2[1]);
			break;
		}
		break;
	    case LATEX_DOCS:
		switch (Line1[0]) {
		    case '!':
		    case '$':
		    case '&':
			break;
		    case '@':
			fprintf(Fout, "%s", &Line1[1]);
			break;
		    default:
			fprintf(stderr,
			    "Undefine first char command at line %d.\n",
			    LineNum);
			/* Let it print without the first char... */
		    case ' ':
		    case 0:
    		    case 10:
		    case 13:
			fprintf(Fout, "%s", Line1[1] == 0 ? "\n" : &Line1[1]);
			break;
		}
		break;
	    case IRIT_HELP_DOCS:
		switch (Line1[0]) {
		    case '@':
		    case '&':
			break;
		    case '!':
			fprintf(Fout, "%s",  &Line1[1]);
			break;
		    case '$':
			fprintf(Fout, "$\n");
			break;
		    default:
			fprintf(stderr,
			    "Undefine first char command at line %d.\n",
			    LineNum);
			/* Let it print without the first char... */
		    case ' ':
		    case 0:
		    case 10:
		    case 13:
			FilterLatexMods(Line1, Line2);
			fprintf(Fout, "%s", &Line2[1]);
			break;
		}
		break;
	}
    }
}

/*****************************************************************************
* Filters out expression of the form '{\cmd * }' in Line1 into '*' in line2. *
* These are latex modifiers not wanted in plain text output.		     *
*   Also are filtered out any \? to ?, any $*$ to * and \verb+^+ to ^.       *
*   A space is forced as first char in line.				     *
*****************************************************************************/
void FilterLatexMods(char *Line1, char *Line2)
{
    int i = 0,
	j = 0,
	InModifier = FALSE;
    char Line3[LINE_LEN];

    Line3[j++] = ' ';

    while (Line1[i]) {
	if (Line1[i] == '{' && Line1[i + 1] == '\\' && !isspace(Line1[i + 2])) {
	    /* Here is one - filter it out. */
	    while (!isspace(Line1[i++]));
	    while (isspace(Line1[i++]));
	    i--;
	    InModifier = TRUE;
	}
	else if (Line1[i] == '}' && InModifier) {
	    i++;
	    InModifier = FALSE;
	}
	else if (strncmp(&Line1[i], "\\verb+^+", 8) == 0) {
	    i += 8;
	    Line3[j++] = '^';
	}
	else if (Line1[i] == '\\') {
	    i++;
	}
	else if (Line1[i] == '$' && i > 0) {
	    i++;
	}
	else
	    Line3[j++] = Line1[i++];
    }
    Line3[j] = 0;
    strcpy(Line2, Line3);
}

[ RETURN TO DIRECTORY ]