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

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

/*  
 R2Functions.c of

 Rtf2: a facility to convert RTF manuscript files to files 
 compatible with the ATK file format.

 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.

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

 $Header: /usr2/multimedia/RCS/MMEdit//R2Functions.c,v 1.47 93/01/08 16:55:57 suzuki Exp $
*/


#include <stdio.h>
#include <sys/file.h>
#import <strings.h>
#include <ctype.h>
#import <streams/streams.h>
#import "rtf2.h"
#import "mem_file_desc.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 itoa();
extern reverse();
extern char *makelower();
extern rtf2_FONT rtf2_Font;
extern rtf2_TABLE rtf2_Table;
rtf2_TABLE rtf2_FindNode();
void rtf2_CloseFiles();
long int rtf2_ParseText();
char fontheader[2000];
extern int offset();
rtf2_FP rtf2_AssignFunc();
void rtf2_AbsorbWhiteSpace(),exit(), rtf2_AbsorbSpace(), to64();
NXStream *next2basic();
char *rtf2_GetInstruction(), *deltoken();
int roffset(),atoi(),R2UniqueID(), R2Delete(), R2Symbol(), R2NOP(), R2Footnote(), R2Caps(), R2SCaps(), R2Newpage(), R2Par(), R2FontDefine(), R2Margl(), R2Margr(), R2Font(), R2StyleSheet(), R2Plain(), R2Size(), R2Index(), R2Hidden(), R2Header(), R2Field(), R2Tab(), R2Current(), R2Indent(), R2Pard(), R2TabChange();
int R2MMtiff(), rtf2_Execute();

rtf2_FP rtf2_AssignFunc(ezword)
     char *ezword;
/*
 *
 *  Function that returns a pointer to the function
 *  associated with EZWORD.
 *
 */
{
  static struct rtf2_func_words rtf2_fnlist[FUNCTION_SIZE+1] = {
      {"mmtiff",              R2MMtiff},
      {"caps",                R2Caps},
      {"current",             R2Current},
      {"delete",              R2Delete},
      {"field",               R2Field},
      {"font",                R2Font},
      {"fontdefine",          R2FontDefine},
      {"footnote",            R2Footnote},
      {"header",              R2Header},
      {"hidden",              R2Hidden},
      {"index",               R2Index},
      {"indent",              R2Indent},
      {"margl",               R2Margl},
      {"margr",               R2Margr},
      {"newpage",             R2Newpage},
      {"nop",                 R2NOP},
      {"par",                 R2Par},
      {"pard",                R2Pard},
      {"plain",               R2Plain},
      {"scaps",               R2SCaps},
      {"size",                R2Size},
      {"stylesheet",          R2StyleSheet},
      {"symbol",              R2Symbol},
      {"tab",                 R2Tab},
      {"tabchange",           R2TabChange}
  };
  int i;

  for(i = 0; i < FUNCTION_SIZE+1; i++)
     if(!strcmp(ezword, rtf2_fnlist[i].word))
       return(rtf2_fnlist[i].fname);

  return(R2NOP);
}

