#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". 
# Note:  This script will NOT overwrite any existing files.
# If this archive is complete, you will see the following message at the end:
#		"End of shell archive."
#
# Contents:
#   README.HTML rtf2html.c Makefile.html
#
# Wrapped by cjh@cray.com on Mon Jul 19 07:29:23 1993
#
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README.HTML -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README.HTML\"
else
echo shar: Extracting \"README.HTML\" \(4953 characters\)
sed "s/^X//" >README.HTML <<'END_OF_README.HTML'
XRTF to HTML Conversion		Release 1.0
XJuly 19, 1993	Chris Hector	cjh@cray.com
X
XThis distribution contains source and documentation for rtf2html - a simple
XRTF to HTML translation tool. To build this you will also need an RTF
Xreader which is available at ftp.primate.wisc.edu/pub/RTF. 
XThis tool was based on release 7 of the RTF reader.
X
XTo build this tool.
X1)	Obtain the RTF reader and place the files in this directory.
X2)	Look at the RTF reader distribution and set up it's makeilf
X	for your machine.
X3)	Edit Makefile.html for your machines configuration
X4)	type make -f Makefile.html
X
X      
X
Xrtfhtml -RTF to HTML translator
X      Initial Implementation by Chris Hector (cjh@cray.com)
X      
X      This translator was based on rtfskel.
X      Kudos to Paul DuBois for his work in developing the
X      rtf reader and skeleton code.
X      
X      In this translator we will capture all of the text of an RTF file
X      and then use the paragraph style (heading 1, Normal,...), text
X      style (Bold, Italic) and the destination (header, footnote,
X      title) to choose appropriate HTML markup. In addition to
X      capturing text, pictures (Macintosh PICT format) will be captured
X      and each will be generated into it's own file.
X      
X      Most of the transformations are straightforward. The list
X      transformations (<ul>, <dir>...) are a little more complicated. I
X      have created multiple RTF styles that map to the same HTML
X      markup. These styles differ in how tab characters are treated
X      within the input. The description of the various list styles
X      follows:
X      
X
Xlist and markedlist styles
X      Thes styles both map to the HTML markup <ul>. In the "markedlist"
X      style, the translator assumes that each paragraph in the list
X      begins with :
X      string<tab>
X      Where the string is some sort of leader (like a "-" or bullet)
X      Since the <ul> markup will cause most browsers to add bullets to
X      the list, this translator will strip all characters up to  and
X      including the first tab. If there is no tab in the paragraph, all
X      text will be lost! (a warning is generated for this situation.)
X      If you don't want anything stripped off of the input, use the
X      "list" style.
X      
X
Xnumberedlist and orderedlist styles
X      These styles both map to the HTML markup <ol>. In the
X      "numberedlist " style, the translator assumes that each paragraph
X      in the list begins with :
X      string<tab>
X      Where the string is some sort of numeric leader (like 1 or 1.4.5)
X      Since the <ol> markup will cause most browsers to add sequence
X      numbers to the list, this translator will strip all characters up
X      to and including the first tab. If there is no tab in the
X      paragraph, all text will be lost!(a warning is generated for this
X      situation.) If you don't want anything stripped off of the input,
X      use the "orderedlist" style.
X      
X
Xglossary style
X      This style maps to the HTML markup <dl>. In the "glossary" style,
X      the translator assumes that each paragraph in the list begins
X      with :
X      string<tab>
X      Where the string is the term being defined. The remaining text in
X      the paragraph will be assumed to be the definition. If there is
X      no tab in the paragraph, you will get entries with terms but no
X      definitions. This may cause problems with some HTML browsers.
X      
X
Xdir style
X      This style maps to the HTML markup <dir>. In the "dir" style, the
X      translator assumes that directory entries are separated by either
X      tabs or paragraph marks. The directory entries may also come as a
X      table, in which case each cell contains a separate entry.
X
Xmenu style
X      This style maps to the HTML markup <menu>. In the "menu" style,
X      the translator assumes that menu entries are separated by
X      paragraph marks.
X      
X
XCharacter Translation
X      Bold Text translates to the HTML markup <b>.
X      Italic Text translates to the HTML markup <i>.
X      Underlined Text translates to the HTML markup <bu>.
X      Allcaps and Smallcaps cause translation to upper case.
X      '<', '&', and '>' are escaped on output
X
Xobjects:
X      imbedded objects (links) are ignored except that the result is
X      inserted inline.
X
Xpictures:
X      pictures (macintosh PICT format) are written to a separate file
X      and an link is made to them. the file name is pict[n].pict where
X      [n] is a unique integer. The link is to pict[n].multi assuming
X      that an external converter may be used to create the xbm or gif
X      format (picttoppm|ppmtogif.)
X
Xtitle:
X      The title is obtained from the info block and put into a <title>
X      block.
X
Xheaders and footers:
X      Headers and footers are expanded inline.
X
Xfootnotes:
X      Footnotes are appended to the end of the document. At the
X      footnote, a link is made to the footnote. The text of the
X      footnote is generated using the <dl> markup.
X      
END_OF_README.HTML
if test 4953 -ne `wc -c <README.HTML`; then
    echo shar: \"README.HTML\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rtf2html.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rtf2html.c\"
