1 #include "a.h" 2 3 /* 4 * Translate Unicode to HTML by asking tcs(1). 5 * This way we don't have yet another table. 6 */ 7 Rune* 8 rune2html(Rune r) 9 { 10 static Biobuf b; 11 static int fd = -1; 12 static Rune **tcscache[256]; 13 int p[2]; 14 char *q; 15 16 if(r == '\n') 17 return L("\n"); 18 19 if(tcscache[r>>8] && tcscache[r>>8][r&0xFF]) 20 return tcscache[r>>8][r&0xFF]; 21 22 if(fd < 0){ 23 if(pipe(p) < 0) 24 sysfatal("pipe: %r"); 25 switch(fork()){ 26 case -1: 27 sysfatal("fork: %r"); 28 case 0: 29 dup(p[0], 0); 30 dup(p[1], 1); 31 close(p[0]); 32 close(p[1]); 33 execl("/bin/tcs", "tcs", "-t", "html", nil); 34 _exits(0); 35 default: 36 fd = p[1]; 37 Binit(&b, p[0], OREAD); 38 break; 39 } 40 } 41 /* HACK: extra newlines force rune+\n through tcs now */ 42 fprint(fd, "%C\n\n\n\n", r); 43 q = Brdline(&b, '\n'); 44 while (q != nil && *q == '\n') 45 q = Brdline(&b, '\n'); 46 if(q == nil) 47 sysfatal("tcs: early eof"); 48 q[Blinelen(&b)-1] = 0; 49 if(tcscache[r>>8] == nil) 50 tcscache[r>>8] = emalloc(256*sizeof tcscache[0][0]); 51 tcscache[r>>8][r&0xFF] = erunesmprint("%s", q); 52 return tcscache[r>>8][r&0xFF]; 53 } 54 55 /* 56 * Translate troff to Unicode by looking in troff's utfmap. 57 * This way we don't have yet another hard-coded table. 58 */ 59 typedef struct Trtab Trtab; 60 struct Trtab 61 { 62 char t[3]; 63 Rune r; 64 }; 65 66 static Trtab trtab[200]; 67 int ntrtab; 68 69 static Trtab trinit[] = 70 { 71 "pl", Upl, 72 "eq", Ueq, 73 "em", 0x2014, 74 "en", 0x2013, 75 "mi", Umi, 76 "fm", 0x2032, 77 }; 78 79 Rune 80 troff2rune(Rune *rs) 81 { 82 char *file, *f[10], *p, s[3]; 83 int i, nf; 84 Biobuf *b; 85 86 if(rs[0] >= Runeself || rs[1] >= Runeself) 87 return Runeerror; 88 s[0] = rs[0]; 89 s[1] = rs[1]; 90 s[2] = 0; 91 if(ntrtab == 0){ 92 for(i=0; i<nelem(trinit) && ntrtab < nelem(trtab); i++){ 93 trtab[ntrtab] = trinit[i]; 94 ntrtab++; 95 } 96 file = "/sys/lib/troff/font/devutf/utfmap"; 97 if((b = Bopen(file, OREAD)) == nil) 98 sysfatal("open %s: %r", file); 99 while((p = Brdline(b, '\n')) != nil){ 100 p[Blinelen(b)-1] = 0; 101 nf = getfields(p, f, nelem(f), 0, "\t"); 102 for(i=0; i+2<=nf && ntrtab<nelem(trtab); i+=2){ 103 chartorune(&trtab[ntrtab].r, f[i]); 104 memmove(trtab[ntrtab].t, f[i+1], 2); 105 ntrtab++; 106 } 107 } 108 Bterm(b); 109 110 if(ntrtab >= nelem(trtab)) 111 fprint(2, "%s: trtab too small\n", argv0); 112 } 113 114 for(i=0; i<ntrtab; i++) 115 if(strcmp(s, trtab[i].t) == 0) 116 return trtab[i].r; 117 return Runeerror; 118 } 119 120