/*************************************************************
 *
 * txttomif.c
 * 
 * principal author - drf -
 * Copyright 1987, Frame Technology Corporation. 
 * 
 * Post 1.11 Modification history:  
 *  06 Dec 87 drf - Match Maker 1.12 MIF format
 * 
 **************************************************************/
static char cpy[] = "(c)1987FrameTechnologyCorp";

/*
	This program converts a plain-old-text file into a MIF file suitable
	to be input to Maker.  By putting the executable into the Maker bin.*
	directories, and making sure that both "suffixlist" and "MakerFilter"
	(in the .makerinit directory) have appropriate entries, we can cause
	Maker to automatically run this program as a filter whenever a file
	who's name ends with ".txt" is opened (or imported).  Indeed, this
	program is meant to server as a simple model of how other input
	filters can be written and installed.

	This program attempts to retain just a little bit of formatting
	information; specifically, we try to get paragraphs to come out right.
	Just a simple heuristic is used, so it's not perfect, but it's quite
	predictable and it's correct most of the time.  In particular, extra
	white space after a newline causes a new paragraph to be started, where
	"white space" means "tabs, spaces, and newlines".  Thus, two
	newlines in a row cause a paragraph to be started, as does any kind of
	indentation.  All the white space in front of a paragraph is eaten up,
	so there are no empty paragraphs produced.

	MIF files output by this program contain a call implicitly include
	the contents of the file "txttomif.m4" which contains formatting 
	control information.  The default version, on .makerinit, can be
	copied to your home directory and customized for other formats.

	Typical changes might include font style and size of the resulting
	maker document.  The main complexity has to do with paragraph
	indentation, however.  When this program detects the beginning of
	a new paragraph, it strips off all the tabs and spaces, but keeps
	track of how many total spaces they account for, and then uses this
	number as part of a special tag name for the paragraph.  Thus, a
	paragraph that starts with no white space is tagged "Indent0",
	while a paragraph that starts with two tabs and two spaces is
	tagged with paragraph type "Indent18", and a paragraph that starts
	with a space, a tab, two spaces, and two tabs is tagged "Indent24"
	(the spaces are rendered invisible by the following tabs).
	Note that the fact that tabs move you up to the next divisible-by-8
	position causes no problem even if you want to get a different
	number of spaces per tab in the output effect: simply change the
	catalog in txttomif.m4 appropriately.

	Control characters are dropped, and a few special characters
	are backslashed, so that Maker will read them properly.

	Input from stdin, output to stdout.

	-drf Nov 16, 1986
*/

#include <stdio.h>


/* 
   Put out a character in a MIF <String>.  Illegal chars are dropped,
   and some funny characters are quoted.
*/

print_a_string_char(c)
	char c;
	{
	switch (c) {
		case '\t': printf("\\t"); break;
		case '>' : printf("\\>"); break;
		case '`' : printf("\\xD4 "); break;
		case '\'' : printf("\\xD5 "); break;
		case '\\': printf("\\\\"); break;
		default:
			if (' '<=c && c<='~') putchar(c);
		}
	}

/*
   The routines below scan the input and always leave the NEXT unprocessed
   character here:
*/

int c;	/* has the next input character to be handled */

/*
   This routine reads a single line of input and puts out MIF for it.
   Spaces at the end of the line are dropped.  On entry, the first character
   is already in "c".  On exit, the first character that's not part of
   the line is left in "c".
*/

do_a_line() {
	int need_space=0; /* number of pending spaces */
	printf("ln `");
	do { /* handle one character */
		if (c==' ')
			need_space++;
		else {
			while (need_space--)
				print_a_string_char(' ');
			need_space=0;
			print_a_string_char(c);
			}
		c=getchar(); /* consume that character */
		} while (c!='\n' && c!=EOF);
	if (c=='\n') c=getchar(); /* consume the NL that ended the line */
	printf(" ' en\n"); /* space to separate us from any text following */
	}

/*
   This routine puts out a whole paragraph, or maybe it just returns if
   there's nothing but skippable white space and an EOF left in the input.
   A paragraph ends when we see white space after a line, or EOF.
   This routine also handles the indentation counting and labelling.
   On entry, the first character is already in "c".  On exit, the first
   character that's not part of the line is left in "c".
*/

do_a_paragraph() {
	int indent=0; char skipping=1;
	while (skipping) {
		switch (c) {
			case ' ' : indent++; break;
			case '\t': indent = (indent+8) & (-8); break;
			case '\n': indent = 0; break;
			default:   skipping=0; break;
			}
		if (skipping) c=getchar();
		}
	if (c==EOF) return; /* return if no paragraph to do */
	printf("pr\n");
	printf("<PgfTag `Indent%2d'>\n",indent);
	do do_a_line(); while (c!=EOF && c!=' ' && c!='\t' && c!='\n');
	printf("ep\n\n");
	}

/*
   Doing the whole thing is easy: just keep doing paragraphs until we find EOF.
*/

main () {
	/* Identify ourselves */
	printf("<MIFFile 1.01> # created by txttomif 1.12\n");
	printf("include(mif_read.m4)\n");

	/* Include the header file */
	printf("include(txttomif.m4)\n");

	/* Macros to begin/end a paragraph */
	printf("define(pr,`<Para')\n");
	printf("define(ep,`>')\n");

	/* Macros to begin/end a line */
	printf("define(ln,`<ParaLine <String')\n");
	printf("define(en,`>>')\n");

	/* Do all the input text */
	c = getchar(); /* prime the buffer */
	while (c!=EOF) do_a_paragraph();

	/* Finish off the MIF file */
	printf("# End of MIFFile\n");
	}


