xref: /plan9/sys/src/cmd/dict/pcollinsg.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include "dict.h"
5 
6 /*
7  * Routines for handling dictionaries in the "Paperback Collins"
8  * `German' format (with tags surrounded by \5⋯\6 and \xba⋯\xba)
9  */
10 
11 /*
12  *	\5⋯\6 escapes (fonts, mostly)
13  *
14  *	h	headword (helvetica 7 pt)
15  *	c	clause (helvetica 7 pt)
16  *	3	helvetica 7 pt
17  *	4	helvetica 6.5 pt
18  *	s	helvetica 8 pt
19  *	x	helvetica 8 pt
20  *	y	helvetica 5 pt
21  *	m	helvetica 30 pt
22  *	1	roman 6 pt
23  *	9	roman 4.5 pt
24  *	p	roman 7 pt
25  *	q	roman 4.5 pt
26  *	2	italic 6 pt
27  *	7	italic 4.5 pt
28  *	b	bold 6 pt
29  *	a	`indent 0:4 left'
30  *	k	`keep 9'
31  *	l	`size 12'
32  */
33 
34 enum {
35 	IBASE=L'i',	/* dotless i */
36 	Taglen=32,
37 };
38 
39 static Rune intab[256] = {
40 	/*0*/	/*1*/	/*2*/	/*3*/	/*4*/	/*5*/	/*6*/	/*7*/
41 /*00*/	NONE,	NONE,	NONE,	NONE,	NONE,	TAGS,	TAGE,	NONE,
42 	NONE,	NONE,	NONE,	NONE,	NONE,	L' ',	NONE,	NONE,
43 /*10*/	NONE,	L'-',	L' ',	L' ',	NONE,	NONE,	NONE,	NONE,
44 	L' ',	NONE,	NONE,	NONE,	L' ',	NONE,	NONE,	L'-',
45 /*20*/	L' ',	L'!',	L'"',	L'#',	L'$',	L'%',	L'&',	L'\'',
46 	L'(',	L')',	L'*',	L'+',	L',',	L'-',	L'.',	L'/',
47 /*30*/  L'0',	L'1',	L'2',	L'3',	L'4',	L'5',	L'6',	L'7',
48 	L'8',	L'9',	L':',	L';',	L'<',	L'=',	L'>',	L'?',
49 /*40*/  L'@',	L'A',	L'B',	L'C',	L'D',	L'E',	L'F',	L'G',
50 	L'H',	L'I',	L'J',	L'K',	L'L',	L'M',	L'N',	L'O',
51 /*50*/	L'P',	L'Q',	L'R',	L'S',	L'T',	L'U',	L'V',	L'W',
52 	L'X',	L'Y',	L'Z',	L'[',	L'\\',	L']',	L'^',	L'_',
53 /*60*/	L'`',	L'a',	L'b',	L'c',	L'd',	L'e',	L'f',	L'g',
54 	L'h',	L'i',	L'j',	L'k',	L'l',	L'm',	L'n',	L'o',
55 /*70*/	L'p',	L'q',	L'r',	L's',	L't',	L'u',	L'v',	L'w',
56 	L'x',	L'y',	L'z',	L'{',	L'|',	L'}',	L'~',	NONE,
57 /*80*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
58 	NONE,	NONE,	L' ',	NONE,	NONE,	NONE,	NONE,	NONE,
59 /*90*/	L'ß',	L'æ',	NONE,	MOE,	NONE,	NONE,	NONE,	L'ø',
60 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
61 /*A0*/	NONE,	NONE,	L'"',	L'£',	NONE,	NONE,	NONE,	NONE,
62 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
63 /*B0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	L'~',
64 	NONE,	IBASE,	SPCS,	NONE,	NONE,	NONE,	NONE,	NONE,
65 /*C0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
66 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
67 /*D0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
68 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
69 /*E0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
70 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
71 /*F0*/	L' ',	L' ',	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
72 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
73 };
74 
75 static Nassoc numtab[] = {
76 	{1,	L'+'},
77 	{4,	L'='},
78 	{7,	L'°'},
79 	{11,	L'≈'},
80 	{69,	L'♦'},
81 	{114,	L'®'},
82 	{340,	L'ɛ'},
83 	{341,	L'ɔ'},
84 	{342,	L'ʌ'},
85 	{343,	L'ə'},
86 	{345,	L'ʒ'},
87 	{346,	L'ʃ'},
88 	{347,	L'ɵ'},
89 	{348,	L'ʊ'},
90 	{349,	L'ˈ'},
91 	{351,	L'ɪ'},
92 	{352,	L'ɜ'},
93 	{354,	L'ɑ'},
94 	{355,	L'~'},
95 	{356,	L'ɒ'},
96 	{384,	L'ɳ'},
97 	{445,	L'ð'},	/* BUG -- should be script eth */
98 };
99 
100 static Nassoc overtab[] = {
101 	{L',',	LCED},
102 	{L'/',	LACU},
103 	{L':',	LUML},
104 	{L'\\',	LGRV},
105 	{L'^',	LFRN},
106 	{L'~',	LTIL},
107 };
108 
109 static uchar *reach(uchar*, int);
110 
111 static Entry	curentry;
112 static char	tag[Taglen];
113 
114 void
pcollgprintentry(Entry e,int cmd)115 pcollgprintentry(Entry e, int cmd)
116 {
117 	uchar *p, *pe;
118 	int r, rprev = NONE, rx, over = 0, font;
119 	char buf[16];
120 
121 	p = (uchar *)e.start;
122 	pe = (uchar *)e.end;
123 	curentry = e;
124 	if(cmd == 'h')
125 		outinhibit = 1;
126 	while(p < pe){
127 		if(cmd == 'r'){
128 			outchar(*p++);
129 			continue;
130 		}
131 		switch(r = intab[*p++]){	/* assign = */
132 		case TAGS:
133 			if(rprev != NONE){
134 				outrune(rprev);
135 				rprev = NONE;
136 			}
137 			p = reach(p, 0x06);
138 			font = tag[0];
139 			if(cmd == 'h')
140 				outinhibit = (font != 'h');
141 			break;
142 
143 		case TAGE:	/* an extra one */
144 			break;
145 
146 		case SPCS:
147 			p = reach(p, 0xba);
148 			r = looknassoc(numtab, asize(numtab), strtol(tag,0,0));
149 			if(r < 0){
150 				if(rprev != NONE){
151 					outrune(rprev);
152 					rprev = NONE;
153 				}
154 				sprint(buf, "\\N'%s'", tag);
155 				outchars(buf);
156 				break;
157 			}
158 			/* else fall through */
159 
160 		default:
161 			if(over){
162 				rx = looknassoc(overtab, asize(overtab), r);
163 				if(rx > 0)
164 					rx = liglookup(rx, rprev);
165 				if(rx > 0 && rx != NONE)
166 					outrune(rx);
167 				else{
168 					outrune(rprev);
169 					if(r == ':')
170 						outrune(L'¨');
171 					else{
172 						outrune(L'^');
173 						outrune(r);
174 					}
175 				}
176 				over = 0;
177 				rprev = NONE;
178 			}else if(r == '^'){
179 				over = 1;
180 			}else{
181 				if(rprev != NONE)
182 					outrune(rprev);
183 				rprev = r;
184 			}
185 		}
186 
187 	}
188 	if(rprev != NONE)
189 		outrune(rprev);
190 	if(cmd == 'h')
191 		outinhibit = 0;
192 	outnl(0);
193 }
194 
195 long
pcollgnextoff(long fromoff)196 pcollgnextoff(long fromoff)
197 {
198 	int c, state = 0, defoff = -1;
199 
200 	if(Bseek(bdict, fromoff, 0) < 0)
201 		return -1;
202 	while((c = Bgetc(bdict)) >= 0){
203 		if(c == '\r')
204 			defoff = Boffset(bdict);
205 		switch(state){
206 		case 0:
207 			if(c == 0x05)
208 				state = 1;
209 			break;
210 		case 1:
211 			if(c == 'h')
212 				state = 2;
213 			else
214 				state = 0;
215 			break;
216 		case 2:
217 			if(c == 0x06)
218 				return (Boffset(bdict)-3);
219 			else
220 				state = 0;
221 			break;
222 		}
223 	}
224 	return defoff;
225 }
226 
227 void
pcollgprintkey(void)228 pcollgprintkey(void)
229 {
230 	Bprint(bout, "No pronunciation key yet\n");
231 }
232 
233 static uchar *
reach(uchar * p,int tagchar)234 reach(uchar *p, int tagchar)
235 {
236 	int c; char *q=tag;
237 
238 	while(p < (uchar *)curentry.end){
239 		c = *p++;
240 		if(c == tagchar)
241 			break;
242 		*q++ = c;
243 		if(q >= &tag[sizeof tag-1])
244 			break;
245 	}
246 	*q = 0;
247 	return p;
248 }
249