slang.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "dict.h"
  5. /* Possible tags */
  6. enum {
  7. DF, /* definition */
  8. DX, /* definition/example */
  9. ET, /* etymology */
  10. EX, /* example */
  11. LA, /* label */
  12. ME, /* main entry */
  13. NU, /* sense number */
  14. PR, /* pronunciation */
  15. PS, /* grammar part */
  16. XR, /* cross reference */
  17. XX, /* cross reference (whole entry) */
  18. };
  19. /* Assoc tables must be sorted on first field */
  20. static Assoc tagtab[] = {
  21. {"df", DF},
  22. {"dx", DX},
  23. {"et", ET},
  24. {"ex", EX},
  25. {"la", LA},
  26. {"me", ME},
  27. {"nu", NU},
  28. {"pr", PR},
  29. {"ps", PS},
  30. {"xr", XR},
  31. {"xx", XX},
  32. };
  33. static long sget(char *, char *, char **, char **);
  34. static void soutpiece(char *, char *);
  35. void
  36. slangprintentry(Entry e, int cmd)
  37. {
  38. char *p, *pe, *vs, *ve;
  39. long t;
  40. p = e.start;
  41. pe = e.end;
  42. if(cmd == 'h') {
  43. t = sget(p, pe, &vs, &ve);
  44. if(t == ME)
  45. soutpiece(vs, ve);
  46. outnl(0);
  47. return;
  48. }
  49. while(p < pe) {
  50. switch(sget(p, pe, &vs, &ve)) {
  51. case DF:
  52. soutpiece(vs, ve);
  53. outchars(". ");
  54. break;
  55. case DX:
  56. soutpiece(vs, ve);
  57. outchars(". ");
  58. break;
  59. case ET:
  60. outchars("[");
  61. soutpiece(vs, ve);
  62. outchars("] ");
  63. break;
  64. case EX:
  65. outchars("E.g., ");
  66. soutpiece(vs, ve);
  67. outchars(". ");
  68. break;
  69. case LA:
  70. outchars("(");
  71. soutpiece(vs, ve);
  72. outchars(") ");
  73. break;
  74. case ME:
  75. outnl(0);
  76. soutpiece(vs, ve);
  77. outnl(0);
  78. break;
  79. case NU:
  80. outnl(2);
  81. soutpiece(vs, ve);
  82. outchars(". ");
  83. break;
  84. case PR:
  85. outchars("[");
  86. soutpiece(vs, ve);
  87. outchars("] ");
  88. break;
  89. case PS:
  90. outnl(1);
  91. soutpiece(vs, ve);
  92. outchars(". ");
  93. break;
  94. case XR:
  95. outchars("See ");
  96. soutpiece(vs, ve);
  97. outchars(". ");
  98. break;
  99. case XX:
  100. outchars("See ");
  101. soutpiece(vs, ve);
  102. outchars(". ");
  103. break;
  104. default:
  105. ve = pe; /* will end loop */
  106. break;
  107. }
  108. p = ve;
  109. }
  110. outnl(0);
  111. }
  112. long
  113. slangnextoff(long fromoff)
  114. {
  115. long a;
  116. char *p;
  117. a = Bseek(bdict, fromoff, 0);
  118. if(a < 0)
  119. return -1;
  120. for(;;) {
  121. p = Brdline(bdict, '\n');
  122. if(!p)
  123. break;
  124. if(p[0] == 'm' && p[1] == 'e' && p[2] == ' ')
  125. return (Boffset(bdict)-Blinelen(bdict));
  126. }
  127. return -1;
  128. }
  129. void
  130. slangprintkey(void)
  131. {
  132. Bprint(bout, "No key\n");
  133. }
  134. /*
  135. * Starting from b, find next line beginning with a tag.
  136. * Don't go past e, but assume *e==0.
  137. * Return tag value, or -1 if no more tags before e.
  138. * Set pvb to beginning of value (after tag).
  139. * Set pve to point at newline that ends the value.
  140. */
  141. static long
  142. sget(char *b, char *e, char **pvb, char **pve)
  143. {
  144. char *p;
  145. char buf[3];
  146. long t, tans;
  147. buf[2] = 0;
  148. tans = -1;
  149. for(p = b;;) {
  150. if(p[2] == ' ') {
  151. buf[0] = p[0];
  152. buf[1] = p[1];
  153. t = lookassoc(tagtab, asize(tagtab), buf);
  154. if(t < 0) {
  155. if(debug)
  156. err("tag %s\n", buf);
  157. p += 3;
  158. } else {
  159. if(tans < 0) {
  160. p += 3;
  161. tans = t;
  162. *pvb = p;
  163. } else {
  164. *pve = p;
  165. break;
  166. }
  167. }
  168. }
  169. p = strchr(p, '\n');
  170. if(!p || ++p >= e) {
  171. if(tans >= 0)
  172. *pve = e-1;
  173. break;
  174. }
  175. }
  176. return tans;
  177. }
  178. static void
  179. soutpiece(char *b, char *e)
  180. {
  181. int c, lastc;
  182. lastc = 0;
  183. while(b < e) {
  184. c = *b++;
  185. if(c == '\n')
  186. c = ' ';
  187. if(!(c == ' ' && lastc == ' ') && c != '@')
  188. outchar(c);
  189. lastc = c;
  190. }
  191. }