/***************************************************************************** * 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 #endif /* __MSDOS__ */ #include #include #include #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); }