]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/htmlroff/char.c
Import sources from 2011-03-30 iso image
[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(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