plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

char.c (2169B)


      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[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 }
     51 
     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 };
     62 
     63 static Trtab trtab[200];
     64 int ntrtab;
     65 
     66 static Trtab trinit[] =
     67 {
     68 	"pl",		Upl,
     69 	"eq",	Ueq,
     70 	"em",	0x2014,
     71 	"en",	0x2013,
     72 	"mi",	Umi,
     73 	"fm",	0x2032
     74 };
     75 
     76 Rune
     77 troff2rune(Rune *rs)
     78 {
     79 	char *file, *f[10], *p, s[3];
     80 	int i, nf;
     81 	Biobuf *b;
     82 
     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++;
    103 			}
    104 		}
    105 		Bterm(b);
    106 
    107 		if(ntrtab >= nelem(trtab))
    108 			fprint(2, "%s: trtab too small\n", argv0);
    109 	}
    110 
    111 	for(i=0; i<ntrtab; i++)
    112 		if(strcmp(s, trtab[i].t) == 0)
    113 			return trtab[i].r;
    114 	return Runeerror;
    115 }