]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/htmlroff/char.c
ndb/dns: remove single-ip-address assuptions
[plan9front.git] / sys / src / cmd / htmlroff / char.c
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