123 lines · 2.3 KB · C
RawDownload
#include "a.h" /* * hopeless if runes are not 16 bits */ /* * 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(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[3];	Rune r;}; static Trtab trtab[200];int ntrtab; static Trtab trinit[] ={	"pl",		Upl,	"eq",	Ueq,	"em",	0x2014,	"en",	0x2013,	"mi",	Umi,	"fm",	0x2032,}; Runetroff2rune(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;}