[comp.lang.postscript] Postscript Pretty Printer

mh@awds26.eaton.com (Mike Hoegeman) (02/08/90)

Here is the postscript indenter / pretty printer which i alluded to yesterday.
It was written by Josh Siegel, not me. It's a *really* nifty program.

Note: you need lex to make it.

p.s. sorry for the gimpy shar format, but it's the only one i could dig up
at the moment.  cd to parent directory you want the source in then do 
mkdir pspp, then ....
-----------------------SNIP here and run thru /bin/sh -----------------------
echo x - pspp/Makefile
sed 's/^X//' >pspp/Makefile <<'*-*-END-of-pspp/Makefile-*-*'
XCFLAGS		 = -g
X
XLEX = lex -v
X
XDEST	      = .
X
XEXTHDRS	      =
X
XHDRS	      =
X
XLDFLAGS	      =
X
XLIBS	      =  -ll
X
XLINKER	      = cc
X
XMAKEFILE      = Makefile
X
XOBJS	      = pspp.o
X
XPRINT	      = pr
X
XPROGRAM	      = pspp
X
XSRCS	      = pspp.l
X
Xall:		$(PROGRAM)
X
X${PROGRAM}.shar: $(SRCS) ${MAKEFILE} README test patchlevel.h
X	shar -a $(SRCS) ${MAKEFILE} README test  patchlevel.h> ${PROGRAM}.shar
X
X$(PROGRAM):     $(OBJS)
X		@echo -n "Loading $(PROGRAM) ... "
X		@$(LINKER) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
X		@echo "done"
X
Xclean:;		@rm -f $(OBJS)
X
Xdepend:;	@mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST)
X
Xindex:;		@ctags -wx $(HDRS) $(SRCS)
X
Xinstall:	$(PROGRAM)
X		@echo Installing $(PROGRAM) in $(DEST)
X		@install -s $(PROGRAM) $(DEST)
X
Xprint:;		@$(PRINT) $(HDRS) $(SRCS)
X
Xprogram:        $(PROGRAM)
X
Xtags:           $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS)
X
Xupdate:		$(DEST)/$(PROGRAM)
X
X###
*-*-END-of-pspp/Makefile-*-*
echo x - pspp/README
sed 's/^X//' >pspp/README <<'*-*-END-of-pspp/README-*-*'
X
X                    Copyright (c) 1989, Josh Siegel
X
XYou may copy the pspp kit in whole or in part as long as you don't try to
Xmake money off it, or pretend that you wrote it.
X
X            --Josh Siegel
X            siegel@hc.dspo.gov
X
XControlable things:
X        1) Backslashing inner strings (\(\))           bs
X        2) rearrange function definitions              ra  (not implemented)
X            Turn:
X              /foo { % bar
X            Into:
X              /foo % bar
X              {
X        3) newline before 
X            "def"                        db
X            "begin"                      bb
X            "classbegin"                 cbb
X            "dictbegin"                  dbb
X            "end"                        eb
X            "classend"                   ceb
X            "dictend"                    deb
X            "grestore"                   grb
X            "gsave"                      gsb
X            "if"                         ib
X            "{"                          lcb
X            "}"                          rcb
X            "["                          lbb
X            "]"                          rbb
X        4) newline after  
X            "def"                         da
X            "begin"                      ba
X            "classbegin"                 cba
X            "dictbegin"                  dba
X            "end"                        ea
X            "classend"                   cea
X            "dictend"                    dea
X            "grestore"                   gra
X            "gsave"                      gsa
X            "if"                         ia
X            "["                          lba
X            "]"                          rba
X            "{"                          lca
X            "}"                          rca
X
XDefault flags:
X    ba bb bs cba cbb cea ceb da dba dbb dea deb ea eb lca rcb pn ia gi
X
XWays to change flags:
X
X    Put a command line into your PostScript code...
X
X    example:
X        <beginning of line>%%= -bs +cea -dba
X
X    Put a command line into a .pspp in your home directory
X
X    example:
X        -lba -rba -lca
X
X    Set options when you call program...
X
X    example:
X        pspp -rca
X
XTo run:
X
X% pspp [options files] < file.in > file.out
X
XOr, run it from vi...
X
X:%!pspp
X
XOr,
X
X% pspp -lba foo.cps +lba foobar.ps
X
XSpecial NeWS related features...
X
X    lines beginning with cdef are assumed to be cdef calls under NeWS.
X    This causes the rest of the file (till the next cdef) to be indented one.
X
X    Lines beginning with "#" or "%" are passed through unmodified.
X
XNote to hackers:
X    You may notice how I stuck lots of the keywords together into
X    a single lex rule... I am not going to explain this... there is
X    a reason for this... don't worry about it for now.  The reason
X	doesn't show up in this version.
X
*-*-END-of-pspp/README-*-*
echo x - pspp/patchlevel.h
sed 's/^X//' >pspp/patchlevel.h <<'*-*-END-of-pspp/patchlevel.h-*-*'
X#define PATCHLEVEL 3
*-*-END-of-pspp/patchlevel.h-*-*
echo x - pspp/pspp.l
sed 's/^X//' >pspp/pspp.l <<'*-*-END-of-pspp/pspp.l-*-*'
X
X%{
X
X/*
X
X                    Copyright (c) 1989, Josh Siegel
X
XYou may copy the pspp kit in whole or in part as long as you don't try to
Xmake money off it, or pretend that you wrote it.
X
X Version 0.04
X    Fixed a fix in 0.03
X    Made it callable on files and sets of files.
X
X Version 0.03
X    Fixed run away white space problem...
X    Fixed (()) matching
X    Fixed it turning (\(\)) into (\\(\\))
X
X Version 0.02
X    Added bracstack as well as fixing problems associated with class.ps
X
X Version 0.01
X    initial release
X*/
X
X#define FLAG_BA        0x1
X#define FLAG_BB        0x2
X#define FLAG_BS        0x4
X#define FLAG_CBA    0x8
X#define FLAG_CBB    0x10
X#define FLAG_CEA    0x20
X#define FLAG_CEB    0x40
X#define FLAG_DA        0x80
X#define FLAG_DB        0x100
X#define FLAG_DBA    0x200
X#define FLAG_DBB    0x400
X#define FLAG_DEA    0x800
X#define FLAG_DEB    0x1000
X#define FLAG_EA        0x2000
X#define FLAG_EB        0x4000
X#define FLAG_LCA    0x8000
X#define FLAG_LCB    0x10000
X#define FLAG_RCA    0x20000
X#define FLAG_RCB    0x40000
X#define FLAG_PN        0x80000
X#define FLAG_IB        0x100000
X#define FLAG_IA        0x200000
X#define FLAG_LBB    0x400000
X#define FLAG_LBA    0x800000
X#define FLAG_RBB    0x1000000
X#define FLAG_RBA    0x2000000
X#define FLAG_GSB    0x4000000
X#define FLAG_GSA    0x8000000
X#define FLAG_GRB    0x10000000
X#define FLAG_GRA    0x20000000
X#define FLAG_GI        0x40000000
X#define FLAG_RA     0x80000000
X
X#define DEFAULT_FLAG (FLAG_BA|FLAG_BB|FLAG_BS|FLAG_CBA|FLAG_CBB|\
X        FLAG_CEA|FLAG_CEB|FLAG_DA|FLAG_DBA|FLAG_DBB|FLAG_DEA|\
X        FLAG_DEB|FLAG_EA|FLAG_EB|FLAG_LCA|FLAG_RCB| \
X        FLAG_PN | FLAG_IA | FLAG_GI)
X
X#define check_flag(x) ((x) & flags)
X
X#define STACK_LEVELS 32
X
Xint neednew,i,level,braclevel,flags,minlevel;
Xint minstack[STACK_LEVELS],flagstack[STACK_LEVELS],minstackpnt,flagstackpnt;
Xint bracstack[STACK_LEVELS],bracpnt;
X%}
XW    [ \t]+    
X%%
X\(        {
X            int pcount;
X
X            pcount=1;
X            i = 1;
X
X            while(pcount) {
X                yytext[i]=input();
X                switch(yytext[i]) {
X                    case '\\':
X                        i++;
X                        yytext[i]=input();
X                        break;
X                    case '(': 
X                        pcount++; 
X                        if(check_flag(FLAG_BS)) {
X                            yytext[i++]='\\';
X                            yytext[i]='(';
X                        }
X                        break;
X                    case ')': 
X                        pcount--; 
X                        if(pcount) {
X                            if(check_flag(FLAG_BS)) {
X                                yytext[i++]='\\';
X                                yytext[i]=')';
X                            }
X                        }
X                        break;
X                    case '\n':
X                        yytext[i++]='\\';
X                        yytext[i]='n';
X                        break;
X                    default: break;
X                }
X                i++;
X            }
X            yytext[i]= '\0';
X            newline();
X            fprintf(yyout,"%s",yytext);
X        }
X
X\{[ \t]*\}    { /* Yet another special case */ newline(); fprintf(yyout,yytext); }
X
X"def"    {
X                if(check_flag(FLAG_DB))  
X                    neednew=1;
X                newline(); 
X                fprintf(yyout,"%s",yytext);
X                if(check_flag(FLAG_DA)) 
X                    neednew=1;
X        }
X
X"{"    {
X        if(check_flag(FLAG_LCB))
X            neednew=1;
X        newline();
X        level++;
X        pushbraclevel();
X        fprintf(yyout,"%s",yytext);
X        if(check_flag(FLAG_LCA))
X            neednew=1;
X    }
X
X"}"    {
X    if(check_flag(FLAG_RCB))
X        neednew=1;
X    level--;
X    popbraclevel();
X    newline();
X    fprintf(yyout,"%s",yytext);
X    if(check_flag(FLAG_RCA))
X        neednew=1;
X    }
X
X"begin"|"dictbegin"|"classbegin"|"["|"gsave"    {
X                switch(yytext[0]) {
X                case 'd':
X                    if(check_flag(FLAG_DBB))
X                        neednew=1;
X                    break;
X                case 'b':
X                    if(check_flag(FLAG_BB))
X                        neednew=1;
X                    break;
X                case 'c':
X                    if(check_flag(FLAG_CBB))
X                        neednew=1;
X                    break;
X                case 'g':
X                    if(check_flag(FLAG_GSB))
X                        neednew=1;
X                    break;
X                case '[':
X                    if(check_flag(FLAG_LBB))
X                        neednew=1;
X                    break;
X                }
X                newline();
X            
X                fprintf(yyout,"%s",yytext);
X                braclevel++;
X                switch(yytext[0]) {
X                case 'd':
X                    if(check_flag(FLAG_DBA))
X                        neednew=1;
X                    break;
X                case 'b':
X                    if(check_flag(FLAG_BA))
X                        neednew=1;
X                    break;
X                case 'c':
X                    if(check_flag(FLAG_CBA))
X                        neednew=1;
X                    break;
X                case 'g':
X                    if(check_flag(FLAG_GSA)) 
X                        neednew=1;
X                    if(!check_flag(FLAG_GI))
X                        braclevel--;
X                    break;
X                case '[':
X                    if(check_flag(FLAG_LBA))
X                        neednew=1;
X                    break;
X                }
X            }
X
X
X"end"|"dictend"|"classend"|"]"|"grestore"     {
X                braclevel--;
X                switch(yytext[0]) {
X                case 'd':
X                    if(check_flag(FLAG_DEB))
X                        neednew=1;
X                    break;
X                case 'e':
X                    if(check_flag(FLAG_EB))
X                        neednew=1;
X                    break;
X                case 'c':
X                    if(check_flag(FLAG_CEB))
X                        neednew=1;
X                    break;
X                case 'g':
X                    if(check_flag(FLAG_GRB))
X                        neednew=1;
X                    if(!check_flag(FLAG_GI))
X                        braclevel++;
X                    break;
X                case ']':
X                    if(check_flag(FLAG_RBB)) 
X                        neednew=1;
X                    break;
X                }
X
X                newline();
X                fprintf(yyout,"%s",yytext);
X                switch(yytext[0]) {
X                case 'd':
X                    if(check_flag(FLAG_DEA))
X                        neednew=1;
X                    break;
X                case 'e':
X                    if(check_flag(FLAG_EA))
X                        neednew=1;
X                    break;
X                case 'c':
X                    if(check_flag(FLAG_CEA))
X                        neednew=1;
X                    break;
X                case 'g':
X                    if(check_flag(FLAG_GRA))
X                        neednew=1;
X                    break;
X                case ']':
X                    if(check_flag(FLAG_RBA))
X                        neednew=1;
X                    break;
X                }
X            }
X
X(if|ifelse)            {
X
X                if(check_flag(FLAG_IB)) 
X                    neednew=1;
X                newline(); 
X                fprintf(yyout,"%s",yytext);
X                if(check_flag(FLAG_IA))  
X                    neednew=1;
X                }
X^cdef    {
X            level=0;
X            minlevel=0;
X            newline();
X            fprintf(yyout,"%s",yytext);
X            level=1; /* Indent one so it looks ncie */
X            braclevel=0; /* Reset the bracket level */
X            bracpnt=0;  /* Reset the stack */
X            minlevel=1;
X        }
X^\%\%=.*\n    {
X                if(neednew) 
X                    fprintf(yyout,"\n");
X                yytext[yyleng-1]='\0';
X                fprintf(yyout,"%s",yytext);
X                parseflag(&yytext[3]);
X                neednew=1;
X            }
X^#.*\n    |
X^\%.*\n    {
X            if(neednew) 
X                fprintf(yyout,"\n");
X            yytext[yyleng-1]='\0';
X            fprintf(yyout,"%s",yytext);
X            neednew=1;
X        }
X^[ \t]+\%.*\n {    
X                char *p;
X
X                newline();
X                yytext[yyleng-1]='\0';
X                p = yytext;
X                while(*p!='%') p++;
X                fprintf(yyout,"%s",p);
X                neednew=1;
X                }
X\%.*\n    {
X            yytext[yyleng-1]='\0';
X            fprintf(yyout,"%s",yytext);
X            neednew=1;
X        }
X^{W}       neednew=1;
X{W}       fprintf(yyout," ");
X^[ \t]*\n    { if(check_flag(FLAG_PN)) fprintf(yyout,"\n");}
X\n        neednew=1;
X[^ \t\n\[\]\{\}\(]+ |
X.        {newline();
X            fprintf(yyout,"%s",yytext);
X            ; /* Almost everything falls to this */ }
X%%
X
X
X
Xmain(argc, argv)
X    int             argc;
X    char           *argv[];
X{
X
X    FILE           *fp, *fopen(), *fpo;
X    char            buff[255];
X    int do_stdio;
X
X    do_stdio = 1;
X    minstackpnt = 0;
X    flagstackpnt = 0;
X    bracpnt = 0;
X    neednew = 0;
X    level = 0;
X    braclevel = 0;
X    minlevel = 0;
X    flags = DEFAULT_FLAG;
X
X    sprintf(buff, "%s/.pspp", getenv("HOME"));
X
X    fp = fopen(buff, "r");
X
X    if(fp!=NULL) {
X        while(fgets(buff,255,fp)!=NULL)
X            parseflag(buff);
X        fclose(fp);
X    }
X
X    while (--argc) {
X        if( argv[argc][0]=='-' || argv[argc][0]=='+' )
X            parseflag(argv[argc]);
X        else
X            {
X            do_stdio = 0;
X
X            sprintf(buff,"%s.BAK",argv[argc]);
X            unlink(buff);
X            if(rename(argv[argc],buff)!=0) {
X                perror("rename");
X                exit(0);
X            }
X            fpo = fopen(argv[argc],"w");
X            fp = fopen(buff,"r");
X            yyin = fp;
X            yyout = fpo;
X            yylex();
X            fprintf(fpo,"\n");
X            fclose(fp);
X            fclose(fpo);
X        }
X    }
X
X    if(do_stdio) {
X        yylex();
X        fprintf(yyout,"\n");
X    }
X    exit(0);
X}
Xnewline()
X{
X    int             cnt;
X
X    if (!neednew)
X        return;
X
X    fprintf(yyout,"\n");
X
X    if (level < minlevel)        /* Save ourselves from errors in the 
X                                postscript */
X        level = minlevel;
X
X    if(bracpnt>0) {
X        if(braclevel < bracstack[bracpnt-1]) 
X                braclevel = bracstack[bracpnt-1];
X    }  else {
X        if(braclevel<0)
X            braclevel = 0;
X    }
X
X    cnt = level + braclevel;
X
X    while (cnt--)
X        fprintf(yyout,"    ");
X
X    neednew = 0;
X}
Xparseflag(str)
X    char           *str;
X{
X    char           *p;
X    int             effect, the_flag;
X
X
X    p = str;
X
X
X    while (*p) {
X        while (*p == ' ' || *p == '\t')
X            p++;
X
X        effect = 1;    /* Set flag (default) */
X        the_flag = 0;
X
X        switch (*p) {
X        case '+':
X            p++;
X            break;
X        case '-':
X            effect = 0;
X            p++;
X            break;
X        default:
X            break;
X        }
X
X        /*
X         * I make no defense of the code below... later I will make a
X         * proper hash table (yes.. yes.. I know there are lots of
X         * incorrect sets )
X         */
X
X        if(effect<2)
X        switch (p[0]) {
X        case 'b':
X            switch (p[1]) {
X            case 'a':
X                the_flag = FLAG_BA;
X                break;
X            case 'b':
X                the_flag = FLAG_BB;
X                break;
X            case 's':
X                the_flag = FLAG_BS;
X                break;
X            default:
X                break;
X            }
X            break;
X        case 'c':
X            if (p[1] == 'b')
X                if (p[2] == 'a')
X                    the_flag = FLAG_CBA;
X                else
X                    the_flag = FLAG_CBB;
X            else if (p[2] == 'a')
X                the_flag = FLAG_CEA;
X            else
X                the_flag = FLAG_CEB;
X            break;
X        case 'd':
X            switch (p[1]) {
X            case 'a':
X                the_flag = FLAG_DA;
X                break;
X            case 'b':
X                switch (p[2]) {
X                case 'a':
X                    the_flag = FLAG_DBA;
X                    break;
X                case 'b':
X                    the_flag = FLAG_DBB;
X                    break;
X                default:
X                    the_flag = FLAG_DB;
X                    break;
X                }
X                break;
X            case 'e':
X                if (p[2] == 'a')
X                    the_flag = FLAG_DEA;
X                else
X                    the_flag = FLAG_DEB;
X                break;
X            default:
X                break;
X            }
X            break;
X        case 'i':
X            if (p[1] == 'a')
X                the_flag = FLAG_IA;
X            else
X                the_flag = FLAG_IB;
X            break;
X        case 'e':
X            if (p[1] == 'a')
X                the_flag = FLAG_EA;
X            else
X                the_flag = FLAG_EB;
X            break;
X        case 'l':
X            if (p[1] == 'c')
X                if (p[2] == 'a')
X                    the_flag = FLAG_LCA;
X                else
X                    the_flag = FLAG_LCB;
X            else
X                if (p[2] == 'a')
X                    the_flag = FLAG_LBA;
X                else
X                    the_flag = FLAG_LBB;
X            break;
X        case 'g':
X            switch(p[1]) {
X                case 'i':
X                    the_flag = FLAG_GI;
X                    break;
X                case 's':
X                    if(p[2]=='b')
X                        the_flag = FLAG_GSB;
X                    else
X                        the_flag = FLAG_GSA;
X                    break;
X                case 'r':
X                    if(p[2]=='b')
X                        the_flag = FLAG_GRB;
X                    else
X                        the_flag = FLAG_GRA;
X                    break;
X            }
X            break;
X        case 'r':
X            switch(p[1]) {
X                case 'c':
X                    if (p[2] == 'a')
X                        the_flag = FLAG_RCA;
X                    else
X                        the_flag = FLAG_RCB;
X                    break;
X                case 'b':
X                    if (p[2] == 'a')
X                        the_flag = FLAG_RBA;
X                    else 
X                        the_flag = FLAG_RBB;
X                    break;
X                case 'a':
X                    the_flag = FLAG_RA;
X                    break;
X                default: 
X                    break;
X            }
X            break;
X        case 'p':
X            the_flag = FLAG_PN;
X            break;
X        default:
X            break;
X        }
X
X        if (the_flag) {
X            if (effect)
X                flags |= the_flag;
X            else
X                flags &= ~the_flag;
X        }
X        p++;
X
X        while (*p >= 'a' && *p <= 'z')
X            p++;
X    }
X}
Xpushflag()
X{
X    flagstack[flagstackpnt]=flags;
X
X    if(flagstackpnt<STACK_LEVELS) 
X        flagstackpnt++;
X}
Xpopflag()
X{
X    if(flagstackpnt>0) 
X        flagstackpnt--;
X    else
X        return;
X
X    flags=flagstack[flagstackpnt];
X}
Xpushmin()
X{
X    minstack[minstackpnt]=minlevel;
X
X    if(minstackpnt<STACK_LEVELS) 
X        minstackpnt++;
X}
Xpopmin()
X{
X    if(minstackpnt>0) 
X        minstackpnt--;
X    else
X        return;
X
X    minlevel=minstack[minstackpnt];
X}
Xpushbraclevel()
X{
X    bracstack[bracpnt]=braclevel;
X
X    if(bracpnt<STACK_LEVELS) 
X        bracpnt++;
X}
Xpopbraclevel()
X{
X    if(bracpnt>0) 
X        bracpnt--;
X    else
X        return;
X
X    braclevel=bracstack[bracpnt];
X}
*-*-END-of-pspp/pspp.l-*-*
exit

jco@reef.cis.ufl.edu (Dumpmaster John) (02/05/91)

At one time I had a Pretty Printer that took in C (or anything else that you
wrote a lexer for.)  The package also Bolded key words and italiced vars.
and in general was a realy nice package.  You could write anysort of
frontend for it and it came with a bunch.

Does anyone know what this package was or where I can get it?

If you know anything about it PLEASE send me mail <jco@reef.cis.ufl.edu>.

thanx
jco

--
"BSD the strongest Operating System avaible today without a prescription."
In Real Life:		
John C. Orthoefer	Internet: jco@smuggler.cis.ufl.edu
University of Florida	Floyd Mailing List: eclipse-request@beach.cis.ufl.edu

me@anywhere.EBay.Sun.COM (Wayne Thompson - IR Workstation Support SE) (02/07/91)

Try uunet.uu.net[137.39.1.2]:comp.source.unix/volume17/pps.Z

Wayne