int R2MMtiff(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
{
   char name[1024], *extension=NULL;
   char ch, *contenttype=NULL;
   char *msgid=NULL;
   char *filename=NULL;
   char *site=NULL;
   char *site1=NULL;
   char *dir=NULL;
   char *ptr=NULL;
   int i=0;
   struct mem_file_desc *adpp;

   sentence[0]='\0';
   sentence1[0]='\0';

   rtf2_AbsorbSpace();
   name[0]='\0';
   ptr=name;
  while((ch = fgetc(fin)) != EOF)
    {
      if(ch=='}'){
	  if ( i == 1 ) {
		break;
	  }
	  i++;
          continue;
      }
      if ( ch == '\n' || ch == '\r' || ch == '\254')
	continue;
      else{

	if ( i == 0)
           *ptr++=ch;
        if ((ptr - name) > 1024 )
  	   exit(1);
      }

    }
      *ptr='\0';
        adpp = ( struct mem_file_desc *)Adpp[0]; 

        extension = rindex(name, '.');
        if (extension) {
             ++extension;
        } else extension = NULL;

	Ismultip = 1;
 	multip=1;	
  oldsent[0]='\0';
  sentence[0]='\0';
  sentence1[0]='\0';
	
	if (!extension){
		fprintf(fout,"\r\n--%s\r\n", Boundary);
                contenttype = (char *) calloc (200, sizeof(char));
                strcpy(contenttype,"application/octet-stream");
	fprintf(fout,"Content-Type: %s; name=%s;\r\n", contenttype, name);
 		fprintf(fout,"\ttype=binary\r\n" );
		fprintf(fout,"Content-Transfer-Encoding: base64\r\n" );
		fprintf(fout,"\r\n" );
    	while( adpp != NULL )
   	{
     		if( !strcmp(adpp->fd_name, name))
			to64(adpp->fd_stream, fout);
		adpp= adpp->fd_nextp;
  	 }	
                fprintf(fout,"\r\n--%s\r\n", Boundary);
                fprintf(fout,"Content-Type: text/richtext\r\n");
                fprintf(fout,"\r\n" );
		return(0);
	}


		
       if (!strcmp(extension,"X-news")||!strcmp(extension, "x-news")){
	fprintf(fout,"\r\n--%s\r\n", Boundary);
                 contenttype = (char *) calloc (200, sizeof(char));
                 strcpy(contenttype,"message/external-body");
                 extension = rindex(name, '.');
                 *extension = '\0';
                 msgid = (char *) calloc (200, sizeof(char));
                 strcpy(msgid, name);
        fprintf(fout,"Content-Type: %s; access-type=X-news; name=%s\r\n", contenttype, msgid);
        fprintf(fout,"\r\n" );
                fprintf(fout,"--%s\r\n", Boundary);
                fprintf(fout,"Content-Type: text/richtext\r\n");
                fprintf(fout,"\r\n" );

	return(0);
        } else if (!strcmp(extension,"anon-ftp")|| !strcmp(extension,"ANON-FTP")){
	fprintf(fout,"\r\n--%s\r\n", Boundary);
                 contenttype = (char *) calloc (200, sizeof(char));
                 strcpy(contenttype,"message/external-body");
                 extension = index(name, '@');
                 *extension = '\0';
                 filename = (char *) calloc (200, sizeof(char));
                 strcpy(filename, name);
                 extension++;
                 site1 = rindex(extension, '.');
                 *site1 = '\0';
                 site = (char *) calloc (200, sizeof(char));
                 strcpy(site, extension);

        fprintf(fout,"Content-Type: %s; access-type=ANON-FTP;\r\n", contenttype);
        fprintf(fout,"\tname=%s\r\n", filename);
        fprintf(fout,"\tsite=%s\r\n", site);
        fprintf(fout,"\tdirectory=%s\r\n", dir);
        fprintf(fout,"\tmode=image\r\n");
        fprintf(fout,"\r\n" );
                fprintf(fout,"--%s\r\n", Boundary);
                fprintf(fout,"Content-Type: text/richtext\r\n");
                fprintf(fout,"\r\n" );

	return(0);
        } else if (!strcmp(extension,"local-file")){
	fprintf(fout,"\r\n--%s\r\n", Boundary);
                 contenttype = (char *) calloc (200, sizeof(char));
                 strcpy(contenttype,"message/external-body");
                 extension = rindex(name, '.');
                 *extension = '\0';

        fprintf(fout,"Content-Type: %s; access-type=local-file;\r\n", contenttype);
        fprintf(fout,"\tname=%s\r\n", name);
        fprintf(fout,"\r\n" );
                fprintf(fout,"--%s\r\n", Boundary);
                fprintf(fout,"Content-Type: text/richtext\r\n");
                fprintf(fout,"\r\n" );

	return(0);
        }


    while( adpp != NULL )
   {
     if( !strcmp(adpp->fd_name, name)){
 	extension = rindex(adpp->fd_name, '.');
        if (extension) {
             ++extension;
        } else extension = NULL;

	NXSeek(adpp->fd_stream,(long)0, NX_FROMSTART);
	fprintf(fout,"\r\n--%s\r\n", Boundary);
  	if (!strcmp(extension, "tiff") || !strcmp(extension, "gif") ||
         !strcmp(extension,"jpeg") || !strcmp(extension, "jfif")
         || !strcmp(extension,"eps") ){
		  contenttype = (char *) calloc (200, sizeof(char));
                  sprintf(contenttype,"image/%s; name=%s", extension,name);
	fprintf(fout,"Content-Type: %s\r\n", contenttype);
	fprintf(fout,"Content-Transfer-Encoding: base64\r\n" );
	fprintf(fout,"\r\n" );
	to64(adpp->fd_stream, fout);
        }
   	 else if (!strcmp(extension,"snd")){
		 contenttype = (char *) calloc (200, sizeof(char));
       	         sprintf(contenttype,"audio/basic; name=%s",name);
	fprintf(fout,"Content-Type: %s\r\n", contenttype);
	fprintf(fout,"Content-Transfer-Encoding: base64\r\n" );
	fprintf(fout,"\r\n" );
	to64(next2basic(adpp->fd_stream), fout);
        } else {
		 contenttype = (char *) calloc (200, sizeof(char));
       	         strcpy(contenttype,"application/octet-stream");

	fprintf(fout,"Content-Type: %s; name=%s;\r\n", contenttype, name);
	if (!strcmp(extension,"vox"))
 		fprintf(fout,"\ttype=Voice_mail_data\r\n");
	else
 		fprintf(fout,"\ttype=unknown\r\n" );
	fprintf(fout,"Content-Transfer-Encoding: base64\r\n" );
	fprintf(fout,"\r\n" );
	to64(adpp->fd_stream, fout);
	}

	fprintf(fout,"\r\n" );

	Ismultip = 1;
 	multip=1;	
	break;
     } else
	adpp= adpp->fd_nextp;
   }	

                fprintf(fout,"\r\n--%s\r\n", Boundary);
                fprintf(fout,"Content-Type: text/richtext\r\n");
                fprintf(fout,"\r\n" );

	
  return(0);
}

int R2UniqueID()
/*
 *
 *  Function that returns a unique id number.
 *
 */
{
  return(++Token);
}

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

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

int R2Symbol(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Reads a 2 digit hex number from the input, and writes
 *  its character equivelant to the output file.
 *
 */
{
     int number;
     fscanf(fin, "%2x", &number);
     printf("As number >%d< as char >%c<\n", number, number);
//     fputc((char) number, fout);
  return(0);
}

     

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


int R2Footnote(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Processes footnotes.  Writes required info to output file,
 *  then parses the rest of the input for the footnote.
 *
 */
{
  int token;

  token = R2UniqueID();
//  rtf2_CloseBraces(command);

//  fprintf(fout, "\\footnote{\\\n");
//  fprintf(fout, "\\begindata{fnote,%d}\n", token);
//  fprintf(fout, "\\textdsversion{%d}\n", TextDSVersion);

  strcat(sentence1, "<footing>");
//  fprintf(fout, "<footing>");
//  fnote = 1;
//  rtf2_ParseText(tofind, NORMAL, PRINTTOFILE);
//  fnote = 0;
//  fprintf(fout, "</footing>");

//  fprintf(fout, "\\\n\\enddata{fnote,%d}\n", token);
//  fprintf(fout, "\\view{fnotev,%d,3,0,0}}", token);
  return(0);
}


int R2Begin()
/*
 *
 *  Handles the occurence of a { during parsing of text.  If an
 *  instruction follows it is executed, otherwise the text is
 *  parsed with TOFIND as '}'.
 *
 */
{
  char ch, *makelower();
  char tmp_instruction[TMP_SIZE], instruction[TMP_SIZE]; 
  int in;
  rtf2_TABLE tmp;

  rtf2_AbsorbWhiteSpace();

  in = fgetc(fin);
  if(in==EOF)
    {
      fprintf(ferr, "* End of file reached after new group.\n");
//      rtf2_CloseFiles();
      exit(0);
    }
  
  ch = (char) in;
  if(ch == '\\')
    {
      strcpy(tmp_instruction, rtf2_GetInstruction());
      sscanf(tmp_instruction, "%[A-z]", instruction);
      strcpy(instruction, makelower(instruction));

      tmp = rtf2_FindNode(RTFCOLUMN, instruction);
      if(tmp == NULL)
	{
	  printf("* RTF command \\%s not recognized\n", instruction);
//	  fprintf(fout, "<%s>", tmp_instruction);
	}
      else 
	{
	  rtf2_Execute(tmp_instruction) ;
	  return(0);
	}
    }
  else
    ungetc(ch, fin);

  rtf2_ParseText('}', NORMAL, PRINTTOFILE);
  return(0);
}

int R2FontDefine(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Reads in the font table from the input file, and stores
 *  it in a table for use when fonts are referred to by
 *  number in the input file.
 *
 */
{
	int i;
	char c;


   if ( fon == 0 ){
    for (i=0; (i<1999 && (c = fgetc(fin)) != '}'
              && c != EOF); ++i) {
        fontheader[i] = c;
     } 
     fontheader[i]='\0';
     fon++;
   }

  return(0);
}

int R2Caps(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Converts input text to all capitals in the output file.
 *
 */
{
  //rtf2_ParseText(tofind, CAPS, PRINTTOFILE);
  return(0);
}

int R2SCaps(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Converts input text to all small capitals in the output file.
 *
 */
{
  strcat(sentence1, "<smaller>");
//  fputs("<smaller>", fout);

//  rtf2_ParseText(tofind, CAPS, PRINTTOFILE);

//  fputs("</smaller>", fout);
  return(0);
}

int R2Newpage(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handles page breaks.
 *
 */
{
  int token;

  token = R2UniqueID();
//  fprintf(fout, "\\begindata{bp,%d}\n", token);
//  fprintf(fout, "\\enddata{bp,%d}\n", token);
//  fprintf(fout, "\\view{bpv,%d,1,0,0}\n", token);
  return(0);
}

int R2Margl(command, numdel, tofind)
   char *command;
   int numdel;
   int tofind;
/*
 *
 *  Change left margin.
 *
 */
{
     extern double LeftMargin;

     LeftMargin = (double) numdel/1440.0 - .5;

//     fprintf(fout, "\n\\formatnote{.po %fi}\n", LeftMargin);
  return(0);
}


int R2Margr(command, numdel, tofind)
   char *command;
   int numdel;
   int tofind;
/*
 *
 *  Change right margin.
 *
 */
{
     extern double LeftMargin, RightMargin;

     RightMargin = 8.5 - LeftMargin - (double) numdel/1440.0;

//     fprintf(fout, "\n\\formatnote{.ll %fi}\n", RightMargin);
  return(0);
}

int R2Par(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle par command.  This function should be called for the
 *  first occurence of \par only.
 *
 */
{
   int index, counter;
//   char ch, input[TMP_SIZE], tmp[TMP_SIZE * 5];

   counter = 1;
   index = 0;
/*
   while(1)
   {
      tmp[index++] = ch = (char) fgetc(fin);
      if(ch=='\n' || ch=='\r')
      {
         CurrLine++;
         index--;
      }
      else if(isspace(ch))
         continue;
      else if(ch != '\\')
         break;
      else
      {
         strcpy(input, rtf2_GetInstruction());
         if(!strcmp(input, "par"))
         {
            counter++;
            index = 0;
	 }
         else
         {
            tmp[index] = '\0';
            strcat(tmp, input);
            index += strlen(input);
            tmp[index++] = ' ';
	 }
      }
   }

   for(index--; index>=0; index--)
      ungetc(tmp[index], fin);
   for(; counter>=0; counter--)
*/
      fputs("<nl>\n", fout);
  return(0);
}

int R2Font(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle font changes within the input file by using the
 *  font table to map the font number to the font.
 *
 */
{
   rtf2_FONT tmp = rtf2_Font;
   char *fo=NULL;

   while(tmp != NULL)
   {
      if(tmp->number == numdel)
         break;
      else
         tmp = tmp->next;
   }
	   fo = (char *) calloc (200, sizeof(char));
           sprintf(fo, "<%s%d>", command, numdel);
	   strcat(sentence1, fo);
//   Ismultip=1;
//   multip=1;
  
   if(tmp == NULL)
   {
       /* Continue with old font */
//       printf("Unknown font number %d\n", numdel);
//       rtf2_ParseText(tofind, NORMAL, PRINTTOFILE);
   }
   else
   {
       switch(tmp->ind)
       {
	  case ANDYSANS:
//              fputs("\\sansserif{", fout);
              break;
	  case ANDYTYPE:
//              fputs("\\typewriter{", fout);
              break;
	  case ANDYSYMBOL:
//              fputs("\\symbol{", fout);
              break;
	  case ANDY:
	  case DEFAULT:
              //rtf2_ParseText(tofind, NORMAL, PRINTTOFILE);
              return(0);
       }
//       rtf2_ParseText(tofind, NORMAL, PRINTTOFILE);
//       fputc('}', fout);
   }
  return(0);
}

int GetAttr(from, p1, p2, p3, p4)
     char *from, *p1, *p2, *p3, *p4;
/*
 *
 *  Get the 4 attributes associated with the command in
 *  the style sheet.
 *
 */
{
   static char *Attribs[ATTRIB_SIZE][5] = {
       {"plain", "FontFace", "Plain", "Int", "Set"},
       {"ql", "Justification", "LeftJustified", "Point", "0"},
       {"qr", "Justification", "RightJustified", "Point", "0"},
       {"qj", "Justification", "LeftAndRightJustified", "Point", "0"},
       {"qc", "Justification", "Centered", "Point", "0"},
       {"b", "FontFace", "Bold", "Int", "Set"},
       {"i", "FontFace", "Italic", "Int", "Set"},
       {"li", "LeftMargin", "ConstantMargin", "Inch", ""},
       {"ri", "RightMargin", "ConstantMargin", "Inch", ""},
       {"fi", "Indentation", "ConstantMargin", "Inch", ""},
       {"sb", "Above", "ConstantMargin", "Inch", ""},
       {"sa", "Below", "ConstantMargin", "Inch", ""},
       {"sl", "InterlineSpacing", "ConstantMargin", "Inch", ""},
       {"f", "FontFamily", "", "Int", "0"},
       {"fs", "FontSize", "ConstantFontSize", "Inch", ""},
       {"up", "Script", "ConstantScriptMovement", "Inch", ""},
       {"dn", "Script", "ConstantScriptMovement", "Inch", ""},
       {"tx", "Tabs", "LeftAligned", "Inch", ""}
   };
   int i, j, k;
   int len = strlen(from);
   int del = -1;
   int ret_val = 0;
   char tmp[TMP_SIZE], delstring[TMP_SIZE], *makelower();
   rtf2_FONT tmpfont = rtf2_Font;

   i = j = k = 0;

   while((i < len) && (from[i++] != '\\'))
      ;
   while((i < len) && (from[i] != '\\'))
   {
      if(isalpha(from[i]))
        tmp[j++] = from[i];
      else if(!isspace(from[i]))
        delstring[k++] = from[i];
      i++;
   }
   tmp[j] = '\0';
   delstring[k] = '\0';
   strcpy(tmp, makelower(tmp));
   if(k > 0)
     del = atoi(delstring);
   strcpy(from, &from[i]);

   for(i=0;i<ATTRIB_SIZE;i++)
      if(!strcmp(tmp, Attribs[i][0]))
      {
         ret_val++;
         break;
      }

   if(ret_val)
   {
      strcpy(p1, Attribs[i][1]);
      strcpy(p2, Attribs[i][2]);
      strcpy(p3, Attribs[i][3]);
      strcpy(p4, Attribs[i][4]);
      if(del>=0)
      {
         if((!strcmp(tmp,"b")) && !del)
            strcpy(p4, "Clear");
         else if((!strcmp(tmp,"i")) && !del)
            strcpy(p4, "Clear");
         else if(!strcmp(tmp,"f"))
         {
	     while(tmpfont != NULL)
	     {
		 if(tmpfont->number == del)
		     break;
		 else
		     tmpfont = tmpfont->next;
	     }
	     switch(tmpfont->ind)
	     {
		 case ANDYSANS:
		     strcpy(p2, "AndySans");
		     break;
		 case ANDY:
		     strcpy(p2, "Andy");
		     break;
		 case ANDYSYMBOL:
		     strcpy(p2, "AndySymbol");
		     break;
		 case ANDYTYPE:
                     strcpy(p2, "AndyType");
                     break;
		 case DEFAULT:
		     strcpy(p2, "Default");
		     break;
		 default:
                     ret_val = 0;
                     break;
	     }
	 }
         else
         {
             del = del * 65536 / 1440;
             if(tmp=="dn")
               del = -del;
             itoa(del, delstring);
             strcpy(p4, delstring);
	 }
      }
   }

   return(ret_val);
}


int R2StyleSheet(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Process the style sheet declaration in the input file by
 *  defining the different styles in the output document, and
 *  adding them to a menu.
 *
 */
{
   static int done = 0;
   char tmpstring[TMP_SIZE],
        name[TMP_SIZE],
        type[TMP_SIZE],
        basis[TMP_SIZE],
        unit[TMP_SIZE],
        param[TMP_SIZE];
   int in, check, a;

//   printf("Found stylesheet.\n");   
 
   if(done)
      printf("Error - Multiple Style Sheet declarations exist.");
   else
   {
      while((in=fgetc(fin)) != '}')
      {
         while(in != '{')
            in = fgetc(fin);

	 fscanf(fin, "%[^;];}", tmpstring);
         a = roffset(tmpstring, ' ');

         strcpy(name, &tmpstring[a+1]);
         tmpstring[a] = '\0';

         if((strcmp(tmpstring, "")) && (strcmp(name, "Normal")))
         {
//           fprintf(fout, "\\define{%s\n", name);
//       	   fprintf(fout, "menu:[Style, %s]\n", name);
           while(strcmp(tmpstring, ""))
           { 
              check = GetAttr(tmpstring, type, basis, unit, param);
              if(check)
//                fprintf(fout, "attr:[%s %s %s %s]\n", type, basis, unit, param);
		  ;
	   }
//	   fputs("}\n", fout);  
	 }
      }
   }

   done++;
  return(0);
}

int R2Plain(command, numdel, tofind)
   char *command;
   int numdel;
   int tofind;
/*
 *
 *  Process the plain command in the input file by closing
 *  off all styles that are currently in effect in the output
 *  file.
 *
 */
{
//   rtf2_CloseBraces(command);
  return(0);
}

int R2Size(command, numdel, tofind)
   char *command;
   int numdel;
   int tofind;
/*
 *
 *  Handle changes in the font size.
 *
 */
{
   int change = numdel - FontSize;
   int n = change / 4;
   int i;
   int fontsize;
   he=numdel;

if ( n == 0){
   if ( Levels > 0 ){
        for (i = Levels*2 ;  i >= 0 ; --i ){
   	strcpy(oldsent, deltoken("bigger", oldsent));
   	strcpy(sentence1, deltoken("bigger", sentence1));
        }
   }
   if ( Levels1 > 0 ){
        for (i = Levels1*2 ;  i >= 0 ; --i ){
   	strcpy(oldsent, deltoken("smaller", oldsent));
   	strcpy(sentence1, deltoken("smaller", sentence1));
        }
   }
   Levels=0;
   Levels1=0;
   return(0);
}
        for (i = Levels*2 ;  i >= 0 ; --i ){
   	strcpy(oldsent, deltoken("bigger", oldsent));
   	strcpy(sentence1, deltoken("bigger", sentence1));
        }
        for (i = Levels1*2 ;  i >= 0 ; --i ){
   	strcpy(oldsent, deltoken("smaller", oldsent));
   	strcpy(sentence1, deltoken("smaller", sentence1));
        }
	if(n<0){
	     n = -n;
     		for(i=1; i<(n+1); i++){
        		if( i % 10 )
         		 strcat(oldsent, "<smaller>");
        		else{
        		  strcat(oldsent, "<smaller>\r\n");
       			 }
    		 }
     		Levels1 = n;
     		Levels=0;
	}else{
     		for(i=1; i<(n+1); i++){
       			 if( i % 10 )
       			   strcat(oldsent, "<bigger>");
       			 else{
       			   strcat(oldsent, "<bigger>\r\n");
       			 }
     		}
     		Levels = n;
     		Levels1=0;
	}
   fontsize = numdel;
//   }
//   else{
//     for(i=0; i<n; i++)
//     {
//        strcat(sentence1, ((change>0) ? "<bigger>" : "<smaller>"));
//      fputs(((change>0) ? "<bigger>" : "<smaller>"), fout);
//        Levels++;
//     }
//   }

//   rtf2_ParseText('}', NORMAL, PRINTTOFILE);

//   if(Levels>save)
//      FontSize -= change;
//      fontsize -= change;
//   for(; Levels>save; Levels--)
//	;
//      fputc('}', fout);
//      fputs(((change>0) ? "</bigger>" : "</smaller>"), fout);

   return(tofind);
}

int R2Hidden(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handles hidden text for annotations.  Currently only
 *  recognizes hidden text as either part of an index entry
 *  or an annotation.  It looks through the text to see if
 *  it's an index entry by checking if there is a group
 *  before a } that starts off "{\xe", or one of the four
 *  equivelent indexing commands, and if so, hands control
 *  over to R2Index(), otherwise it treats the hidden text
 *  as an annotation.
 *
 */
{
//   int index;
//   int token, token2;
//   char ch, string[TMP_SIZE * 5], inst[TMP_SIZE];
//
//   /* If the RTF document was originally run through
//      2rtf, there will be a scripted style sheet to
//      replace the RTF style sheet. */
//
//   for(index = 0; index < 11; index++)
//      string[index] = (char) fgetc(fin);
//   string[index] = '\0';
//   if(!strcmp(string, "STYLESHEET:"))
//   {
//      while((ch = (char) fgetc(fin)) != '}')
//         switch(ch)
//         {
//	     case '|':
////		 fputs("\\", fout);
//		 break;
//	     case '(':
//		 fputs("{", fout);
//		 break;
//	     case ')':
//		 fputs("}", fout);
//		 break;
//	     default:
////		 fputc(ch, fout);
//		 break;
//	 }
//      return(tofind);
//   }
//   else
//      for(index = 10; index >= 0; index--)
//         ungetc(string[index], fin);
//
//
//   /* Check to see if a Style was scripted by 2rtf
//      The expansion of the style needs to be eliminated. */
//
//
//   for(index = 0; index < 7; index++)
//      string[index] = (char) fgetc(fin);
//   string[index] = '\0';
//   if(!strcmp(string, "STYLE: "))
//   {
//      fscanf(fin, "%[^}]}", string);
//      while((ch = (char) fgetc(fin)) == '\\')
//         while(!isspace(ch))
//            ch = (char) fgetc(fin);
//      ungetc(ch, fin);
//	strcat(sentence1, "<footing>");
////      fprintf(fout, "<footing>");
////      rtf2_ParseText(tofind, NORMAL, PRINTTOFILE);
////      fputs("}", fout);
////      fputs("</footing>", fout);
//      ungetc('}', fin);
//      return(tofind);
//   }
//   else
//      for(index = 6; index >= 0; index--)
//         ungetc(string[index], fin);
//
//
//   /* Make sure it is not an index entry. */
//
//   index = 0;
//   ch = (char) fgetc(fin);
//   while((ch != '}') && (ch != '{'))
//   {
//     string[index++] = ch;
//     ch = (char) fgetc(fin);
//   }
//   if(ch == '{')
//   {
//     ch = (char) fgetc(fin);
//     if(ch == '\\')
//     {
//        strcpy(inst, rtf2_GetInstruction());
//        if(strcmp(inst, "xe"))
//          sscanf(inst, "%c%s", ch, inst);
//        if(!strcmp(inst, "xe"))
//        {
//          if(ch != '\\')
//            sprintf(inst, "%c%s", ch, inst);
//          R2Index(inst, 0, tofind);
//          //rtf2_ParseText('}', NORMAL, PRINTTOFILE);
//          return(0);
//	}
//        else
//        {
//          sprintf(inst, "%c%s", ch, inst);
//          string[index++] = '\\';
//          string[index] = '\0';
//          strcat(string, inst);
//          while(string[index] != '\0')
//             index++;
//	}
//     }
//     else
//     {
//       string[index++] = '{';
//       string[index++] = ch;
//     }
//   }
//   else
//     string[index++] = ch;
//   while(index>0)
//     ungetc(string[--index], fin);
//
//   /* Annotation */
//
//   token = R2UniqueID();
//   token2 = R2UniqueID();
////   fprintf(fout, "\n\\begindata{note,%d}\n", token);
////   fprintf(fout, "200 100 1\n");
//
//   /* Check to see if author field was scripted by 2rtf */
//   for(index = 0; index < 9; index++)
//      string[index] = (char) fgetc(fin);
//   string[index] = '\0';
//   if(!strcmp(string, "Author: "))
//   {
//      fscanf(fin, "%[^.].  ", string);
////      fprintf(fout, "\title{%s}\n", string);
//	strcat(sentence1, "<heading>");
////      fprintf(fout, "<heading>%s", string);
//   }
//   else
//      for(index = 8; index >= 0; index--)
//         ungetc(string[index], fin);
//
////   fprintf(fout, "\\begindata{text,%d}\n", token2);
////   fprintf(fout, "\\textdsversion{%d}\n", TextDSVersion);
//
////   rtf2_ParseText('}', NORMAL, PRINTTOFILE);
//
////   fprintf(fout, "\\\n\\enddata{text,%d}\n", token2);
////   fprintf(fout, "\\enddata{note,%d}\n", token);
////   fprintf(fout, "\\view{noteview,%d,0,0,0}", token);
////   fprintf(fout, "</heading>");
  return(0);
}

int R2Index(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handles index entries.  Due to the nature of rtf, it
 *  is difficult to determine whether or not an index entry
 *  is to be invisible or not.  This procedure works based
 *  on the assumption that all invisible index entries will
 *  start like this: "\xe\pard\plain {\v" with or without
 *  the space.  If something else is encountered, it is
 *  made into a visible index entry.  Due to the nature of
 *  EZ, it is not easy to keep the entries correct if the
 *  words are also formatted, so in both cases, formatting
 *  is stripped, and an invisible index entry is made.  For
 *  visible entries, the formatted text is parsed over again.
 *
 */
{
   int i, n;
   char tmp[TMP_SIZE], entry[TMP_SIZE], ch;

   n = 0;
   for(i=0; i<2; i++)
   {
      tmp[n++] = ch = (char) fgetc(fin);
      if(ch == '\\')
      {
         strcpy(entry, rtf2_GetInstruction());
         tmp[n] = '\0';
         strcat(tmp, entry);
         n += strlen(entry);
         tmp[n++] = ' ';
         if(strcmp(entry, "pard"))
           break;
      }
      else
         break;
   }

   if(!strcmp(entry, "plain"))
   {
      /* Check for " {\v", or "{\v", if neither are
         there put everything back into the input
         file and declare it a visible index entry */

      rtf2_AbsorbSpace();
      tmp[n++] = ch = (char) fgetc(fin);
      if(ch == '{')
      {
         tmp[n++] = ch = (char) fgetc(fin);
         if(ch == '\\')
         {
            tmp[n++] = ch = (char) fgetc(fin);
            if(ch == 'v')
            {
	       /* Invisible index entry.  Strip out
	          formatting comands.  Second ParseText
	          is there because the \v was skipped,
	          and its group needs to be handled. */

               while(1)
               {
                  ch = (char) fgetc(fin);
                  if(ch == '\\')
                     //rtf2_ParseText(' ', NORMAL, NOP);
			;
                  else if(!isspace(ch))
                  {
                     ungetc(ch, fin);
                     break;
		  }
	       }
//               fputs("\\indexi{", fout);
//	       rtf2_ParseText('}', NORMAL, PRINTTOFILE);
//	       fputc('}', fout);
//	       rtf2_ParseText('}', NORMAL, PRINTTOFILE);
               return(0);
	    }
            else
            {
               ungetc(ch, fin);
               ungetc('\\', fin);
               n -= 2;
	    }
	 }
         else
         {
            ungetc(ch, fin);
            n -= 1;
	 }
      }
      else
      {
         ungetc(ch, fin);
         n -= 1;
      }
   }

   /* Turn visible index entry into an invisible one, while
      preserving the text without a visible index entry. */

   i = 0;
   while(1)
   {
      tmp[n++] = ch = (char) fgetc(fin);
      if(ch == '{')
         continue;
      else if(ch == '\\')
         while(!isspace(ch))
            tmp[n++] = ch = (char) fgetc(fin);
      else if(!isspace(ch))
      {
	  while(ch != '}')
          {
             entry[i++] = ch;
             tmp[n++] = ch = (char) fgetc(fin);
	  }
          entry[i] = '\0';
          break;
      }
   }

   for(n--; n>=0; n--)
      ungetc(tmp[n], fin);
//   fprintf(fout, "\\indexi{%s}", entry);
//   rtf2_ParseText('}', NORMAL, PRINTTOFILE);
  return(0);
}

int R2Field(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle fields only by finding \fldrslt and copying
 *  that.
 *
 */
{
//   rtf2_ParseText('}', NORMAL, PRINTTOFILE);
//   if(!strcmp(command, "fldrslt"))
//     rtf2_ParseText('}', NORMAL, NOP);
  return(0);
}

int R2Header(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle headers and footers.  Breaks up left, center,
 *  and right by tabs in the rtf document.  When it sets
 *  flag to 1, that tells the tab routine that it's
 *  handling a header/footer.
 *
 */
{
   int token1, token2;
   int head = 0;
   int done = 0;
   char special;

   if(!strncmp(command, "header", 6))
     head = 1;
   special = command[6];

   token1 = R2UniqueID();
//   fprintf(fout, "\\begindata{header,%d}\n", token1);
//   fprintf(fout, "where:%s\n", head ? "header" : "footer");
//   fprintf(fout, "active:111\n");

   token2 = R2UniqueID();
//   fprintf(fout, "\\begindata{text,%d}\n", token2);
//   fprintf(fout, "\\textdsversion{%d}\n", TextDSVersion);
   strcat(sentence1,"<heading>");
//   fprintf(fout, "<heading>");

   flag = 1;
   /* Parse text until a tab or end is encountered. */
//   rtf2_ParseText('}', NORMAL, PRINTTOFILE);
   /* Set done if end is reached */
   if(flag)
     done = 1;

//   fprintf(fout, "\\\n\\enddata{text,%d}\n", token2);

   token2 = R2UniqueID();
//   fprintf(fout, "\\begindata{text,%d}\n", token2);
//  fprintf(fout, "\\textdsversion{%d}\n", TextDSVersion);

   /* Parse text until a tab or end is encountered. */
   if(!done)
   {
      flag = 1;
//      rtf2_ParseText('}', NORMAL, PRINTTOFILE);
      /* Set done if end is reached */
      if(flag)
        done = 1;
   }

//   fprintf(fout, "\\\n\\enddata{text,%d}\n", token2);
//   fprintf(fout, "</heading>\n");

   token2 = R2UniqueID();
//   fprintf(fout, "\\begindata{text,%d}\n", token2);
//   fprintf(fout, "\\textdsversion{%d}\n", TextDSVersion);
//     strcat(sentence1, "<heading>");
//   fprintf(fout, "<heading>");

   /* Parse text until the end of the group. */
//   if(!done)
//     rtf2_ParseText('}', NORMAL, PRINTTOFILE);

//   fprintf(fout, "</heading>\n");
//   fprintf(fout, "\\\n\\enddata{text,%d}\n", token2);

//   fprintf(fout, "\\enddata{header,%d}\n", token1);
//   fprintf(fout, "\\view{headrtv,%d,%d,0,0}\n", token1,
//	    head ? 15 : 17);

   flag = 0;
  return(0);
}

int R2Tab(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle tabs.  If flag is set, then we are dealing
 *  with a header/footer.
 *
 */
{
   if(flag)
   {
     flag = 0;
     return('}');
   }
   else
//     fputc('\t', fout);
     fprintf(fout, "\t");

  return(0);
}

int R2Current(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle current date & time, as well as pagenumber.
 *
 */
{
//   if(!strcmp(command, "chpgn"))
//     fputs("  $page", fout);
//   else if(!strcmp(command, "chdate"))
//     fputs("$date", fout);
//   else if(!strcmp(command, "chtime"))
//     fputs("$timeofday", fout);
  return(0);
}

/*
int R2Indent(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
 *
 *
 *  Handle local indentation.  Using formatnote.
 *
 *
{
   extern double LeftMargin, RightMargin;
   double m;
   int left;

   left = strcmp(command, "ri");

   if(left)
      m = LeftMargin + (double) numdel/1440.0;
   else
      m = RightMargin - (double) numdel/1440.0;

//   fprintf(fout, "\\formatnote{%s %.2fi}\n\n", left ? ".po" : ".ll", m);

   indented = 1;
}
*/

int R2Indent(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle local indentation.  Rounding to LeftIndent and
 *  RightIndent.
 *
 */
{
   int left;
   int i, n;

   left = strcmp(command, "ri");

   for(n = 0; numdel>0; numdel -= 720)
      n++;
   if(n>1 && numdel<-360)
      n--;

   for(i=0; i<n; i++){
//      fprintf(fout, "\\%s{", left ? "leftindent" : "rightindent");
      strcat(sentence1, (left ? "<indent>" : "<indentright>"));
//      fprintf(fout, "<%s>", left ? "indent" : "indentright");
	}
   indented += n;
  return(0);
}

int R2Pard(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Reset default paragraph specifications.
 *
 */
{
   if(fnote)
      return(0);

/*
   if(indented)
   {
      fprintf(fout, "\\formatnote{.po %.2fi}\n\n", LeftMargin);
      fprintf(fout, "\\formatnote{.ll %.2fi}\n\n", RightMargin);
      indented = 0;
   }
*/

   if(indented)
      for(; indented>0; indented--)
//	 fputs("}", fout);
	 fputs("<nl>\n", fout);

   if(tabs)
   {
      fprintf(fout, "<nl>\n\n");
      tabs = 0;
   }
  return(0);
}


int R2TabChange(command, numdel, tofind)
     char *command;
     int numdel;
     int tofind;
/*
 *
 *  Handle local tab changes.
 *
 */
{
/*
   static char type = 'L';

   if(!strcmp(command, "tqr"))
   {
      type = 'R';
      return;
   }
   if(!strcmp(command, "tqc"))
   {
      type = 'C';
      return;
   }

   fprintf(fout, "\t");
//   if(type != 'L')
//   {
//      fputc(type, fout);
//      type = 'L';
//   }
   fputs("<nl>\n", fout);
   tabs = 1;
*/
  return(0);
}

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