Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
228
pcollgprintkey(void)
229
{
230
	Bprint(bout, "No pronunciation key yet\n");
231
}
232
 
233
static uchar *
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
}