Annotation of researchv10no/cmd/picasso/troffgen.c, revision 1.1.1.1

1.1       root        1: /*     Copyright (c) 1988 AT&T */
                      2: /*       All Rights Reserved   */
                      3: 
                      4: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
                      5: /*     The copyright notice above does not evidence any        */
                      6: /*     actual or intended publication of such source code.     */
                      7: 
                      8: /*     @(#)picasso:troffgen.c  1.0     */
                      9: 
                     10: #include <string.h>
                     11: #include <ctype.h>
                     12: #include "font.h"
                     13: #include "picasso.h"
                     14: #include "y.tab.h"
                     15: 
                     16: char   esc         = '\\';
                     17: char   eqn_delim[] = "\0";
                     18: 
                     19: /* the following table of troff names for special characters is in ASCII   */
                     20: /* order of their names, so that a binary search could be done if desired. */
                     21: /* the font field MUST conform to the font initialization in fonts.c, with */
                     22: /* the "standard" Times Roman in position 0 and the symbol font as font 1. */
                     23: 
                     24: struct trcode  {char name[2];  char font;  unsigned char value;}
                     25:        trcode[]  =
                     26:                {'\0','\0','\0','\0',           /* null entry, never matched. */
                     27:                '!','=', 1, 0271,               /* not equal */
                     28:                '!','b', 1, 0313,               /* not subset */
                     29:                '!','m', 1, 0317,               /* not member */
                     30:                '"','a', 0, 0315,               /* hungarumlaut accent */
                     31:                '\'','\'',0,0272,               /* right double quote */
                     32:                '*','*', 1, '*',                /* math star */
                     33: 
                     34:                '*','A', 1, 'A', '*','B', 1, 'B', '*','C', 1, 'X',   /* greek */
                     35:                '*','D', 1, 'D', '*','E', 1, 'E', '*','F', 1, 'F',   /* alpha-*/
                     36:                '*','G', 1, 'G', '*','H', 1, 'Q', '*','I', 1, 'I',   /* bet.  */
                     37:                '*','K', 1, 'K', '*','L', 1, 'L', '*','M', 1, 'M',
                     38:                '*','N', 1, 'N', '*','O', 1, 'O', '*','P', 1, 'P',
                     39:                '*','Q', 1, 'Y', '*','R', 1, 'R', '*','S', 1, 'S',
                     40:                '*','T', 1, 'T', '*','U', 1, 'U', '*','W', 1, 'W',
                     41:                '*','X', 1, 'C', '*','Y', 1, 'H', '*','Z', 1, 'Z',
                     42:                '*','a', 1, 'a', '*','b', 1, 'b', '*','c', 1, 'x',
                     43:                '*','d', 1, 'd', '*','e', 1, 'e', '*','f', 1, 'f',
                     44:                '*','g', 1, 'g', '*','h', 1, 'q', '*','i', 1, 'i',
                     45:                '*','k', 1, 'k', '*','l', 1, 'l', '*','m', 1, 'm',
                     46:                '*','n', 1, 'n', '*','o', 1, 'o', '*','p', 1, 'p',
                     47:                '*','q', 1, 'y', '*','r', 1, 'r', '*','s', 1, 's',
                     48:                '*','t', 1, 't', '*','u', 1, 'u', '*','w', 1, 'w',
                     49:                '*','x', 1, 'c', '*','y', 1, 'h', '*','z', 1, 'z',
                     50: 
                     51:                '+','-', 1, 0261,               /* plus-minus */
                     52:                ',','a', 0, 0313,               /* cedilla accent */
                     53:                '-','>', 1, 0256,               /* right arrow */
                     54:                '-','a', 0, 0305,               /* macron accent */
                     55:                '.','a', 0, 0307,               /* dot accent */
                     56:                ':','a', 0, 0310,               /* dieresis accent */
                     57:                '<','-', 1, 0254,               /* left arrow */
                     58:                '<','=', 1, 0243,               /* less than or equal */
                     59:                '=','=', 1, 0272,               /* identically equal */
                     60:                '>','=', 1, 0263,               /* greater than or equal */
                     61:                'C','O', 1, 0343,               /* copyright (sanserif) */
                     62:                'C','R', 1, 0277,               /* carriage return */
                     63:                'C','a', 0, 0316,               /* ogonek accent */
                     64:                'I','f', 1, 0301,               /* I (fraktur) */
                     65:                'L','B', 1, 0350,               /* paren, left bottom */
                     66:                'L','T', 1, 0346,               /* paren, left top */
                     67:                'O','+', 1, 0305,               /* circled plus */
                     68:                'O','x', 1, 0304,               /* circled times */
                     69:                'R','B', 1, 0370,               /* paren, right bottom */
                     70:                'R','G', 1, 0342,               /* registered (sanserif) */
                     71:                'R','T', 1, 0366,               /* paren, right top */
                     72:                'R','f', 1, 0302,               /* R (fraktur) */
                     73:                'T','M', 1, 0344,               /* trademark (sanserif) */
                     74:                'U','a', 0, 0306,               /* breve accent */
                     75:                '^','a', 0, 0303,               /* circumflex accent */
                     76:                '`','`', 0, 0252,               /* left double quote */
                     77:                'a','a', 0, 0302,               /* circumflex accent */
                     78:                'a','b', 1, 0253,               /* arrow both (left & right) */
                     79:                'a','f', 1, 0300,               /* aleph */
                     80:                'a','h', 1, 0276,               /* arrow horizontal extender */
                     81:                'a','n', 1, 0320,               /* angle */
                     82:                'a','p', 1, '~',                /* approximates */
                     83:                'a','v', 1, 0275,               /* arrow vertical extender */
                     84:                'b','<', 1, 0341,               /* left angle bracket */
                     85:                'b','>', 1, 0361,               /* right angle bracket */
                     86:                'b','u', 0, 0267,               /* bullet */
                     87:                'b','v', 1, 0352,               /* bold vertical (extender) */
                     88:                'c','.', 1, 0327,               /* centered dot */
                     89:                'c','a', 1, 0307,               /* cap */
                     90:                'c','g', 1, '@',                /* congruent to */
                     91:                'c','o', 1, 0323,               /* copyright (serif) */
                     92:                'c','r', 0, 0250,               /* currency */
                     93:                'c','t', 0, 0242,               /* cent */
                     94:                'c','u', 1, 0310,               /* cup */
                     95:                'd','a', 1, 0257,               /* down arrow */
                     96:                'd','d', 0, 0263,               /* double dagger */
                     97:                'd','e', 1, 0260,               /* degree */
                     98:                'd','g', 0, 0262,               /* dagger */
                     99:                'd','i', 1, 0270,               /* divide */
                    100:                'e','l', 0, 0274,               /* ellipsis */
                    101:                'e','m', 0, 0320,               /* emdash */
                    102:                'e','n', 0, 0261,               /* endash */
                    103:                'e','q', 1, '=',                /* equals */
                    104:                'e','s', 1, 0306,               /* empty set */
                    105:                'f','a', 1, '"',                /* for all */
                    106:                'f','i', 0, 0256,               /* fi ligature */
                    107:                'f','l', 0, 0257,               /* fl ligature */
                    108:                'f','m', 1, 0242,               /* minute (footmark) */
                    109:                'f','n', 0, 0246,               /* florin */
                    110:                'f','r', 0, 0244,               /* fraction bar */
                    111:                'g','a', 0, 0301,               /* circumflex accent */
                    112:                'g','r', 1, 0321,               /* gradient */
                    113:                'h','y', 0, '-',                /* hyphen */
                    114:                'i','b', 1, 0315,               /* improper subset  */
                    115:                'i','f', 1, 0245,               /* infinity */
                    116:                'i','p', 1, 0312,               /* improper superset */
                    117:                'i','s', 1, 0362,               /* integral sign */
                    118:                'l','&', 1, 0331,               /* logical and */
                    119:                'l','b', 1, 0356,               /* brace, left bottom */
                    120:                'l','c', 1, 0351,               /* square bracket l. ceiling */
                    121:                'l','f', 1, 0353,               /* square bracket l. floor */
                    122:                'l','k', 1, 0355,               /* brace, left middle */
                    123:                'l','t', 1, 0354,               /* brace, left top */
                    124:                'l','z', 1, 0340,               /* lozenge */
                    125:                'l','|', 1, 0332,               /* logical or */
                    126:                'm','i', 1, '-',                /* minus */
                    127:                'm','o', 1, 0316,               /* member of */
                    128:                'm','u', 1, 0264,               /* multiply */
                    129:                'n','o', 1, 0330,               /* logical not */
                    130:                'o','a', 0, 0312,               /* ring accent */
                    131:                'o','r', 1, '|',                /* or (vertical bar) */
                    132:                'p','d', 1, 0266,               /* partial derivative */
                    133:                'p','g', 0, 0266,               /* paragraph */
                    134:                'p','l', 1, '+',                /* plus */
                    135:                'p','p', 1, '^',                /* perpendicular */
                    136:                'p','s', 0, 0243,               /* pound sterling */
                    137:                'p','t', 1, 0265,               /* proportional to */
                    138:                'r','b', 1, 0376,               /* brace, right bottom */
                    139:                'r','c', 1, 0371,               /* square bracket r. ceiling */
                    140:                'r','f', 1, 0373,               /* square bracket r. floor */
                    141:                'r','g', 1, 0322,               /* registered (serif) */
                    142:                'r','k', 1, 0375,               /* brace, right middle */
                    143:                'r','n', 1, '\'',               /* root extender (en) */
                    144:                'r','t', 1, 0374,               /* brace, right top */
                    145:                's','b', 1, 0314,               /* subset */
                    146:                's','c', 0, 0247,               /* section */
                    147:                's','l', 1, '/',                /* slash */
                    148:                's','p', 1, 0311,               /* superset */
                    149:                's','r', 1, 0326,               /* square root */
                    150:                's','t', 1, '`',                /* such that */
                    151:                't','e', 1, '$',                /* there exists */
                    152:                't','f', 1, '\\',               /* therefore */
                    153:                't','m', 1, 0324,               /* trademark (serif) */
                    154:                't','s', 1, 'V',                /* terminal sigma */
                    155:                'u','a', 1, 0255,               /* up arrow */
                    156:                'u','l', 1, '_',                /* underscore */
                    157:                'v','a', 0, 0317,               /* caron accent */
                    158:                'w','s', 1, 0303,               /* Weierstrass P */
                    159:                'y','n', 0, 0245,               /* yen */
                    160:                '~','a', 0, 0304,               /* tilde accent */
                    161:                '~','~', 1, 0273,               /* approximately */
                    162: 
                    163:                '\0','\0','\0','\0',            /* sentinel; loop terminus */
                    164:                };
                    165: 
                    166: int    troffcode(str)
                    167:        char    *str;
                    168: {
                    169:        int     n;
                    170: 
                    171:        for (n = 1; trcode[n].name[0] != '\0'; n++)
                    172:                if (str[0] == trcode[n].name[0] && str[1] == trcode[n].name[1])
                    173:                        return n;
                    174:        return 0;
                    175: }
                    176: 
                    177: static
                    178: troffparm(name, parm, prev)
                    179:        char    *name, *parm;
                    180:        int     *prev;                  /* the previous value */
                    181: {
                    182: extern double  atof();
                    183:        double  r, s=0, t;
                    184: 
                    185:        while (isspace(*parm))
                    186:                ++parm;
                    187:        t = getfval(name);
                    188:        if (*parm == '\0')
                    189:                r = *prev;
                    190:        else {
                    191:                r = atof(parm);
                    192:                if (*parm == '+' || *parm == '-')
                    193:                        s = t;
                    194:                while (*parm && !isspace(*parm))
                    195:                        parm++;
                    196:                switch (parm[-1]) {
                    197:                        case 'i':       r *= 72;                break;
                    198:                        case 'c':       r *= (72.*50./127.);    break;
                    199:                        case 'P':       r *= 12;                break;
                    200:                        case 'u':       r /= 6;                 break;
                    201:                }
                    202:        }
                    203:        *prev = t;
                    204:        setfval(name, r+s);
                    205: }
                    206: 
                    207: /* The following should be regarded as a kludge, since these values don't
                    208: get set by textsize = , etc.  There is confusion between picasso's ideas
                    209: of these variables and troff's. */
                    210: static int     ft;             /* save previous font for \fP and .ft */
                    211: static int     psize = 10,     /* ditto previous point size */
                    212:                vsize = 12;     /*    and vertical spacing */
                    213: 
                    214: troff(s)
                    215:        char    *s;
                    216: {
                    217:        int     i, fp;
                    218: 
                    219:        if (s[1] == 'f' && s[2] == 't') {
                    220:                for (s += 3; isspace(*s); ++s)
                    221:                        ;
                    222:                i = getfval("textfont");        /* save current font */
                    223:                if (s == '\0')                  /* reset previous */
                    224:                        fp = ft;
                    225:                else if (isdigit(*s))           /* allow multi-digit nums */
                    226:                        fp = checkfont((double)atoi(s));
                    227:                else
                    228:                        fp = setfont(tostring(s));
                    229:                ft = i;
                    230:                setfval("textfont", fp);
                    231:        }
                    232:        else if (s[1] == 'p' && s[2] == 's')
                    233:                troffparm("textsize", s+3, &psize);
                    234:        else if (s[1] == 'v' && s[2] == 's')
                    235:                troffparm("textspace", s+3, &vsize);
                    236:        else if (s[1] == 'e')
                    237:                if (s[2] == 'o')
                    238:                        esc = '\0';
                    239:                else if (s[2] == 'c') {
                    240:                        for (s += 3; isspace(*s); ++s)
                    241:                                ;
                    242:                        esc = *s ? *s : '\\';
                    243:                }
                    244: }
                    245: 
                    246: obj    *troffgen(s)
                    247:        YYSTYPE s;
                    248: {
                    249:        troff(s.p);
                    250:        save_one(CENTER, 0, 0, 0, s.p);
                    251:        free(s.p);
                    252:        return makenode(TROFF, 0, (int)getfval("curlayer"));
                    253: }
                    254: 
                    255: char   *parse_text (txt, fp, sp)       /* split txt into substrings with */
                    256:        char    *txt;                   /* uniform font and pointsize;    */
                    257:        int     *fp, *sp;               /* some '\0' chars are put in txt.*/
                    258: {
                    259:        extern int  parsing;
                    260: static char    buf[256];
                    261: static int     n   = 0,
                    262:                lim = 0;
                    263:        int     i, j;
                    264:        char    *bp;
                    265: 
                    266:        if (n == 0) {   /* new string; initialize */
                    267:                lim = strlen(txt);
                    268:                ft = *fp;
                    269:        }
                    270:        else if (n == lim) {
                    271:                n = 0;
                    272:                return NULL;
                    273:        }
                    274:        for (bp = buf; n < lim; ) {
                    275:                if (txt[n] != esc && txt[n] != *eqn_delim)
                    276:                        *bp++ = txt[n++];
                    277:                else if (txt[n] == *eqn_delim) {
                    278:                        if (!parsing) {
                    279:                                do n++;
                    280:                                while (txt[n] != eqn_delim[1] && n < lim);
                    281:                                n++;
                    282:                                continue;
                    283:                        }
                    284:                        if (bp > buf) { *bp = '\0'; return buf; }
                    285:                        eqn_save(".EQ");
                    286:                        while (txt[++n] != eqn_delim[1] && n < lim)
                    287:                                *bp++ = txt[n];
                    288:                        if (n < lim)
                    289:                                ++n;
                    290:                        strcpy(bp, "\n.EN");
                    291:                        eqn_save(buf);
                    292:                        eqn_gen(TEXT);
                    293:                        bp = buf;
                    294:                        *bp++ = '\0';   /* fudge, to prevent a 2nd save_one() */
                    295:                }
                    296:                else {                          /* fonts, sizes, troff codes  */
                    297:                        switch (txt[n+1]) {
                    298:                        default:
                    299:                                *bp++ = txt[n++];
                    300:                                break;
                    301:                        case '&':               /* zero-width char */
                    302:                                n += 2;         /* discard it */
                    303:                                break;
                    304:                        case '(':
                    305:                                if ((i = troffcode(txt+n+2)) == 0)
                    306:                                        *bp++ = txt[n++];       /* unknown */
                    307:                                else {
                    308:                                        if (bp > buf && *fp != trcode[i].font)
                    309:                                                { *bp = '\0'; return buf; }
                    310:                                        *bp++ = trcode[i].value;
                    311:                                        ft = *fp;
                    312:                                        *fp = trcode[i].font;
                    313:                                        txt[++n] = '\\';
                    314:                                        txt[n+1] = 'f';
                    315:                                        txt[n+2] = 'P'; /* restore old font */
                    316:                                }
                    317:                                break;
                    318:                        case 'N':
                    319:                                n += 3;
                    320:                                *bp++ = atoi(txt+n);
                    321:                                while (isdigit(txt[n])) n++;
                    322:                                break;
                    323:                        case 'f':
                    324:                                if (bp > buf) { *bp = '\0'; return buf; }
                    325:                                n += 2;
                    326:                                i = *fp;                /* save current font */
                    327:                                if (txt[n] == 'P') {    /* reset previous */
                    328:                                        *fp = ft;
                    329:                                        ++n;
                    330:                                }
                    331:                                else if (isdigit(txt[n]))
                    332:                                        *fp = checkfont((double)(txt[n++]-'0'));
                    333:                                else {
                    334:                                        if (txt[n] != '(')
                    335:                                                *bp++ = txt[n++];
                    336:                                        else {
                    337:                                                *bp++ = txt[++n];
                    338:                                                *bp++ = txt[++n];
                    339:                                                ++n;
                    340:                                        }
                    341:                                        *bp = '\0';
                    342:                                        *fp = setfont(tostring(bp=buf));
                    343:                                }
                    344:                                ft = i;
                    345:                                break;
                    346:                        case 's':
                    347:                                if (bp > buf) { *bp = '\0'; return buf; }
                    348:                                n += 2;
                    349:                                if (txt[n] == '+' || txt[n] == '-') {
                    350:                                        if ((i = *sp) == 0)
                    351:                                                i = getfval("textsize");
                    352:                                        if (txt[n] == '-')
                    353:                                                i = -i;
                    354:                                        ++n;
                    355:                                }
                    356:                                else
                    357:                                        i = 0; 
                    358:                                j = 0;
                    359:                                if (i == 0 && txt[n] == '0'){/* use previous */
                    360:                                        i = psize;
                    361:                                        ++n;
                    362:                                }
                    363:                                else {
                    364:                                        if (isdigit(txt[n]))
                    365:                                                j = txt[n++] - '0';
                    366:                                        if (j && isdigit(txt[n]))
                    367:                                                j = j * 10 + txt[n++] - '0';
                    368:                                }
                    369:                                psize = *sp = (i < 0 ? -(i+j) : i+j);
                    370:                                break;
                    371:                        }
                    372:                }
                    373:        }
                    374:        *bp = '\0';
                    375:        if (bp != buf)
                    376:                return buf;
                    377:        else {
                    378:                n = 0;
                    379:                return NULL;
                    380:        }
                    381: }
                    382: 
                    383: int    eqn_count         = 0;
                    384: char   psfname[L_tmpnam] = "";
                    385: char   dpost[] = "dpost";
                    386: FILE   *eqnfp  = NULL,
                    387:        *pipefp = NULL;
                    388: int    no_eqn = 0;
                    389: 
                    390: eqn_save(s)
                    391:        char    *s;
                    392: {
                    393: extern char    *gwblib;
                    394:        char    *dp, private[64], buf[BUFSIZ];
                    395: 
                    396:        if (pipefp == NULL && !no_eqn){/* open up eqn|troff|dpost subprocess */
                    397:                if (access("/usr/bin/eqn", 1))  /* kludge! */
                    398:                        no_eqn = 1;
                    399:                else {
                    400:                        sprintf(private, "%s/%s", gwblib, dpost);
                    401:                        dp = access(private,1) ? dpost : private;
                    402:                        tmpnam(psfname);
                    403:                        sprintf(buf, "eqn|troff -Tpost|%s -B>%s", dp, psfname);
                    404:                        if ((pipefp = popen(buf, "w")) == NULL)
                    405:                                fatal("cannot pipe through eqn");
                    406:                }
                    407:        }
                    408:        if (no_eqn) {
                    409:                if (strncmp(s, ".EQ", 3) == 0 || strncmp(s, ".EN", 3) == 0 ||
                    410:                                        strncmp(s, "delim", 5) == 0)
                    411:                        ;
                    412:                else
                    413:                        savetext(CENTER, s);
                    414:                return;
                    415:        }
                    416:        if (s[0] == '.' && s[1] == 'E' && s[2] == 'Q') {
                    417:                double  f = getfval("textfont");
                    418:                sprintf(buf,".ft %s\n.ps %d\n.vs %d\n", mount[(int)f]->name,
                    419:                        (int)getfval("textsize"), (int)getfval("textspace"));
                    420:                fputs(buf, pipefp);
                    421:        }
                    422:        fputs(s, pipefp);
                    423:        fputc('\n', pipefp);
                    424:        scan_delim(s);
                    425: }
                    426: 
                    427: scan_delim(s)
                    428:        char    *s;
                    429: {
                    430:        while (isspace(*s))
                    431:                ++s;
                    432:        /* probably eqn's syntax is less restrictive than the following */
                    433:        if (strncmp(s,"delim",5)==0) {
                    434:                for (s += 5; isspace(*s); ++s)
                    435:                        ;
                    436:                if (strcmp(s,"off")==0)
                    437:                        eqn_delim[1] = eqn_delim[0] = '\0';
                    438:                else {
                    439:                        eqn_delim[1] = eqn_delim[0] = *s;
                    440:                        if (*s++)
                    441:                                if (*s)
                    442:                                        eqn_delim[1] = *s;
                    443:                }
                    444:        }
                    445: }
                    446: 
                    447: eqn_gen(type)
                    448:        int     type;
                    449: {
                    450: extern int     ntextlines;
                    451:        obj     *p;
                    452:        char    buf[8];
                    453: 
                    454:        if (!no_eqn) {
                    455:                fputs(".bp\n", pipefp);
                    456:                sprintf(buf, "%d", ++eqn_count);
                    457:                save_one(EQNTXT, 0, 0, ntextlines, buf);
                    458:        }
                    459:        if (type == TROFF) {
                    460:                p = makenode(TROFF, 0, (int)getfval("curlayer"));
                    461:                checktextcolor(p);
                    462:                codegen = 1;
                    463:        }
                    464: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.