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