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