ftp.nice.ch/pub/next/text/tex/apps/Bibliography.1.2a.s.tar.gz#/Bibliography.1.2a/Bbl2rtf.m

This is Bbl2rtf.m in view mode; [Download] [Up]

//	Copyright H. Giesen, University of Koblenz-Landau 1996


#define	LBRACE '{'
#define	RBRACE '}'

#define	LPARA	'('
#define	RPARA	')'

#define	LBRACKET	'['
#define	RBRACKET	']'


#import "Bbl2rtf.h"

static	char buf[512];

const char *rtfHeader =
	"{\\rtf0\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\n"
	"\\paperw8640\\paperh8280\\margl120\\margr120\n"
	"\\f0\\pard\\tx200\\tx1040\\tx2080\\tx3920\\fc0\\cf0"
	"\\fi-1060\\li1060\n";

const char *rtfTail = "}\\\n";

const char *htmlHeader = "<HTML><BODY>";
const char *htmlTail   = "</BODY></HTML>";

typedef struct{
	const char *texCmd;
	const char *hdr[4];
}cvTblType;


cvTblType cvTable[] = {
	{ "begin",		{NULL,	NULL,		"<table>", NULL }},
	{ "end",		{NULL,	NULL,		"</table>", NULL }},
	{ "bibitem",	{"\\\n", NULL,		"<P>", NULL }},
	{ "newblock",	{" ", NULL,			" ", " " }},
	{ "mbox",		{NULL, NULL,		NULL, NULL }},
	{ "em",			{"\\i", "\\i0",		"<CITE>", "</CITE>" }},
	{ "it",			{"\\i", "\\i0",		"<I>", "</I>" }},
	{ "bf",			{"\\b", "\\b0",		"<B>", "</B>" }},
	{ NULL,			{NULL, NULL, NULL }}
};


@implementation Bbl2rtf


- initFromStream:(NXStream *)stream
{
	[super init];
	memStream = stream;

	// create the output stream and position
	textStream = NXOpenMemory(0, 0, NX_READWRITE);
	NXSeek(textStream, 0L, NX_FROMSTART);
	citeNumber = 0;
	if( stack==nil )stack = [[List alloc] init];
	return self;
}


- initFromFile:(const char *)fname
{
	NXStream *locStream = NXMapFile(fname, NX_READONLY);
	if( locStream ) return [self initFromStream:locStream];
	return nil;
}


/* appendRTF: appends an arbitrary RTF string
 * to the RTF object
 */
- appendRTF:(const char *)string
{
	NXSeek(textStream, 0L, NX_FROMEND);
	NXWrite(textStream, string, strlen(string));
	return self;
}


- (void)nextChar
{
	token = NXGetc( memStream );
	if( token=='\n' ){
		//lineNumber++;
	}
	if( token==EOF ) token=0;
}


- (int) indexOfCmd:(const char *)cmd
{
	int i=0;
	while( cvTable[i].texCmd ){
		if( strcmp( cmd, cvTable[i].texCmd )==0 ){
			return i;
		}
		i++;
	}
	return -1;
}


//	called when '\' is found
- (int)cmd
{
	int	i=0;
	
	[self nextChar];
	while( NXIsAlpha(token) ){
		buf[i++] = token;
		[self nextChar];
	}
	if( i==0 ){	// was a quoted character
		NXPutc(textStream, '\\');
		/////NXUngetc( memStream );
		return -1;
	}
	//	TeX macro was found
	buf[i] = '\0';
	//if( token==LBRACE ) NXPutc(textStream, '\\');
	//NXUngetc( memStream );
	return [self indexOfCmd:buf];
}


- (void)copyBracket
{
	while( token && (token!=LBRACKET) ) [self nextChar];
	NXPutc(textStream, token);	// output leftbracket
	[self nextChar];	// skip leftbracket
	while( token && (token!=RBRACKET) ){
		NXPutc(textStream, token);
		[self nextChar];
	}
	NXPutc(textStream, token);
	[self nextChar];	// skip last bracket
}

//	syntax of \bibitem :
//		\bibitem[label]{cite_key}
//		\bibitem{cite_key}	// [label] must be generated
- (void) deleteBlock
{
	while( token && (token!=LBRACE) ) [self nextChar];
	while( token && (token!=RBRACE) )[self nextChar];
	// token = rightbrace
	lastToken = token;
	[self nextChar];	// skip last rightbrace
}


