char.c 2.2 KB

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