ftp.nice.ch/pub/next/connectivity/news/NewsBase.3.02.s.tar.gz#/NewsBase302.source/MMEdit/2RFunctions.c

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

/*  

 2RFunctions.c of

 2rtf: a facility to convert files in the ATK file format to
 RTF manuscript files.

 Rtf2 is copyright (c) 1991 by the Massachusetts Institute of
 Technology.

 RTF is a product of the Microsoft Corporation.

 Permission to use, copy, modify, and distribute this software and
 its documentation for any purpose and without fee is hereby granted,
 provided that the above copyright notice and the name of the author(s)
 appear in all copies; that both that copyright notice, the name of
 the author(s) and this permission notice appear in supporting
 documentation; and that the name of the Massachusetts Institute of
 Technology not be used in advertising or publicity pertaining to
 distribution of the software without specific, written prior
 permission.  The Massachusetts Institute of Technology makes no
 representations about the suitability of this software for any purpose.
 It is provided "as is" without express or implied warranty.

 2rtf was written by Scott Rixner, rixner@ATHENA.MIT.EDU and Jeremy Paul Kirby, jpkirby@ATHENA.MIT.EDU

 $Header: /usr2/multimedia/RCS/MMEdit//2RFunctions.c,v 3.2 93/01/08 16:33:40 suzuki Exp $
*/


#include <stdio.h>
#import <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <ctype.h>
#include "2rtf.h"

#define fgetc(x) NXGetc(x)
#define fputc(x,stream) NXPutc(stream,x)
#define fputs(x,stream) NXPrintf(stream,x)
#define ungetc(x,y) NXUngetc(y)
#define fprintf NXPrintf
#define fscanf NXScanf


extern char *makelower();
extern struct TableStruct *Table;
extern struct IdStackStruct *IdStack;
extern struct StyleStackStruct *Style;
struct TableStruct *FindNode();
void CloseFiles();
long int ParseText();
long int richParseText();
void Newlines(), AbsorbNewlines();
int RStyleConvert(), atoi();
FP AssignFunc();
char *GetInstruction();
int RSLMargin(), RSRMargin(), RSTMargin(), RSBMargin(), RSIndent(), RSIpSpacing(), RSAbove(), RSBelow(), RSIlSpacing(), RSFontFamily(), RSFontSize(), RSFontScript(), RSTabChange(), RSFontFace(), RSJustify();
int RNOP(), RDelete(), RError(), RBegin(), RDSVer(), REnd(), RText(), RAnnotation(), RFootnote(), RSkip(), RTitle(), RNewpage(), RTable(), RHeader(), RSize(), RFont(), RTemplate(), RIndent(), RIndex(), RStyleMain(), RScript(), RLeft(), RMajorHeading(), RHeading(), RSubHeading(), RChapter(), RSection(), RSubSection(), RParagraph(), RCaption(), RQuotation(), RDescription(), RExample(), RDisplay(), RVerbatim();
int r_small(), r_big(), r_indent(), r_indentright(), r_script();
int r_heading(), r_footing(), r_excerpt(), r_paragraph();
int r_outdent(), r_outdentright();

FP AssignFunc(rtfword)
     char *rtfword;
/*
 *
 *  Function that returns a pointer to the function
 *  associated with RTFWORD.
 *
 */
{
  static struct func_words fnlist[FUNCTION_SIZE+12] = {
// Mime functions.
      {"r.small",           r_small},
      {"r.big",             r_big},
      {"r.indent",          r_indent},
      {"r.indentright",     r_indentright},
      {"r.outdent",         r_outdent},
      {"r.outdentright",    r_outdentright},
      {"r.script",          r_script},
      {"r.script",          r_script},
      {"r.heading",         r_heading},
      {"r.footing",         r_footing},
      {"r.excerpt",         r_excerpt},
      {"r.paragraph",       r_paragraph},
//
      {"begin",		    RBegin},
      {"caption",	    RCaption},
      {"chapter",	    RChapter},
      {"delete",	    RDelete},
      {"description",	    RDescription},
      {"display",	    RDisplay},
      {"dsver",		    RDSVer},
      {"end",		    REnd},
      {"example",	    RExample},
      {"font",		    RFont},
      {"heading",	    RHeading},
      {"indent",	    RIndent},
      {"index",		    RIndex},
      {"left",		    RLeft},
      {"majorheading",	    RMajorHeading},
      {"nop",		    RNOP},
      {"paragraph",	    RParagraph},
      {"quotation",	    RQuotation},
      {"script",	    RScript},
      {"section",	    RSection},
      {"size",		    RSize},
      {"skip",		    RSkip},
      {"style",		    RStyleMain},
      {"subheading",	    RSubHeading},
      {"subsection",	    RSubSection},
      {"template",	    RTemplate},
      {"title",		    RTitle},
      {"verbatim",	    RVerbatim}
  };
  int i;

  for(i = 0; i < FUNCTION_SIZE+12; i++)
     if(!strcmp(rtfword, fnlist[i].word))
       return(fnlist[i].fname);

  return(RNOP);
}

int r_small(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   long oldfont;

   oldfont = State.CurFontSize;
   State.CurFontSize -= 4;
   fprintf(fout, "{\\fs%d ", State.CurFontSize);
   richParseText(tofind, transform, PRINTTOFILE);

   fputs("}\n", fout);
   State.CurFontSize = oldfont;
   return(0);
}

int r_footing(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   fputs("{\\fs18\\up6 \\chftn {\\footnote \\pard\\plain\n", fout);
   fputs("\\s246 \\fs20 {\\fs18\\up6 \\chftn }", fout);
   richParseText(tofind, transform, PRINTTOFILE);
   fputs("}}\n", fout);
   return(0);
}

