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