ref: fe1eb39db7ae6904924f3ab1f6f9b34416f2eb1b
dir: /sys/src/cmd/dict/slang.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "dict.h" /* Possible tags */ enum { DF, /* definition */ DX, /* definition/example */ ET, /* etymology */ EX, /* example */ LA, /* label */ ME, /* main entry */ NU, /* sense number */ PR, /* pronunciation */ PS, /* grammar part */ XR, /* cross reference */ XX, /* cross reference (whole entry) */ }; /* Assoc tables must be sorted on first field */ static Assoc tagtab[] = { {"df", DF}, {"dx", DX}, {"et", ET}, {"ex", EX}, {"la", LA}, {"me", ME}, {"nu", NU}, {"pr", PR}, {"ps", PS}, {"xr", XR}, {"xx", XX}, }; static long sget(char *, char *, char **, char **); static void soutpiece(char *, char *); void slangprintentry(Entry e, int cmd) { char *p, *pe, *vs, *ve; long t; p = e.start; pe = e.end; if(cmd == 'h') { t = sget(p, pe, &vs, &ve); if(t == ME) soutpiece(vs, ve); outnl(0); return; } while(p < pe) { switch(sget(p, pe, &vs, &ve)) { case DF: soutpiece(vs, ve); outchars(". "); break; case DX: soutpiece(vs, ve); outchars(". "); break; case ET: outchars("["); soutpiece(vs, ve); outchars("] "); break; case EX: outchars("E.g., "); soutpiece(vs, ve); outchars(". "); break; case LA: outchars("("); soutpiece(vs, ve); outchars(") "); break; case ME: outnl(0); soutpiece(vs, ve); outnl(0); break; case NU: outnl(2); soutpiece(vs, ve); outchars(". "); break; case PR: outchars("["); soutpiece(vs, ve); outchars("] "); break; case PS: outnl(1); soutpiece(vs, ve); outchars(". "); break; case XR: outchars("See "); soutpiece(vs, ve); outchars(". "); break; case XX: outchars("See "); soutpiece(vs, ve); outchars(". "); break; default: ve = pe; /* will end loop */ break; } p = ve; } outnl(0); } long slangnextoff(long fromoff) { long a; char *p; a = Bseek(bdict, fromoff, 0); if(a < 0) return -1; for(;;) { p = Brdline(bdict, '\n'); if(!p) break; if(p[0] == 'm' && p[1] == 'e' && p[2] == ' ') return (Boffset(bdict)-Blinelen(bdict)); } return -1; } void slangprintkey(void) { Bprint(bout, "No key\n"); } /* * Starting from b, find next line beginning with a tag. * Don't go past e, but assume *e==0. * Return tag value, or -1 if no more tags before e. * Set pvb to beginning of value (after tag). * Set pve to point at newline that ends the value. */ static long sget(char *b, char *e, char **pvb, char **pve) { char *p; char buf[3]; long t, tans; buf[2] = 0; tans = -1; for(p = b;;) { if(p[2] == ' ') { buf[0] = p[0]; buf[1] = p[1]; t = lookassoc(tagtab, asize(tagtab), buf); if(t < 0) { if(debug) err("tag %s\n", buf); p += 3; } else { if(tans < 0) { p += 3; tans = t; *pvb = p; } else { *pve = p; break; } } } p = strchr(p, '\n'); if(!p || ++p >= e) { if(tans >= 0) *pve = e-1; break; } } return tans; } static void soutpiece(char *b, char *e) { int c, lastc; lastc = 0; while(b < e) { c = *b++; if(c == '\n') c = ' '; if(!(c == ' ' && lastc == ' ') && c != '@') outchar(c); lastc = c; } }