int r_excerpt(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   long left, right;
//   char ch;

   left = State.CurLeftIndentation;
   right = State.CurRightIndentation;

   State.CurLeftIndentation += 720;
//   State.CurRightIndentation += 720;
   State.CurRightIndentation += 20;

   if(!paragraph)
      fputs("\\par", fout);
   fprintf(fout, "\\li%d\\ri%d ", State.CurLeftIndentation,
				  State.CurRightIndentation);

   richParseText(tofind, transform, PRINTTOFILE);

//   ch = (char) fgetc(fin);
//   if(ch == '\n' || ch == '\r')
//   {
//       CurrLine++;
//       ch = (char) fgetc(fin);
//       if(ch == '\n' || ch == '\r')
//           Newlines();
//       else
//           ungetc(ch, fin);
//   }
//   else
//       ungetc(ch, fin);
   fprintf(fout, "\\par\\li%d\\ri%d ", left, right);

   State.CurLeftIndentation = left;
   State.CurRightIndentation = right;

   return(0);
}

int r_paragraph(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   richParseText(tofind, transform, PRINTTOFILE);
   return(0);
}

int r_heading(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   char type[TMP_SIZE];
   int header = 0;
   int active;

   fscanf(fin, "\nwhere:%s\n", type);
   if(strcmp(type, "footing"))
      header = 1;

   fscanf(fin, "active:%d\n", &active);
   CurrLine += 3;

   fprintf(fout, "{\\%s \\pard", header ? "header" : "footer");
   fprintf(fout, "\\plain \\s%d", header ? 244 : 243);
   fprintf(fout, "\\tqc\\tx4320\\tqr\\tx8640 ");
   richParseText(tofind, HEADER, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int r_script(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   int up = 0;
   long oldpos;

   oldpos = State.CurScriptMovement;

   if(strcmp(command, "subscript"))
       up = 1;
   if(up)
       State.CurScriptMovement += 6;
   else
       State.CurScriptMovement -= 6;

   fprintf(fout, "{\\%s%d ", up ? "up" : "dn", State.CurScriptMovement);
   richParseText(tofind, transform, PRINTTOFILE);
   fputs("}", fout);

   State.CurScriptMovement = oldpos;

   return(0);
}

int r_indentright(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   long left, right;
   char ch;

   left = State.CurLeftIndentation;
   right = State.CurRightIndentation;

//   State.CurLeftIndentation += 720;
   State.CurLeftIndentation += 0;
   State.CurRightIndentation += 720;

   if(!paragraph)
      fputs("\\par", fout);
   fprintf(fout, "\\li%d\\ri%d ", State.CurLeftIndentation,
				  State.CurRightIndentation);

   richParseText(tofind, transform, PRINTTOFILE);

   ch = (char) fgetc(fin);
   if(ch == '\n' || ch == '\r')
   {
       CurrLine++;
       ch = (char) fgetc(fin);
       if(ch == '\n' || ch == '\r')
           Newlines();
       else
           ungetc(ch, fin);
   }
   else
       ungetc(ch, fin);
   fprintf(fout, "\\par\\li%d\\ri%d ", left, right);

   State.CurLeftIndentation = left;
   State.CurRightIndentation = right;

   return(0);
}

int r_indent(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   long left, right;
   char ch;

   left = State.CurLeftIndentation;
   right = State.CurRightIndentation;

   State.CurLeftIndentation += 720;
//   State.CurRightIndentation += 720;
   State.CurRightIndentation += 0;

   if(!paragraph)
      fputs("\\par", fout);
   fprintf(fout, "\\li%d\\ri%d ", State.CurLeftIndentation,
				  State.CurRightIndentation);

   richParseText(tofind, transform, PRINTTOFILE);

   ch = (char) fgetc(fin);
   if(ch == '\n' || ch == '\r')
   {
       CurrLine++;
       ch = (char) fgetc(fin);
       if(ch == '\n' || ch == '\r')
           Newlines();
       else
           ungetc(ch, fin);
   }
   else
       ungetc(ch, fin);
   fprintf(fout, "\\par\\li%d\\ri%d ", left, right);

   State.CurLeftIndentation = left;
   State.CurRightIndentation = right;

   return(0);
}

int r_outdentright(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   long left, right;
   char ch;

   left = State.CurLeftIndentation;
   right = State.CurRightIndentation;

//   State.CurLeftIndentation += 720;
   State.CurRightIndentation -= 720;
   State.CurRightIndentation += 0;

   if(!paragraph)
      fputs("\\par", fout);
   fprintf(fout, "\\li%d\\ri%d ", State.CurLeftIndentation,
                                  State.CurRightIndentation);

   richParseText(tofind, transform, PRINTTOFILE);

   ch = (char) fgetc(fin);
   if(ch == '\n' || ch == '\r')
   {
       CurrLine++;
       ch = (char) fgetc(fin);
       if(ch == '\n' || ch == '\r')
           Newlines();
       else
           ungetc(ch, fin);
   }
   else
       ungetc(ch, fin);
   fprintf(fout, "\\par\\li%d\\ri%d ", left, right);

   State.CurLeftIndentation = left;
   State.CurRightIndentation = right;

   return(0);
}

int r_outdent(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   long left, right;
   char ch;

   left = State.CurLeftIndentation;
   right = State.CurRightIndentation;

   State.CurLeftIndentation -= 720;
//   State.CurRightIndentation += 720;
   State.CurRightIndentation += 0;

   if(!paragraph)
      fputs("\\par", fout);
   fprintf(fout, "\\li%d\\ri%d ", State.CurLeftIndentation,
                                  State.CurRightIndentation);

   richParseText(tofind, transform, PRINTTOFILE);

   ch = (char) fgetc(fin);
   if(ch == '\n' || ch == '\r')
   {
       CurrLine++;
       ch = (char) fgetc(fin);
       if(ch == '\n' || ch == '\r')
           Newlines();
       else
           ungetc(ch, fin);
   }
   else
       ungetc(ch, fin);
   fprintf(fout, "\\par\\li%d\\ri%d ", left, right);

   State.CurLeftIndentation = left;
   State.CurRightIndentation = right;

   return(0);
}

int r_big(command, transform, tofind)
     char *command;
     int transform, tofind;
{
   long oldfont;

   oldfont = State.CurFontSize;
   State.CurFontSize += 4;
   fprintf(fout, "{\\fs%d ", State.CurFontSize);
   richParseText(tofind, transform, PRINTTOFILE);

//               while((c = fgetc(fin)) != EOF)
//               {
//                  if(c != '<' )
//                  {
//                     ungetc(c, fin);
//                     break;
//                  }
//                  fputc(c, fout);
//               }
   fputs("}\n", fout);
   State.CurFontSize = oldfont;
   return(0);
}

int RDelete(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Function that parses all of the text associated with COMMAND
 *  without processing it or writing it to the output file.
 *
 */
{
   ParseText(tofind, NORMAL, NOP);
   return(0);
}

  
int RNOP(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  NOP function.
 *
 */
{
   return(0);
}

int RError(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Notification of errors.
 *
 */
{
  fprintf(ferr, "* Unknown error!\n* %s: unknown error in input file.\n", me);
   return(0);
}

int RBegin(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  On encountering a \begindata in the ez document, set up
 *  an entry on the IdStack to keep track of the new recursion.
 *  Pass POP_JOB as tofind, which is an identifier that
 *  will be used by enddata to finish the recursion.
 *  Look up the data object to see if there is a function
 *  to handle it, if not, process the text normally.
 *
 */
{
   char type[TMP_SIZE];
   long int id = 0;
   struct IdStackStruct *tmp;
   int i;
   FP function = RNOP;
   static struct func_words typelist[TYPE_SIZE] = {
       {"text",			RText},
       {"note",			RAnnotation},
       {"fnote",		RFootnote},
       {"bp",			RNewpage},
       {"header",		RHeader},
       {"table",		RNOP/*RTable*/}
   };

   fscanf(fin, "%[^,],%ld}", type, &id);

   for(i = 0; i < TYPE_SIZE; i++)
      if(!strcmp(type, typelist[i].word))
      {
         function = typelist[i].fname;
         break;
      }

   tmp = (struct IdStackStruct *) malloc(sizeof(struct IdStackStruct));
   tmp->idnum = id;
   tmp->next = IdStack;
   IdStack = tmp;
   if(function == RNOP)
      ParseText(POP_JOB, transform, PRINTTOFILE);
   else
      function(type, transform, POP_JOB);
   return(0);
}

int REnd(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  On encountering an \enddata in the ez document, check to
 *  see that the id number correctly matches the id number
 *  of the corresponding \begindata, if so pass POP_JOB back
 *  to ParseText() to let it know that the recursion is finished.
 *  This procedure will be called with transform set to
 *  HEADER four times for each headertext data object, and
 *  the first two times, a tab needs to be inserted to keep
 *  consistency with rtf headers.
 *
 */
{
   char type[TMP_SIZE];
   long int id;
   static int headerflag = 0;

   if(transform == HEADER && !headerflag)
      headerflag = 4;

   fscanf(fin, "%[^,],%ld}", type, &id);
   if((IdStack != NULL) && (id == IdStack->idnum))
   {
      IdStack = IdStack->next;
      if(transform == HEADER)
         if(headerflag-- > 2)
            ungetc('\t', fin);
      return(POP_JOB);
   }
   else
   {
      printf("* Improper \\enddata encountered.  Id #: %ld", id);
   }
   return(0);
}

int RDSVer(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Check for correct TextDSVersion.
 *
 */
{
   int version;

   fscanf(fin, "%d}", &version);
   if(version != TextDSVersion)
     ; //fprintf(stderr, "* Error:\n* %s: Wrong TextDSVersion: %d.\n", me, version);
   return(0);
}

int RText(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Process text normally for a text data object.
 *
 */
{
   ParseText(tofind, transform, PRINTTOFILE);
   return(0);
}

int RAnnotation(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Process text for an annotation object by converting it
 *  into hidden text in rtf.
 *
 */
{
   int a, b, c;

   fscanf(fin, "%d %d %d", &a, &b, &c);
   fputs("{\\v ", fout);
   ParseText(tofind, NORMAL, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RFootnote(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Process footnote data object.
 *
 */
{
   fputs("{\\fs18\\up6 \\chftn {\\footnote \\pard\\plain\n", fout);
   fputs("\\s246 \\fs20 {\\fs18\\up6 \\chftn }", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}}\n", fout);
   return(0);
}

int RSkip(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Used for unknown commands, or commands that do nothing
 *  in rtf.  Processes the text associated with the command
 *  as if the command weren't there.
 *
 */
{
   ParseText(tofind, transform, PRINTTOFILE);
   return(0);
}

int RTitle(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Used for the title in an annotation.  This is scripted
 *  into "Author: nnnnnn.  " in rtf.
 *
 */
{
   fputs("Author: ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs(".  ", fout);
   return(0);
}

int RNewpage(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle page break data object.
 *
 */
{
   fputs("\\page ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   return(0);
}

int RHeader(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Headertext data objects - ParseText() with transform
 *  as HEADER, so that enddata knows to insert tabs, and the
 *  ez $ header commands are treated properly.  Styles 243 and
 *  244 are rtf's default footer and header styles.
 *
 */
{
   char type[TMP_SIZE];
   int header = 0;
   int active;

   fscanf(fin, "\nwhere:%s\n", type);
   if(strcmp(type, "footer"))
      header = 1;

   fscanf(fin, "active:%d\n", &active);
   CurrLine += 3;

   fprintf(fout, "{\\%s \\pard", header ? "header" : "footer");
   fprintf(fout, "\\plain \\s%d", header ? 244 : 243);
   fprintf(fout, "\\tqc\\tx4320\\tqr\\tx8640 ");
   ParseText(tofind, HEADER, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RTable(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle processing tables.
 *
 */
{
   return(0);
}

int RSize(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle changes in font sizes.  Increase or decrease
 *  the fontsize, parse the text, then reset the fontsize
 *  to its value before the call.
 *
 */
{
   long oldfont;

   oldfont = State.CurFontSize;

   if(strcmp(command, "smaller"))
       State.CurFontSize += 4;
   else
       State.CurFontSize -= 4;

   fprintf(fout, "{\\fs%d ", State.CurFontSize);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}", fout);

   State.CurFontSize = oldfont;
   return(0);
}

int RScript(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle changes in script location.  Increase of decrease
 *  the script location, parse the text, then reset the
 *  script location to its value before the call.
 *
 */
{
   int up = 0;
   long oldpos;

   oldpos = State.CurScriptMovement;

   if(strcmp(command, "subscript"))
       up = 1;
   if(up)
       State.CurScriptMovement += 6;
   else
       State.CurScriptMovement -= 6;

   fprintf(fout, "{\\%s%d ", up ? "up" : "dn", State.CurScriptMovement);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}", fout);

   State.CurScriptMovement = oldpos;
   return(0);
}

int RFont(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle changes in fonts.  New York is the default
 *  font, and Chicago, Monaco, and Symbol were chosen
 *  for their universal availability on the Mac.
 *
 */
{
   static struct FontStruct fonts[FONT_SIZE] = {
       {"sansserif",	CHICAGO},
       {"typewriter",	MONACO},
       {"symbol",	SYMBOL}
   };
   int i;
   int n = NEW_YORK;

   State.CurFontFamily = "andy";
   for(i=0; i<FONT_SIZE; i++)
      if(!strcmp(command, fonts[i].name))
      {
         n = fonts[i].num;
	 State.CurFontFamily = fonts[i].name;
         break;
      }

   fprintf(fout, "{\\f%d ", n);
   ParseText(tofind, transform, PRINTTOFILE);
   fprintf(fout, "}");
   return(0);
}

int RTemplate(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Currently checks if the template is default.  If
 *  not, it prints an error and continues.  Ultimately
 *  it should send the template file through the style
 *  sheet interpreter.
 *
 */
{
   char temp[TMP_SIZE];

   fscanf(fin, "%[^}]}", temp);
   if(strcmp(temp, "default"))
     printf("Warning, template other than default: %s.\n", temp);
   return(0);
}

int RLeft(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle changes in the left margin.
 *
 *  RTF imposes a paragraph boundry on indent styles.
 *  EZ's redisplay acts wrong when an indent occurs in
 *  the middle of a paragraph:  the left and right indent
 *  displayed conform to the indent in place at the
 *  beginning of the line.  Converting from EZ to RTF
 *  will cut a paragraph in two if an indent is discovered
 *  in the middle of a paragraph.  This is the right thing!
 *
 */
{
   long oldmar;
   char ch;

   oldmar = State.CurLeftIndentation;

   State.CurLeftIndentation += 720;
   if(!paragraph)
       fputs("\\par", fout);
   fprintf(fout, "\\li%d ", State.CurLeftIndentation);
   ParseText(tofind, transform, PRINTTOFILE);

   ch = (char) fgetc(fin);
   if(ch == '\n' || ch == '\r')
   {
       CurrLine++;
       ch = (char) fgetc(fin);
       if(ch == '\n' || ch == '\r')
	   Newlines();
       else
	   ungetc(ch, fin);
   }
   else
       ungetc(ch, fin);
   fprintf(fout, "\\par\\li%d ", oldmar);

   State.CurLeftIndentation = oldmar;
   return(0);
}

int RIndent(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle calls to indent by checking with the left
 *  and right indentations and changing them accordingly.
 *
 *  RTF imposes a paragraph boundry on indent styles.
 *  EZ's redisplay acts wrong when an indent occurs in
 *  the middle of a paragraph:  the left and right indent
 *  displayed conform to the indent in place at the
 *  beginning of the line.  Converting from EZ to RTF
 *  will cut a paragraph in two if an indent is discovered
 *  in the middle of a paragraph.  This is the right thing!
 *
 */
{
   long left, right;
   char ch;

   left = State.CurLeftIndentation;
   right = State.CurRightIndentation;

   State.CurLeftIndentation += 720;
   State.CurRightIndentation += 720;

   if(!paragraph)
      fputs("\\par", fout);
   fprintf(fout, "\\li%d\\ri%d ", State.CurLeftIndentation, State.CurRightIndentation);

   ParseText(tofind, transform, PRINTTOFILE);

   ch = (char) fgetc(fin);
   if(ch == '\n' || ch == '\r')
   {
       CurrLine++;
       ch = (char) fgetc(fin);
       if(ch == '\n' || ch == '\r')
	   Newlines();
       else
	   ungetc(ch, fin);
   }
   else
       ungetc(ch, fin);
   fprintf(fout, "\\par\\li%d\\ri%d ", left, right);

   State.CurLeftIndentation = left;
   State.CurRightIndentation = right;
   return(0);
}

int RIndex(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle visible and invisible index entries.  For
 *  invisible entries, the transform is set to INDEX
 *  so that "++" seperator gets properly parsed into
 *  "\:".
 *
 */
{
   fputs("{\\v {\\xe\\pard\\plain ", fout);
   if(!strcmp(command, "indexi"))
   {
      fputs("{\\v ", fout);
      ParseText(tofind, INDEX, PRINTTOFILE);
      fputs("}}}", fout);
   }
   else
   {
      ParseText(tofind, NORMAL, PRINTTOFILE);
      fputs("}}", fout);
   }
   return(0);
}

int RStyleDefine(style_sheet)
   char *style_sheet;
/*
 *
 *  Parse through the attributes of a style, and use
 *  RStyleConvert() to actually convert each attribute.
 *  Set up a new entry on the StyleStack that contains
 *  the styleid and its associated expansion string.
 *
 */
{
   char name[TMP_SIZE], type[TMP_SIZE],
        p1[TMP_SIZE], p2[TMP_SIZE], p3[TMP_SIZE], p4[TMP_SIZE],
        ch;
   int i, n;
   struct StyleStackStruct *tmp;
   static int styleid = 0;

   tmp = (struct StyleStackStruct *) malloc(sizeof(struct StyleStackStruct));

   fprintf(fout, "{\\s%d ", ++styleid);
   fscanf(fin, "%s", name);
   sprintf(style_sheet, "%s%s\n", style_sheet, name);

   tmp->idnum = styleid;
   strcpy(tmp->name, name);
   for(n=0; n<STATES; n++)
   {
      tmp->state_attribute[n] = style_None;
      tmp->modify[n] = 0;
   }
   tmp->state_count = 0;
   tmp->next = Style;
   tmp->string[0] = '\0';
   Style = tmp;

   while(1)
   {
      AbsorbNewlines();
      fscanf(fin, "%[^:}]:", type);
      if(!strcmp(type, "menu"))
      {
	 sprintf(style_sheet, "%smenu:", style_sheet);
         ch = ' ';
         while(ch != ']')
         {
            ch = (char) fgetc(fin);
            sprintf(style_sheet, "%s%c", style_sheet, ch);
	 }
         sprintf(style_sheet, "%s\n", style_sheet);
      }
      else if(!strcmp(type, "attr"))
      {
	  sprintf(style_sheet, "%sattr:", style_sheet);
          fscanf(fin, "[%s %s %s ", p1, p2, p3);
          i = 0;
          while((ch = (char) fgetc(fin)) != ']')
             p4[i++] = ch;
          p4[i] = '\0';

          sprintf(style_sheet, "%s[%s %s %s %s]\n", style_sheet, p1, p2, p3, p4);

          /* handle actual conversion to rtf... */
          RStyleConvert(p1, p2, p3, p4, Style);
      }
      else
      {
          ch = ' ';
	  while(ch != ']' && ch != '}')
             ch = (char) fgetc(fin);
	  if(ch == '}')
	     ungetc(ch, fin);
      }

      AbsorbNewlines();
      ch = (char) fgetc(fin);
      if(ch != '}')
         ungetc(ch, fin);
      else
      {
	 sprintf(style_sheet, "%s)\n", style_sheet);
         break;
      }
   }

   fprintf(fout, "\\sbasedon0\\snext%d %s;}", styleid, name);
   return(0);
}

int RStyleMain(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Should only be called for the first occurence of
 *  \define in the ez document.  Standard styles for
 *  footers, headers, footnote reference, and footnote
 *  text are hard coded into the style sheet (as well
 *  as the Normal style).  As long as "\define"'s are
 *  encountered, RStyleDefine is called to handle them.
 *
 */
{
   char style_sheet[10000];
   char temp[TMP_SIZE], ch;
   int i;
   static int done = 0;

   if(done)
   {
      RDelete(command, transform, tofind);
      return(0);
   }
   else
      done = 1;

   fputs("{\\stylesheet", fout);
   fputs("{\\s243\\tqc\\tx4320\\tqr\\tx8640 \\sbasedon0\\snext243 footer;}", fout);
   fputs("{\\s244\\tqc\\tx4320\\tqr\\tx8640 \\sbasedon0\\snext244 header;}\n", fout);
   fputs("{\\s245 \\fs18\\up6 \\sbasedon0\\snext0 footnote reference;}", fout);
   fputs("{\\s246 \\fs20 \\sbasedon0\\snext246 footnote text;}\n", fout);
   fputs("{\\sbasedon222\\snext0 Normal;}", fout);

   sprintf(style_sheet, "%s", "|define(");
   RStyleDefine(style_sheet);
   while(1)
   {
      ch = ' ';
      while(isspace(ch))
      {
         AbsorbNewlines();
         ch = (char) fgetc(fin);
      }
      if(ch != '\\')
      {
         ungetc(ch, fin);
         break;
      }

      ch = (char) fgetc(fin);
      if(ch == '\\' || ch == '{' || ch == '}')
      {
          ungetc(ch, fin);
          ungetc('\\', fin);
          break;
      }

      i = 0;
      while(1)
      {
         if(ch == '{' || isspace(ch))
            break;
         temp[i++] = ch;
         ch = (char) fgetc(fin);
      }
      temp[i] = '\0';

      if(!strcmp(temp, "define"))
      {
	 sprintf(style_sheet, "%s|%s(", style_sheet, temp);
         RStyleDefine(style_sheet);
      }
      else
      {
         ungetc(ch, fin);
         for(i--; i>=0; i--)
            ungetc(temp[i], fin);
         ungetc('\\', fin);
         break;
      }
   }

   fputs("}\n", fout);
   fprintf(fout, "{\\v STYLESHEET:\n%s}", style_sheet);
   return(0);
}

int RStyleApply(tmp)
     struct StyleStackStruct *tmp;
/*
 *
 *  Called when a style is encountered inside the document,
 *  so that ez style name can be replaced by style number
 *  and expansion of style attributes.
 *
 */
{
   char ch;
   int k;
   int done = 0;
   int do_new = 0;
   long save[STATES];
   long save2[STATES];

/*   fprintf(fout, "{\\s%d%s ", tmp->idnum, tmp->string);*/
   fprintf(fout, "{{\\v STYLE: %s}%s", tmp->name, tmp->string);

   for(k=0; k<=tmp->state_count; k++)
   {
       switch(tmp->state_attribute[k])
       {
	   case style_FontSizeAttr:
	       save[k] = State.CurFontSize;
	       State.CurFontSize += tmp->modify[k];
	       fprintf(fout, "\\fs%d", State.CurFontSize);
	       break;
	   case style_ScriptAttr:
	       save[k] = State.CurScriptMovement;
	       State.CurScriptMovement -= tmp->modify[k];
	       if(State.CurScriptMovement > 0)
		  fprintf(fout, "\\up%d", State.CurScriptMovement);
	       else
		  fprintf(fout, "\\dn%d", - State.CurScriptMovement);
	       break;
	   case style_LeftMarginAttr:
	       save[k] = State.CurLeftMargin;
               State.CurLeftMargin += tmp->modify[k];
	       if(!paragraph)
               {
		   fputs("\\par", fout);
                   paragraph = 1;
	       }
/*               fprintf(fout, "\\li%d", State.CurLeftMargin);*/
               break;
	   case style_RightMarginAttr:
	       save[k] = State.CurRightMargin;
               State.CurRightMargin += tmp->modify[k];
	       if(!paragraph)
               {
		   fputs("\\par", fout);
                   paragraph = 1;
	       }
/*               fprintf(fout, "\\ri%d", State.CurRightMargin);*/
               break;
	   case style_IndentAttr:
               save[k] = State.CurLeftIndentation;
               save2[k] = State.CurRightIndentation;
               State.CurLeftIndentation += tmp->modify[k];
               State.CurRightIndentation += tmp->modify[k];
	       if(!paragraph)
		   fputs("\\par", fout);
/*               fprintf(fout, "\\li%d\\ri%d", State.CurLeftIndentation, State.CurRightIndentation);*/
               break;
	   case style_None:
	   default:
	       break;
       }
   }
   if(k>0)
      fputs(" ", fout);

   ch = ' ';
   while(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
   {
      ch = (char) fgetc(fin);
      if(ch=='\n' || ch=='\r')
         Newlines();
   }

   if(ch != '{')
      ungetc(ch, fin);
   
   ParseText('}', NORMAL, PRINTTOFILE);
   fputs("}", fout);

   for(k=0; k<=tmp->state_count; k++)
   {
       switch(tmp->state_attribute[k])
       {
	   case style_FontSizeAttr:
	       State.CurFontSize = save[k];
	       break;
	   case style_ScriptAttr:
	       State.CurScriptMovement = save[k];
	       break;
	   case style_LeftMarginAttr:
               fprintf(fout, "\\li%d", State.CurLeftMargin);
               State.CurLeftMargin = save[k];
               if(!done)
               {
		   ch = (char) fgetc(fin);
		   if(ch == '\n' || ch == '\r')
		   {
		       CurrLine++;
		       ch = (char) fgetc(fin);
		       if(ch == '\n' || ch == '\r')
			   do_new = 1;
		       else
			   ungetc(ch, fin);
		   }
		   else
		       ungetc(ch, fin);
		   done = 1;
	       }
               break;
	   case style_RightMarginAttr:
               fprintf(fout, "\\ri%d", State.CurRightMargin);
               State.CurRightMargin = save[k];
               if(!done)
               {
		   ch = (char) fgetc(fin);
		   if(ch == '\n' || ch == '\r')
		   {
		       CurrLine++;
		       ch = (char) fgetc(fin);
		       if(ch == '\n' || ch == '\r')
			   do_new = 1;
		       else
			   ungetc(ch, fin);
		   }
		   else
		       ungetc(ch, fin);
		   done = 1;
	       }
               break;
	   case style_IndentAttr:
               fprintf(fout, "\\li%d\\ri%d", State.CurLeftIndentation, State.CurRightIndentation);
               State.CurLeftIndentation = save[k];
	       State.CurRightIndentation = save2[k];
	       ch = (char) fgetc(fin);
	       if(ch == '\n' || ch == '\r')
	       {
		   CurrLine++;
		   ch = (char) fgetc(fin);
		   if(ch == '\n' || ch == '\r')
		       Newlines();
		   else
		       ungetc(ch, fin);
	       }
	       else
		   ungetc(ch, fin);
	       fprintf(fout, "\\par\\li%d\\ri%d ", State.CurLeftIndentation, State.CurRightIndentation);
               break;
	   case style_None:
	   default:
	       break;
       }
   }
   if(do_new)
      Newlines();
   if(done)
       fprintf(fout, "\\par\\pard\\li%d\\ri%d ", State.CurLeftMargin, State.CurRightMargin);
   return(0);
}

int RStyleConvert(p1, p2, p3, p4, tmp)
    char *p1, *p2, *p3, *p4;
    struct StyleStackStruct *tmp;
/*
 *
 *  Call the function that handles the particular type
 *  of style attribute.
 *
 */
{
   static struct func_words Attribs[15] = {
      {"LeftMargin",		RSLMargin},
      {"RightMargin",		RSRMargin},
      {"TopMargin",		RSTMargin},
      {"BottomMargin",		RSBMargin},
      {"Indentation",		RSIndent},
      {"InterparagraphSpacing",	RSIpSpacing},
      {"Above",			RSAbove},
      {"Below",			RSBelow},
      {"InterlineSpacing",	RSIlSpacing},
      {"FontFamily",		RSFontFamily},
      {"FontSize",		RSFontSize},
      {"Script",		RSFontScript},
      {"TabChange",		RSTabChange},
      {"FontFace",		RSFontFace},
      {"Justification",		RSJustify}
   };
   int i;

   for(i=0; i<15; i++)
      if(!strcmp(p1, Attribs[i].word))
      {
         Attribs[i].fname(p2, p3, p4, tmp);
         break;
      }
   return(0);
}

int Delimeter(units, n)
   char *units, *n;
/*
 *
 *  Convert the delimeter from whatever it is into twips
 *  for use by rtf.
 *
 *  (A twip is 1/20th of a point)
 *
 */
{
   struct divider
   {
       char *name;
       float div;
   };
   static struct divider types[UNITS] = {
      {"inch", 45.5},
      {"cm", 114.0},
      {"point", 0.05},
      {"rawdot", 0.05}
   };
   int i, numdel = UNBOUND;

   strcpy(units, makelower(units));

   for(i=0; i<UNITS; i++)
      if(!strcmp(units, types[i].name))
      {
         numdel = ((float) atoi(n)) / types[i].div;
         break;
      }

   if(numdel == UNBOUND)
      fprintf(ferr, "*Error:  Unknown unit of measurement, %s.\n", units);

   return(numdel);
}

int RSLMargin(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   LeftMargin
 *   LeftEdge
 *   RightMargin
 *   RightEdge
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   fprintf(fout, "\\li%d ", numdel);
   if(!strcmp(basis, "ConstantMargin"))
      sprintf(tmp->string, "%s\\li%d ", tmp->string, numdel);
   else if(!strcmp(basis, "LeftMargin"))
   {
       tmp->modify[tmp->state_count] = numdel;
       tmp->state_attribute[tmp->state_count] = style_LeftMarginAttr;
       tmp->state_count++;
   }
   return(0);
}

int RSRMargin(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   LeftMargin
 *   LeftEdge
 *   RightMargin
 *   RightEdge
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   fprintf(fout, "\\ri%d ", numdel);
   if(!strcmp(basis, "ConstantMargin"))
      sprintf(tmp->string, "%s\\ri%d ", tmp->string, numdel);
   else if(!strcmp(basis, "RightMargin"))
   {
       tmp->modify[tmp->state_count] = numdel;
       tmp->state_attribute[tmp->state_count] = style_RightMarginAttr;
       tmp->state_count++;
   }
   return(0);
}

int RSTMargin(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   TopMargin
 *   TopEdge
 *   BottomMargin
 *   BottomEdge
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   return(0);
}

int RSBMargin(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   TopMargin
 *   TopEdge
 *   BottomMargin
 *   BottomEdge
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   return(0);
}

int RSIndent(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   PreviousIndentation
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   if(!strcmp(basis, "ConstantMargin"))
   {
       fprintf(fout, "\\li%d\\ri%d ", numdel, numdel);
       sprintf(tmp->string, "%s\\li%d\\ri%d ", tmp->string, numdel, numdel);
   }
   else if(!strcmp(basis, "PreviousIndentation"))
   {
       tmp->modify[tmp->state_count] = numdel;
       tmp->state_attribute[tmp->state_count] = style_IndentAttr;
       tmp->state_count++;
   }
   return(0);
}

int RSIpSpacing(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   return(0);
}

int RSAbove(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   AboveSpacing
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   fprintf(fout, "\\sb%d ", numdel);
   sprintf(tmp->string, "%s\\sb%d ", tmp->string, numdel);
   return(0);
}

int RSBelow(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   BelowSpacing
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   fprintf(fout, "\\sa%d ", numdel);
   sprintf(tmp->string, "%s\\sa%d ", tmp->string, numdel);
   return(0);
}

int RSIlSpacing(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   ConstantMargin
 *   InterlineSpacing
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   fprintf(fout, "\\sl%d ", numdel);
   sprintf(tmp->string, "%s\\sl%d ", tmp->string, numdel);
   return(0);
}

int RSFontFamily(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
{
   static struct FontStruct type[FTSIZE] = {
       {"Andy",		    NEW_YORK},
       {"AndySans",	    CHICAGO},
       {"AndyType",	    MONACO},
       {"AndySymbol",	    SYMBOL},
       {"Default",	    NEW_YORK}
   };
   int i;

   for(i=0; i<FTSIZE; i++)
      if(!strcmp(basis, type[i].name))
         break;

   if(i<FTSIZE)
   {
      fprintf(fout, "\\f%d ", type[i].num);
      sprintf(tmp->string, "%s\\f%d ", tmp->string, type[i].num);
   }
   return(0);
}

int RSFontSize(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   PreviousFontSize
 *   ConstantFontSize
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   numdel /= 10;
   fprintf(fout, "\\fs%d ", numdel);
   if(!strcmp(basis, "ConstantFontSize"))
      sprintf(tmp->string, "%s\\fs%d", tmp->string, numdel);
   else if(!strcmp(basis, "PreviousFontSize"))
   {
      tmp->modify[tmp->state_count] = numdel;
      tmp->state_attribute[tmp->state_count] = style_FontSizeAttr;
      tmp->state_count++;
   }
   return(0);
}

int RSFontScript(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
/*
 *
 *   PreviousScriptMovement
 *   ConstantScriptMovement
 *
 */
{
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   numdel /= 10;
   if(!strcmp(basis, "ConstantScriptMovement"))
   {
      if(numdel<0)
      {
         fprintf(fout, "\\up%d ", - numdel);
         sprintf(tmp->string, "%s\\up%d ", tmp->string, - numdel);
      }
      else
      {
         fprintf(fout, "\\dn%d ", numdel);
         sprintf(tmp->string, "%s\\dn%d ", tmp->string, numdel);
      }
   }
   else if(!strcmp(basis, "PreviousScriptMovement"))
   {
      fprintf(fout, "\\dn%d ", numdel);
      tmp->state_attribute[tmp->state_count] = style_ScriptAttr;
      tmp->modify[tmp->state_count] = numdel;
      tmp->state_count++;
   }
   return(0);
}

int RSTabChange(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
{
   static struct style_words type[TSIZE] = {
       {"LeftAligned",		"tx"},
       {"RightAligned",		"tqr\\tx"},
       {"CenteredOnTab",	"tqc\\tx"},
       {"CenteredBetweenTab",	"tqc\\tx"},
       {"TabDivide",		"tb"}
   };
   int i;
   int numdel;

   if((numdel = Delimeter(unit, operand)) == UNBOUND)
      return(0);

   for(i=0; i<TSIZE; i++)
      if(!strcmp(basis, type[i].ezword))
         break;

   if(i<TSIZE)
   {
      fprintf(fout, "\\%s%d ", type[i].rtfword, numdel);
      sprintf(tmp->string, "%s\\%s%d ", tmp->string, type[i].rtfword, numdel);
   }
   return(0);
}

int RSFontFace(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
{
   static struct style_words type[FSIZE] = {
       {"Plain",	"plain"},
       {"Bold",		"b"},
       {"Italic",	"i"}
   };
   int i;

   for(i=0; i<FSIZE; i++)
      if(!strcmp(basis, type[i].ezword))
         break;

   if(i<FSIZE)
   {
      fprintf(fout, "\\%s ", type[i].rtfword);
      sprintf(tmp->string, "%s\\%s ", tmp->string, type[i].rtfword);
   }
   return(0);
}

int RSJustify(basis, unit, operand, tmp)
     char *basis, *unit, *operand;
     struct StyleStackStruct *tmp;
{
   static struct style_words type[JSIZE] = {
       {"LeftJustified",		"ql"},
       {"RightJustified",		"qr"},
       {"LeftAndRightJustified",	"qj"},
       {"LeftThenRightJustified",	"qj"},
       {"Centered",			"qc"}
   };
   int i;

   for(i=0; i<JSIZE; i++)
      if(!strcmp(basis, type[i].ezword))
         break;

   if(i<JSIZE)
   {
      fprintf(fout, "\\%s ", type[i].rtfword);
      sprintf(tmp->string, "%s\\%s ", tmp->string, type[i].rtfword);
   }
   return(0);
}

int RMajorHeading(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle MajorHeading style.
 *
 */
{
   int oldsize;

   oldsize = State.CurFontSize;
   State.CurFontSize += 8;

   fprintf(fout, "{\\fs%d\\qc ", State.CurFontSize);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);

   State.CurFontSize = oldsize;
   return(0);
}

int RHeading(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Heading style.
 *
 */
{
   fputs("{\\b\\ql\\fi-350 ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RSubHeading(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle SubHeading style.
 *
 */
{
   fputs("{\\b\\ql ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RChapter(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Chapter style.
 *
 */
{
   int oldsize;

   oldsize = State.CurFontSize;
   State.CurFontSize += 8;

   fprintf(fout, "{\\fs%d\\b\\ql ", State.CurFontSize);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);

   State.CurFontSize = oldsize;
   return(0);
}

int RSection(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Section style.
 *
 */
{
   int oldsize;

   oldsize = State.CurFontSize;
   State.CurFontSize += 4;

   fprintf(fout, "{\\fs%d\\b\\ql ", State.CurFontSize);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);

   State.CurFontSize = oldsize;
   return(0);
}

int RSubSection(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle SubSection style.
 *
 */
{
   fputs("{\\b\\ql ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RParagraph(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Paragraph style.
 *
 */
{
   fputs("{\\i\\ql ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RCaption(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Caption style.
 *
 */
{
   fputs("{\\b\\qc ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RQuotation(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Quotation style.
 *
 */
{
   fputs("{\\i\\li720\\ri720 ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RDescription(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Description style.
 *
 */
{
   fputs("{\\fi-720\\li720 ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RExample(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Example style.
 *
 */
{
   fprintf(fout, "{\\ql\\li720\\f%d ", MONACO);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RDisplay(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Display style.
 *
 */
{
   fputs("{\\ql\\li720\\ri720 ", fout);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

int RVerbatim(command, transform, tofind)
     char *command;
     int transform, tofind;
/*
 *
 *  Handle Verbatim style.
 *
 */
{
   fprintf(fout, "{\\ql\\f%d ", MONACO);
   ParseText(tofind, transform, PRINTTOFILE);
   fputs("}\n", fout);
   return(0);
}

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