126 lines
2.4 KiB
C
126 lines
2.4 KiB
C
#include "a.h"
|
|
|
|
/*
|
|
* Translate Unicode to HTML by asking tcs(1).
|
|
* This way we don't have yet another table.
|
|
*/
|
|
Rune*
|
|
rune2html(Rune r)
|
|
{
|
|
static Biobuf b;
|
|
static int fd = -1;
|
|
static Rune **tcscache[256];
|
|
int p[2];
|
|
char *q;
|
|
|
|
if(r == '\n')
|
|
return L("\n");
|
|
|
|
if(((uint)r&~0xFFFF) != 0){
|
|
/* The cache must grow a lot to handle them */
|
|
fprint(2, "%s: can't handle rune '%C'\n", argv0, r);
|
|
return L("?");
|
|
}
|
|
|
|
if(tcscache[r>>8] && tcscache[r>>8][r&0xFF])
|
|
return tcscache[r>>8][r&0xFF];
|
|
|
|
if(fd < 0){
|
|
if(pipe(p) < 0)
|
|
sysfatal("pipe: %r");
|
|
switch(fork()){
|
|
case -1:
|
|
sysfatal("fork: %r");
|
|
case 0:
|
|
dup(p[0], 0);
|
|
dup(p[1], 1);
|
|
close(p[0]);
|
|
close(p[1]);
|
|
execl("/bin/tcs", "tcs", "-t", "html", nil);
|
|
_exits(0);
|
|
default:
|
|
fd = p[1];
|
|
Binit(&b, p[0], OREAD);
|
|
break;
|
|
}
|
|
}
|
|
/* HACK: extra newlines force rune+\n through tcs now */
|
|
fprint(fd, "%C\n\n\n\n", r);
|
|
q = Brdline(&b, '\n');
|
|
while (q != nil && *q == '\n')
|
|
q = Brdline(&b, '\n');
|
|
if(q == nil)
|
|
sysfatal("tcs: early eof");
|
|
q[Blinelen(&b)-1] = 0;
|
|
if(tcscache[r>>8] == nil)
|
|
tcscache[r>>8] = emalloc(256*sizeof tcscache[0][0]);
|
|
tcscache[r>>8][r&0xFF] = erunesmprint("%s", q);
|
|
return tcscache[r>>8][r&0xFF];
|
|
}
|
|
|
|
/*
|
|
* Translate troff to Unicode by looking in troff's utfmap.
|
|
* This way we don't have yet another hard-coded table.
|
|
*/
|
|
typedef struct Trtab Trtab;
|
|
struct Trtab
|
|
{
|
|
char t[UTFmax];
|
|
Rune r;
|
|
};
|
|
|
|
static Trtab trtab[200];
|
|
int ntrtab;
|
|
|
|
static Trtab trinit[] =
|
|
{
|
|
"pl", Upl,
|
|
"eq", Ueq,
|
|
"em", 0x2014,
|
|
"en", 0x2013,
|
|
"mi", Umi,
|
|
"fm", 0x2032,
|
|
};
|
|
|
|
Rune
|
|
troff2rune(Rune *rs)
|
|
{
|
|
char *file, *f[10], *p, s[3];
|
|
int i, nf;
|
|
Biobuf *b;
|
|
|
|
if(rs[0] >= Runeself || rs[1] >= Runeself)
|
|
return Runeerror;
|
|
s[0] = rs[0];
|
|
s[1] = rs[1];
|
|
s[2] = 0;
|
|
if(ntrtab == 0){
|
|
for(i=0; i<nelem(trinit) && ntrtab < nelem(trtab); i++){
|
|
trtab[ntrtab] = trinit[i];
|
|
ntrtab++;
|
|
}
|
|
file = "/sys/lib/troff/font/devutf/utfmap";
|
|
if((b = Bopen(file, OREAD)) == nil)
|
|
sysfatal("open %s: %r", file);
|
|
while((p = Brdline(b, '\n')) != nil){
|
|
p[Blinelen(b)-1] = 0;
|
|
nf = getfields(p, f, nelem(f), 0, "\t");
|
|
for(i=0; i+2<=nf && ntrtab<nelem(trtab); i+=2){
|
|
chartorune(&trtab[ntrtab].r, f[i]);
|
|
memmove(trtab[ntrtab].t, f[i+1], 2);
|
|
ntrtab++;
|
|
}
|
|
}
|
|
Bterm(b);
|
|
|
|
if(ntrtab >= nelem(trtab))
|
|
fprint(2, "%s: trtab too small\n", argv0);
|
|
}
|
|
|
|
for(i=0; i<ntrtab; i++)
|
|
if(strcmp(s, trtab[i].t) == 0)
|
|
return trtab[i].r;
|
|
return Runeerror;
|
|
}
|
|
|