- doBibItem
{
	while( token && (token!=LBRACKET) && (token!=LBRACE) ) [self nextChar];

	if( citeNumber && html ){
		NXPrintf(textStream, "</td></tr>" );	// close last bibitem
	}
	citeNumber++;
	if( html ) NXPrintf(textStream, "<tr><td valign=top>" ); // new row
	if( token==LBRACKET ) [self copyBracket];
	else{	// generate the label
		NXPrintf(textStream, "[%d]", citeNumber );
	}
	if( html ) NXPrintf(textStream, "</td><td>" ); 
	[self deleteBlock];
	return self;
}


/* - convertTeX appends a TeX text, "escaping"
 * all of the special characters in the text.
 */
- convertTeX
{
	int	count = 0;
	int	cmdInx;

	[self nextChar];
	while( token ){
		switch( token ) {
			/* escape special characters */
			case '\n'	:
				if( lastToken=='\n' ){
					if( html==2 ) NXPrintf(textStream, "<BR>");
					else NXPrintf(textStream, "\\\n" );
				}
				break;

			case '-'	:{
				unsigned char dash = '-';	// -X
				if( html==2 ) break;
				lastToken = '-';
				[self nextChar];
				if( token=='-' ){	// --
					[self nextChar];
					if( token=='-' ){	//	---
						dash = 'Ð';	// emDash
					}
					else{// --X
						dash = '±';	// enDash
					}
				}
				NXPutc(textStream, dash);
				continue;
				}

			case '~'	:
				if( html==2 ){
					NXPrintf(textStream, "&nbsp;");
					lastToken = token;
					[self nextChar];
					continue;
				}
				else NXPutc(textStream, '\\');
				break;

			case LBRACE	:
				[self convertTeX];
				lastToken = token;	// is right brace
				[self nextChar];
				continue;

			case RBRACE	:
				while( count ){
					NXPrintf(textStream, "%s",
						(char *)[stack removeLastObject]);
					count--;
				}
				return self;

			case '\\'	:
				cmdInx = [self cmd];
				if( cmdInx<0 ){	// not in the table
					lastToken = token;
					continue;
				}
				// the TeX-command was found in the rtf/html - list
				if( cvTable[cmdInx].hdr[html+0] )
					NXPrintf(textStream, "%s", cvTable[cmdInx].hdr[html+0] );
				if( cvTable[cmdInx].hdr[html+1] ){
					[stack addObject:(id)cvTable[cmdInx].hdr[html+1]];
					count++;
				}
				// evaluate the command
				if( cmdInx==0 ){	//begin
					//	skip to end of line
					while( token && (token!='\n') ) [self nextChar];
					lastToken = token;
					continue;
				}
				if( cmdInx==1 ){	//end
					//	skip to end of line
					while( token && (token!='\n') ) [self nextChar];
					lastToken = token;
					continue;
				}
				if( cmdInx==2 ){	//bibitem
				  [self doBibItem];
				  NXPutc(textStream, '\t' );
				  continue;
				}
				lastToken = token;
				continue;

			default: break;
		}
		NXPutc(textStream, token);
		lastToken = token;
		[self nextChar];
	}
	return self;
}


- (BOOL) convert2Rtf
{
	NXSeek(textStream, 0L, NX_FROMSTART);
	NXWrite(textStream, rtfHeader, strlen(rtfHeader));

	NXGetMemoryBuffer(memStream, &fBuffer, &fLength, &fMaxLength);
	NXSeek(memStream, 0L, NX_FROMSTART);
	token = lastToken = ' ';
	html = 0;
	[self convertTeX];

	NXWrite(textStream, rtfTail, strlen(rtfTail));
	return YES;
}


- (BOOL) convert2HTML
{
	NXSeek(textStream, 0L, NX_FROMSTART);
	NXWrite(textStream, htmlHeader, strlen(htmlHeader));

	NXGetMemoryBuffer(memStream, &fBuffer, &fLength, &fMaxLength);
	NXSeek(memStream, 0L, NX_FROMSTART);
	token = lastToken = ' ';
	html = 2;
	[self convertTeX];

	NXWrite(textStream, htmlTail, strlen(htmlTail));
	return YES;
}


- saveTo:(const char *)fname
{
	NXFlush( textStream );
	NXSaveToFile( textStream, fname );
	NXCloseMemory( textStream, NX_FREEBUFFER );
	textStream = NULL;
	return self;
}


- (NXStream *)stream
{
	return textStream;
}


- free
{
	if( textStream )NXCloseMemory(textStream, NX_FREEBUFFER);
	if( memStream ) NXCloseMemory( memStream, NX_FREEBUFFER );
	[stack free];
	return [super free];
}

@end

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