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, " "); 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.