xref: /plan9/sys/src/cmd/dict/robert.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
5 
6 /*
7  * Robert Électronique.
8  */
9 
10 enum
11 {
12 	CIT = MULTIE+1,	/* citation ptr followed by long int and ascii label */
13 	BROM,		/* bold roman */
14 	ITON,		/* start italic */
15 	ROM,		/* roman */
16 	SYM,		/* symbol font? */
17 	HEL,		/* helvetica */
18 	BHEL,		/* helvetica bold */
19 	SMALL,		/* smaller? */
20 	ITOFF,		/* end italic */
21 	SUP,		/* following character is superscript */
22 	SUB		/* following character is subscript */
23 };
24 
25 static Rune intab[256] = {
26 	/*0*/	/*1*/	/*2*/	/*3*/	/*4*/	/*5*/	/*6*/	/*7*/
27 /*00*/	NONE,	L'☺',	L'☻',	L'♥',	L'♦',	L'♣',	L'♠',	L'•',
28 	0x25d8,	L'ʘ',	L'\n',	L'♂',	L'♀',	L'♪',	0x266b,	L'※',
29 /*10*/	L'⇨',	L'⇦',	L'↕',	L'‼',	L'¶',	L'§',	L'⁃',	L'↨',
30 	L'↑',	L'↓',	L'→',	L'←',	L'⌙',	L'↔',	0x25b4,	0x25be,
31 /*20*/	L' ',	L'!',	L'"',	L'#',	L'$',	L'%',	L'&',	L''',
32 	L'(',	L')',	L'*',	L'+',	L',',	L'-',	L'.',	L'/',
33 /*30*/	L'0',	L'1',	L'2',	L'3',	L'4',	L'5',	L'6',	L'7',
34 	L'8',	L'9',	L':',	L';',	L'<',	L'=',	L'>',	L'?',
35 /*40*/	L'@',	L'A',	L'B',	L'C',	L'D',	L'E',	L'F',	L'G',
36 	L'H',	L'I',	L'J',	L'K',	L'L',	L'M',	L'N',	L'O',
37 /*50*/	L'P',	L'Q',	L'R',	L'S',	L'T',	L'U',	L'V',	L'W',
38 	L'X',	L'Y',	L'Z',	L'[',	L'\\',	L']',	L'^',	L'_',
39 /*60*/	L'`',	L'a',	L'b',	L'c',	L'd',	L'e',	L'f',	L'g',
40 	L'h',	L'i',	L'j',	L'k',	L'l',	L'm',	L'n',	L'o',
41 /*70*/	L'p',	L'q',	L'r',	L's',	L't',	L'u',	L'v',	L'w',
42 	L'x',	L'y',	L'z',	L'{',	L'|',	L'}',	L'~',	L'',
43 /*80*/	L'Ç',	L'ü',	L'é',	L'â',	L'ä',	L'à',	L'å',	L'ç',
44 	L'ê',	L'ë',	L'è',	L'ï',	L'î',	L'ì',	L'Ä',	L'Å',
45 /*90*/	L'É',	L'æ',	L'Æ',	L'ô',	L'ö',	L'ò',	L'û',	L'ù',
46 	L'ÿ',	L'Ö',	L'Ü',	L'¢',	L'£',	L'¥',	L'₧',	L'ʃ',
47 /*a0*/	L'á',	L'í',	L'ó',	L'ú',	L'ñ',	L'Ñ',	L'ª',	L'º',
48 	L'¿',	L'⌐',	L'¬',	L'½',	L'¼',	L'¡',	L'«',	L'»',
49 /*b0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
50 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
51 /*c0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
52 	CIT,	BROM,	NONE,	ITON,	ROM,	SYM,	HEL,	BHEL,
53 /*d0*/	NONE,	SMALL,	ITOFF,	SUP,	SUB,	NONE,	NONE,	NONE,
54 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
55 /*e0*/	L'α',	L'ß',	L'γ',	L'π',	L'Σ',	L'σ',	L'µ',	L'τ',
56 	L'Φ',	L'Θ',	L'Ω',	L'δ',	L'∞',	L'Ø',	L'ε',	L'∩',
57 /*f0*/	L'≡',	L'±',	L'≥',	L'≤',	L'⌠',	L'⌡',	L'÷',	L'≈',
58 	L'°',	L'∙',	L'·',	L'√',	L'ⁿ',	L'²',	L'∎',	L' ',
59 };
60 
61 static Rune suptab[] = {
62 	['0'] L'⁰',	['1'] L'ⁱ',	['2'] L'⁲',	['3'] L'⁳',
63 	['4'] L'⁴',	['5'] L'⁵',	['6'] L'⁶',	['7'] L'⁷',
64 	['8'] L'⁸',	['9'] L'⁹',	['+'] L'⁺',	['-'] L'⁻',
65 	['='] L'⁼',	['('] L'⁽',	[')'] L'⁾',	['a'] L'ª',
66 	['n'] L'ⁿ',	['o'] L'º'
67 };
68 
69 static Rune subtab[] = {
70 	['0'] L'₀',	['1'] L'₁',	['2'] L'₂',	['3'] L'₃',
71 	['4'] L'₄',	['5'] L'₅',	['6'] L'₆',	['7'] L'₇',
72 	['8'] L'₈',	['9'] L'₉',	['+'] L'₊',	['-'] L'₋',
73 	['='] L'₌',	['('] L'₍',	[')'] L'₎'
74 };
75 
76 #define	GSHORT(p)	(((p)[0]<<8) | (p)[1])
77 #define	GLONG(p)	(((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])
78 
79 static char	cfile[] = "/lib/dict/robert/cits.rob";
80 static char	dfile[] = "/lib/dict/robert/defs.rob";
81 static char	efile[] = "/lib/dict/robert/etym.rob";
82 static char	kfile[] = "/lib/dict/robert/_phon";
83 
84 static Biobuf *	cb;
85 static Biobuf *	db;
86 static Biobuf *	eb;
87 
88 static Biobuf *	Bouvrir(char*);
89 static void	citation(int, int);
90 static void	robertprintentry(Entry*, Entry*, int);
91 
92 void
robertindexentry(Entry e,int cmd)93 robertindexentry(Entry e, int cmd)
94 {
95 	uchar *p = (uchar *)e.start;
96 	long ea, el, da, dl, fa;
97 	Entry def, etym;
98 
99 	ea = GLONG(&p[0]);
100 	el = GSHORT(&p[4]);
101 	da = GLONG(&p[6]);
102 	dl = GSHORT(&p[10]);
103 	fa = GLONG(&p[12]);
104 	USED(fa);
105 
106 	if(db == 0)
107 		db = Bouvrir(dfile);
108 	def.start = malloc(dl+1);
109 	def.end = def.start + dl;
110 	def.doff = da;
111 	Bseek(db, da, 0);
112 	Bread(db, def.start, dl);
113 	*def.end = 0;
114 	if(cmd == 'h'){
115 		robertprintentry(&def, 0, cmd);
116 	}else{
117 		if(eb == 0)
118 			eb = Bouvrir(efile);
119 		etym.start = malloc(el+1);
120 		etym.end = etym.start + el;
121 		etym.doff = ea;
122 		Bseek(eb, ea, 0);
123 		Bread(eb, etym.start, el);
124 		*etym.end = 0;
125 		robertprintentry(&def, &etym, cmd);
126 		free(etym.start);
127 	}
128 	free(def.start);
129 }
130 
131 static void
robertprintentry(Entry * def,Entry * etym,int cmd)132 robertprintentry(Entry *def, Entry *etym, int cmd)
133 {
134 	uchar *p, *pe;
135 	Rune r; int c, n;
136 	int baseline = 0;
137 	int lineno = 0;
138 	int cit = 0;
139 
140 	p = (uchar *)def->start;
141 	pe = (uchar *)def->end;
142 	while(p < pe){
143 		if(cmd == 'r'){
144 			outchar(*p++);
145 			continue;
146 		}
147 		c = *p++;
148 		switch(r = intab[c]){	/* assign = */
149 		case BROM:
150 		case ITON:
151 		case ROM:
152 		case SYM:
153 		case HEL:
154 		case BHEL:
155 		case SMALL:
156 		case ITOFF:
157 		case NONE:
158 			if(debug)
159 				outprint("\\%.2ux", c);
160 			baseline = 0;
161 			break;
162 
163 		case SUP:
164 			baseline = 1;
165 			break;
166 
167 		case SUB:
168 			baseline = -1;
169 			break;
170 
171 		case CIT:
172 			n = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
173 			p += 4;
174 			if(debug)
175 				outprint("[%d]", n);
176 			while(*p == ' ' || ('0'<=*p && *p<='9') || *p == '.'){
177 				if(debug)
178 					outchar(*p);
179 				++p;
180 			}
181 			++cit;
182 			outnl(2);
183 			citation(n, cmd);
184 			baseline = 0;
185 			break;
186 
187 		case '\n':
188 			outnl(0);
189 			baseline = 0;
190 			++lineno;
191 			break;
192 
193 		default:
194 			if(baseline > 0 && r < nelem(suptab))
195 				r = suptab[r];
196 			else if(baseline < 0 && r < nelem(subtab))
197 				r = subtab[r];
198 			if(cit){
199 				outchar('\n');
200 				cit = 0;
201 			}
202 			outrune(r);
203 			baseline = 0;
204 			break;
205 		}
206 		if(r == '\n'){
207 			if(cmd == 'h')
208 				break;
209 			if(lineno == 1 && etym)
210 				robertprintentry(etym, 0, cmd);
211 		}
212 	}
213 	outnl(0);
214 }
215 
216 static void
citation(int addr,int cmd)217 citation(int addr, int cmd)
218 {
219 	Entry cit;
220 
221 	if(cb == 0)
222 		cb = Bouvrir(cfile);
223 	Bseek(cb, addr, 0);
224 	cit.start = Brdline(cb, 0xc8);
225 	cit.end = cit.start + Blinelen(cb) - 1;
226 	cit.doff = addr;
227 	*cit.end = 0;
228 	robertprintentry(&cit, 0, cmd);
229 }
230 
231 long
robertnextoff(long fromoff)232 robertnextoff(long fromoff)
233 {
234 	return (fromoff & ~15) + 16;
235 }
236 
237 void
robertprintkey(void)238 robertprintkey(void)
239 {
240 	Biobuf *db;
241 	char *l;
242 
243 	db = Bouvrir(kfile);
244 	while(l = Brdline(db, '\n'))	/* assign = */
245 		Bwrite(bout, l, Blinelen(db));
246 	Bterm(db);
247 }
248 
249 void
robertflexentry(Entry e,int cmd)250 robertflexentry(Entry e, int cmd)
251 {
252 	uchar *p, *pe;
253 	Rune r; int c;
254 	int lineno = 1;
255 
256 	p = (uchar *)e.start;
257 	pe = (uchar *)e.end;
258 	while(p < pe){
259 		if(cmd == 'r'){
260 			Bputc(bout, *p++);
261 			continue;
262 		}
263 		c = *p++;
264 		r = intab[c];
265 		if(r == '$')
266 			r = '\n';
267 		if(r == '\n'){
268 			++lineno;
269 			if(cmd == 'h' && lineno > 2)
270 				break;
271 		}
272 		if(cmd == 'h' && lineno < 2)
273 			continue;
274 		if(r > MULTIE){
275 			if(debug)
276 				Bprint(bout, "\\%.2ux", c);
277 			continue;
278 		}
279 		if(r < Runeself)
280 			Bputc(bout, r);
281 		else
282 			Bputrune(bout, r);
283 	}
284 	outnl(0);
285 }
286 
287 long
robertnextflex(long fromoff)288 robertnextflex(long fromoff)
289 {
290 	int c;
291 
292 	if(Bseek(bdict, fromoff, 0) < 0)
293 		return -1;
294 	while((c = Bgetc(bdict)) >= 0){
295 		if(c == '$')
296 			return Boffset(bdict);
297 	}
298 	return -1;
299 }
300 
301 static Biobuf *
Bouvrir(char * fichier)302 Bouvrir(char *fichier)
303 {
304 	Biobuf *db;
305 
306 	db = Bopen(fichier, OREAD);
307 	if(db == 0){
308 		fprint(2, "%s: impossible d'ouvrir %s: %r\n", argv0, fichier);
309 		exits("ouvrir");
310 	}
311 	return db;
312 }
313