else
echo shar: Extracting \"rtf2html.c\" \(28407 characters\)
sed "s/^X//" >rtf2html.c <<'END_OF_rtf2html.c'
X/*
X	rtfhtml	-	RTF to HTML translator
X
X			Initial Implementation by Chris Hector (cjh@cray.com)
X
X			This translator was based on rtfskel. 
X			Kudos to Paul DuBois for his work in developing the
X			rtf reader and skeleton code.
X
X	July 13, 1993	Initial implementation.
X	General Design Notes:
X		First, familiarize yourself with the rtf reader and basic
X		design of rtf2troff, rtf2text.
X
X		To handle rtf groups, we create a stack which is pushed and
X		popped using PushStack/PopStack. When a group is begun,
X		the current values for all state information (for
X		example, what is the current character format) are pushed
X		onto the stack. The values are restored (popped) when the group
X		ends.
X
X		When a style change occurs, we expand the style (to obtain
X		any formatting imbedded in the style.) Then if the style
X		matches any of our HTML styles, we output the beginning 
X		marker (i.e. <h1>) We save the ending marker for that style
X		(</h1>) to be output at the next change of style.
X
X		A special case of this is for lists. In addition to the 
X		<ul> </ul> markers, we must output a <li> at each paragraph.
X		We do this by changing the end of paragraph string (usually
X		"<p>\n") to "\n<li>".
X
X		Character formats are handled by setting a corresponding 
X		bit for each style (bold, italic, etc.) When text is output,
X		the current character style is compared to the style of the
X		last character output. If it is different, then the required
X		markers are output to change the style. 
X
X		Design Issues:
X		HTML does not allow the nesting that is implied by
X		my interpretation of RTF. In particular, 
X		<h1><b><i></i></b></h1> is not legal HTML. 
X		To address this, I will use the paragraph style if it
X		matches one of the special ones (heading, list ...)
X		Otherwise I will handle the text style in the order:
X		Use the current style if one is active, else
X			pick the style in the order:
X			Bold 
X			Italic
X			Underline
X		Since Caps translation is done here rather than the
X		HTML viewer, I will perform that translation regardless
X		of the paragraph style or any other text styles.
X*/
X# include	<stdio.h>
X# include	<malloc.h>
X# include	"rtf.h"
X
X
Xint debug=0;
X#define MAXLOST		80
Xchar LostText[MAXLOST+1];		/* Buffer to keep discarded text */
Xint numlost=0;
X/* Attributes of input stream */
X
X/*	Text Styles */
X# define	stylePlain	0
X# define        styleBold       (1<<0)
X# define        styleItalic     (1<<1)
X# define        styleSmallCaps  (1<<2)
X# define        styleAllCaps    (1<<3)
X# define	styleAnyCaps	(styleSmallCaps |styleAllCaps)
X# define        styleInvisible  (1<<4)
X# define        styleUnderline  (1<<5)
X
X# define	ParNormal	0
X# define	ParNoCol1	1
X# define	ParMarkCol	2
X# define	ParTab2Par	3
X
X# define	PSAtCol1	0
X# define	PSInCol1	1
X# define	PSAtCol2	2
X# define	PSInCol2	3
X
Xstruct {
X    char *Name;
X    char *StartTag;
X    char *EndTag;
X    int TextStyleAllowed;
X    char *Col1Mark;
X    char *Col2Mark;
X    int ParProcess;
X} HS[] = {
X"NoSTyle",      "",               "",                1,"<p>\n","@",ParNormal,
X"heading 1",   "<h1>\n",         "</h1>",         0,"<p>\n","",ParNormal,
X"heading 2",   "<h2>\n",         "</h2>",         0,"<p>\n","",ParNormal,
X"heading 3",   "<h3>\n",         "</h3>",         0,"<p>\n","",ParNormal,
X"heading 4",   "<h4>\n",         "</h4>",         0,"<p>\n","",ParNormal,
X"heading 5",   "<h5>\n",         "</h5>",         0,"<p>\n","",ParNormal,
X"heading 6",   "<h6>\n",         "</h6>",         0,"<p>\n","",ParNormal,
X"address",     "<address>\n",    "</address>",    0,"<p>\n","",ParNormal,
X"pre",         "<pre>",        "</pre>",        0,"\n"   ,"",ParNormal,
X"blockquote",  "<blockquote>\n", "</blockquote>", 0,"<p>\n","",ParNormal,
X"dir",         "<dir>",        "</dir>",        0,"\n<li>","",ParTab2Par,
X"menu",        "<menu>",       "</menu>",       0,"\n<li>","\t",ParMarkCol,
X"glossary",    "<dl>",         "</dl>",         0,"\n<dt>","<dd>",ParMarkCol,
X"markedlist",        "<ul>",         "</ul>",         0,"","\n<li>",ParNoCol1,
X"list",   "<ul>",         "</ul>",         0,"","\n<li>",ParMarkCol,
X"numberedlist", "<ol>",         "</ol>",         0,"","\n<li>",ParNoCol1,
X"orderedlist", "<ol>",         "</ol>",         0,"","\n<li>",ParMarkCol,
XNULL,		NULL,		 NULL,		    0,NULL,NULL,ParNormal
X};
X
Xint ParStyle=0;
Xint TextStyle=0;
X
X/* Attributes of output stream */
X
X
X
X
X
X/* Destinations can be files or strings.  */
Xstatic void	EndFile();
Xstatic void	CloseFile();
Xstatic void	WriteTitle();
X
X#define DSALLOC		256
Xstruct ODest {
X    void (*Flush)();
X    int OldTextStyle;
X    int OldParStyle;
X    int ParState;
X    int FootNum;
X    FILE *outfile;
X    char *ptr;
X    int alloc;
X    int used;
X} 
XFile1={EndFile,0,0,0,0,stdout,NULL,0,0},
XPictFile={CloseFile,0,0,0,0,NULL,NULL,0,0},
XTitle={WriteTitle,0,0,0,0,NULL,NULL,0,0},
XFootnote={NULL,0,0,0,0,NULL,NULL,0,0},
X*OD=&File1;
X
X
Xstruct InStateStack {
X    void (*TextCallBack)();
X    int TextStyle;
X    int ParStyle;
X    struct InStateStack *Next;
X    struct ODest * OD;
X} *ISS=NULL;
X
Xchar FootRef[32];
X
Xstatic void
XCloseFile(){
X    fclose(OD->outfile);
X}
X
Xstatic void
XWriteTitle(){
X    if(Title.used>0){
X	Title.ptr[Title.used]='\0';
X	fprintf(ISS->OD->outfile,"<TITLE>%s</TITLE>\n",Title.ptr);
X	Title.used=0;
X    }   
X}
X
Xstatic void	UnknownClass ();
Xstatic void	GroupClass ();
Xstatic void	TextClass ();
Xstatic void	ControlClass ();
X
Xstatic void	Destination ();
Xstatic void	CharSet ();
Xstatic void	SpecialChar ();
Xstatic void	DocAttr ();
Xstatic void	SectAttr ();
Xstatic void	TblAttr ();
Xstatic void	ParAttr ();
Xstatic void	CharAttr ();
Xstatic void	PictAttr ();
Xstatic void	NeXTGrAttr ();
Xstatic void	FieldAttr ();
Xstatic void	TOCAttr ();
Xstatic void	PosAttr ();
Xstatic void 	AppendText();
X
X/*
X	structure for mapping character values >= 128 to text strings
X	for different character sets.
X*/
X
Xtypedef struct CharMap	CharMap;
X
Xstruct CharMap
X{
X	int	charVal;
X	char	*charStr;
X};
X
Xextern CharMap	ansiCharMap[];	/* these are defined below */
Xextern CharMap	macCharMap[];
Xextern CharMap	pcCharMap[];
Xextern CharMap	pcaCharMap[];
X
X/*
X	Default is ANSI but I hope we don't see \ansi, since its char
X	map is empty...
X*/
X
XCharMap	*charMap = ansiCharMap;
X
X
Xstatic void	PutHTML ();
Xstatic void	SaveText ();
Xstatic void	PutHex ();
Xstatic void 	PutStr();
Xstatic void PictAttr();
X
X
Xchar filename[256];
Xint outfuniq=0;
Xint main (argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	RTFInit ();
X
X	--argc;
X	++argv;
X
X	/* not clever; only allows stdin or one named file to be read */
X
X	if (argc > 0)
X	{
X		if (freopen (argv[0], "r", stdin) == NULL)
X		{
X			fprintf (stderr, "Can't open \"%s\"\n", argv[0]);
X			exit (1);
X		}
X	}
X
X	/* install class callbacks */
X
X	RTFSetClassCallback (rtfUnknown, UnknownClass);
X	RTFSetClassCallback (rtfGroup, GroupClass);
X	RTFSetClassCallback (rtfText, PutHTML);
X	RTFSetClassCallback (rtfControl, ControlClass);
X
X	/* de-install default destination callbacks */
X	RTFSetDestinationCallback(rtfInfo, NULL);
X	RTFSetDestinationCallback(rtfPict, NULL);
X
X        /*               
X                Process the input stream.  Make sure the first intoken is
X                a "{" so a state push will occur before anything else
X                (need to preserve state 0 intact for section, paragraph,
X                character default restoration).
X        */               
X                         
X        (void) RTFGetToken ();
X        if (!RTFCheckCM (rtfGroup, rtfBeginGroup))
X        {                
X                fprintf (stderr, "malformed rtf file - ");
X                fprintf (stderr, "does not begin with \"{\"\n");
X                exit (1);
X        }
X        RTFRouteToken ();       /* send "{" through router */
X        RTFRead ();             /* read everything else */
X
X	if(OD->Flush){
X	    OD->Flush();
X	}
X
X	exit (0);
X}
X
X
X/*
X	Token class callbacks
X*/
X
X
Xstatic void UnknownClass ()
X{
X	/* use this to print warnings about unknown tokens */
X	fprintf (stderr, "Unknown symbol %s\n", rtfTextBuf);
X}
X
X
Xstatic void GroupClass ()
X{
X	switch (rtfMajor)
X	{
X	case rtfBeginGroup:
X		/* push state */
X		PushIState();
X		break;
X	case rtfEndGroup:
X		/* pop state */
X		PopIState();
X		break;
X	}
X}
X
Xstatic void TextClass ()
X{
X	/* rtfMajor contains character value */
X}
X
X
X/*
X	Process control symbol.
X*/
X
Xstatic void ControlClass ()
X{
X	switch (rtfMajor)
X	{
X	case rtfVersion:
X		break;
X	case rtfDefFont:
X		/*
X			rtfParam contains the default font number.  Beware
X			that there is no guarantee that this font will actually
X			be listed in the font table!
X		*/
X		break;
X	case rtfCharSet:
X		CharSet ();
X		break;
X	case rtfDestination:
X		Destination ();
X		break;
X	case rtfFontFamily:
X		/* only occurs within font table - can ignore */
X		break;
X	case rtfColorName:
X		/* only occurs within color table - can ignore */
X		break;
X	case rtfSpecialChar:
X		SpecialChar ();
X		break;
X	case rtfStyleAttr:
X		/* only occurs within stylesheet - can ignore */
X		break;
X	case rtfDocAttr:
X		DocAttr ();
X		break;
X	case rtfSectAttr:
X		SectAttr ();
X		break;
X	case rtfTblAttr:
X		TblAttr ();
X		break;
X	case rtfParAttr:
X		ParAttr ();
X		break;
X	case rtfCharAttr:
X		CharAttr ();
X		break;
X	case rtfPictAttr:
X		PictAttr ();
X		break;
X	case rtfNeXTGrAttr:
X		NeXTGrAttr ();
X		break;
X	case rtfFieldAttr:
X		FieldAttr ();
X		break;
X	case rtfTOCAttr:
X		TOCAttr ();
X		break;
X	case rtfPosAttr:
X		PosAttr ();
X		break;
X	}
X}
X
X
X/*
X	Control class major number handlers.  Each one switches on
X	the minor numbers that occur within the major number.
X*/
X
X
Xstatic void CharSet ()
X{
X	switch (rtfMinor)
X	{
X	case rtfAnsiCharSet:
X		charMap = ansiCharMap;
X		break;
X	case rtfMacCharSet:
X		charMap = macCharMap;
X		break;
X	case rtfPcCharSet:
X		charMap = pcCharMap;
X		break;
X	case rtfPcaCharSet:
X		charMap = pcaCharMap;
X		break;
X	}
X}
X
X
Xstatic void Destination ()
X{
X	switch (rtfMinor)
X	{
X	case rtfPict:
X		break;
X	case rtfNeXTGraphic:
X		break;
X	case rtfFootnote:
X		/* change the destination to the footnote string */
X		fprintf(OD->outfile," <A href=\"#fn%d\">fn%d</A> ",OD->FootNum,
X		OD->FootNum);
X		RTFSetClassCallback (rtfText, SaveText);
X		OD=&Footnote;
X		if(Footnote.used==0)AppendText("<dl>");
X		sprintf(FootRef,"\n<dt>fn%d<dd>",OD->FootNum++);
X		AppendText(FootRef);
X		break;
X	case rtfHeader:
X		RTFSkipGroup ();
X		break;
X	case rtfHeaderLeft:
X		RTFSkipGroup ();
X		break;
X	case rtfHeaderRight:
X		RTFSkipGroup ();
X		break;
X	case rtfHeaderFirst:
X		RTFSkipGroup ();
X		break;
X	case rtfFooter:
X		RTFSkipGroup ();
X		break;
X	case rtfFooterLeft:
X		RTFSkipGroup ();
X		break;
X	case rtfFooterRight:
X		RTFSkipGroup ();
X		break;
X	case rtfFooterFirst:
X		RTFSkipGroup ();
X		break;
X	case rtfFNSep:
X		break;
X	case rtfFNContSep:
X		RTFSkipGroup ();
X		break;
X	case rtfFNContNotice:
X		RTFSkipGroup ();
X		break;
X	case rtfInfo:
X		break;
X	case rtfStyleSheet:
X		/* will never occur because of default destination reader */
X		break;
X	case rtfFontTbl:
X		/* will never occur because of default destination reader */
X		break;
X	case rtfColorTbl:
X		/* will never occur because of default destination reader */
X		break;
X	case rtfField:
X		break;
X	case rtfFieldInst:
X		break;
X	case rtfFieldResult:
X		break;
X	case rtfIndex:
X		break;
X	case rtfIndexBold:
X		break;
X	case rtfIndexItalic:
X		break;
X	case rtfIndexText:
X		break;
X	case rtfIndexRange:
X		RTFSkipGroup ();
X		break;
X	case rtfTOC:
X		break;
X	case rtfBookmarkStart:
X		break;
X	case rtfBookmarkEnd:
X		break;
X	case rtfITitle:
X		/* change the destination to the title string */
X		RTFSetClassCallback (rtfText, SaveText);
X		OD=&Title;
X		break;
X	case rtfISubject:
X		RTFSkipGroup ();
X		break;
X	case rtfIAuthor:
X		RTFSkipGroup ();
X		break;
X	case rtfIOperator:
X		RTFSkipGroup ();
X		break;
X	case rtfIKeywords:
X		RTFSkipGroup ();
X		break;
X	case rtfIComment:
X		RTFSkipGroup ();
X		break;
X	case rtfIVersion:
X		RTFSkipGroup ();
X		break;
X	case rtfIDoccomm:
X		RTFSkipGroup ();
X		break;
X	case rtfObject:
X		break;
X	case rtfObjData:
X		RTFSkipGroup ();
X		break;
X	case rtfObjClass:
X		RTFSkipGroup ();
X		break;
X	case rtfObjName:
X		RTFSkipGroup ();
X		break;
X	case rtfObjResult:
X		break;
X	}
X}
X
X
Xstatic void SpecialChar ()
X{
X	switch (rtfMinor)
X	{
X	case rtfCurHeadPage:
X		break;
X	case rtfCurFNote:
X		break;
X	case rtfCurHeadPict:
X		break;
X	case rtfCurHeadDate:
X		break;
X	case rtfCurHeadTime:
X		break;
X	case rtfFormula:
X		break;
X	case rtfNoBrkSpace:
X		rtfMajor=' ';
X		PutHTML();
X		break;
X	case rtfNoReqHyphen:
X		break;
X	case rtfNoBrkHyphen:
X		rtfMajor='-';
X		PutHTML();
X	case rtfRow:
X		break;
X	case rtfSect:
X	case rtfPage:
X	case rtfLine:
X	case rtfPar:
X		if(debug)printf("Par,t=%d,s=%d\n",HS[ParStyle].ParProcess,OD->ParState);
X		if(HS[ParStyle].ParProcess==ParNormal){
X		    PutStr (HS[ParStyle].Col1Mark);
X		} else {
X		    if(HS[ParStyle].ParProcess==ParNoCol1&
X		    OD->ParState==PSInCol1){
X			/* list entry with only deleted text? */
X			LostText[numlost]='\0';
X			fprintf(stderr,
X			"Warning - A list element contained only a leader and was deleted:\n   \"%s\"\n",LostText);
X		    }
X		    OD->ParState=PSAtCol1;
X		    numlost=0;
X		}
X		break;
X	case rtfBullet:
X		rtfMajor='*';
X		PutHTML();
X		break;
X	case rtfTab:
X	case rtfCell:
X		if(debug)printf("Tab,t=%d,s=%d\n",HS[ParStyle].ParProcess,OD->ParState);
X		if(HS[ParStyle].ParProcess==ParTab2Par){
X		    OD->ParState=PSAtCol1;
X		} else if(HS[ParStyle].ParProcess==ParNormal|
X		   OD->ParState>PSAtCol2){
X		    PutStr ("\t");
X		} else {
X		    OD->ParState=PSAtCol2;
X		}
X		break;
X	case rtfCurAnnot:
X		break;
X	case rtfAnnotation:
X		break;
X	case rtfAnnotID:
X		break;
X	case rtfCurAnnotRef:
X		break;
X	case rtfFNoteSep:
X		break;
X	case rtfFNoteCont:
X		break;
X	case rtfColumn:
X		break;
X	case rtfOptDest:
X		RTFSkipGroup ();
X		break;
X	case rtfIIntVersion:
X		break;
X	case rtfICreateTime:
X		break;
X	case rtfIRevisionTime:
X		break;
X	case rtfIPrintTime:
X		break;
X	case rtfIBackupTime:
X		break;
X	case rtfIEditTime:
X		break;
X	case rtfIYear:
X		break;
X	case rtfIMonth:
X		break;
X	case rtfIDay:
X		break;
X	case rtfIHour:
X		break;
X	case rtfIMinute:
X		break;
X	case rtfINPages:
X		break;
X	case rtfINWords:
X		break;
X	case rtfINChars:
X		break;
X	case rtfIIntID:
X		break;
X	}
X}
X
X
Xstatic void DocAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfPaperWidth:
X		break;
X	case rtfPaperHeight:
X		break;
X	case rtfLeftMargin:
X		break;
X	case rtfRightMargin:
X		break;
X	case rtfTopMargin:
X		break;
X	case rtfBottomMargin:
X		break;
X	case rtfFacingPage:
X		break;
X	case rtfGutterWid:
X		break;
X	case rtfDefTab:
X		break;
X	case rtfWidowCtrl:
X		break;
X	case rtfHyphHotZone:
X		break;
X	case rtfFNoteEndSect:
X		break;
X	case rtfFNoteEndDoc:
X		break;
X	case rtfFNoteText:
X		break;
X	case rtfFNoteBottom:
X		break;
X	case rtfFNoteStart:
X		break;
X	case rtfFNoteRestart:
X		break;
X	case rtfPageStart:
X		break;
X	case rtfLineStart:
X		break;
X	case rtfLandscape:
X		break;
X	case rtfFracWidth:
X		break;
X	case rtfNextFile:
X		break;
X	case rtfTemplate:
X		break;
X	case rtfMakeBackup:
X		break;
X	case rtfRTFDefault:
X		break;
X	case rtfRevisions:
X		break;
X	case rtfMirrorMargin:
X		break;
X	case rtfRevDisplay:
X		break;
X	case rtfRevBar:
X		break;
X	}
X}
X
X
Xstatic void SectAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfSectDef:
X		break;
X	case rtfNoBreak:
X		break;
X	case rtfColBreak:
X		break;
X	case rtfPageBreak:
X		break;
X	case rtfEvenBreak:
X		break;
X	case rtfOddBreak:
X		break;
X	case rtfPageStarts:
X		break;
X	case rtfPageCont:
X		break;
X	case rtfPageRestart:
X		break;
X	case rtfPageDecimal:
X		break;
X	case rtfPageURoman:
X		break;
X	case rtfPageLRoman:
X		break;
X	case rtfPageULetter:
X		break;
X	case rtfPageLLetter:
X		break;
X	case rtfPageNumLeft:
X		break;
X	case rtfPageNumTop:
X		break;
X	case rtfHeaderY:
X		break;
X	case rtfFooterY:
X		break;
X	case rtfLineModulus:
X		break;
X	case rtfLineDist:
X		break;
X	case rtfLineStarts:
X		break;
X	case rtfLineRestart:
X		break;
X	case rtfLineRestartPg:
X		break;
X	case rtfLineCont:
X		break;
X	case rtfTopVAlign:
X		break;
X	case rtfBottomVAlign:
X		break;
X	case rtfCenterVAlign:
X		break;
X	case rtfJustVAlign:
X		break;
X	case rtfColumns:
X		break;
X	case rtfColumnSpace:
X		break;
X	case rtfColumnLine:
X		break;
X	case rtfENoteHere:
X		break;
X	case rtfTitleSpecial:
X		break;
X	}
X}
X
X
Xstatic void TblAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfCellBordBottom:
X		break;
X	case rtfCellBordTop:
X		break;
X	case rtfCellBordLeft:
X		break;
X	case rtfCellBordRight:
X		break;
X	case rtfRowDef:
X		break;
X	case rtfRowLeft:
X		break;
X	case rtfRowRight:
X		break;
X	case rtfRowCenter:
X		break;
X	case rtfRowGapH:
X		break;
X	case rtfRowHt:
X		break;
X	case rtfRowLeftEdge:
X		break;
X	case rtfCellPos:
X		break;
X	case rtfMergeRngFirst:
X		break;
X	case rtfMergePrevious:
X		break;
X	}
X}
X
Xint parnest=0;
X
Xstatic void ParAttr ()
X{
X	RTFStyle *newstyle;
X	int i;
X	switch (rtfMinor)
X	{
X	case rtfParDef:	/* set the input paragraph stype to null */
X		ParStyle=0;		
X		break;
X	case rtfStyleNum:
X		/* When we call RTFExpandStyle, ParAttr will get recursively
X		called. We only perform processing on the outermost style. */
X		if(parnest==0){
X		    newstyle=RTFGetStyle(rtfParam);
X		    ParStyle=0;
X		    for(i=1;HS[i].Name!=NULL;i++){
X			if(strcmp(newstyle->rtfSName,HS[i].Name)==0){
X			    ParStyle=i;
X			    break;
X			}
X		    }
X		    parnest++;
X		    RTFExpandStyle(rtfParam);
X		    parnest--;
X		}
X		break;
X	case rtfQuadLeft:
X		break;
X	case rtfQuadRight:
X		break;
X	case rtfQuadJust:
X		break;
X	case rtfQuadCenter:
X		break;
X	case rtfFirstIndent:
X		break;
X	case rtfLeftIndent:
X		break;
X	case rtfRightIndent:
X		break;
X	case rtfSpaceBefore:
X		break;
X	case rtfSpaceAfter:
X		break;
X	case rtfSpaceBetween:
X		break;
X	case rtfInTable:
X		break;
X	case rtfKeep:
X		break;
X	case rtfKeepNext:
X		break;
X	case rtfSideBySide:
X		break;
X	case rtfPBBefore:
X		break;
X	case rtfNoLineNum:
X		break;
X	case rtfTabPos:
X		break;
X	case rtfTabRight:
X		break;
X	case rtfTabCenter:
X		break;
X	case rtfTabDecimal:
X		break;
X	case rtfTabBar:
X		break;
X	case rtfBorderTop:
X		break;
X	case rtfBorderBottom:
X		break;
X	case rtfBorderLeft:
X		break;
X	case rtfBorderRight:
X		break;
X	case rtfBorderBar:
X		break;
X	case rtfBorderBox:
X		break;
X	case rtfBorderBetween:
X		break;
X	case rtfBorderSingle:
X		break;
X	case rtfBorderThick:
X		break;
X	case rtfBorderShadow:
X		break;
X	case rtfBorderDouble:
X		break;
X	case rtfBorderDot:
X		break;
X	case rtfBorderHair:
X		break;
X	case rtfBorderSpace:
X		break;
X	case rtfLeaderDot:
X		break;
X	case rtfLeaderHyphen:
X		break;
X	case rtfLeaderUnder:
X		break;
X	case rtfLeaderThick:
X		break;
X	}
X}
X
X
X/*
X	Several of the attributes can be turned off with param value
X	of zero (e.g., \b vs. \b0), but since the value of rtfParam
X	is 0 if no param is given, test the text of the token directly.
X*/
X
Xstatic void CharAttr ()
X{
Xint	turnOn = (rtfTextBuf[rtfTextLen-1] != '0');
X
X	switch (rtfMinor)
X	{
X	case rtfPlain:
X		TextStyle = stylePlain;
X		break;
X	case rtfBold:
X		if(turnOn){
X		    TextStyle |= styleBold;
X		} else {
X		    TextStyle &= ~styleBold;
X		}
X		break;
X	case rtfItalic:
X		if(turnOn){
X		    TextStyle |= styleItalic;
X		} else {
X		    TextStyle &= ~styleItalic;
X		}
X		break;
X	case rtfStrikeThru:
X		break;
X	case rtfOutline:
X		break;
X	case rtfShadow:
X		break;
X	case rtfSmallCaps:
X		if(turnOn){
X		    TextStyle |= styleSmallCaps;
X		} else {
X		    TextStyle &= ~styleSmallCaps;
X		}
X		break;
X	case rtfAllCaps:
X		if(turnOn){
X		    TextStyle |= styleAllCaps;
X		} else {
X		    TextStyle &= ~styleAllCaps;
X		}
X		break;
X	case rtfInvisible:
X		if(turnOn){ /* Not currently used */
X		    TextStyle |= styleInvisible;
X		} else {
X		    TextStyle &= ~styleInvisible;
X		}
X		break;
X	case rtfFontNum:
X		break;
X	case rtfFontSize:
X		break;
X	case rtfExpand:
X		break;
X	case rtfUnderline:
X		if(turnOn){
X		    TextStyle |= styleUnderline;
X		} else {
X		    TextStyle &= ~styleUnderline;
X		}
X		break;
X	case rtfWUnderline:
X		if(turnOn){
X		    TextStyle |= styleUnderline;
X		} else {
X		    TextStyle &= ~styleUnderline;
X		}
X		break;
X	case rtfDUnderline:
X		if(turnOn){
X		    TextStyle |= styleUnderline;
X		} else {
X		    TextStyle &= ~styleUnderline;
X		}
X		break;
X	case rtfDbUnderline:
X		if(turnOn){
X		    TextStyle |= styleUnderline;
X		} else {
X		    TextStyle &= ~styleUnderline;
X		}
X		break;
X	case rtfSuperScript:
X		break;
X	case rtfNoUnderline:
X		    TextStyle &= ~styleUnderline;
X		break;
X	case rtfSubScript:
X		break;
X	case rtfRevised:
X		break;
X	case rtfForeColor:
X		break;
X	case rtfBackColor:
X		break;
X	}
X}
X
Xchar zeros[512];
X
Xstatic void PictAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfMacQD:
X		/* change the destination to a pict file */
X		sprintf(filename,"pic%d.pict",++outfuniq);
X		fprintf(OD->outfile,"<A href=\"pic%d.multi\">Picture %d</A>",outfuniq,
X		    outfuniq);
X		PictFile.outfile=fopen(filename,"w");
X		if(PictFile.outfile==NULL){
X		    fprintf(stderr,"Open of %s Failed\n",filename);
X		    exit(1);
X		}
X		fwrite(zeros,512,1,PictFile.outfile); 
X		RTFSetClassCallback (rtfText, PutHex);
X		OD=&PictFile;
X		break;
X	case rtfWinMetafile:
X		break;
X	case rtfWinBitmap:
X		break;
X	case rtfPicWid:
X		break;
X	case rtfPicHt:
X		break;
X	case rtfPicGoalWid:
X		break;
X	case rtfPicGoalHt:
X		break;
X	case rtfPicScaleX:
X		break;
X	case rtfPicScaleY:
X		break;
X	case rtfPicScaled:
X		break;
X	case rtfPicCropTop:
X		break;
X	case rtfPicCropBottom:
X		break;
X	case rtfPicCropLeft:
X		break;
X	case rtfPicCropRight:
X		break;
X	case rtfPixelBits:
X		break;
X	case rtfBitmapPlanes:
X		break;
X	case rtfBitmapWid:
X		break;
X	case rtfPicBinary:
X		break;
X	}
X}
X
X
Xstatic void NeXTGrAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfNeXTGWidth:
X		break;
X	case rtfNeXTGHeight:
X		break;
X	}
X}
X
X
Xstatic void FieldAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfFieldDirty:
X		break;
X	case rtfFieldEdited:
X		break;
X	case rtfFieldLocked:
X		break;
X	case rtfFieldPrivate:
X		break;
X	}
X}
X
X
Xstatic void TOCAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfTOCType:
X		break;
X	case rtfTOCLevel:
X		break;
X	}
X}
X
X
Xstatic void PosAttr ()
X{
X	switch (rtfMinor)
X	{
X	case rtfPosX:
X		break;
X	case rtfPosXCenter:
X		break;
X	case rtfPosXInside:
X		break;
X	case rtfPosXLeft:
X		break;
X	case rtfPosXOutSide:
X		break;
X	case rtfPosXRight:
X		break;
X	case rtfPosY:
X		break;
X	case rtfPosYInline:
X		break;
X	case rtfPosYTop:
X		break;
X	case rtfPosYCenter:
X		break;
X	case rtfPosYBottom:
X		break;
X	case rtfAbsWid:
X		break;
X	case rtfTextDistX:
X		break;
X	case rtfTextDistY:
X		break;
X	case rtfRPosMargV:
X		break;
X	case rtfRPosPageV:
X		break;
X	case rtfRPosMargH:
X		break;
X	case rtfRPosPageH:
X		break;
X	case rtfRPosColH:
X		break;
X	}
X}
X
Xchar twochar[3];
Xint charnum=0;
X
Xstatic void
XPutHex()
X{
X    int xval;
X    twochar[charnum]=rtfMajor;
X    if(++charnum==2){
X	sscanf(twochar,"%2x",&xval);
X	fputc((char) xval,OD->outfile);
X	charnum=0;
X    }
X}
X
Xstatic void
XSaveText()
X{
X    if(OD->alloc<=OD->used+1){
X        OD->alloc+=DSALLOC;
X	if(OD->ptr==NULL){
X	    OD->ptr=(char  *) malloc(
X		sizeof(char )*OD->alloc);
X	} else {
X	    OD->ptr=(char  *) realloc((void *) OD->ptr,
X		sizeof(char )*OD->alloc);
X	}
X        if(OD->ptr==NULL){
X            fprintf(stderr,"Memory Allocation Failed\n");
X                exit(1);
X        }
X    }
X    OD->ptr[(OD->used)++]=rtfMajor;
X}
X
Xstatic void
XAppendText(text)
Xchar * text;
X{
X    int need;
X    need=OD->used+1+strlen(text);
X    if(OD->alloc<=OD->used+1+strlen(text)){
X        OD->alloc+=need>DSALLOC? need : DSALLOC;
X	if(OD->ptr==NULL){
X	    OD->ptr=(char  *) malloc(
X		sizeof(char )*OD->alloc);
X	} else {
X	    OD->ptr=(char  *) realloc((void *) OD->ptr,
X		sizeof(char )*OD->alloc);
X	}
X        if(OD->ptr==NULL){
X            fprintf(stderr,"Memory Allocation Failed\n");
X                exit(1);
X        }
X    }
X    strcpy(&(OD->ptr[(OD->used)]),text);
X    OD->used+=strlen(text);
X}
X
X
Xstatic void
XTestStyle()
X{
X/*
X	Change the style of the output text to the new style.
X	If the style changes, force correct nesting of HTML tags.
X*/
Xint i,j;
X
X	/* If we have an active text style and styles are not allowed or
X	If the active style in no longer on, then turn it off */
X	if(OD->OldTextStyle &&(!HS[ParStyle].TextStyleAllowed || 
X	!(OD->OldTextStyle&TextStyle))){
X	    if(OD->OldTextStyle&styleBold){
X		fputs("</b>",OD->outfile);
X	    } else if (OD->OldTextStyle&styleItalic){
X		fputs("</i>",OD->outfile);
X	    } else if (OD->OldTextStyle&styleUnderline){
X		fputs("</u>",OD->outfile);
X	    }
X	    OD->OldTextStyle=stylePlain; 
X	} 
X	if(ParStyle!=OD->OldParStyle){ /* Change the Paragraph Style */
X	    fputs(HS[OD->OldParStyle].EndTag,OD->outfile);
X	    fputs(HS[ParStyle].StartTag,OD->outfile);
X	    OD->OldParStyle=ParStyle;
X	}
X	/* If TextStyles are allowed turn them on */
X	if(HS[ParStyle].TextStyleAllowed&&!OD->OldTextStyle && TextStyle){
X	    if(TextStyle&styleBold){
X		fputs("<b>",OD->outfile);
X		OD->OldTextStyle=styleBold;
X	    } else if (TextStyle&styleItalic){
X		fputs("<i>",OD->outfile);
X		OD->OldTextStyle=styleItalic;
X	    } else if (TextStyle&styleUnderline){
X		fputs("<u>",OD->outfile);
X		OD->OldTextStyle=styleUnderline;
X	    } 
X	}
X}
X
Xstatic void
XPutStr(s)
Xchar *s;
X{
X	if(ParStyle!=OD->OldParStyle){ /* Change the Paragraph Style */
X	    if(debug)printf("o=%d,n=%d,s=%s",OD->OldParStyle,ParStyle,s);
X	}
X	TestStyle();
X	fputs(s,OD->outfile);
X}
X
Xstatic void 
XPutHTML ()
X{
XCharMap	*cmp;
Xchar	*p = "X";
Xint i,j;
X
X	if(ParStyle!=OD->OldParStyle){ /* Change the Paragraph Style */
X	    if(debug)printf("o=%d,n=%d,c=%c",OD->OldParStyle,ParStyle,rtfMajor);
X	}
X    TestStyle();
X    if(debug)printf("chr,t=%d,s=%d\n",HS[ParStyle].ParProcess,OD->ParState);
X    if(HS[ParStyle].ParProcess!=ParNormal){
X	if(OD->ParState==PSAtCol2){
X	    fputs(HS[ParStyle].Col2Mark,OD->outfile);
X	    OD->ParState=PSInCol2;
X	} else if(HS[ParStyle].ParProcess==ParMarkCol|
X	    HS[ParStyle].ParProcess==ParTab2Par){
X	    if(OD->ParState==PSAtCol1){
X		fputs(HS[ParStyle].Col1Mark,OD->outfile);
X		OD->ParState=PSInCol1;
X	    }
X	} else {/* ParNoCol1 */
X	    if(OD->ParState<PSAtCol2){ /* Skip all of column 1 */
X		if(numlost<MAXLOST)LostText[numlost++]=rtfMajor;
X		OD->ParState=PSInCol1;
X		return;
X	    }
X	}
X    }
X    
X    if(rtfMajor == '<')fputs("&lt",OD->outfile);
X    else if(rtfMajor == '>')fputs("&gt",OD->outfile);
X    else if(rtfMajor == '&')fputs("&amp",OD->outfile);
X    else if (rtfMajor < 128){
X	    if((TextStyle&styleAnyCaps)&&(islower (rtfMajor))){
X		fputc (toupper (rtfMajor),OD->outfile);
X	    } else {
X		fputc (rtfMajor,OD->outfile);
X	    }
X    } else {
X	    for (cmp = charMap; cmp->charStr != (char *) NULL; cmp++)
X	    {
X		    if (rtfMajor == cmp->charVal)
X		    {
X			    p = cmp->charStr;
X			    break;
X		    }
X	    }
X	    fputs (p, OD->outfile);
X    }
X}
X
X
XCharMap	ansiCharMap [] =
X{
X	0,	NULL
X};
X
X
XCharMap	macCharMap [] =
X{
X	0xa0,	"+",		/* dagger */
X	0xa1,	"deg.",		/* degree */
X	0xa2,	"cents",	/* cent */
X	0xa5,	"o",		/* bullet */
X	0xa7,	"B",		/* German B? */
X	0xa8,	"reg.",		/* registered */
X	0xa9,	"(c)",		/* copyright */
X	0xaa,	"(TM)",		/* trademark */
X	0xab,	"'",		/* acute accent */
X	0xad,	"!=",		/* not equal */
X	0xae,	"AE",		/* joined A-E */
X	0xb1,	"+/-",		/* plus or minus */
X	0xb2,	"<=",		/* less than or equal */
X	0xb3,	">=",		/* greater than or equal */
X	0xb5,	"u",		/* micro */
X	0xb6,	"d",		/* delta */
X	0xbe,	"ae",		/* joined a-e */
X	0xc5,	"~",		/* approximately */
X	0xc7,	"<<",		/* alternate quote */
X	0xc8,	">>",		/* alternate end-quote*/
X	0xc9,	"...",		/* ellipsis */
X	0xca,	" ",		/* unbreakable space */
X	0xd0,	"-",		/* short dash */
X	0xd1,	"--",		/* long dash */
X	0xd2,	"\"",		/* left curly double quote */
X	0xd3,	"\"",		/* right curly double quote */
X	0xd4,	"`",		/* left curly single quote */
X	0xd5,	"'",		/* right curly single quote */
X	0xd6,	"/",		/* divide */
X	0,	NULL
X};
X
X
XCharMap	pcCharMap [] =
X{
X	0,	NULL
X};
X
X
XCharMap	pcaCharMap [] =
X{
X	0,	NULL
X};
X
XPushIState(){
X/*
X	Push the current state. Note that defaults are not set,
X	so resetting the default state (such as for headers/footers)
X	must be done after the Push.
X*/
X    struct InStateStack *Current=ISS;
X    ISS=(struct InStateStack *) malloc(
X	sizeof(struct InStateStack));
X    if(ISS==NULL){
X	fprintf(stderr,"Memory Allocation Failed\n");
X	    exit(1);
X    }
X    ISS->TextCallBack=RTFGetClassCallback(rtfText);
X    ISS->TextStyle=TextStyle;
X    ISS->ParStyle=ParStyle;
X    ISS->OD=OD;
X    ISS->Next=Current;
X}
X
XPopIState(){
X    struct InStateStack *Current=ISS;
X    if(ISS==NULL){
X	fprintf(stderr,"Input State Stack Popped too many times\n");
X	exit(1);
X    }
X    TextStyle=ISS->TextStyle;
X    ParStyle=ISS->ParStyle;
X    if(ISS->OD!=OD){ /* Changed Output Destinations */
X	if(OD->Flush){
X	    OD->Flush();
X	}
X	OD=ISS->OD;
X    }
X    RTFSetClassCallback (rtfText, ISS->TextCallBack);
X    ISS=ISS->Next;
X    free(Current);
X}
X
Xstatic void
XEndFile(){
X    /* Force closing of any tags */
X    ParStyle=0;
X    TextStyle=stylePlain;
X    TestStyle();
X    if(Footnote.used>0){
X	Footnote.ptr[Footnote.used]='\0';
X	fputs(Footnote.ptr,OD->outfile);
X	fputs("</dl>\n",OD->outfile);
X	Footnote.used=0;
X    }
X
X    fclose(OD->outfile);
X}
X
END_OF_rtf2html.c
if test 28407 -ne `wc -c <rtf2html.c`; then
    echo shar: \"rtf2html.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile.html -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile.html\"
else
echo shar: Extracting \"Makefile.html\" \(288 characters\)
sed "s/^X//" >Makefile.html <<'END_OF_Makefile.html'
Xrtf2html:	rtfreader  rtf.h rtf2html.c
X	${CC}	${CCFLAGS} reader.o rtf2html.c -o rtf2html
X
Xclean:	
X	rm rtf2html rtf2html.o
X
Xrtfreader:	reader.c
X	${MAKE}	reader.o
X
Xreader.c:	
X	@ echo You need to get the RTF package from ftp.primate.wisc.edu
X	@ echo and put it into this directory.
X	@ exit 1
END_OF_Makefile.html
if test 288 -ne `wc -c <Makefile.html`; then
    echo shar: \"Makefile.html\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
