]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/dict/pcollinsg.c
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[plan9front.git] / sys / src / cmd / dict / pcollinsg.c
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 }