aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/htmlroff/char.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2006-02-21 18:37:05 +0000
committerrsc <devnull@localhost>2006-02-21 18:37:05 +0000
commitc42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4 (patch)
tree400f263e56681842ba1e6e1fdd8be453856474ef /src/cmd/htmlroff/char.c
parent49a1496cbbb871bc623cfd0925566628e246c9ba (diff)
downloadplan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.tar.gz
plan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.tar.bz2
plan9port-c42a1d3d6168df56f966ea1f3ba3ef39ebbff4e4.zip
add
Diffstat (limited to 'src/cmd/htmlroff/char.c')
-rw-r--r--src/cmd/htmlroff/char.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/cmd/htmlroff/char.c b/src/cmd/htmlroff/char.c
new file mode 100644
index 00000000..1c7d1237
--- /dev/null
+++ b/src/cmd/htmlroff/char.c
@@ -0,0 +1,116 @@
+#include "a.h"
+
+/*
+ * Translate Unicode to HTML by asking tcs(1).
+ * This way we don't have yet another table.
+ */
+Rune*
+rune2html(Rune r)
+{
+ static Biobuf b;
+ static int fd = -1;
+ static Rune **tcscache[256];
+ int p[2];
+ char *q;
+
+ if(r == '\n')
+ return L("\n");
+
+ if(tcscache[r>>8] && tcscache[r>>8][r&0xFF])
+ return tcscache[r>>8][r&0xFF];
+
+ if(fd < 0){
+ if(pipe(p) < 0)
+ sysfatal("pipe: %r");
+ switch(fork()){
+ case -1:
+ sysfatal("fork: %r");
+ case 0:
+ dup(p[0], 0);
+ dup(p[0], 1);
+ close(p[1]);
+ execl("tcs", "tcs", "-t", "html", nil);
+ _exits(0);
+ default:
+ close(p[0]);
+ fd = p[1];
+ Binit(&b, fd, OREAD);
+ break;
+ }
+ }
+ fprint(fd, "%C\n", r);
+ q = Brdline(&b, '\n');
+ if(q == nil)
+ sysfatal("tcs: early eof");
+ q[Blinelen(&b)-1] = 0;
+ if(tcscache[r>>8] == nil)
+ tcscache[r>>8] = emalloc(256*sizeof tcscache[0][0]);
+ tcscache[r>>8][r&0xFF] = erunesmprint("%s", q);
+ return tcscache[r>>8][r&0xFF];
+}
+
+/*
+ * Translate troff to Unicode by looking in troff's utfmap.
+ * This way we don't have yet another hard-coded table.
+ */
+typedef struct Trtab Trtab;
+struct Trtab
+{
+ char t[3];
+ Rune r;
+};
+
+static Trtab trtab[200];
+int ntrtab;
+
+static Trtab trinit[] =
+{
+ "pl", Upl,
+ "eq", Ueq,
+ "em", 0x2014,
+ "en", 0x2013,
+ "mi", Umi,
+ "fm", 0x2032,
+};
+
+Rune
+troff2rune(Rune *rs)
+{
+ char *file, *f[10], *p, s[3];
+ int i, nf;
+ Biobuf *b;
+
+ if(rs[0] >= Runeself || rs[1] >= Runeself)
+ return Runeerror;
+ s[0] = rs[0];
+ s[1] = rs[1];
+ s[2] = 0;
+ if(ntrtab == 0){
+ for(i=0; i<nelem(trinit) && ntrtab < nelem(trtab); i++){
+ trtab[ntrtab] = trinit[i];
+ ntrtab++;
+ }
+ file = "/sys/lib/troff/font/devutf/utfmap";
+ if((b = Bopen(file, OREAD)) == nil)
+ sysfatal("open %s: %r", file);
+ while((p = Brdline(b, '\n')) != nil){
+ p[Blinelen(b)-1] = 0;
+ nf = getfields(p, f, nelem(f), 0, "\t");
+ for(i=0; i+2<=nf && ntrtab<nelem(trtab); i+=2){
+ chartorune(&trtab[ntrtab].r, f[i]);
+ memmove(trtab[ntrtab].t, f[i+1], 2);
+ ntrtab++;
+ }
+ }
+ Bterm(b);
+
+ if(ntrtab >= nelem(trtab))
+ fprint(2, "%s: trtab too small\n", argv0);
+ }
+
+ for(i=0; i<ntrtab; i++)
+ if(strcmp(s, trtab[i].t) == 0)
+ return trtab[i].r;
+ return Runeerror;
+}
+