xref: /plan9-contrib/sys/src/cmd/dict/pcollinsg.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  * Routines for handling dictionaries in the "Paperback Collins"
8219b2ee8SDavid du Colombier  * `German' format (with tags surrounded by \5⋯\6 and \xba⋯\xba)
9219b2ee8SDavid du Colombier  */
10219b2ee8SDavid du Colombier 
11219b2ee8SDavid du Colombier /*
12219b2ee8SDavid du Colombier  *	\5⋯\6 escapes (fonts, mostly)
13219b2ee8SDavid du Colombier  *
14219b2ee8SDavid du Colombier  *	h	headword (helvetica 7 pt)
15219b2ee8SDavid du Colombier  *	c	clause (helvetica 7 pt)
16219b2ee8SDavid du Colombier  *	3	helvetica 7 pt
17219b2ee8SDavid du Colombier  *	4	helvetica 6.5 pt
18219b2ee8SDavid du Colombier  *	s	helvetica 8 pt
19219b2ee8SDavid du Colombier  *	x	helvetica 8 pt
20219b2ee8SDavid du Colombier  *	y	helvetica 5 pt
21219b2ee8SDavid du Colombier  *	m	helvetica 30 pt
22219b2ee8SDavid du Colombier  *	1	roman 6 pt
23219b2ee8SDavid du Colombier  *	9	roman 4.5 pt
24219b2ee8SDavid du Colombier  *	p	roman 7 pt
25219b2ee8SDavid du Colombier  *	q	roman 4.5 pt
26219b2ee8SDavid du Colombier  *	2	italic 6 pt
27219b2ee8SDavid du Colombier  *	7	italic 4.5 pt
28219b2ee8SDavid du Colombier  *	b	bold 6 pt
29219b2ee8SDavid du Colombier  *	a	`indent 0:4 left'
30219b2ee8SDavid du Colombier  *	k	`keep 9'
31219b2ee8SDavid du Colombier  *	l	`size 12'
32219b2ee8SDavid du Colombier  */
33219b2ee8SDavid du Colombier 
34219b2ee8SDavid du Colombier enum {
35219b2ee8SDavid du Colombier 	IBASE=L'i',	/* dotless i */
36219b2ee8SDavid du Colombier 	Taglen=32,
37219b2ee8SDavid du Colombier };
38219b2ee8SDavid du Colombier 
39219b2ee8SDavid du Colombier static Rune intab[256] = {
40219b2ee8SDavid du Colombier 	/*0*/	/*1*/	/*2*/	/*3*/	/*4*/	/*5*/	/*6*/	/*7*/
41219b2ee8SDavid du Colombier /*00*/	NONE,	NONE,	NONE,	NONE,	NONE,	TAGS,	TAGE,	NONE,
42219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	L' ',	NONE,	NONE,
43219b2ee8SDavid du Colombier /*10*/	NONE,	L'-',	L' ',	L' ',	NONE,	NONE,	NONE,	NONE,
44219b2ee8SDavid du Colombier 	L' ',	NONE,	NONE,	NONE,	L' ',	NONE,	NONE,	L'-',
45219b2ee8SDavid du Colombier /*20*/	L' ',	L'!',	L'"',	L'#',	L'$',	L'%',	L'&',	L'\'',
46219b2ee8SDavid du Colombier 	L'(',	L')',	L'*',	L'+',	L',',	L'-',	L'.',	L'/',
47219b2ee8SDavid du Colombier /*30*/  L'0',	L'1',	L'2',	L'3',	L'4',	L'5',	L'6',	L'7',
48219b2ee8SDavid du Colombier 	L'8',	L'9',	L':',	L';',	L'<',	L'=',	L'>',	L'?',
49219b2ee8SDavid du Colombier /*40*/  L'@',	L'A',	L'B',	L'C',	L'D',	L'E',	L'F',	L'G',
50219b2ee8SDavid du Colombier 	L'H',	L'I',	L'J',	L'K',	L'L',	L'M',	L'N',	L'O',
51219b2ee8SDavid du Colombier /*50*/	L'P',	L'Q',	L'R',	L'S',	L'T',	L'U',	L'V',	L'W',
52219b2ee8SDavid du Colombier 	L'X',	L'Y',	L'Z',	L'[',	L'\\',	L']',	L'^',	L'_',
53219b2ee8SDavid du Colombier /*60*/	L'`',	L'a',	L'b',	L'c',	L'd',	L'e',	L'f',	L'g',
54219b2ee8SDavid du Colombier 	L'h',	L'i',	L'j',	L'k',	L'l',	L'm',	L'n',	L'o',
55219b2ee8SDavid du Colombier /*70*/	L'p',	L'q',	L'r',	L's',	L't',	L'u',	L'v',	L'w',
56219b2ee8SDavid du Colombier 	L'x',	L'y',	L'z',	L'{',	L'|',	L'}',	L'~',	NONE,
57219b2ee8SDavid du Colombier /*80*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
58219b2ee8SDavid du Colombier 	NONE,	NONE,	L' ',	NONE,	NONE,	NONE,	NONE,	NONE,
59219b2ee8SDavid du Colombier /*90*/	L'ß',	L'æ',	NONE,	MOE,	NONE,	NONE,	NONE,	L'ø',
60219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
61219b2ee8SDavid du Colombier /*A0*/	NONE,	NONE,	L'"',	L'£',	NONE,	NONE,	NONE,	NONE,
62219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
63219b2ee8SDavid du Colombier /*B0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	L'~',
64219b2ee8SDavid du Colombier 	NONE,	IBASE,	SPCS,	NONE,	NONE,	NONE,	NONE,	NONE,
65219b2ee8SDavid du Colombier /*C0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
66219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
67219b2ee8SDavid du Colombier /*D0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
68219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
69219b2ee8SDavid du Colombier /*E0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
70219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
71219b2ee8SDavid du Colombier /*F0*/	L' ',	L' ',	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
72219b2ee8SDavid du Colombier 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
73219b2ee8SDavid du Colombier };
74219b2ee8SDavid du Colombier 
75219b2ee8SDavid du Colombier static Nassoc numtab[] = {
76219b2ee8SDavid du Colombier 	{1,	L'+'},
77219b2ee8SDavid du Colombier 	{4,	L'='},
78219b2ee8SDavid du Colombier 	{7,	L'°'},
79219b2ee8SDavid du Colombier 	{11,	L'≈'},
80219b2ee8SDavid du Colombier 	{69,	L'♦'},
81219b2ee8SDavid du Colombier 	{114,	L'®'},
82219b2ee8SDavid du Colombier 	{340,	L'ɛ'},
83219b2ee8SDavid du Colombier 	{341,	L'ɔ'},
84219b2ee8SDavid du Colombier 	{342,	L'ʌ'},
85219b2ee8SDavid du Colombier 	{343,	L'ə'},
86219b2ee8SDavid du Colombier 	{345,	L'ʒ'},
87219b2ee8SDavid du Colombier 	{346,	L'ʃ'},
88219b2ee8SDavid du Colombier 	{347,	L'ɵ'},
89219b2ee8SDavid du Colombier 	{348,	L'ʊ'},
90219b2ee8SDavid du Colombier 	{349,	L'ˈ'},
91219b2ee8SDavid du Colombier 	{351,	L'ɪ'},
92219b2ee8SDavid du Colombier 	{352,	L'ɜ'},
93219b2ee8SDavid du Colombier 	{354,	L'ɑ'},
94219b2ee8SDavid du Colombier 	{355,	L'~'},
95219b2ee8SDavid du Colombier 	{356,	L'ɒ'},
96219b2ee8SDavid du Colombier 	{384,	L'ɳ'},
97219b2ee8SDavid du Colombier 	{445,	L'ð'},	/* BUG -- should be script eth */
98219b2ee8SDavid du Colombier };
99219b2ee8SDavid du Colombier 
100219b2ee8SDavid du Colombier static Nassoc overtab[] = {
101219b2ee8SDavid du Colombier 	{L',',	LCED},
102219b2ee8SDavid du Colombier 	{L'/',	LACU},
103219b2ee8SDavid du Colombier 	{L':',	LUML},
104219b2ee8SDavid du Colombier 	{L'\\',	LGRV},
105219b2ee8SDavid du Colombier 	{L'^',	LFRN},
106219b2ee8SDavid du Colombier 	{L'~',	LTIL},
107219b2ee8SDavid du Colombier };
108219b2ee8SDavid du Colombier 
109*7dd7cddfSDavid du Colombier static uchar *reach(uchar*, int);
110219b2ee8SDavid du Colombier 
111219b2ee8SDavid du Colombier static Entry	curentry;
112219b2ee8SDavid du Colombier static char	tag[Taglen];
113219b2ee8SDavid du Colombier 
114219b2ee8SDavid du Colombier void
pcollgprintentry(Entry e,int cmd)115219b2ee8SDavid du Colombier pcollgprintentry(Entry e, int cmd)
116219b2ee8SDavid du Colombier {
117219b2ee8SDavid du Colombier 	uchar *p, *pe;
118219b2ee8SDavid du Colombier 	int r, rprev = NONE, rx, over = 0, font;
119219b2ee8SDavid du Colombier 	char buf[16];
120219b2ee8SDavid du Colombier 
121219b2ee8SDavid du Colombier 	p = (uchar *)e.start;
122219b2ee8SDavid du Colombier 	pe = (uchar *)e.end;
123219b2ee8SDavid du Colombier 	curentry = e;
124219b2ee8SDavid du Colombier 	if(cmd == 'h')
125219b2ee8SDavid du Colombier 		outinhibit = 1;
126219b2ee8SDavid du Colombier 	while(p < pe){
127219b2ee8SDavid du Colombier 		if(cmd == 'r'){
128219b2ee8SDavid du Colombier 			outchar(*p++);
129219b2ee8SDavid du Colombier 			continue;
130219b2ee8SDavid du Colombier 		}
131219b2ee8SDavid du Colombier 		switch(r = intab[*p++]){	/* assign = */
132219b2ee8SDavid du Colombier 		case TAGS:
133219b2ee8SDavid du Colombier 			if(rprev != NONE){
134219b2ee8SDavid du Colombier 				outrune(rprev);
135219b2ee8SDavid du Colombier 				rprev = NONE;
136219b2ee8SDavid du Colombier 			}
137219b2ee8SDavid du Colombier 			p = reach(p, 0x06);
138219b2ee8SDavid du Colombier 			font = tag[0];
139219b2ee8SDavid du Colombier 			if(cmd == 'h')
140219b2ee8SDavid du Colombier 				outinhibit = (font != 'h');
141219b2ee8SDavid du Colombier 			break;
142219b2ee8SDavid du Colombier 
143219b2ee8SDavid du Colombier 		case TAGE:	/* an extra one */
144219b2ee8SDavid du Colombier 			break;
145219b2ee8SDavid du Colombier 
146219b2ee8SDavid du Colombier 		case SPCS:
147219b2ee8SDavid du Colombier 			p = reach(p, 0xba);
148219b2ee8SDavid du Colombier 			r = looknassoc(numtab, asize(numtab), strtol(tag,0,0));
149219b2ee8SDavid du Colombier 			if(r < 0){
150219b2ee8SDavid du Colombier 				if(rprev != NONE){
151219b2ee8SDavid du Colombier 					outrune(rprev);
152219b2ee8SDavid du Colombier 					rprev = NONE;
153219b2ee8SDavid du Colombier 				}
154219b2ee8SDavid du Colombier 				sprint(buf, "\\N'%s'", tag);
155219b2ee8SDavid du Colombier 				outchars(buf);
156219b2ee8SDavid du Colombier 				break;
157219b2ee8SDavid du Colombier 			}
158219b2ee8SDavid du Colombier 			/* else fall through */
159219b2ee8SDavid du Colombier 
160219b2ee8SDavid du Colombier 		default:
161219b2ee8SDavid du Colombier 			if(over){
162219b2ee8SDavid du Colombier 				rx = looknassoc(overtab, asize(overtab), r);
163219b2ee8SDavid du Colombier 				if(rx > 0)
164219b2ee8SDavid du Colombier 					rx = liglookup(rx, rprev);
165219b2ee8SDavid du Colombier 				if(rx > 0 && rx != NONE)
166219b2ee8SDavid du Colombier 					outrune(rx);
167219b2ee8SDavid du Colombier 				else{
168219b2ee8SDavid du Colombier 					outrune(rprev);
169219b2ee8SDavid du Colombier 					if(r == ':')
170219b2ee8SDavid du Colombier 						outrune(L'¨');
171219b2ee8SDavid du Colombier 					else{
172219b2ee8SDavid du Colombier 						outrune(L'^');
173219b2ee8SDavid du Colombier 						outrune(r);
174219b2ee8SDavid du Colombier 					}
175219b2ee8SDavid du Colombier 				}
176219b2ee8SDavid du Colombier 				over = 0;
177219b2ee8SDavid du Colombier 				rprev = NONE;
178219b2ee8SDavid du Colombier 			}else if(r == '^'){
179219b2ee8SDavid du Colombier 				over = 1;
180219b2ee8SDavid du Colombier 			}else{
181219b2ee8SDavid du Colombier 				if(rprev != NONE)
182219b2ee8SDavid du Colombier 					outrune(rprev);
183219b2ee8SDavid du Colombier 				rprev = r;
184219b2ee8SDavid du Colombier 			}
185219b2ee8SDavid du Colombier 		}
186219b2ee8SDavid du Colombier 
187219b2ee8SDavid du Colombier 	}
188219b2ee8SDavid du Colombier 	if(rprev != NONE)
189219b2ee8SDavid du Colombier 		outrune(rprev);
190219b2ee8SDavid du Colombier 	if(cmd == 'h')
191219b2ee8SDavid du Colombier 		outinhibit = 0;
192219b2ee8SDavid du Colombier 	outnl(0);
193219b2ee8SDavid du Colombier }
194219b2ee8SDavid du Colombier 
195219b2ee8SDavid du Colombier long
pcollgnextoff(long fromoff)196219b2ee8SDavid du Colombier pcollgnextoff(long fromoff)
197219b2ee8SDavid du Colombier {
198219b2ee8SDavid du Colombier 	int c, state = 0, defoff = -1;
199219b2ee8SDavid du Colombier 
200219b2ee8SDavid du Colombier 	if(Bseek(bdict, fromoff, 0) < 0)
201219b2ee8SDavid du Colombier 		return -1;
202*7dd7cddfSDavid du Colombier 	while((c = Bgetc(bdict)) >= 0){
203219b2ee8SDavid du Colombier 		if(c == '\r')
204219b2ee8SDavid du Colombier 			defoff = Boffset(bdict);
205219b2ee8SDavid du Colombier 		switch(state){
206219b2ee8SDavid du Colombier 		case 0:
207219b2ee8SDavid du Colombier 			if(c == 0x05)
208219b2ee8SDavid du Colombier 				state = 1;
209219b2ee8SDavid du Colombier 			break;
210219b2ee8SDavid du Colombier 		case 1:
211219b2ee8SDavid du Colombier 			if(c == 'h')
212219b2ee8SDavid du Colombier 				state = 2;
213219b2ee8SDavid du Colombier 			else
214219b2ee8SDavid du Colombier 				state = 0;
215219b2ee8SDavid du Colombier 			break;
216219b2ee8SDavid du Colombier 		case 2:
217219b2ee8SDavid du Colombier 			if(c == 0x06)
218219b2ee8SDavid du Colombier 				return (Boffset(bdict)-3);
219219b2ee8SDavid du Colombier 			else
220219b2ee8SDavid du Colombier 				state = 0;
221219b2ee8SDavid du Colombier 			break;
222219b2ee8SDavid du Colombier 		}
223219b2ee8SDavid du Colombier 	}
224219b2ee8SDavid du Colombier 	return defoff;
225219b2ee8SDavid du Colombier }
226219b2ee8SDavid du Colombier 
227219b2ee8SDavid du Colombier void
pcollgprintkey(void)228219b2ee8SDavid du Colombier pcollgprintkey(void)
229219b2ee8SDavid du Colombier {
230219b2ee8SDavid du Colombier 	Bprint(bout, "No pronunciation key yet\n");
231219b2ee8SDavid du Colombier }
232219b2ee8SDavid du Colombier 
233219b2ee8SDavid du Colombier static uchar *
reach(uchar * p,int tagchar)234219b2ee8SDavid du Colombier reach(uchar *p, int tagchar)
235219b2ee8SDavid du Colombier {
236219b2ee8SDavid du Colombier 	int c; char *q=tag;
237219b2ee8SDavid du Colombier 
238219b2ee8SDavid du Colombier 	while(p < (uchar *)curentry.end){
239219b2ee8SDavid du Colombier 		c = *p++;
240219b2ee8SDavid du Colombier 		if(c == tagchar)
241219b2ee8SDavid du Colombier 			break;
242219b2ee8SDavid du Colombier 		*q++ = c;
243219b2ee8SDavid du Colombier 		if(q >= &tag[sizeof tag-1])
244219b2ee8SDavid du Colombier 			break;
245219b2ee8SDavid du Colombier 	}
246219b2ee8SDavid du Colombier 	*q = 0;
247219b2ee8SDavid du Colombier 	return p;
248219b2ee8SDavid du Colombier }
249