This is TeXClass.m in view mode; [Download] [Up]
// Copyright H. Giesen, University of Koblenz-Landau 1996
#import "Controller.h"
#import "TeXClass.h"
#import "BibTeXObject.h"
#import "BibliographicFile.h"
#import "MyBrowserCell.h"
#import "Preferences.h"
#import "Subprocess.h"
#import "Bbl2rtf.h"
static char *fName = "Bib";
char buf[1024];
static char *texType[] =
{ "tex",
NULL
};
// special entryNames
static int STRING = -1;
static int PREAMBLE = -1;
@implementation TeXClass
- (void)alert:(char *)txt :(char *)para
{
NXRunAlertPanel("Bibliography",
txt,
" OK ", // 1: default button
NULL, // 0: alternate
NULL, //-1: other
para
);
}
- init
/*
creates the popUpList as pushDownList
*/
{
[super init];
if( !myPanel ){
[NXApp loadNibSection:"TeX.nib" owner:self];
}
[splitView addSubview:upperView]; // default template view
[splitView addSubview:lowerView];
[texText setDelegate:self];
popUpList = [[PopUpList alloc] init];
[popUpList changeButtonTitle:NO]; // is now a pullDownMenu
[popUpButton setTitle:"open file"];
[popUpButton setEnabled:NO];
filesExist = NO;
[myPanel setFrameUsingName:"TeXWindow"];
[myPanel setFrameAutosaveName:"TeXWindow"];
[myPanel setMiniwindowIcon:"multiBook"];
//[myPanel orderFront:self];
//[myPanel display];
return self;
}
- (void) setup
{
preferences = [Preferences new];
// get temporary directory name from preferences
bibDir = [preferences tempDirectory];
sprintf( buf, "TeXfiles are in directory: %s", bibDir );
[directoryTextField setStringValue:buf];
// load the templatefile (if it exists)
[self loadTemplateFile:[preferences templateFile]];
STRING = [preferences indexOfEntryname:"STRING"];
PREAMBLE = [preferences indexOfEntryname:"PREAMBLE"];
[self buildPreviewMenuFor:preViewButton];
}
- (void)showPanel // called from mainmenu
{
if( preferences==nil ) [self setup];
[myPanel orderFront:self];
}
- (void)copyObject:(BibTeXObject*)obj ofType:(int)type
{
if( [obj entryType]==type ){
NXPutc( texStream, '\n');
[obj copyToStream:texStream];
NXPutc( texStream, '\n');
}
}
- (void)copy:(List *)aList toFile:(const char *)aFile
// 'aList' is the list of browsercells of class MyBrowserCell
{
int i, j;
id fileList = [[List alloc] init];
if( !texStream )
texStream = NXOpenMemory(NULL, 0, NX_READWRITE);
NXSeek(texStream, 0, NX_FROMSTART);
// how many files are involved ?
for( i=0; i<[aList count]; i++ ){
[fileList addObjectIfAbsent:[[aList objectAt:i] fileObject]];
}
// copy all entries to the desired file
// first copy PREAMBLE from ALL source files
for( j=0; j<[fileList count]; j++ ){
BibliographicFile *theFile = [fileList objectAt:j];
for( i=0; i<[theFile entries]; i++ ){
[self copyObject:[theFile objectAt:i] ofType:PREAMBLE];
}
}
// we need ALL STRINGs from ALL source files
for( j=0; j<[fileList count]; j++ ){
BibliographicFile *theFile = [fileList objectAt:j];
for( i=0; i<[theFile entries]; i++ ){
[self copyObject:[theFile objectAt:i] ofType:STRING];
}
}
// and now the rest
for( i=0; i<[aList count]; i++ ){
id entryObj = [[aList objectAt:i] object];
if( !( ([entryObj entryType]==PREAMBLE)
|| ([entryObj entryType]==STRING)) ){
NXPutc( texStream, '\n');
[entryObj copyToStream:texStream];
NXPutc( texStream, '\n');
}
}
NXFlush( texStream );
NXSaveToFile( texStream, aFile );
NXCloseMemory( texStream, NX_FREEBUFFER );
texStream = NULL;
[fileList free];
}
- (PopUpList *)buildPreviewMenuFor:aButton
{
PopUpList *previewList = [[PopUpList alloc] init];
Menu *subMenu;
Matrix *menuList;
MenuCell *menuCell, *popUpCell;
int i;
subMenu = [[[NXApp mainMenu] findCellWithTag:6] target];
menuList = [subMenu itemList];
for( i=1; i<=4; i++ ){
menuCell = [menuList cellAt:i :0];
popUpCell = [previewList addItem:[menuCell title]];
[popUpCell setTarget:[menuCell target]];
[popUpCell setAction:[menuCell action]];
[popUpCell setTag:[menuCell tag]];
}
NXAttachPopUpList( aButton, previewList );
[aButton setTitle:"preview..."];
//[previewList sizeButton:aButton];
[aButton setEnabled:YES];
[previewList changeButtonTitle:NO]; // is now a pullDownMenu
//[aButton display];
return previewList;
}
#include <sys/dir.h> /* POSIX applications #include <dirent.h> */
- (void)popUpAllFiles
{
DIR *dirp;
struct direct *dp;
dirp = opendir( bibDir );
if( dirp==NULL ){
sprintf( buf, "%s\n%s", bibDir, strerror(errno) );
[self alert:" %s" :buf];
return;
}
for( dp = readdir(dirp); dp != NULL; dp = readdir(dirp) ) {
char *fn = dp->d_name; // filename
if( fn[0]=='_' ) continue;
if( fn[0]=='.' && fn[1]=='\0' ) continue;
if( fn[0]=='.' && fn[1]=='.' && fn[2]=='\0' ) continue;
[popUpList addItem:fn];
}
closedir(dirp);
NXAttachPopUpList( popUpButton, popUpList );
[[popUpList setAction:@selector(bibPopup:)] setTarget:self];
[popUpList sizeButton:popUpButton];
[popUpButton setEnabled:YES];
[[popUpButton window] display];
}
- (void)bibPopup:sender // sender is Matrix
{
int isCmd = [sender mouseDownFlags]&(NX_COMMANDMASK|NX_CONTROLMASK);
BOOL rtn;
if( [sender selectedRow]==0 ) return;
#ifdef SomeKeyBoardMasks
#define NX_ALPHASHIFTMASK (1 << 16) /* if alpha lock is on */
#define NX_SHIFTMASK (1 << 17) /* if shift key is down */
#define NX_CONTROLMASK (1 << 18) /* if control key is down */
#define NX_ALTERNATEMASK (1 << 19) /* if alt key is down */
#define NX_COMMANDMASK (1 << 20) /* if command key is down */
#define NX_NUMERICPADMASK (1 << 21) /* if key on numeric pad */
#define NX_HELPMASK (1 << 22) /* if help key is down */
#endif
sprintf( buf, "%s/%s", bibDir, [[sender selectedCell] title] );
if(isCmd)
rtn = [[Application workspace] openFile:buf withApplication:"Edit"];
else
rtn = [[Application workspace] openFile:buf];
if( rtn==NO )
NXRunAlertPanel ("Can't open file",
"The file %s could not be opened",
NULL, NULL, NULL, buf);
}
// the subprocess has come to an end
- (void)showFormatted:sender
{
char *data;
int length;
BOOL rtn;
pboard = [Pasteboard newName:NXDragPboard];
[[theView setSel:0 :[theView textLength]] replaceSel:NULL]; // clear
if( previewType==RUNRTF ){
[self createRtf:sender];
return;
}
if( previewType==RUNHTML ){
[self createHTML:sender];
return;
}
sprintf( buf, "%s/%s.eps", bibDir, fName );
/* place the name of the file on the pasteboard. */
[pboard declareTypes:&NXFilenamePboardType num:1 owner:nil];
[pboard writeType:NXFilenamePboardType
data:buf length:strlen( buf )+1];
[pboard readType:NXFilenamePboardType data:&data length:&length];
[theView draggingEntered:(id <NXDraggingInfo>)self];
rtn = [theView prepareForDragOperation:(id <NXDraggingInfo>)self];
if( rtn==YES ){
rtn = [theView performDragOperation:(id <NXDraggingInfo>)self];
}
if( rtn==YES ){
[theView concludeDragOperation:(id <NXDraggingInfo>)self];
}
}
- (BOOL)saveFile:(const char *)theFile from:view
{
int fd;
NXStream *stream;
fd = open(theFile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
stream = NXOpenFile(fd, NX_WRITEONLY);
if( stream==NULL ) return NO;
[view writeText:stream];
NXFlush(stream);
NXClose(stream);
close(fd);
return YES;
}
- (BOOL)loadFile:(const char *)theFile to:view
{
NXStream *memStream;
if( access(theFile, R_OK)==0 ){ // read from file
memStream = NXMapFile([preferences templateFile], NX_READONLY);
[view readText:memStream];
NXCloseMemory( memStream, NX_FREEBUFFER );
return YES;
}
return NO;
}
// saves the content of the scrollView = texText to 'theFile'
- saveTextToFile:(const char *)theFile
{
if( [self saveFile:theFile from:texText] ){
[myPanel setDocEdited:NO];
return self;
}
NXRunAlertPanel ("Bibliography", // title
"The file %s could not be opened", // message
" OK ", // 1: default button
NULL, // 0: alternate
NULL, //-1: other
theFile
);
return nil;
}
- (BOOL)restoreFromTeXfile:(const char *)theFile
{
NXStream *memStream;
if( access(theFile, W_OK)==0 ){ // read from file
memStream = NXMapFile(theFile, NX_READONLY);
[texText readText:memStream];
NXCloseMemory( memStream, NX_FREEBUFFER );
return YES; // file exists
}
// load template ???
return NO; // not .tex - file found
}
- placeStopButton
{
NXRect frame, stopFrame;
[popUpButton getFrame:&frame];
[stopButton getFrame:&stopFrame];
stopFrame.X= frame.X + 11.0;
stopFrame.Y= frame.Y - 34.0;
[stopButton setFrame:&stopFrame];
[[myPanel contentView] replaceSubview:popUpButton with:stopButton];
[myPanel display];
return self;
}
- removeStopButton
{
isRunning = NO;
[[myPanel contentView] replaceSubview:stopButton with:popUpButton];
[self popUpAllFiles];
//[myPanel display];
return self;
}
- stopRunning:sender
{
isRunning = NO;
cancelled = YES;
[theSubprocess terminate:self];
return self;
}
static char* auxText=
"\\relax\n"
"\\bibdata{Bib}\n"
"\\bibstyle{%s}\n"
"\\citation{*}\n";
// creates an .aux-file and runs bibtex
- runRTFfor:aList
{
int fd;
const char *shell;
sprintf( buf, "%s/%s.bbl", bibDir, fName );
if(0)if( access(buf, R_OK)==0 ){
[self showFormatted:self]; // ??? maybe the style€changed !!!
return self;
}
unlink( buf );
//sprintf( buf, "%s/%s.aux", bibDir, fName ); unlink( buf );
sprintf( buf, "%s/%s.aux", bibDir, fName );
fd = open( buf, O_CREAT | O_WRONLY | O_TRUNC, 0666 );
sprintf( buf, auxText, [preferences theStyle] );
write( fd, buf, strlen( buf ) );
close(fd);
if( aList ){
sprintf( buf, "%s/%s.bib", bibDir, fName );
[self copy:aList toFile:(const char *)buf];
}
if( preferences==nil ) [self setup];
shell = [preferences theShell];
sprintf( buf, "(cd %s; %s -c 'bibtex %s'\n)",
bibDir, shell, fName );
if( theSubprocess ) [theSubprocess free];
[upperView setDocView:logText];
[logText clearText];
[logText setEditable:NO];
[switchMatrix selectCellAt:1 :0];
isRunning = YES;
[self placeStopButton];
cancelled = NO;
theSubprocess = [[Subprocess alloc]
init:buf withDelegate:self];
return self;
}
// aList is the list of browserCells of class MyBrowserCell
// it's not really TeX !
- runTeXfor:aList tag:(int)tag
{
int rtn;
const char *shell;
if( preferences==nil ) [self setup];
shell = [preferences theShell];
previewType = tag;
if( theSubprocess ) [theSubprocess terminate:self];
[myPanel orderFront:self];
if( tag==RUNRTF ){
[self runRTFfor:aList];
return self;
}
if( tag==RUNHTML ){
[self runRTFfor:aList];
return self;
}
sprintf( buf, "%s/%s.tex", bibDir, fName );
if( [myPanel isDocEdited]==YES ){
rtn = NXRunAlertPanel("Bibliography",
"TeX text did change, use changed text ?",
" YES ", // 1: default button
" NO ", // 0: alternate
NULL //-1: other
);
if( rtn==NX_ALERTDEFAULT ){ // use changed text
[self saveTextToFile:buf];
}
else if( [self restoreFromTeXfile:buf]==NO ){
NXRunAlertPanel("Bibliography",
"no .tex - file found",
" OK ", // 1: default button
NULL, // 0: alternate
NULL //-1: other
);
return self;
}
}
else [self saveTextToFile:buf];
if( aList ){
sprintf( buf, "%s/%s.bib", bibDir, fName );
[self copy:aList toFile:(const char *)buf];
}
// else: use the already existing .bib - file
// rm *.dvi *.eps *.bbl
sprintf( buf, "%s/%s.dvi", bibDir, fName ); unlink( buf );
sprintf( buf, "%s/%s.eps", bibDir, fName ); unlink( buf );
sprintf( buf, "%s/%s.bbl", bibDir, fName ); unlink( buf );
sprintf( buf, "%s/%s.aux", bibDir, fName ); unlink( buf );
sprintf( buf, "(cd %s; %s -c 'latex %s'\n"
"%s -c 'bibtex %s'\n"
"%s -c 'latex %s'\n"
"%s -c 'latex %s'\n"
"%s -c 'dvips -E -o %s.eps %s.dvi'\n) 2>&1",
bibDir, shell, fName, // cd ... latex
shell, fName, // bibtex
shell, fName, // latex
shell, fName, // latex
shell, fName, fName // dvips
);
if( theSubprocess ) [theSubprocess free];
[upperView setDocView:logText];
[logText clearText];
[logText setEditable:NO];
[switchMatrix selectCellAt:1 :0];
isRunning = YES;
[self placeStopButton];
cancelled = NO;
theSubprocess = [[Subprocess alloc]
init:buf withDelegate:self];
return self;
}
- subprocess:sender done:(int)exitStatus
{
filesExist = YES;
[self removeStopButton];
if( cancelled ) return self;
//[self popUpAllFiles];
cancelled = NO;
[self showFormatted:self];
return self;
}
- subprocess:sender output:(char *)buffer;
{
//fprintf( stderr, "%s\n", buffer );
[logText addText:buffer];
[logText addText:"\n"];
return self;
}
- subprocess:sender stderrOutput:(char *)buffer;
{
fprintf( stderr, "%s\n", buffer );
//[texText addText:buffer];
return self;
}
- subprocess:sender error:(const char *)errorString;
{
fprintf( stderr, "%s\n", errorString );
//[texText addText:buffer];
return self;
}
- (BOOL)isRunning
{
return isRunning;
}
- showUpperView:sender
{
switch( [sender selectedRow] ){
case 0: [upperView setDocView:texText]; break;
case 1: [upperView setDocView:logText]; break;
default: break;
}
return self;
}
- prepareLaTeX:(int)tag
{
[self runTeXfor:nil tag:tag];
return self;
}
- createLaTeX:sender
{
if( [self isRunning] ){
[self alert:"bibtex is still running, please wait\n": NULL ];
return self;
}
[self prepareLaTeX:RUNLATEX];
return self;
}
- printDvi:sender
{
[theView printPSCode:sender];
return self;
}
- textDidGetKeys:sender isEmpty:(BOOL)flag
{
[myPanel setDocEdited:YES];
return self;
}
- saveTemplate:sender // called from 'save' button
{
[self saveTextToFile:[preferences templateFile]];
return self;
}
- loadTemplateFile:(const char *)template
{
NXStream *memStream;
if( access(template, W_OK)==0 ){ // read from file
memStream = NXMapFile(template, NX_READONLY);
[texText readText:memStream];
NXCloseMemory( memStream, NX_FREEBUFFER );
}
else
[self loadDefault:self];
[myPanel setDocEdited:NO];
return self;
}
- loadTemplate:sender // called from 'load' button
{
int rtn;
const char* fileName = {NULL};
id openPanel = [OpenPanel new];
if ( (rtn=[openPanel runModalForTypes:texType] )
&& (fileName = [openPanel filename]) ) {
[self loadTemplateFile:fileName];
}
else{
if( rtn==NX_OKTAG )
[self alert:"cannot not open\n\n %s\n" :(char *)fileName ];
}
[myPanel setDocEdited:NO];
return self;
}
- loadDefault:sender // called from 'default' button
{
char buf[MAXPATHLEN];
NXStream *input;
id m = [NXBundle mainBundle];
// load TeXtemplate from the bundle
if( [m getPath:buf forResource:"TeXtemplate" ofType:""] ){
input = NXMapFile(buf, NX_READONLY);
[texText readText:input];
NXCloseMemory(input, NX_FREEBUFFER);
}
else {
[self alert:"cannot load default file" :"TeXtemplate"];
return self;
}
[myPanel setDocEdited:NO];
return self;
}
// returns the new state of the menuCell
// YES = enabled
// NO = disabled
- (BOOL)updateMenuFor:menuCell
{
BOOL newState=NO; // .. and the compiler keeps silent
switch( [menuCell tag] ){
case CUT :
case COPY :
case PASTE :
case SELECTALL :
case ENTERSELECTION : newState = YES; break;
case PRVWINDOW : newState = YES; break;
case RUNLATEX :
case RUNRTF :
case RUNHTML : newState = filesExist; break; // ????
case PRINT : newState = filesExist; break; // ????
default : newState = [[NXApp delegate]updateMenuFor:menuCell];
break;
}
return newState;
}
// copy selected text to findPasteBoard
- enterSelection:sender
{
[[NXApp delegate] enterSelectionFor:[myPanel firstResponder]];
return self;
}
// creates rtf-text (and a file!) from a .bbl-file
- createRtf:sender
{
id rtfObject;
NXStream *textStream;
if(0)if( [self isRunning] ){
[self alert:"bibtex is still running, please wait\n": NULL ];
return self;
}
sprintf( buf, "%s/%s.bbl", bibDir, fName );
rtfObject = [[Bbl2rtf alloc] initFromFile:buf];
if( rtfObject ){
[rtfObject convert2Rtf];
sprintf( buf, "%s/%s.rtf", bibDir, fName );
if( previewType==RUNRTF ){
textStream = [rtfObject stream];
NXSeek(textStream, 0, NX_FROMSTART);
[theView readRichText:textStream]; // CRASH
}
[rtfObject saveTo:buf];
[rtfObject free];
[self popUpAllFiles];
}
return self;
}
- createHTML:sender
{
id rtfObject;
NXStream *textStream;
if(0)if( [self isRunning] ){
[self alert:"bibtex is still running, please wait\n": NULL ];
return self;
}
sprintf( buf, "%s/%s.bbl", bibDir, fName );
rtfObject = [[Bbl2rtf alloc] initFromFile:buf];
if( rtfObject ){
[rtfObject convert2HTML];
sprintf( buf, "%s/%s.html", bibDir, fName );
if( previewType==RUNHTML ){
textStream = [rtfObject stream];
NXSeek(textStream, 0, NX_FROMSTART);
[theView readText:textStream];
}
[rtfObject saveTo:buf];
[rtfObject free];
[self popUpAllFiles];
}
return self;
}
// ========= dragging
- (BOOL)isDraggingSourceLocal
{
//fprintf( stderr, "isDraggingSourceLocal\n" );
return YES;
}
- draggingSource
{
//fprintf( stderr, "draggingSource\n" );
return self;
}
- (NXDragOperation)draggingSourceOperationMask
{
//fprintf( stderr, "draggingSourceOperationMask\n" );
return NX_DragOperationGeneric
| NX_DragOperationCopy
| NX_DragOperationPrivate;
}
- draggingDestinationWindow
{
//fprintf( stderr, "draggingDestinationWindow\n" );
return nil;
}
- (Pasteboard *)draggingPasteboard
{
char *data;
int length;
[pboard readType:NXFilenamePboardType data:&data length:&length];
return pboard;
}
- (int)draggingSequenceNumber
{
return 77;
}
- (NXPoint)draggingLocation
{
NXPoint pnt = {50.0, 50.0};
return pnt;
}
- (NXImage *)draggedImage
{
return nil;
}
- (NXImage *)draggedImageCopy
{
return nil;
}
- (NXPoint)draggedImageLocation
{
NXPoint pnt = {50.0, 50.0};
return pnt;
}
- slideDraggedImageTo:(NXPoint *)screenPoint
{
return self;
}
- (NXDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
{
return NX_DragOperationCopy;
}
- draggedImage:(NXImage *)image
endedAt:(NXPoint *)screenPoint
deposited:(BOOL)didDeposit
{
return nil;
}
- saveTexText:sender
{
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.