Date: Thu, 4 Aug 1994 17:23:12 -0400 (EDT) From: GOLDEN@huhept.harvard.edu To: ginsparg@qfwfq.lanl.gov Cc: GOLDEN@huhept.harvard.edu Subject: P.S. If you post that on xxx, be sure to tell people that the new version of dvips may not work with the old version (as of 5.491) of tex.pro. (I found out the hard way that the old version of dvips doesn't work with the new tex.pro.) They really should do a full install. ------------------------------------------------------- From: HUHEPL::GOLDEN 3-AUG-1994 17:41:35.70 To: SMTP%"rokicki@cs.stanford.edu" CC: GOLDEN Subj: html specials in dvips I have made a modification to dospecial.c in dvips so that it now ignores the "html:" special. This is a new \special command that is used to create hypertext links in TeX documents. The present version, 5.55 or earlier, produce errors when such specials come up. I would like this to be included in a new version of dvips. The file below is the modified version. - Mitch Golden golden@physics.harvard.edu ---------------------------------------------------------------------------- /* * This routine handles special commands; * predospecial() is for the prescan, dospecial() for the real thing. */ #include "dvips.h" /* The copyright notice in that file is included too! */ #include extern int atoi(); extern void fil2ps(); extern FILE *search(); extern int system(); /* * These are the external routines called: */ /**/ #ifdef TPIC /* * Fri Mar 9 1990 jourdan@minos.inria.fr (MJ) * Upgraded to accommodate tpic release 2.0 extended output language. * Should prove upward compatible! */ /* * Wed Aug 3 1994 golden@physics.harvard.edu (MG) * Now ignores html: specials, for use with hypertex files */ extern void setPenSize(); extern void flushPath(); extern void flushDashed(); extern void flushDashed(); extern void addPath(); extern void arc(); extern void flushSpline(); extern void shadeLast(); extern void whitenLast(); extern void blackenLast(); extern void SetShade() ; #endif extern shalfword dvibyte() ; extern int add_header() ; extern void hvpos() ; extern void figcopyfile() ; extern void nlcmdout() ; extern void cmdout() ; extern void numout() ; extern void scout() ; extern void stringend() ; extern void error() ; extern void psflush() ; extern void emspecial() ; /* IBM: color - begin */ extern void pushcolor() ; extern void popcolor() ; extern void resetcolorstack() ; extern void background() ; /* IBM: color - end */ extern char errbuf[] ; extern shalfword linepos; extern Boolean usesspecial ; extern Boolean usescolor ; /* IBM: color */ extern int landscape ; extern char *paperfmt ; extern char *nextstring; extern char *maxstring; extern char *oname; extern FILE *bitfile; extern int quiet; extern fontdesctype *curfnt ; extern int actualdpi ; extern int vactualdpi ; extern integer hh, vv; extern int lastfont ; extern real conv ; extern real vconv ; extern integer hpapersize, vpapersize ; extern Boolean pprescan ; extern char *figpath ; extern int prettycolumn ; extern Boolean disablecomments ; #ifdef DEBUG extern integer debug_flag; #endif extern void scanfontcomments() ; extern void handlepapersize() ; static int specialerrors = 20 ; struct bangspecial { struct bangspecial *next ; char actualstuff[1] ; /* more space will actually be allocated */ } *bangspecials = NULL ; void specerror(s) char *s ; { if (specialerrors > 0) { error(s) ; specialerrors-- ; } else if (specialerrors == 0) { error("more errors in special, being ignored . . .") ; specialerrors-- ; } } static void trytobreakout(p) register char *p ; { register int i ; register int instring = 0 ; int lastc = 0 ; i = 0 ; (void)putc('\n', bitfile) ; while (*p) { if (i > 65 && *p == ' ' && instring == 0) { (void)putc('\n', bitfile) ; i = 0 ; } else { (void)putc(*p, bitfile) ; i++ ; } if (*p == '(' && lastc != '\\') instring = 1 ; else if (*p == ')' && lastc != '\\') instring = 0 ; lastc = *p ; p++ ; } (void)putc('\n', bitfile) ; } static void dobs(q) register struct bangspecial *q ; { if (q) { dobs(q->next) ; trytobreakout(q->actualstuff) ; } } void outbangspecials() { if (bangspecials) { cmdout("TeXDict") ; cmdout("begin") ; cmdout("@defspecial\n") ; dobs(bangspecials) ; cmdout("\n@fedspecial") ; cmdout("end") ; } } /* We recommend that new specials be handled by the following general * (and extensible) scheme, in which the user specifies one or more * `key=value' pairs separated by spaces. * The known keys are given in KeyTab; they take values * of one of the following types: * * None: no value, just a keyword (in which case the = sign is omitted) * String: the value should be "' ' && *s!='=') s++ ; if (0 != (t = *s)) *s++ = 0 ; for(i=0; iscaledsize) * conv * 72 / DPI ; } break ; default: break ; } return (s) ; } /* * Now our routines. We get the number of bytes specified and place them * into the string buffer, and then parse it. Numerous conventions are * supported here for historical reasons. */ void predospecial(numbytes, scanning) integer numbytes ; Boolean scanning ; { register char *p = nextstring ; register int i = 0 ; int j ; if (nextstring + numbytes > maxstring) error("! out of string space in predospecial") ; for (i=numbytes; i>0; i--) #ifdef VMCMS /* IBM: VM/CMS */ *p++ = ascii2ebcdic[(char)dvibyte()] ; #else #ifdef MVSXA /* IBM: MVS/XA */ *p++ = ascii2ebcdic[(char)dvibyte()] ; #else *p++ = (char)dvibyte() ; #endif /* IBM: VM/CMS */ #endif if (pprescan) return ; while (p[-1] <= ' ' && p > nextstring) p-- ; /* trim trailing blanks */ if (p==nextstring) return ; /* all blank is no-op */ *p = 0 ; p = nextstring ; while (*p <= ' ') p++ ; #ifdef DEBUG if (dd(D_SPECIAL)) (void)fprintf(stderr, "Preprocessing special: %s\n", p) ; #endif /* * We use strncmp() here to also pass things like landscape() * or landscape: or such. */ if (strncmp(p, "landscape", 9)==0) { if (hpapersize || vpapersize) error( "both landscape and papersize specified: ignoring landscape") ; else landscape = 1 ; return ; } else if (strncmp(p, "papersize", 9)==0) { p += 9 ; while (*p == '=' || *p == ' ') p++ ; if (hpapersize == 0 || vpapersize == 0) { if (landscape) { error( "both landscape and papersize specified: ignoring landscape") ; landscape = 0 ; } handlepapersize(p, &hpapersize, &vpapersize) ; } return ; } if (strncmp(p, "xtex:", 5)==0) return ; /* Don't do anything with html specials - MG 8/3/94 */ if (strncmp(p, "html:", 5)==0) return ; usesspecial = 1 ; /* now the special prolog will be sent */ if (strncmp(p, "header", 6)==0) { char *q ; p += 6 ; while ((*p <= ' ' || *p == '=' || *p == '(') && *p != 0) p++ ; q = p ; /* we will remove enclosing parentheses */ p = p + strlen(p) - 1 ; while ((*p <= ' ' || *p == ')') && p >= q) p-- ; p[1] = 0 ; if (p >= q) (void)add_header(q) ; } /* IBM: color - added section here for color header and color history */ if (strncmp(p, "background", 10) == 0) { usescolor = 1 ; p +=11 ; while ( *p <= ' ' ) p++ ; background(p) ; } if (strncmp(p, "color", 5) == 0) { usescolor = 1 ; p += 6 ; while ( *p <= ' ' ) p++ ; if (strncmp(p, "push", 4) == 0 ) { p += 5 ; while ( *p <= ' ' ) p++ ; pushcolor(p, 0) ; } else if (strncmp(p, "pop", 3) == 0 ) { popcolor(0) ; } else { resetcolorstack(p,0) ; } } /* IBM: color - end changes */ else if (*p == '!') { register struct bangspecial *q ; p++ ; q = (struct bangspecial *)mymalloc((integer) (sizeof(struct bangspecial) + strlen(p))) ; (void)strcpy(q->actualstuff, p) ; q->next = bangspecials ; bangspecials = q ; } else if (scanning && *p != '"' && (p=GetKeyVal(p, &j)) != NULL && j==0) scanfontcomments(ValStr) ; } int maccess(s) char *s ; { FILE *f = search(figpath, s, "r") ; if (f) fclose(f) ; return (f != 0) ; } char *tasks[] = { 0, "iff2ps", "tek2ps" } ; static char psfile[511] ; void dospecial(numbytes) integer numbytes ; { register char *p = nextstring ; register int i = 0 ; int j, systemtype = 0 ; register char *q ; Boolean psfilewanted = 1 ; char *task = 0 ; char cmdbuf[111] ; if (nextstring + i > maxstring) error("! out of string space in dospecial") ; for (i=numbytes; i>0; i--) #ifdef VMCMS /* IBM: VM/CMS */ *p++ = ascii2ebcdic[(char)dvibyte()] ; #else #ifdef MVSXA /* IBM: MVS/XA */ *p++ = ascii2ebcdic[(char)dvibyte()] ; #else *p++ = (char)dvibyte() ; #endif /* IBM: VM/CMS */ #endif while (p[-1] <= ' ' && p > nextstring) p-- ; /* trim trailing blanks */ if (p==nextstring) return ; /* all blank is no-op */ *p = 0 ; p = nextstring ; while (*p <= ' ') p++ ; #ifdef DEBUG if (dd(D_SPECIAL)) (void)fprintf(stderr, "Processing special: %s\n", p) ; #endif if (strncmp(p, "em:", 3)==0) { /* emTeX specials in emspecial.c */ emspecial(p); return; } if (strncmp(p, "ps:", 3)==0) { psflush() ; /* now anything can happen. */ if (p[3]==':') { if (strncmp(p+4, "[begin]", 7) == 0) { hvpos() ; trytobreakout(&p[11]); } else if (strncmp(p+4, "[end]", 5) == 0) trytobreakout(&p[9]); else trytobreakout(&p[4]); } else if (strncmp(p+3, " plotfile ", 10) == 0) { char *sfp ; hvpos() ; p += 13; /* * Fixed to allow popen input for plotfile * TJD 10/20/91 */ while (*p == ' ') p++; if (*p == '"') { p++; for (sfp = p; *sfp && *sfp != '"'; sfp++) ; } else { for (sfp = p; *sfp && *sfp != ' '; sfp++) ; } *sfp = '\0'; if (*p == '`') figcopyfile(p+1, 1); else figcopyfile (p, 0); /* End TJD changes */ } else { hvpos() ; trytobreakout(&p[3]); psflush() ; hvpos() ; } return; } if (strncmp(p, "landscape", 9)==0 || strncmp(p, "header", 6)==0 || strncmp(p, "html:", 5)==0 || /* Ignore! - MG 8/3/94 */ strncmp(p, "papersize", 9)==0 || *p=='!') return ; /* already handled in prescan */ /* IBM: color - begin changes */ if ( strncmp(p, "background", 10) == 0 ) return ; /* already handled in prescan */ if (strncmp(p, "color", 5) == 0) { p += 6 ; while ( *p <= ' ' ) p++ ; if (strncmp(p, "push", 4) == 0 ) { p += 4 ; while ( *p <= ' ' ) p++ ; pushcolor(p,1); } else if (strncmp(p, "pop", 3) == 0 ) { popcolor(1) ; } else { resetcolorstack(p,1) ; } return ; } /* IBM: color - end changes*/ #ifdef TPIC /* ordered as in tpic 2.0 documentation for ease of cross-referencing */ if (strncmp(p, "pn ", 3) == 0) {setPenSize(p+2); return;} if (strncmp(p, "pa ", 3) == 0) {addPath(p+2); return;} if (strcmp(p, "fp") == 0) {flushPath(0); return;} if (strcmp(p, "ip") == 0) {flushPath(1); return;} /* tpic 2.0 */ if (strncmp(p, "da ", 3) == 0) {flushDashed(p+2, 0); return;} if (strncmp(p, "dt ", 3) == 0) {flushDashed(p+2, 1); return;} if (strcmp(p, "sp") == 0) {flushSpline(p+2); return;} /* tpic 2.0 */ if (strncmp(p, "sp ", 3) == 0) {flushSpline(p+3); return;} /* tpic 2.0 */ if (strncmp(p, "ar ", 3) == 0) {arc(p+2, 0); return;} /* tpic 2.0 */ if (strncmp(p, "ia ", 3) == 0) {arc(p+2, 1); return;} /* tpic 2.0 */ if (strcmp(p, "sh") == 0) {shadeLast(p+2); return;} /* tpic 2.0 */ if (strncmp(p, "sh ", 3) == 0) {shadeLast(p+3); return;} /* tpic 2.0 */ if (strcmp(p, "wh") == 0) {whitenLast(); return;} if (strcmp(p, "bk") == 0) {blackenLast(); return;} if (strncmp(p, "tx ", 3) == 0) {SetShade(p+3); return;} #endif if (*p == '"') { hvpos() ; cmdout("@beginspecial") ; cmdout("@setspecial") ; trytobreakout(p+1) ; cmdout("\n@endspecial") ; return ; } /* At last we get to the key/value conventions */ psfile[0] = '\0'; hvpos(); cmdout("@beginspecial"); while( (p=GetKeyVal(p,&j)) != NULL ) switch (j) { case -1: /* for compatability with old conventions, we allow a file name * to be given without the 'psfile=' keyword */ if (!psfile[0] && maccess(KeyStr)==0) /* yes we can read it */ (void)strcpy(psfile,KeyStr) ; else { sprintf(errbuf, "Unknown keyword (%s) in \\special will be ignored", KeyStr) ; specerror(errbuf) ; } break ; case 0: case 1: case 2: /* psfile */ if (psfile[0]) { sprintf(errbuf, "More than one \\special %s given; %s ignored", "psfile", ValStr) ; specerror(errbuf) ; } else (void)strcpy(psfile,ValStr) ; task = tasks[j] ; break ; default: /* most keywords are output as PostScript procedure calls */ if (KeyTab[j].Type == Integer) numout((integer)ValInt); else if (KeyTab[j].Type == String) for (q=ValStr; *q; q++) scout(*q) ; else if (KeyTab[j].Type == None) ; else { /* Number or Dimension */ ValInt = (integer)(ValNum<0? ValNum-0.5 : ValNum+0.5) ; if (ValInt-ValNum < 0.001 && ValInt-ValNum > -0.001) numout((integer)ValInt) ; else { (void)sprintf(cmdbuf, "%f", ValNum) ; cmdout(cmdbuf) ; } } (void)sprintf(cmdbuf, "@%s", KeyStr); cmdout(cmdbuf) ; } cmdout("@setspecial"); if(psfile[0]) { if (task == 0) { systemtype = (psfile[0]=='`') ; figcopyfile(psfile+systemtype, systemtype); } else { fil2ps(task, psfile) ; } } else if (psfilewanted) specerror("No \\special psfile was given; figure will be blank") ; cmdout("@endspecial"); } extern char realnameoffile[] ; extern char *pictpath ; void fil2ps(task, iname) char *task, *iname ; { char cmd[400] ; FILE *f ; if (0 != (f=search(pictpath, iname, "r"))) { fclose(f) ; } else { fprintf(stderr, " couldn't open %s\n", iname) ; return ; } if (!quiet) { fprintf(stderr, " [%s", realnameoffile) ; fflush(stderr) ; } if (oname && oname[0] && oname[0] != '-') { putc(10, bitfile) ; fclose(bitfile) ; sprintf(cmd, "%s -f %s %s", task, realnameoffile, oname) ; system(cmd) ; if ((bitfile=fopen(oname, "a"))==NULL) error("! couldn't reopen PostScript file") ; linepos = 0 ; } else { sprintf(cmd, "%s -f %s", task, realnameoffile) ; system(cmd) ; } if (!quiet) fprintf(stderr, "]") ; }