123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- #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;
- }
|