1997-03-14 06:22:29 +00:00
|
|
|
/*
|
|
|
|
* escape.c - Escape and special character input processing portion of
|
|
|
|
* nroff word processor
|
|
|
|
*
|
|
|
|
* adapted for atariST/TOS by Bill Rosenkranz 11/89
|
|
|
|
* net: rosenkra@hall.cray.com
|
|
|
|
* CIS: 71460,17
|
|
|
|
* GENIE: W.ROSENKRANZ
|
|
|
|
*
|
|
|
|
* original author:
|
|
|
|
*
|
|
|
|
* Stephen L. Browning
|
|
|
|
* 5723 North Parker Avenue
|
|
|
|
* Indianapolis, Indiana 46220
|
|
|
|
*
|
|
|
|
* history:
|
|
|
|
*
|
|
|
|
* - Originally written in BDS C;
|
|
|
|
* - Adapted for standard C by W. N. Paul
|
|
|
|
* - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
|
|
|
|
* - Heavily modified by Devin Reade to avoid memory trashing bugs.
|
|
|
|
*
|
1997-03-20 06:40:51 +00:00
|
|
|
* $Id: escape.c,v 1.2 1997/03/20 06:40:50 gdr Exp $
|
1997-03-14 06:22:29 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef __ORCAC__
|
|
|
|
segment "escape____";
|
1997-03-20 06:40:51 +00:00
|
|
|
#pragma noroot
|
|
|
|
#pragma optimize 79
|
1997-03-14 06:22:29 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define INVERSE '\xF'
|
|
|
|
#define NORMAL '\xE'
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#ifdef __GNO__
|
|
|
|
#include <err.h>
|
|
|
|
#else
|
1997-03-20 06:40:51 +00:00
|
|
|
#include "unix/err.h"
|
1997-03-14 06:22:29 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef sparc
|
1997-03-20 06:40:51 +00:00
|
|
|
#include "unix/sunos.h"
|
1997-03-14 06:22:29 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "nroff.h"
|
|
|
|
#include "escape.h"
|
|
|
|
#include "macros.h"
|
|
|
|
|
|
|
|
static int specialchar (char *s, char *c);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* expesc
|
|
|
|
*
|
|
|
|
* Expand escape sequences in the buffer <src>, placing the results
|
|
|
|
* in buffer <dest>. If the number of characters written into <dest>
|
|
|
|
* would be more than <len-1> characters, then abort with an error
|
|
|
|
* message.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
expesc (char *src, char *dest, size_t len) {
|
|
|
|
register char *s;
|
|
|
|
register char *t;
|
|
|
|
register char *pstr;
|
|
|
|
register int i;
|
|
|
|
register int val;
|
|
|
|
register int autoinc;
|
|
|
|
char c;
|
|
|
|
char fs[5]; /* for font change */
|
|
|
|
char nrstr[20];
|
|
|
|
char fmt[20];
|
|
|
|
char name[10];
|
|
|
|
int nreg;
|
|
|
|
char *pfs;
|
|
|
|
int inc;
|
|
|
|
int tmp;
|
|
|
|
char delim;
|
|
|
|
const char *percent = "%";
|
|
|
|
char *scratch;
|
|
|
|
|
|
|
|
|
|
|
|
s = src;
|
|
|
|
t = dest;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* if escape parsing is not on, just copy string
|
|
|
|
*/
|
|
|
|
if (dc.escon == NO) {
|
|
|
|
if (strlen(src) > len-1) {
|
|
|
|
errx(-1, "buffer overflow at %s:%d", __FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
strcpy (dest, src);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* do it...
|
|
|
|
*/
|
|
|
|
while (*s != EOS) {
|
|
|
|
if (*s != dc.escchr) {
|
|
|
|
/*
|
|
|
|
* not esc, continue...
|
|
|
|
*/
|
|
|
|
*t++ = *s++;
|
|
|
|
} else if (*(s + 1) == dc.escchr) {
|
|
|
|
/*
|
|
|
|
* \\ escape escape
|
|
|
|
*/
|
|
|
|
*t++ = *s++;
|
|
|
|
++s;
|
|
|
|
} else {
|
|
|
|
switch(*(s+1)) {
|
|
|
|
|
|
|
|
|
|
|
|
case 'n':
|
|
|
|
/*
|
|
|
|
* \nx, \n(xx register
|
|
|
|
*
|
|
|
|
* first check for \n+... or \n-... (either form)
|
|
|
|
*/
|
|
|
|
s += 2;
|
|
|
|
autoinc = 0;
|
|
|
|
if (*s == '+') {
|
|
|
|
autoinc = 1;
|
|
|
|
s += 1;
|
|
|
|
}
|
|
|
|
if (*s == '-') {
|
|
|
|
autoinc = -1;
|
|
|
|
s += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* was this \nx or \n(xx form?
|
|
|
|
*/
|
|
|
|
if (isalpha (*s)) {
|
|
|
|
/*
|
|
|
|
* \nx form. find reg (a-z)
|
|
|
|
*/
|
|
|
|
nreg = tolower (*s) - 'a';
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* was this \n+x or \n-x? if so, do the
|
|
|
|
* auto incr
|
|
|
|
*/
|
|
|
|
if (autoinc > 0) {
|
|
|
|
dc.nr[nreg] += dc.nrauto[nreg];
|
|
|
|
} else if (autoinc < 0) {
|
|
|
|
dc.nr[nreg] -= dc.nrauto[nreg];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* display format
|
|
|
|
*/
|
|
|
|
if (dc.nrfmt[nreg] == '1') {
|
|
|
|
/*
|
|
|
|
* normal decimal digits
|
|
|
|
*/
|
|
|
|
t += itoda (dc.nr[nreg], t, 6) - 1;
|
|
|
|
} else if (dc.nrfmt[nreg] == 'i') {
|
|
|
|
/*
|
|
|
|
* lower roman
|
|
|
|
*/
|
|
|
|
t += itoroman (dc.nr[nreg], t, 24) - 1;
|
|
|
|
} else if (dc.nrfmt[nreg] == 'I') {
|
|
|
|
/*
|
|
|
|
* upper roman
|
|
|
|
*/
|
|
|
|
t += itoROMAN (dc.nr[nreg], t, 24) - 1;
|
|
|
|
} else if (dc.nrfmt[nreg] == 'a') {
|
|
|
|
/*
|
|
|
|
* lower letters
|
|
|
|
*/
|
|
|
|
t += itoletter (dc.nr[nreg], t, 12) - 1;
|
|
|
|
} else if (dc.nrfmt[nreg] == 'A') {
|
|
|
|
/*
|
|
|
|
* upper letters
|
|
|
|
*/
|
|
|
|
t += itoLETTER (dc.nr[nreg], t, 12) - 1;
|
|
|
|
} else if (dc.nrfmt[nreg] & 0x80) {
|
|
|
|
/*
|
|
|
|
* zero-filled decimal
|
|
|
|
*/
|
|
|
|
sprintf (fmt, "%%0%dld", (int)(dc.nrfmt[nreg] & 0x7F));
|
|
|
|
fmt[5] = '\0';
|
|
|
|
sprintf (nrstr, fmt, (long) dc.nr[nreg]);
|
|
|
|
tmp = dc.nrfmt[nreg] & 0x7F;
|
|
|
|
nrstr[tmp] = '\0';
|
|
|
|
|
|
|
|
strcpy (t, nrstr);
|
|
|
|
t += strlen (nrstr);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* normal (default)
|
|
|
|
*/
|
|
|
|
t += itoda (dc.nr[nreg], t, 6) - 1;
|
|
|
|
}
|
|
|
|
++s;
|
|
|
|
} else if (*s == '%') {
|
|
|
|
/*
|
|
|
|
* \n% form. find index into reg struct
|
|
|
|
*/
|
|
|
|
FINDREG(percent, nreg, scratch);
|
|
|
|
if (nreg < 0) {
|
|
|
|
errx(-1, "no register match");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* was this \n+% or \n-%? if so, do the
|
|
|
|
* auto incr
|
|
|
|
*/
|
|
|
|
if (autoinc > 0) {
|
|
|
|
rg[nreg].rval += rg[nreg].rauto;
|
|
|
|
} else if (autoinc < 0) {
|
|
|
|
rg[nreg].rval -= rg[nreg].rauto;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* display format
|
|
|
|
*/
|
|
|
|
if (rg[nreg].rfmt == '1') {
|
|
|
|
/*
|
|
|
|
* normal decimal digits
|
|
|
|
*/
|
|
|
|
t += itoda (rg[nreg].rval, t, 6) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'i') {
|
|
|
|
/*
|
|
|
|
* lower roman
|
|
|
|
*/
|
|
|
|
t += itoroman (rg[nreg].rval, t, 24) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'I') {
|
|
|
|
/*
|
|
|
|
* upper roman
|
|
|
|
*/
|
|
|
|
t += itoROMAN (rg[nreg].rval, t, 24) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'a') {
|
|
|
|
/*
|
|
|
|
* lower letters
|
|
|
|
*/
|
|
|
|
t += itoletter (rg[nreg].rval, t, 12) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'A') {
|
|
|
|
/*
|
|
|
|
* upper letters
|
|
|
|
*/
|
|
|
|
t += itoLETTER (rg[nreg].rval, t, 12) - 1;
|
|
|
|
} else if (rg[nreg].rfmt & 0x80) {
|
|
|
|
/*
|
|
|
|
* zero-filled decimal
|
|
|
|
*/
|
|
|
|
sprintf (fmt, "%%0%dld",
|
|
|
|
(int)(rg[nreg].rfmt & 0x7F));
|
|
|
|
fmt[5] = '\0';
|
|
|
|
sprintf (nrstr, fmt, (long) rg[nreg].rval);
|
|
|
|
tmp = rg[nreg].rfmt & 0x7F;
|
|
|
|
nrstr[tmp] = '\0';
|
|
|
|
|
|
|
|
strcpy (t, nrstr);
|
|
|
|
t += strlen (nrstr);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* normal (default)
|
|
|
|
*/
|
|
|
|
t += itoda (rg[nreg].rval, t, 6) - 1;
|
|
|
|
}
|
|
|
|
s += 1;
|
|
|
|
} else if (*s == '(') {
|
|
|
|
/*
|
|
|
|
* \n(xx form. find index into reg struct
|
|
|
|
*/
|
|
|
|
s += 1;
|
|
|
|
name[0] = *s;
|
|
|
|
name[1] = *(s + 1);
|
|
|
|
if (name[1] == ' ' || name[1] == '\t'
|
|
|
|
|| name[1] == '\n' || name[1] == '\r') {
|
|
|
|
name[1] = '\0';
|
|
|
|
}
|
|
|
|
name[2] = '\0';
|
|
|
|
FINDREG(name, nreg, scratch);
|
|
|
|
if (nreg < 0) {
|
|
|
|
errx(-1, "no register match");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* was this \n+(xx or \n-(xx? if so, do the
|
|
|
|
* auto incr
|
|
|
|
*/
|
|
|
|
if (rg[nreg].rflag & RF_WRITE) {
|
|
|
|
if (autoinc > 0) {
|
|
|
|
rg[nreg].rval += rg[nreg].rauto;
|
|
|
|
} else if (autoinc < 0) {
|
|
|
|
rg[nreg].rval -= rg[nreg].rauto;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* display format
|
|
|
|
*/
|
|
|
|
if (rg[nreg].rfmt == '1') {
|
|
|
|
/*
|
|
|
|
* normal decimal digits
|
|
|
|
*/
|
|
|
|
t += itoda (rg[nreg].rval, t, 6) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'i') {
|
|
|
|
/*
|
|
|
|
* lower roman
|
|
|
|
*/
|
|
|
|
t += itoroman (rg[nreg].rval, t, 24) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'I') {
|
|
|
|
/*
|
|
|
|
* upper roman
|
|
|
|
*/
|
|
|
|
t += itoROMAN (rg[nreg].rval, t, 24) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'a') {
|
|
|
|
/*
|
|
|
|
* lower letters
|
|
|
|
*/
|
|
|
|
t += itoletter (rg[nreg].rval, t, 12) - 1;
|
|
|
|
} else if (rg[nreg].rfmt == 'A') {
|
|
|
|
/*
|
|
|
|
* upper letters
|
|
|
|
*/
|
|
|
|
t += itoLETTER (rg[nreg].rval, t, 12) - 1;
|
|
|
|
} else if (rg[nreg].rfmt & 0x80) {
|
|
|
|
/*
|
|
|
|
* zero-filled decimal
|
|
|
|
*/
|
|
|
|
sprintf (fmt, "%%0%dld",
|
|
|
|
(int)(rg[nreg].rfmt & 0x7F));
|
|
|
|
fmt[5] = '\0';
|
|
|
|
sprintf (nrstr, fmt, (long) rg[nreg].rval);
|
|
|
|
tmp = rg[nreg].rfmt & 0x7F;
|
|
|
|
nrstr[tmp] = '\0';
|
|
|
|
|
|
|
|
strcpy (t, nrstr);
|
|
|
|
t += strlen (nrstr);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* normal (default)
|
|
|
|
*/
|
|
|
|
t += itoda (rg[nreg].rval, t, 6) - 1;
|
|
|
|
}
|
|
|
|
s += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case '"': /* \" comment */
|
|
|
|
*s = EOS;
|
|
|
|
*t = *s;
|
|
|
|
return;
|
|
|
|
|
|
|
|
case '*': /* \*x, \*(xx string */
|
|
|
|
/*
|
|
|
|
|
|
|
|
*/
|
|
|
|
s += 2;
|
|
|
|
if (*s == '(') {
|
|
|
|
/*
|
|
|
|
* \*(xx form
|
|
|
|
*/
|
|
|
|
s += 1;
|
|
|
|
name[0] = *s;
|
|
|
|
name[1] = *(s + 1);
|
|
|
|
name[2] = '\0';
|
|
|
|
pstr = getstr (name);
|
|
|
|
if (!pstr) {
|
|
|
|
errx(-1,"string not found");
|
|
|
|
}
|
|
|
|
while (*pstr) {
|
|
|
|
*t++ = *pstr++;
|
|
|
|
}
|
|
|
|
s += 2;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* \*x form
|
|
|
|
*/
|
|
|
|
name[0] = *s;
|
|
|
|
name[1] = '\0';
|
|
|
|
pstr = getstr (name);
|
|
|
|
if (!pstr) {
|
|
|
|
errx(-1, "string not found");
|
|
|
|
}
|
|
|
|
while (*pstr) {
|
|
|
|
*t++ = *pstr++;
|
|
|
|
}
|
|
|
|
s += 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'f': /* \fx font */
|
|
|
|
s += 2;
|
|
|
|
pfs = fs; /* set up ret string */
|
|
|
|
fs[0] = '\0';
|
|
|
|
|
|
|
|
/*
|
|
|
|
* it parses 1-2 char of s and returns esc seq for
|
|
|
|
* \fB and \fR (\fI is same as \fB)
|
|
|
|
*/
|
|
|
|
fontchange (*s, pfs);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* imbed the atari (vt52) escape seq
|
|
|
|
*/
|
|
|
|
while (*pfs) {
|
|
|
|
*t++ = *pfs++;
|
|
|
|
}
|
|
|
|
++s; /* skip B,I,R,S,P */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '(': /* \(xx special char */
|
|
|
|
s += 2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* it returns num char to skip and sets c to
|
|
|
|
* the ascii value of the char
|
|
|
|
*/
|
|
|
|
inc = specialchar (s, &c);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* skip proper num char in s and add c to target
|
|
|
|
*/
|
|
|
|
if (inc) {
|
|
|
|
s += inc;
|
|
|
|
*t++ = c;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'e': /* \e printable version of escape */
|
|
|
|
*t++ = dc.escchr;
|
|
|
|
s += 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '-': /* \- minus */
|
|
|
|
case '`': /* \` grave, like \(ga */
|
|
|
|
case '\'': /* \' accute, like \(aa */
|
|
|
|
case '.': /* \. period */
|
|
|
|
case ' ': /* \(space) space */
|
|
|
|
|
|
|
|
/* verbatim */
|
|
|
|
*t++ = *(s+1);
|
|
|
|
s += 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '0': /* \0 digital width space */
|
|
|
|
*t++ = ' ';
|
|
|
|
s += 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '|': /* \| narrow width char (0 in nroff) */
|
|
|
|
case '^': /* \^ narrow width char (0 in nroff) */
|
|
|
|
case '&': /* \& non-printing zero width */
|
|
|
|
case '!': /* \! transparent copy line */
|
|
|
|
case '$': /* \$N interpolate arg 1<=N<=9 */
|
|
|
|
case 'a': /* \a */
|
|
|
|
case 'b': /* \b'abc...' */
|
|
|
|
case 'c': /* \c */
|
|
|
|
case 'd': /* \d */
|
|
|
|
case 'k': /* \kx */
|
|
|
|
case 'l': /* \l'Nc' */
|
|
|
|
case 'L': /* \L'Nc' */
|
|
|
|
case 'p': /* \p */
|
|
|
|
case 'r': /* \r */
|
|
|
|
case 's': /* \sN,\s+-N */
|
|
|
|
case 'u': /* \u */
|
|
|
|
case 'w': /* \w'str' */
|
|
|
|
case 'x': /* \x'N' */
|
|
|
|
case '{': /* \{ */
|
|
|
|
case '}': /* \} */
|
|
|
|
case '\n': /* \(newline) ignore newline */
|
|
|
|
case '\r': /* \(newline) ignore newline */
|
|
|
|
|
|
|
|
s += 2; /* currently ignored */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '%': /* \% hyphen */
|
|
|
|
*t++ = '-';
|
|
|
|
*t++ = '-';
|
|
|
|
s += 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'h': /* \h'N' horiz motion*/
|
|
|
|
s += 2;
|
|
|
|
delim = *s++;
|
|
|
|
val = atoi (s);
|
|
|
|
for (i = 0; i < val; i++) {
|
|
|
|
*t++ = ' ';
|
|
|
|
}
|
|
|
|
while (*s != delim) {
|
|
|
|
if (*s == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
if (*s) {
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'o': /* \o'abc...' overstrike*/
|
|
|
|
s += 2;
|
|
|
|
delim = *s++;
|
|
|
|
while (*s != EOS && *s != delim) {
|
|
|
|
*t++ = *s++;
|
|
|
|
*t++ = 0x08;
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 't': /* \t horizontal tab*/
|
|
|
|
*t++ = '\t';
|
|
|
|
s += 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'v': /* \v'N' vert tab*/
|
|
|
|
s += 2;
|
|
|
|
delim = *s++;
|
|
|
|
val = atoi (s);
|
|
|
|
for (i = 0; i < val; i++) {
|
|
|
|
*t++ = 0x0A;
|
|
|
|
}
|
|
|
|
while (*s != delim) {
|
|
|
|
if (*s == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
if (*s) {
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'z': /* \zc print c w/o spacing*/
|
|
|
|
s += 2;
|
|
|
|
*t++ = *s++;
|
|
|
|
*t++ = 0x08;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: /* \X any other character not above*/
|
|
|
|
s += 1;
|
|
|
|
*t++ = *s++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* end the string and return it in original buf
|
|
|
|
*/
|
|
|
|
*t = EOS;
|
|
|
|
/* gdr: this seems to defeat the expansion we just did. */
|
|
|
|
strcpy (src, dest);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* specialchar
|
|
|
|
* handles \(xx escape sequences for special characters (atari-specific)
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
specialchar (register char *s, register char *c) {
|
|
|
|
register char c1;
|
|
|
|
register char c2;
|
|
|
|
|
|
|
|
c1 = *s;
|
|
|
|
c2 = *(s+1);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* symbols (std font)
|
|
|
|
*/
|
|
|
|
if (c1 == 'e' && c2 == 'm') {*c = 0x2D; return 2;} /* dash */
|
|
|
|
if (c1 == 'h' && c2 == 'y') {*c = 0x2D; return 2;} /* hyphen */
|
|
|
|
if (c1 == 'b' && c2 == 'u') {*c = 0xF9; return 2;} /* bullet */
|
|
|
|
if (c1 == 's' && c2 == 'q') {*c = 0xF9; return 2;} /* square */
|
|
|
|
if (c1 == 'r' && c2 == 'u') {*c = 0x5F; return 2;} /* rule */
|
|
|
|
if (c1 == '1' && c2 == '2') {*c = 0xAB; return 2;} /* 1/2 */
|
|
|
|
if (c1 == '1' && c2 == '4') {*c = 0xAC; return 2;} /* 1/4 */
|
|
|
|
if (c1 == 'd' && c2 == 'e') {*c = 0xF8; return 2;} /* degree */
|
|
|
|
if (c1 == 'd' && c2 == 'g') {*c = 0xBB; return 2;} /* dagger */
|
|
|
|
if (c1 == 'f' && c2 == 'm') {*c = 0xBA; return 2;} /* dagger */
|
|
|
|
if (c1 == 'c' && c2 == 't') {*c = 0x9B; return 2;} /* cent */
|
|
|
|
if (c1 == 'c' && c2 == 'o') {*c = 0xBD; return 2;} /* copyrite */
|
|
|
|
if (c1 == 'r' && c2 == 'g') {*c = 0xBE; return 2;} /* registered */
|
|
|
|
if (c1 == 't' && c2 == 'm') {*c = 0xBF; return 2;} /* trademark */
|
|
|
|
if (c1 == 'p' && c2 == '2') {*c = 0xFD; return 2;} /* ^2 */
|
|
|
|
if (c1 == 'p' && c2 == '3') {*c = 0xFE; return 2;} /* ^3 */
|
|
|
|
if (c1 == 'p' && c2 == 'n') {*c = 0xFC; return 2;} /* ^n */
|
|
|
|
if (c1 == 'a' && c2 == 'a') {*c = 0xBA; return 2;} /* acute */
|
|
|
|
if (c1 == 'g' && c2 == 'a') {*c = 0x60; return 2;} /* grave */
|
|
|
|
if (c1 == 'd' && c2 == 't') {*c = 0xFA; return 2;} /* dot */
|
|
|
|
if (c1 == 'p' && c2 == 'p') {*c = 0xBC; return 2;} /* paragraph */
|
|
|
|
if (c1 == '^' && c2 == 'g') {*c = 0x07; return 2;} /* ring bell */
|
|
|
|
if (c1 == 'u' && c2 == 'a') {*c = 0x01; return 2;} /* up arrow */
|
|
|
|
if (c1 == 'd' && c2 == 'a') {*c = 0x02; return 2;} /* dn arrow */
|
|
|
|
if (c1 == '-' && c2 == '>') {*c = 0x03; return 2;} /* rt arrow */
|
|
|
|
if (c1 == '<' && c2 == '-') {*c = 0x04; return 2;} /* lf arrow */
|
|
|
|
if (c1 == 'd' && c2 == 'i') {*c = 0xF6; return 2;} /* divide */
|
|
|
|
if (c1 == 's' && c2 == 'r') {*c = 0xFB; return 2;} /* sq root */
|
|
|
|
if (c1 == '=' && c2 == '=') {*c = 0xF0; return 2;} /* == */
|
|
|
|
if (c1 == '>' && c2 == '=') {*c = 0xF2; return 2;} /* >= */
|
|
|
|
if (c1 == '<' && c2 == '=') {*c = 0xF3; return 2;} /* <= */
|
|
|
|
if (c1 == '+' && c2 == '-') {*c = 0xF1; return 2;} /* +- */
|
|
|
|
if (c1 == '~' && c2 == '=') {*c = 0xF7; return 2;} /* ~= */
|
|
|
|
if (c1 == 'a' && c2 == 'p') {*c = 0x7E; return 2;} /* approx */
|
|
|
|
if (c1 == 'n' && c2 == 'o') {*c = 0xAA; return 2;} /* not */
|
|
|
|
if (c1 == 'm' && c2 == 'o') {*c = 0xEE; return 2;} /* member */
|
|
|
|
if (c1 == 'c' && c2 == 'a') {*c = 0xEF; return 2;} /* intersect */
|
|
|
|
if (c1 == 'c' && c2 == 'u') {*c = 0x55; return 2;} /* union */
|
|
|
|
if (c1 == 'i' && c2 == '1') {*c = 0xF4; return 2;} /* integral1 */
|
|
|
|
if (c1 == 'i' && c2 == '2') {*c = 0xF5; return 2;} /* integral2 */
|
|
|
|
if (c1 == 'b' && c2 == 'r') {*c = 0x7C; return 2;} /* box v rule */
|
|
|
|
if (c1 == 'b' && c2 == 'v') {*c = 0x7C; return 2;} /* bold vert */
|
|
|
|
if (c1 == 'p' && c2 == 'l') {*c = 0x2B; return 2;} /* math plus */
|
|
|
|
if (c1 == 'm' && c2 == 'i') {*c = 0x2D; return 2;} /* math minus */
|
|
|
|
if (c1 == 'e' && c2 == 'q') {*c = 0x3D; return 2;} /* math equal */
|
|
|
|
if (c1 == '*' && c2 == '*') {*c = 0x2A; return 2;} /* math star */
|
|
|
|
if (c1 == 's' && c2 == 'l') {*c = 0x2F; return 2;} /* slash */
|
|
|
|
if (c1 == 'u' && c2 == 'l') {*c = 0x5F; return 2;} /* underrule */
|
|
|
|
if (c1 == 's' && c2 == 'c') {*c = 0xDD; return 2;} /* section */
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* greek
|
|
|
|
*/
|
|
|
|
if (c1 == '*' && c2 == 'a') {*c = 0xE0; return 2;} /* alpha */
|
|
|
|
if (c1 == '*' && c2 == 'b') {*c = 0xE1; return 2;} /* beta */
|
|
|
|
if (c1 == '*' && c2 == 'g') {*c = 0xE2; return 2;} /* gamma */
|
|
|
|
if (c1 == '*' && c2 == 'd') {*c = 0x7F; return 2;} /* delta */
|
|
|
|
if (c1 == '*' && c2 == 's') {*c = 0xE4; return 2;} /* sigma */
|
|
|
|
if (c1 == '*' && c2 == 'p') {*c = 0xE3; return 2;} /* pi */
|
|
|
|
if (c1 == '*' && c2 == 'm') {*c = 0xE6; return 2;} /* mu */
|
|
|
|
|
|
|
|
*c = ' ';
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* fontchange
|
|
|
|
* handles \fx font change escapes for R,B,I,S,P (atari-specific)
|
|
|
|
* resets current and last font in dc struct (last used for .ft
|
|
|
|
* with no args)
|
|
|
|
*/
|
|
|
|
#undef SHORT_STANDOUT
|
|
|
|
|
|
|
|
void
|
|
|
|
fontchange (char fnt, char *s) {
|
|
|
|
int tmp;
|
|
|
|
|
|
|
|
*s = '\0';
|
|
|
|
switch (fnt) {
|
|
|
|
case 'R': /* Times Roman */
|
|
|
|
if (dc.dofnt == YES) {
|
|
|
|
#ifdef SHORT_STANDOUT
|
|
|
|
s[0] = E_STANDOUT; s[1] = 0;
|
|
|
|
#else
|
|
|
|
strcpy (s, e_standout);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
dc.lastfnt = dc.thisfnt;
|
|
|
|
dc.thisfnt = 1;
|
|
|
|
break;
|
|
|
|
case 'I': /* Times italic */
|
|
|
|
if (dc.dofnt == YES) {
|
|
|
|
#ifdef SHORT_STANDOUT
|
|
|
|
s[0] = S_STANDOUT; s[1] = 0;
|
|
|
|
#else
|
|
|
|
strcpy (s, s_standout);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
dc.lastfnt = dc.thisfnt;
|
|
|
|
dc.thisfnt = 2;
|
|
|
|
break;
|
|
|
|
case 'B': /* Times bold */
|
|
|
|
if (dc.dofnt == YES) {
|
|
|
|
#ifdef SHORT_STANDOUT
|
|
|
|
s[0] = S_STANDOUT; s[1] = 0;
|
|
|
|
#else
|
|
|
|
strcpy (s, s_standout);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
dc.lastfnt = dc.thisfnt;
|
|
|
|
dc.thisfnt = 3;
|
|
|
|
break;
|
|
|
|
case 'S': /* math/special */
|
|
|
|
*s = '\0';
|
|
|
|
dc.lastfnt = dc.thisfnt;
|
|
|
|
dc.thisfnt = 4;
|
|
|
|
break;
|
|
|
|
case 'P': /* previous (exchange) */
|
|
|
|
if (dc.dofnt == YES) {
|
|
|
|
if (dc.lastfnt == 1) {
|
|
|
|
#ifdef SHORT_STANDOUT
|
|
|
|
s[0] = E_STANDOUT; s[1] = 0;
|
|
|
|
#else
|
|
|
|
strcpy (s, e_standout); /* to R */
|
|
|
|
#endif
|
|
|
|
} else if (dc.lastfnt == 2) {
|
|
|
|
#ifdef SHORT_STANDOUT
|
|
|
|
s[0] = S_STANDOUT; s[1] = 0;
|
|
|
|
#else
|
|
|
|
strcpy (s, s_standout); /* to I */
|
|
|
|
#endif
|
|
|
|
} else if (dc.lastfnt == 3) {
|
|
|
|
#ifdef SHORT_STANDOUT
|
|
|
|
s[0] = S_STANDOUT; s[1] = 0;
|
|
|
|
#else
|
|
|
|
strcpy (s, s_standout); /* to B */
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
*s = '\0'; /* nothing */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tmp = dc.thisfnt; /* swap this/last */
|
|
|
|
dc.thisfnt = dc.lastfnt;
|
|
|
|
dc.lastfnt = tmp;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*s = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_ireg (".f", dc.thisfnt, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 /* using macro version */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* findreg
|
|
|
|
*
|
|
|
|
* find register named 'name' in pool. return index into array or -1
|
|
|
|
* if not found.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
findreg (register char *name) {
|
|
|
|
register int i;
|
|
|
|
register char *prname;
|
|
|
|
|
|
|
|
for (i = 0; i < MAXREGS; i++) {
|
|
|
|
prname = rg[i].rname;
|
|
|
|
if (*prname == *name && *(prname + 1) == *(name + 1)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ((i < MAXREGS) ? i : -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|