plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

pcollinsg.c (5094B)


      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=0x69,	/* 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,	0x20,	NONE,	NONE,
     43 /*10*/	NONE,	0x2d,	0x20,	0x20,	NONE,	NONE,	NONE,	NONE,
     44 	0x20,	NONE,	NONE,	NONE,	0x20,	NONE,	NONE,	0x2d,
     45 /*20*/	0x20,	0x21,	0x22,	0x23,	0x24,	0x25,	0x26,	'\'',
     46 	0x28,	0x29,	0x2a,	0x2b,	0x2c,	0x2d,	0x2e,	0x2f,
     47 /*30*/  0x30,	0x31,	0x32,	0x33,	0x34,	0x35,	0x36,	0x37,
     48 	0x38,	0x39,	0x3a,	0x3b,	0x3c,	0x3d,	0x3e,	0x3f,
     49 /*40*/  0x40,	0x41,	0x42,	0x43,	0x44,	0x45,	0x46,	0x47,
     50 	0x48,	0x49,	0x4a,	0x4b,'L',	0x4d,	0x4e,	0x4f,
     51 /*50*/	0x50,	0x51,	0x52,	0x53,	0x54,	0x55,	0x56,	0x57,
     52 	0x58,	0x59,	0x5a,	0x5b,'\\',	0x5d,	0x5e,	0x5f,
     53 /*60*/	0x60,	0x61,	0x62,	0x63,	0x64,	0x65,	0x66,	0x67,
     54 	0x68,	0x69,	0x6a,	0x6b,	0x6c,	0x6d,	0x6e,	0x6f,
     55 /*70*/	0x70,	0x71,	0x72,	0x73,	0x74,	0x75,	0x76,	0x77,
     56 	0x78,	0x79,	0x7a,	0x7b,	0x7c,	0x7d,	0x7e,	NONE,
     57 /*80*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     58 	NONE,	NONE,	0x20,	NONE,	NONE,	NONE,	NONE,	NONE,
     59 /*90*/	0xdf,	0xe6,	NONE,	MOE,	NONE,	NONE,	NONE,	0xf8,
     60 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     61 /*A0*/	NONE,	NONE,	0x22,	0xa3,	NONE,	NONE,	NONE,	NONE,
     62 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     63 /*B0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	0x7e,
     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*/	0x20,	0x20,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     72 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE
     73 };
     74 
     75 static Nassoc numtab[] = {
     76 	{1,	0x2b},
     77 	{4,	0x3d},
     78 	{7,	0xb0},
     79 	{11,	0x2248},
     80 	{69,	0x2666},
     81 	{114,	0xae},
     82 	{340,	0x25b},
     83 	{341,	0x254},
     84 	{342,	0x28c},
     85 	{343,	0x259},
     86 	{345,	0x292},
     87 	{346,	0x283},
     88 	{347,	0x275},
     89 	{348,	0x28a},
     90 	{349,	0x2c8},
     91 	{351,	0x26a},
     92 	{352,	0x25c},
     93 	{354,	0x251},
     94 	{355,	0x7e},
     95 	{356,	0x252},
     96 	{384,	0x273},
     97 	{445,	0xf0},	/* BUG -- should be script eth */
     98 };
     99 
    100 static Nassoc overtab[] = {
    101 	{0x2c,	LCED},
    102 	{0x2f,	LACU},
    103 	{0x3a,	LUML},
    104 	{'\\',	LGRV},
    105 	{0x5e,	LFRN},
    106 	{0x7e,	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(0xa8);
    171 					else{
    172 						outrune(0x5e);
    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 }