char.c 2.1 KB

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