xref: /plan9/sys/src/cmd/dict/robert.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include "dict.h"
5219b2ee8SDavid du Colombier 
6219b2ee8SDavid du Colombier /*
7219b2ee8SDavid du Colombier  * Robert Électronique.
8219b2ee8SDavid du Colombier  */
9219b2ee8SDavid du Colombier 
10219b2ee8SDavid du Colombier enum
11219b2ee8SDavid du Colombier {
12219b2ee8SDavid du Colombier 	CIT = MULTIE+1,	/* citation ptr followed by long int and ascii label */
13219b2ee8SDavid du Colombier 	BROM,		/* bold roman */
14219b2ee8SDavid du Colombier 	ITON,		/* start italic */
15219b2ee8SDavid du Colombier 	ROM,		/* roman */
16219b2ee8SDavid du Colombier 	SYM,		/* symbol font? */
17219b2ee8SDavid du Colombier 	HEL,		/* helvetica */
18219b2ee8SDavid du Colombier 	BHEL,		/* helvetica bold */
19219b2ee8SDavid du Colombier 	SMALL,		/* smaller? */
20219b2ee8SDavid du Colombier 	ITOFF,		/* end italic */
21219b2ee8SDavid du Colombier 	SUP,		/* following character is superscript */
22219b2ee8SDavid du Colombier 	SUB		/* following character is subscript */
23219b2ee8SDavid du Colombier };
24219b2ee8SDavid du Colombier 
25219b2ee8SDavid du Colombier static Rune intab[256] = {
26219b2ee8SDavid du Colombier 	/*0*/	/*1*/	/*2*/	/*3*/	/*4*/	/*5*/	/*6*/	/*7*/
27219b2ee8SDavid du Colombier /*00*/	NONE,	L'☺',	L'☻',	L'♥',	L'♦',	L'♣',	L'♠',	L'•',
28219b2ee8SDavid du Colombier 	0x25d8,	L'ʘ',	L'\n',	L'♂',	L'♀',	L'♪',	0x266b,	L'※',
29219b2ee8SDavid du Colombier /*10*/	L'⇨',	L'⇦',	L'↕',	L'‼',	L'¶',	L'§',	L'⁃',	L'↨',
30219b2ee8SDavid du Colombier 	L'↑',	L'↓',	L'→',	L'←',	L'⌙',	L'↔',	0x25b4,	0x25be,
31219b2ee8SDavid du Colombier /*20*/	L' ',	L'!',	L'"',	L'#',	L'$',	L'%',	L'&',	L''',
32219b2ee8SDavid du Colombier 	L'(',	L')',	L'*',	L'+',	L',',	L'-',	L'.',	L'/',
33219b2ee8SDavid du Colombier /*30*/	L'0',	L'1',	L'2',	L'3',	L'4',	L'5',	L'6',	L'7',
34219b2ee8SDavid du Colombier 	L'8',	L'9',	L':',	L';',	L'<',	L'=',	L'>',	L'?',
35219b2ee8SDavid du Colombier /*40*/	L'@',	L'A',	L'B',	L'C',	L'D',	L'E',	L'F',	L'G',
36219b2ee8SDavid du Colombier 	L'H',	L'I',	L'J',	L'K',	L'L',	L'M',	L'N',	L'O',
37219b2ee8SDavid du Colombier /*50*/	L'P',	L'Q',	L'R',	L'S',	L'T',	L'U',	L'V',	L'W',
38219b2ee8SDavid du Colombier 	L'X',	L'Y',	L'Z',	L'[',	L'\\',	L']',	L'^',	L'_',
39219b2ee8SDavid du Colombier /*60*/	L'`',	L'a',	L'b',	L'c',	L'd',	L'e',	L'f',	L'g',
40219b2ee8SDavid du Colombier 	L'h',	L'i',	L'j',	L'k',	L'l',	L'm',	L'n',	L'o',
41219b2ee8SDavid du Colombier /*70*/	L'p',	L'q',	L'r',	L's',	L't',	L'u',	L'v',	L'w',
42219b2ee8SDavid du Colombier 	L'x',	L'y',	L'z',	L'{',	L'|',	L'}',	L'~',	L'',
43219b2ee8SDavid du Colombier /*80*/	L'Ç',	L'ü',	L'é',	L'â',	L'ä',	L'à',	L'å',	L'ç',
44219b2ee8SDavid du Colombier 	L'ê',	L'ë',	L'è',	L'ï',	L'î',	L'ì',	L'Ä',	L'Å',
45219b2ee8SDavid du Colombier /*90*/	L'É',	L'æ',	L'Æ',	L'ô',	L'ö',	L'ò',	L'û',	L'ù',
46219b2ee8SDavid du Colombier 	L'ÿ',	L'Ö',	L'Ü',	L'¢',	L'£',	L'¥',	L'₧',	L'ʃ',
47219b2ee8SDavid du Colombier /*a0*/	L'á',	L'í',	L'ó',	L'ú',	L'ñ',	L'Ñ',	L'ª',	L'º',
48219b2ee8SDavid du Colombier 	L'¿',	L'⌐',	L'¬',	L'½',	L'¼',	L'¡',	L'«',	L'»',
49219b2ee8SDavid du Colombier /*b0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
50219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
51219b2ee8SDavid du Colombier /*c0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
52219b2ee8SDavid du Colombier 	CIT,	BROM,	NONE,	ITON,	ROM,	SYM,	HEL,	BHEL,
53219b2ee8SDavid du Colombier /*d0*/	NONE,	SMALL,	ITOFF,	SUP,	SUB,	NONE,	NONE,	NONE,
54219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
55219b2ee8SDavid du Colombier /*e0*/	L'α',	L'ß',	L'γ',	L'π',	L'Σ',	L'σ',	L'µ',	L'τ',
56219b2ee8SDavid du Colombier 	L'Φ',	L'Θ',	L'Ω',	L'δ',	L'∞',	L'Ø',	L'ε',	L'∩',
57219b2ee8SDavid du Colombier /*f0*/	L'≡',	L'±',	L'≥',	L'≤',	L'⌠',	L'⌡',	L'÷',	L'≈',
58219b2ee8SDavid du Colombier 	L'°',	L'∙',	L'·',	L'√',	L'ⁿ',	L'²',	L'∎',	L' ',
59219b2ee8SDavid du Colombier };
60219b2ee8SDavid du Colombier 
61219b2ee8SDavid du Colombier static Rune suptab[] = {
62219b2ee8SDavid du Colombier 	['0'] L'⁰',	['1'] L'ⁱ',	['2'] L'⁲',	['3'] L'⁳',
63219b2ee8SDavid du Colombier 	['4'] L'⁴',	['5'] L'⁵',	['6'] L'⁶',	['7'] L'⁷',
64219b2ee8SDavid du Colombier 	['8'] L'⁸',	['9'] L'⁹',	['+'] L'⁺',	['-'] L'⁻',
65219b2ee8SDavid du Colombier 	['='] L'⁼',	['('] L'⁽',	[')'] L'⁾',	['a'] L'ª',
66219b2ee8SDavid du Colombier 	['n'] L'ⁿ',	['o'] L'º'
67219b2ee8SDavid du Colombier };
68219b2ee8SDavid du Colombier 
69219b2ee8SDavid du Colombier static Rune subtab[] = {
70219b2ee8SDavid du Colombier 	['0'] L'₀',	['1'] L'₁',	['2'] L'₂',	['3'] L'₃',
71219b2ee8SDavid du Colombier 	['4'] L'₄',	['5'] L'₅',	['6'] L'₆',	['7'] L'₇',
72219b2ee8SDavid du Colombier 	['8'] L'₈',	['9'] L'₉',	['+'] L'₊',	['-'] L'₋',
73219b2ee8SDavid du Colombier 	['='] L'₌',	['('] L'₍',	[')'] L'₎'
74219b2ee8SDavid du Colombier };
75219b2ee8SDavid du Colombier 
76219b2ee8SDavid du Colombier #define	GSHORT(p)	(((p)[0]<<8) | (p)[1])
77219b2ee8SDavid du Colombier #define	GLONG(p)	(((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])
78219b2ee8SDavid du Colombier 
79219b2ee8SDavid du Colombier static char	cfile[] = "/lib/dict/robert/cits.rob";
80219b2ee8SDavid du Colombier static char	dfile[] = "/lib/dict/robert/defs.rob";
81219b2ee8SDavid du Colombier static char	efile[] = "/lib/dict/robert/etym.rob";
82219b2ee8SDavid du Colombier static char	kfile[] = "/lib/dict/robert/_phon";
83219b2ee8SDavid du Colombier 
84219b2ee8SDavid du Colombier static Biobuf *	cb;
85219b2ee8SDavid du Colombier static Biobuf *	db;
86219b2ee8SDavid du Colombier static Biobuf *	eb;
87219b2ee8SDavid du Colombier 
88219b2ee8SDavid du Colombier static Biobuf *	Bouvrir(char*);
89219b2ee8SDavid du Colombier static void	citation(int, int);
90219b2ee8SDavid du Colombier static void	robertprintentry(Entry*, Entry*, int);
91219b2ee8SDavid du Colombier 
92219b2ee8SDavid du Colombier void
robertindexentry(Entry e,int cmd)93219b2ee8SDavid du Colombier robertindexentry(Entry e, int cmd)
94219b2ee8SDavid du Colombier {
95219b2ee8SDavid du Colombier 	uchar *p = (uchar *)e.start;
96219b2ee8SDavid du Colombier 	long ea, el, da, dl, fa;
97219b2ee8SDavid du Colombier 	Entry def, etym;
98219b2ee8SDavid du Colombier 
99219b2ee8SDavid du Colombier 	ea = GLONG(&p[0]);
100219b2ee8SDavid du Colombier 	el = GSHORT(&p[4]);
101219b2ee8SDavid du Colombier 	da = GLONG(&p[6]);
102219b2ee8SDavid du Colombier 	dl = GSHORT(&p[10]);
103219b2ee8SDavid du Colombier 	fa = GLONG(&p[12]);
104219b2ee8SDavid du Colombier 	USED(fa);
105219b2ee8SDavid du Colombier 
106219b2ee8SDavid du Colombier 	if(db == 0)
107219b2ee8SDavid du Colombier 		db = Bouvrir(dfile);
108219b2ee8SDavid du Colombier 	def.start = malloc(dl+1);
109219b2ee8SDavid du Colombier 	def.end = def.start + dl;
110219b2ee8SDavid du Colombier 	def.doff = da;
111219b2ee8SDavid du Colombier 	Bseek(db, da, 0);
112219b2ee8SDavid du Colombier 	Bread(db, def.start, dl);
113219b2ee8SDavid du Colombier 	*def.end = 0;
114219b2ee8SDavid du Colombier 	if(cmd == 'h'){
115219b2ee8SDavid du Colombier 		robertprintentry(&def, 0, cmd);
116219b2ee8SDavid du Colombier 	}else{
117219b2ee8SDavid du Colombier 		if(eb == 0)
118219b2ee8SDavid du Colombier 			eb = Bouvrir(efile);
119219b2ee8SDavid du Colombier 		etym.start = malloc(el+1);
120219b2ee8SDavid du Colombier 		etym.end = etym.start + el;
121219b2ee8SDavid du Colombier 		etym.doff = ea;
122219b2ee8SDavid du Colombier 		Bseek(eb, ea, 0);
123219b2ee8SDavid du Colombier 		Bread(eb, etym.start, el);
124219b2ee8SDavid du Colombier 		*etym.end = 0;
125219b2ee8SDavid du Colombier 		robertprintentry(&def, &etym, cmd);
126219b2ee8SDavid du Colombier 		free(etym.start);
127219b2ee8SDavid du Colombier 	}
128219b2ee8SDavid du Colombier 	free(def.start);
129219b2ee8SDavid du Colombier }
130219b2ee8SDavid du Colombier 
131219b2ee8SDavid du Colombier static void
robertprintentry(Entry * def,Entry * etym,int cmd)132219b2ee8SDavid du Colombier robertprintentry(Entry *def, Entry *etym, int cmd)
133219b2ee8SDavid du Colombier {
134219b2ee8SDavid du Colombier 	uchar *p, *pe;
135219b2ee8SDavid du Colombier 	Rune r; int c, n;
136219b2ee8SDavid du Colombier 	int baseline = 0;
137219b2ee8SDavid du Colombier 	int lineno = 0;
138219b2ee8SDavid du Colombier 	int cit = 0;
139219b2ee8SDavid du Colombier 
140219b2ee8SDavid du Colombier 	p = (uchar *)def->start;
141219b2ee8SDavid du Colombier 	pe = (uchar *)def->end;
142219b2ee8SDavid du Colombier 	while(p < pe){
143219b2ee8SDavid du Colombier 		if(cmd == 'r'){
144219b2ee8SDavid du Colombier 			outchar(*p++);
145219b2ee8SDavid du Colombier 			continue;
146219b2ee8SDavid du Colombier 		}
147219b2ee8SDavid du Colombier 		c = *p++;
148219b2ee8SDavid du Colombier 		switch(r = intab[c]){	/* assign = */
149219b2ee8SDavid du Colombier 		case BROM:
150219b2ee8SDavid du Colombier 		case ITON:
151219b2ee8SDavid du Colombier 		case ROM:
152219b2ee8SDavid du Colombier 		case SYM:
153219b2ee8SDavid du Colombier 		case HEL:
154219b2ee8SDavid du Colombier 		case BHEL:
155219b2ee8SDavid du Colombier 		case SMALL:
156219b2ee8SDavid du Colombier 		case ITOFF:
157219b2ee8SDavid du Colombier 		case NONE:
158219b2ee8SDavid du Colombier 			if(debug)
159219b2ee8SDavid du Colombier 				outprint("\\%.2ux", c);
160219b2ee8SDavid du Colombier 			baseline = 0;
161219b2ee8SDavid du Colombier 			break;
162219b2ee8SDavid du Colombier 
163219b2ee8SDavid du Colombier 		case SUP:
164219b2ee8SDavid du Colombier 			baseline = 1;
165219b2ee8SDavid du Colombier 			break;
166219b2ee8SDavid du Colombier 
167219b2ee8SDavid du Colombier 		case SUB:
168219b2ee8SDavid du Colombier 			baseline = -1;
169219b2ee8SDavid du Colombier 			break;
170219b2ee8SDavid du Colombier 
171219b2ee8SDavid du Colombier 		case CIT:
172219b2ee8SDavid du Colombier 			n = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
173219b2ee8SDavid du Colombier 			p += 4;
174219b2ee8SDavid du Colombier 			if(debug)
175219b2ee8SDavid du Colombier 				outprint("[%d]", n);
176219b2ee8SDavid du Colombier 			while(*p == ' ' || ('0'<=*p && *p<='9') || *p == '.'){
177219b2ee8SDavid du Colombier 				if(debug)
178219b2ee8SDavid du Colombier 					outchar(*p);
179219b2ee8SDavid du Colombier 				++p;
180219b2ee8SDavid du Colombier 			}
181219b2ee8SDavid du Colombier 			++cit;
182219b2ee8SDavid du Colombier 			outnl(2);
183219b2ee8SDavid du Colombier 			citation(n, cmd);
184219b2ee8SDavid du Colombier 			baseline = 0;
185219b2ee8SDavid du Colombier 			break;
186219b2ee8SDavid du Colombier 
187219b2ee8SDavid du Colombier 		case '\n':
188219b2ee8SDavid du Colombier 			outnl(0);
189219b2ee8SDavid du Colombier 			baseline = 0;
190219b2ee8SDavid du Colombier 			++lineno;
191219b2ee8SDavid du Colombier 			break;
192219b2ee8SDavid du Colombier 
193219b2ee8SDavid du Colombier 		default:
194219b2ee8SDavid du Colombier 			if(baseline > 0 && r < nelem(suptab))
195219b2ee8SDavid du Colombier 				r = suptab[r];
196219b2ee8SDavid du Colombier 			else if(baseline < 0 && r < nelem(subtab))
197219b2ee8SDavid du Colombier 				r = subtab[r];
198219b2ee8SDavid du Colombier 			if(cit){
199219b2ee8SDavid du Colombier 				outchar('\n');
200219b2ee8SDavid du Colombier 				cit = 0;
201219b2ee8SDavid du Colombier 			}
202219b2ee8SDavid du Colombier 			outrune(r);
203219b2ee8SDavid du Colombier 			baseline = 0;
204219b2ee8SDavid du Colombier 			break;
205219b2ee8SDavid du Colombier 		}
206219b2ee8SDavid du Colombier 		if(r == '\n'){
207219b2ee8SDavid du Colombier 			if(cmd == 'h')
208219b2ee8SDavid du Colombier 				break;
209219b2ee8SDavid du Colombier 			if(lineno == 1 && etym)
210219b2ee8SDavid du Colombier 				robertprintentry(etym, 0, cmd);
211219b2ee8SDavid du Colombier 		}
212219b2ee8SDavid du Colombier 	}
213219b2ee8SDavid du Colombier 	outnl(0);
214219b2ee8SDavid du Colombier }
215219b2ee8SDavid du Colombier 
216219b2ee8SDavid du Colombier static void
citation(int addr,int cmd)217219b2ee8SDavid du Colombier citation(int addr, int cmd)
218219b2ee8SDavid du Colombier {
219219b2ee8SDavid du Colombier 	Entry cit;
220219b2ee8SDavid du Colombier 
221219b2ee8SDavid du Colombier 	if(cb == 0)
222219b2ee8SDavid du Colombier 		cb = Bouvrir(cfile);
223219b2ee8SDavid du Colombier 	Bseek(cb, addr, 0);
224219b2ee8SDavid du Colombier 	cit.start = Brdline(cb, 0xc8);
225*7dd7cddfSDavid du Colombier 	cit.end = cit.start + Blinelen(cb) - 1;
226219b2ee8SDavid du Colombier 	cit.doff = addr;
227219b2ee8SDavid du Colombier 	*cit.end = 0;
228219b2ee8SDavid du Colombier 	robertprintentry(&cit, 0, cmd);
229219b2ee8SDavid du Colombier }
230219b2ee8SDavid du Colombier 
231219b2ee8SDavid du Colombier long
robertnextoff(long fromoff)232219b2ee8SDavid du Colombier robertnextoff(long fromoff)
233219b2ee8SDavid du Colombier {
234219b2ee8SDavid du Colombier 	return (fromoff & ~15) + 16;
235219b2ee8SDavid du Colombier }
236219b2ee8SDavid du Colombier 
237219b2ee8SDavid du Colombier void
robertprintkey(void)238219b2ee8SDavid du Colombier robertprintkey(void)
239219b2ee8SDavid du Colombier {
240219b2ee8SDavid du Colombier 	Biobuf *db;
241219b2ee8SDavid du Colombier 	char *l;
242219b2ee8SDavid du Colombier 
243219b2ee8SDavid du Colombier 	db = Bouvrir(kfile);
244219b2ee8SDavid du Colombier 	while(l = Brdline(db, '\n'))	/* assign = */
245*7dd7cddfSDavid du Colombier 		Bwrite(bout, l, Blinelen(db));
246219b2ee8SDavid du Colombier 	Bterm(db);
247219b2ee8SDavid du Colombier }
248219b2ee8SDavid du Colombier 
249219b2ee8SDavid du Colombier void
robertflexentry(Entry e,int cmd)250219b2ee8SDavid du Colombier robertflexentry(Entry e, int cmd)
251219b2ee8SDavid du Colombier {
252219b2ee8SDavid du Colombier 	uchar *p, *pe;
253219b2ee8SDavid du Colombier 	Rune r; int c;
254219b2ee8SDavid du Colombier 	int lineno = 1;
255219b2ee8SDavid du Colombier 
256219b2ee8SDavid du Colombier 	p = (uchar *)e.start;
257219b2ee8SDavid du Colombier 	pe = (uchar *)e.end;
258219b2ee8SDavid du Colombier 	while(p < pe){
259219b2ee8SDavid du Colombier 		if(cmd == 'r'){
260*7dd7cddfSDavid du Colombier 			Bputc(bout, *p++);
261219b2ee8SDavid du Colombier 			continue;
262219b2ee8SDavid du Colombier 		}
263219b2ee8SDavid du Colombier 		c = *p++;
264219b2ee8SDavid du Colombier 		r = intab[c];
265219b2ee8SDavid du Colombier 		if(r == '$')
266219b2ee8SDavid du Colombier 			r = '\n';
267219b2ee8SDavid du Colombier 		if(r == '\n'){
268219b2ee8SDavid du Colombier 			++lineno;
269219b2ee8SDavid du Colombier 			if(cmd == 'h' && lineno > 2)
270219b2ee8SDavid du Colombier 				break;
271219b2ee8SDavid du Colombier 		}
272219b2ee8SDavid du Colombier 		if(cmd == 'h' && lineno < 2)
273219b2ee8SDavid du Colombier 			continue;
274219b2ee8SDavid du Colombier 		if(r > MULTIE){
275219b2ee8SDavid du Colombier 			if(debug)
276219b2ee8SDavid du Colombier 				Bprint(bout, "\\%.2ux", c);
277219b2ee8SDavid du Colombier 			continue;
278219b2ee8SDavid du Colombier 		}
279219b2ee8SDavid du Colombier 		if(r < Runeself)
280*7dd7cddfSDavid du Colombier 			Bputc(bout, r);
281219b2ee8SDavid du Colombier 		else
282219b2ee8SDavid du Colombier 			Bputrune(bout, r);
283219b2ee8SDavid du Colombier 	}
284219b2ee8SDavid du Colombier 	outnl(0);
285219b2ee8SDavid du Colombier }
286219b2ee8SDavid du Colombier 
287219b2ee8SDavid du Colombier long
robertnextflex(long fromoff)288219b2ee8SDavid du Colombier robertnextflex(long fromoff)
289219b2ee8SDavid du Colombier {
290219b2ee8SDavid du Colombier 	int c;
291219b2ee8SDavid du Colombier 
292219b2ee8SDavid du Colombier 	if(Bseek(bdict, fromoff, 0) < 0)
293219b2ee8SDavid du Colombier 		return -1;
294*7dd7cddfSDavid du Colombier 	while((c = Bgetc(bdict)) >= 0){
295219b2ee8SDavid du Colombier 		if(c == '$')
296219b2ee8SDavid du Colombier 			return Boffset(bdict);
297219b2ee8SDavid du Colombier 	}
298219b2ee8SDavid du Colombier 	return -1;
299219b2ee8SDavid du Colombier }
300219b2ee8SDavid du Colombier 
301219b2ee8SDavid du Colombier static Biobuf *
Bouvrir(char * fichier)302219b2ee8SDavid du Colombier Bouvrir(char *fichier)
303219b2ee8SDavid du Colombier {
304219b2ee8SDavid du Colombier 	Biobuf *db;
305219b2ee8SDavid du Colombier 
306219b2ee8SDavid du Colombier 	db = Bopen(fichier, OREAD);
307219b2ee8SDavid du Colombier 	if(db == 0){
308219b2ee8SDavid du Colombier 		fprint(2, "%s: impossible d'ouvrir %s: %r\n", argv0, fichier);
309219b2ee8SDavid du Colombier 		exits("ouvrir");
310219b2ee8SDavid du Colombier 	}
311219b2ee8SDavid du Colombier 	return db;
312219b2ee8SDavid du Colombier }
313