|
|
researchv10 Norman
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* @(#)picasso:troffgen.c 1.0 */
#include <string.h>
#include <ctype.h>
#include "font.h"
#include "picasso.h"
#include "y.tab.h"
char esc = '\\';
char eqn_delim[] = "\0";
/* the following table of troff names for special characters is in ASCII */
/* order of their names, so that a binary search could be done if desired. */
/* the font field MUST conform to the font initialization in fonts.c, with */
/* the "standard" Times Roman in position 0 and the symbol font as font 1. */
struct trcode {char name[2]; char font; unsigned char value;}
trcode[] =
{'\0','\0','\0','\0', /* null entry, never matched. */
'!','=', 1, 0271, /* not equal */
'!','b', 1, 0313, /* not subset */
'!','m', 1, 0317, /* not member */
'"','a', 0, 0315, /* hungarumlaut accent */
'\'','\'',0,0272, /* right double quote */
'*','*', 1, '*', /* math star */
'*','A', 1, 'A', '*','B', 1, 'B', '*','C', 1, 'X', /* greek */
'*','D', 1, 'D', '*','E', 1, 'E', '*','F', 1, 'F', /* alpha-*/
'*','G', 1, 'G', '*','H', 1, 'Q', '*','I', 1, 'I', /* bet. */
'*','K', 1, 'K', '*','L', 1, 'L', '*','M', 1, 'M',
'*','N', 1, 'N', '*','O', 1, 'O', '*','P', 1, 'P',
'*','Q', 1, 'Y', '*','R', 1, 'R', '*','S', 1, 'S',
'*','T', 1, 'T', '*','U', 1, 'U', '*','W', 1, 'W',
'*','X', 1, 'C', '*','Y', 1, 'H', '*','Z', 1, 'Z',
'*','a', 1, 'a', '*','b', 1, 'b', '*','c', 1, 'x',
'*','d', 1, 'd', '*','e', 1, 'e', '*','f', 1, 'f',
'*','g', 1, 'g', '*','h', 1, 'q', '*','i', 1, 'i',
'*','k', 1, 'k', '*','l', 1, 'l', '*','m', 1, 'm',
'*','n', 1, 'n', '*','o', 1, 'o', '*','p', 1, 'p',
'*','q', 1, 'y', '*','r', 1, 'r', '*','s', 1, 's',
'*','t', 1, 't', '*','u', 1, 'u', '*','w', 1, 'w',
'*','x', 1, 'c', '*','y', 1, 'h', '*','z', 1, 'z',
'+','-', 1, 0261, /* plus-minus */
',','a', 0, 0313, /* cedilla accent */
'-','>', 1, 0256, /* right arrow */
'-','a', 0, 0305, /* macron accent */
'.','a', 0, 0307, /* dot accent */
':','a', 0, 0310, /* dieresis accent */
'<','-', 1, 0254, /* left arrow */
'<','=', 1, 0243, /* less than or equal */
'=','=', 1, 0272, /* identically equal */
'>','=', 1, 0263, /* greater than or equal */
'C','O', 1, 0343, /* copyright (sanserif) */
'C','R', 1, 0277, /* carriage return */
'C','a', 0, 0316, /* ogonek accent */
'I','f', 1, 0301, /* I (fraktur) */
'L','B', 1, 0350, /* paren, left bottom */
'L','T', 1, 0346, /* paren, left top */
'O','+', 1, 0305, /* circled plus */
'O','x', 1, 0304, /* circled times */
'R','B', 1, 0370, /* paren, right bottom */
'R','G', 1, 0342, /* registered (sanserif) */
'R','T', 1, 0366, /* paren, right top */
'R','f', 1, 0302, /* R (fraktur) */
'T','M', 1, 0344, /* trademark (sanserif) */
'U','a', 0, 0306, /* breve accent */
'^','a', 0, 0303, /* circumflex accent */
'`','`', 0, 0252, /* left double quote */
'a','a', 0, 0302, /* circumflex accent */
'a','b', 1, 0253, /* arrow both (left & right) */
'a','f', 1, 0300, /* aleph */
'a','h', 1, 0276, /* arrow horizontal extender */
'a','n', 1, 0320, /* angle */
'a','p', 1, '~', /* approximates */
'a','v', 1, 0275, /* arrow vertical extender */
'b','<', 1, 0341, /* left angle bracket */
'b','>', 1, 0361, /* right angle bracket */
'b','u', 0, 0267, /* bullet */
'b','v', 1, 0352, /* bold vertical (extender) */
'c','.', 1, 0327, /* centered dot */
'c','a', 1, 0307, /* cap */
'c','g', 1, '@', /* congruent to */
'c','o', 1, 0323, /* copyright (serif) */
'c','r', 0, 0250, /* currency */
'c','t', 0, 0242, /* cent */
'c','u', 1, 0310, /* cup */
'd','a', 1, 0257, /* down arrow */
'd','d', 0, 0263, /* double dagger */
'd','e', 1, 0260, /* degree */
'd','g', 0, 0262, /* dagger */
'd','i', 1, 0270, /* divide */
'e','l', 0, 0274, /* ellipsis */
'e','m', 0, 0320, /* emdash */
'e','n', 0, 0261, /* endash */
'e','q', 1, '=', /* equals */
'e','s', 1, 0306, /* empty set */
'f','a', 1, '"', /* for all */
'f','i', 0, 0256, /* fi ligature */
'f','l', 0, 0257, /* fl ligature */
'f','m', 1, 0242, /* minute (footmark) */
'f','n', 0, 0246, /* florin */
'f','r', 0, 0244, /* fraction bar */
'g','a', 0, 0301, /* circumflex accent */
'g','r', 1, 0321, /* gradient */
'h','y', 0, '-', /* hyphen */
'i','b', 1, 0315, /* improper subset */
'i','f', 1, 0245, /* infinity */
'i','p', 1, 0312, /* improper superset */
'i','s', 1, 0362, /* integral sign */
'l','&', 1, 0331, /* logical and */
'l','b', 1, 0356, /* brace, left bottom */
'l','c', 1, 0351, /* square bracket l. ceiling */
'l','f', 1, 0353, /* square bracket l. floor */
'l','k', 1, 0355, /* brace, left middle */
'l','t', 1, 0354, /* brace, left top */
'l','z', 1, 0340, /* lozenge */
'l','|', 1, 0332, /* logical or */
'm','i', 1, '-', /* minus */
'm','o', 1, 0316, /* member of */
'm','u', 1, 0264, /* multiply */
'n','o', 1, 0330, /* logical not */
'o','a', 0, 0312, /* ring accent */
'o','r', 1, '|', /* or (vertical bar) */
'p','d', 1, 0266, /* partial derivative */
'p','g', 0, 0266, /* paragraph */
'p','l', 1, '+', /* plus */
'p','p', 1, '^', /* perpendicular */
'p','s', 0, 0243, /* pound sterling */
'p','t', 1, 0265, /* proportional to */
'r','b', 1, 0376, /* brace, right bottom */
'r','c', 1, 0371, /* square bracket r. ceiling */
'r','f', 1, 0373, /* square bracket r. floor */
'r','g', 1, 0322, /* registered (serif) */
'r','k', 1, 0375, /* brace, right middle */
'r','n', 1, '\'', /* root extender (en) */
'r','t', 1, 0374, /* brace, right top */
's','b', 1, 0314, /* subset */
's','c', 0, 0247, /* section */
's','l', 1, '/', /* slash */
's','p', 1, 0311, /* superset */
's','r', 1, 0326, /* square root */
's','t', 1, '`', /* such that */
't','e', 1, '$', /* there exists */
't','f', 1, '\\', /* therefore */
't','m', 1, 0324, /* trademark (serif) */
't','s', 1, 'V', /* terminal sigma */
'u','a', 1, 0255, /* up arrow */
'u','l', 1, '_', /* underscore */
'v','a', 0, 0317, /* caron accent */
'w','s', 1, 0303, /* Weierstrass P */
'y','n', 0, 0245, /* yen */
'~','a', 0, 0304, /* tilde accent */
'~','~', 1, 0273, /* approximately */
'\0','\0','\0','\0', /* sentinel; loop terminus */
};
int troffcode(str)
char *str;
{
int n;
for (n = 1; trcode[n].name[0] != '\0'; n++)
if (str[0] == trcode[n].name[0] && str[1] == trcode[n].name[1])
return n;
return 0;
}
static
troffparm(name, parm, prev)
char *name, *parm;
int *prev; /* the previous value */
{
extern double atof();
double r, s=0, t;
while (isspace(*parm))
++parm;
t = getfval(name);
if (*parm == '\0')
r = *prev;
else {
r = atof(parm);
if (*parm == '+' || *parm == '-')
s = t;
while (*parm && !isspace(*parm))
parm++;
switch (parm[-1]) {
case 'i': r *= 72; break;
case 'c': r *= (72.*50./127.); break;
case 'P': r *= 12; break;
case 'u': r /= 6; break;
}
}
*prev = t;
setfval(name, r+s);
}
/* The following should be regarded as a kludge, since these values don't
get set by textsize = , etc. There is confusion between picasso's ideas
of these variables and troff's. */
static int ft; /* save previous font for \fP and .ft */
static int psize = 10, /* ditto previous point size */
vsize = 12; /* and vertical spacing */
troff(s)
char *s;
{
int i, fp;
if (s[1] == 'f' && s[2] == 't') {
for (s += 3; isspace(*s); ++s)
;
i = getfval("textfont"); /* save current font */
if (s == '\0') /* reset previous */
fp = ft;
else if (isdigit(*s)) /* allow multi-digit nums */
fp = checkfont((double)atoi(s));
else
fp = setfont(tostring(s));
ft = i;
setfval("textfont", fp);
}
else if (s[1] == 'p' && s[2] == 's')
troffparm("textsize", s+3, &psize);
else if (s[1] == 'v' && s[2] == 's')
troffparm("textspace", s+3, &vsize);
else if (s[1] == 'e')
if (s[2] == 'o')
esc = '\0';
else if (s[2] == 'c') {
for (s += 3; isspace(*s); ++s)
;
esc = *s ? *s : '\\';
}
}
obj *troffgen(s)
YYSTYPE s;
{
troff(s.p);
save_one(CENTER, 0, 0, 0, s.p);
free(s.p);
return makenode(TROFF, 0, (int)getfval("curlayer"));
}
char *parse_text (txt, fp, sp) /* split txt into substrings with */
char *txt; /* uniform font and pointsize; */
int *fp, *sp; /* some '\0' chars are put in txt.*/
{
extern int parsing;
static char buf[256];
static int n = 0,
lim = 0;
int i, j;
char *bp;
if (n == 0) { /* new string; initialize */
lim = strlen(txt);
ft = *fp;
}
else if (n == lim) {
n = 0;
return NULL;
}
for (bp = buf; n < lim; ) {
if (txt[n] != esc && txt[n] != *eqn_delim)
*bp++ = txt[n++];
else if (txt[n] == *eqn_delim) {
if (!parsing) {
do n++;
while (txt[n] != eqn_delim[1] && n < lim);
n++;
continue;
}
if (bp > buf) { *bp = '\0'; return buf; }
eqn_save(".EQ");
while (txt[++n] != eqn_delim[1] && n < lim)
*bp++ = txt[n];
if (n < lim)
++n;
strcpy(bp, "\n.EN");
eqn_save(buf);
eqn_gen(TEXT);
bp = buf;
*bp++ = '\0'; /* fudge, to prevent a 2nd save_one() */
}
else { /* fonts, sizes, troff codes */
switch (txt[n+1]) {
default:
*bp++ = txt[n++];
break;
case '&': /* zero-width char */
n += 2; /* discard it */
break;
case '(':
if ((i = troffcode(txt+n+2)) == 0)
*bp++ = txt[n++]; /* unknown */
else {
if (bp > buf && *fp != trcode[i].font)
{ *bp = '\0'; return buf; }
*bp++ = trcode[i].value;
ft = *fp;
*fp = trcode[i].font;
txt[++n] = '\\';
txt[n+1] = 'f';
txt[n+2] = 'P'; /* restore old font */
}
break;
case 'N':
n += 3;
*bp++ = atoi(txt+n);
while (isdigit(txt[n])) n++;
break;
case 'f':
if (bp > buf) { *bp = '\0'; return buf; }
n += 2;
i = *fp; /* save current font */
if (txt[n] == 'P') { /* reset previous */
*fp = ft;
++n;
}
else if (isdigit(txt[n]))
*fp = checkfont((double)(txt[n++]-'0'));
else {
if (txt[n] != '(')
*bp++ = txt[n++];
else {
*bp++ = txt[++n];
*bp++ = txt[++n];
++n;
}
*bp = '\0';
*fp = setfont(tostring(bp=buf));
}
ft = i;
break;
case 's':
if (bp > buf) { *bp = '\0'; return buf; }
n += 2;
if (txt[n] == '+' || txt[n] == '-') {
if ((i = *sp) == 0)
i = getfval("textsize");
if (txt[n] == '-')
i = -i;
++n;
}
else
i = 0;
j = 0;
if (i == 0 && txt[n] == '0'){/* use previous */
i = psize;
++n;
}
else {
if (isdigit(txt[n]))
j = txt[n++] - '0';
if (j && isdigit(txt[n]))
j = j * 10 + txt[n++] - '0';
}
psize = *sp = (i < 0 ? -(i+j) : i+j);
break;
}
}
}
*bp = '\0';
if (bp != buf)
return buf;
else {
n = 0;
return NULL;
}
}
int eqn_count = 0;
char psfname[L_tmpnam] = "";
char dpost[] = "dpost";
FILE *eqnfp = NULL,
*pipefp = NULL;
int no_eqn = 0;
eqn_save(s)
char *s;
{
extern char *gwblib;
char *dp, private[64], buf[BUFSIZ];
if (pipefp == NULL && !no_eqn){/* open up eqn|troff|dpost subprocess */
if (access("/usr/bin/eqn", 1)) /* kludge! */
no_eqn = 1;
else {
sprintf(private, "%s/%s", gwblib, dpost);
dp = access(private,1) ? dpost : private;
tmpnam(psfname);
sprintf(buf, "eqn|troff -Tpost|%s -B>%s", dp, psfname);
if ((pipefp = popen(buf, "w")) == NULL)
fatal("cannot pipe through eqn");
}
}
if (no_eqn) {
if (strncmp(s, ".EQ", 3) == 0 || strncmp(s, ".EN", 3) == 0 ||
strncmp(s, "delim", 5) == 0)
;
else
savetext(CENTER, s);
return;
}
if (s[0] == '.' && s[1] == 'E' && s[2] == 'Q') {
double f = getfval("textfont");
sprintf(buf,".ft %s\n.ps %d\n.vs %d\n", mount[(int)f]->name,
(int)getfval("textsize"), (int)getfval("textspace"));
fputs(buf, pipefp);
}
fputs(s, pipefp);
fputc('\n', pipefp);
scan_delim(s);
}
scan_delim(s)
char *s;
{
while (isspace(*s))
++s;
/* probably eqn's syntax is less restrictive than the following */
if (strncmp(s,"delim",5)==0) {
for (s += 5; isspace(*s); ++s)
;
if (strcmp(s,"off")==0)
eqn_delim[1] = eqn_delim[0] = '\0';
else {
eqn_delim[1] = eqn_delim[0] = *s;
if (*s++)
if (*s)
eqn_delim[1] = *s;
}
}
}
eqn_gen(type)
int type;
{
extern int ntextlines;
obj *p;
char buf[8];
if (!no_eqn) {
fputs(".bp\n", pipefp);
sprintf(buf, "%d", ++eqn_count);
save_one(EQNTXT, 0, 0, ntextlines, buf);
}
if (type == TROFF) {
p = makenode(TROFF, 0, (int)getfval("curlayer"));
checktextcolor(p);
codegen = 1;
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.