Blob


1 #include "a.h"
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;
16 if(r == '\n')
17 return L("\n");
19 if(tcscache[r>>8] && tcscache[r>>8][r&0xFF])
20 return tcscache[r>>8][r&0xFF];
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[0], 1);
31 close(p[1]);
32 execl("tcs", "tcs", "-t", "html", nil);
33 _exits(0);
34 default:
35 close(p[0]);
36 fd = p[1];
37 Binit(&b, fd, OREAD);
38 break;
39 }
40 }
41 fprint(fd, "%C\n", r);
42 q = Brdline(&b, '\n');
43 if(q == nil)
44 sysfatal("tcs: early eof");
45 q[Blinelen(&b)-1] = 0;
46 if(tcscache[r>>8] == nil)
47 tcscache[r>>8] = emalloc(256*sizeof tcscache[0][0]);
48 tcscache[r>>8][r&0xFF] = erunesmprint("%s", q);
49 return tcscache[r>>8][r&0xFF];
50 }
52 /*
53 * Translate troff to Unicode by looking in troff's utfmap.
54 * This way we don't have yet another hard-coded table.
55 */
56 typedef struct Trtab Trtab;
57 struct Trtab
58 {
59 char t[3];
60 Rune r;
61 };
63 static Trtab trtab[200];
64 int ntrtab;
66 static Trtab trinit[] =
67 {
68 "pl", Upl,
69 "eq", Ueq,
70 "em", 0x2014,
71 "en", 0x2013,
72 "mi", Umi,
73 "fm", 0x2032
74 };
76 Rune
77 troff2rune(Rune *rs)
78 {
79 char *file, *f[10], *p, s[3];
80 int i, nf;
81 Biobuf *b;
83 if(rs[0] >= Runeself || rs[1] >= Runeself)
84 return Runeerror;
85 s[0] = rs[0];
86 s[1] = rs[1];
87 s[2] = 0;
88 if(ntrtab == 0){
89 for(i=0; i<nelem(trinit) && ntrtab < nelem(trtab); i++){
90 trtab[ntrtab] = trinit[i];
91 ntrtab++;
92 }
93 file = unsharp("#9/troff/font/devutf/utfmap");
94 if((b = Bopen(file, OREAD)) == nil)
95 sysfatal("open %s: %r", file);
96 while((p = Brdline(b, '\n')) != nil){
97 p[Blinelen(b)-1] = 0;
98 nf = getfields(p, f, nelem(f), 0, "\t");
99 for(i=0; i+2<=nf && ntrtab<nelem(trtab); i+=2){
100 chartorune(&trtab[ntrtab].r, f[i]);
101 memmove(trtab[ntrtab].t, f[i+1], 2);
102 ntrtab++;
105 Bterm(b);
107 if(ntrtab >= nelem(trtab))
108 fprint(2, "%s: trtab too small\n", argv0);
111 for(i=0; i<ntrtab; i++)
112 if(strcmp(s, trtab[i].t) == 0)
113 return trtab[i].r;
114 return Runeerror;