/*
 * rtfcat [-afpP] [rtf-files]
 *
 * Concatenate RTF files on the standard output.
 * Also a handy way to convert RTF -> ascii / PostScript, etc.
 * Options:
 *    -a    stdout will be plain ascii, folded to 72-char lines
 *          and with some common funny characters (bullets, em dashes, etc)
 *          converted to a crude ascii equivalent.
 *    -f    when converting to ascii, don't do the folding and converting.
 *    -p    stdout will be PostScript.
 *    -P    write output to the PasteBoard.
 *
 * Let me know if you make any changes.
 * NB -- PS won't work with < 3.0 release.  See below.
 * NB -- RTFD wrappers not handled.  (They should be!)
 *
 * M. J. Hawley
 * MIT Media Laboratory
 * 20 Ames Street
 * Cambridge, MA 02139
 * mike@media-lab.mit.edu
 * Copyright (c) 1992 MIT Media Laboratory.
 */
#include <appkit/Application.h>
#include <appkit/Window.h>
#include <appkit/Text.h>
#include <streams/streams.h>

#define Case break; case
#define Default break; default
static char *_arg, *_argp; /* use by 'for_each_argument */
static char *av0;       /* will hold name of the command */
#define argument  (_arg=(*_argp? _argp : av[++i==ac? --i : i]),_argp+=strlen(_argp),_arg)
#define for_each_argument av0 = av[0]; for (i=1;i<ac && *av[i]=='-';i++)\
                        for (_argp = &av[i][1]; *_argp;)\
                                switch(*_argp++)

#define ASCII 0
#define RTF   1
#define PS    2

int WriteOutput = RTF;
int ToPasteboard = 0;
int Fold = 1;

e(a,b,c,d) char *a; { fprintf(stderr,a,b,c,d); fprintf(stderr,"\n"); }

use(){
    e("use: %s [-apP] [-s #] [rtf-files]",av0);
    e("Concatenate Rich-Text files on the standard output.");
    e("  -a   write output as plain ascii");
    e("  -f   don't fold ASCII output");
    e("  -p   write output as PostScript");
    e("  -P   send output to Pasteboard");
    exit(1);
}

int folder(){
    FILE *p, *popen();

    if (!Fold || WriteOutput != ASCII) return fileno(stdout);

/* Be careful editing the following kludgy line if using Edit. . . */
    p = popen("tr '\\320\\257\\256\\252\\272\\261\\267\' \'\\020\\006\\007\\016\\017\\261\\005\' | sed \'\ns//*/g\ns//--/g\ns//fl/g\ns//fi/g\ns//``/g\ns//\'"\'\'"\'/g\ns/\\.  /.\\\n/g\' | fmt","w");
    return p? fileno(p) : fileno(stdout);
}


main(ac, av)
     char **av;
{
    NXRect r = {36, 82, 500, 720}, b = {0,0,0,0};
    NXStream *f, *o;
    Text *t;
    Window *w;
    Pasteboard *pb;
    int i, l;
    NXAtom types[] = {NXAsciiPboardType, NXRTFPboardType, (NXAtom)0};

    for_each_argument {
    case 'a': WriteOutput = ASCII;
    Case 'f': Fold = !Fold;
    Case 'p': WriteOutput = PS;
    Case 'P': ToPasteboard = 1;
    Default : use();
    }

    NXApp = [Application new];
    if (ToPasteboard) pb = [Pasteboard new];
    t = [[Text alloc] initFrame: &r];
    if (!t) e("%s: can't create internal text object\n", av0), exit(1);
    [t setMonoFont:NO];
    [t setGraphicsImportEnabled:YES];
    o = NXOpenFile(folder(), NX_WRITEONLY);

    if (i==ac) ac++;
    for (; i<ac; i++) {
	f = av[i]? NXMapFile(av[i], NX_READONLY) :
	           NXOpenFile(fileno(stdin), NX_READONLY);
	if (!f) e("%s: couldn't open '%s'", av0, av[i]);
	else {
            l = [t textLength]; [t setSel:l:l];
	    [t replaceSelWithRichText:f];
	    NXClose(f);
        }
    }

    [t calcLine];
    l = [t textLength];

    switch (WriteOutput){
    case ASCII: if (ToPasteboard){
                    [t setSel:0:l];
                    [t writeSelectionToPasteboard:pb types:types];
                } else
                    [t writeText:o];
    Case RTF: if (ToPasteboard){
                    [t setSel:0:l];
                    [t writeSelectionToPasteboard:pb types:types];
                } else
                    [t writeRichText: o];
    Case PS:    {
		    NXCoord w, h;
		    [t getMinWidth:&w minHeight:&h
			    maxWidth:r.size.width maxHeight:1.0e38];
		    r.size.height = h;
		}
		w = [[Window alloc] initContent:&r
				    style:NX_TITLEDSTYLE
				    backing:NX_RETAINED
				    buttonMask:NX_CLOSEBUTTONMASK
				    defer:NO];
		[t windowChanged:w];
		[w setContentView:t];
		r.origin.x = r.origin.y = 0.;
                if (ToPasteboard)
                    [t writePSCodeInside:&r to:pb];  // no can do under 2.x
                else
		    [t copyPSCodeInside:&r to:o];
    }

    NXClose(o);

    exit(0);
}
