dots

Personal dotfiles
git clone git://git.gormless.xyz/dots.git
Log | Files | Refs

robert.c (7131B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include "dict.h"
      5 
      6 /*
      7  * Robert Électronique.
      8  */
      9 
     10 enum
     11 {
     12 	CIT = MULTIE+1,	/* citation ptr followed by long int and ascii label */
     13 	BROM,		/* bold roman */
     14 	ITON,		/* start italic */
     15 	ROM,		/* roman */
     16 	SYM,		/* symbol font? */
     17 	HEL,		/* helvetica */
     18 	BHEL,		/* helvetica bold */
     19 	SMALL,		/* smaller? */
     20 	ITOFF,		/* end italic */
     21 	SUP,		/* following character is superscript */
     22 	SUB		/* following character is subscript */
     23 };
     24 
     25 static Rune intab[256] = {
     26 	/*0*/	/*1*/	/*2*/	/*3*/	/*4*/	/*5*/	/*6*/	/*7*/
     27 /*00*/	NONE,	0x263a,	0x263b,	0x2665,	0x2666,	0x2663,	0x2660,	0x2022,
     28 	0x25d8,	0x298,'\n',	0x2642,	0x2640,	0x266a,	0x266b,	0x203b,
     29 /*10*/	0x21e8,	0x21e6,	0x2195,	0x203c,	0xb6,	0xa7,	0x2043,	0x21a8,
     30 	0x2191,	0x2193,	0x2192,	0x2190,	0x2319,	0x2194,	0x25b4,	0x25be,
     31 /*20*/	0x20,	0x21,	0x22,	0x23,	0x24,	0x25,	0x26,'\'',
     32 	0x28,	0x29,	0x2a,	0x2b,	0x2c,	0x2d,	0x2e,	0x2f,
     33 /*30*/	0x30,	0x31,	0x32,	0x33,	0x34,	0x35,	0x36,	0x37,
     34 	0x38,	0x39,	0x3a,	0x3b,	0x3c,	0x3d,	0x3e,	0x3f,
     35 /*40*/	0x40,	0x41,	0x42,	0x43,	0x44,	0x45,	0x46,	0x47,
     36 	0x48,	0x49,	0x4a,	0x4b,'L',	0x4d,	0x4e,	0x4f,
     37 /*50*/	0x50,	0x51,	0x52,	0x53,	0x54,	0x55,	0x56,	0x57,
     38 	0x58,	0x59,	0x5a,	0x5b,'\\',	0x5d,	0x5e,	0x5f,
     39 /*60*/	0x60,	0x61,	0x62,	0x63,	0x64,	0x65,	0x66,	0x67,
     40 	0x68,	0x69,	0x6a,	0x6b,	0x6c,	0x6d,	0x6e,	0x6f,
     41 /*70*/	0x70,	0x71,	0x72,	0x73,	0x74,	0x75,	0x76,	0x77,
     42 	0x78,	0x79,	0x7a,	0x7b,	0x7c,	0x7d,	0x7e,	0x7f,
     43 /*80*/	0xc7,	0xfc,	0xe9,	0xe2,	0xe4,	0xe0,	0xe5,	0xe7,
     44 	0xea,	0xeb,	0xe8,	0xef,	0xee,	0xec,	0xc4,	0xc5,
     45 /*90*/	0xc9,	0xe6,	0xc6,	0xf4,	0xf6,	0xf2,	0xfb,	0xf9,
     46 	0xff,	0xd6,	0xdc,	0xa2,	0xa3,	0xa5,	0x20a7,	0x283,
     47 /*a0*/	0xe1,	0xed,	0xf3,	0xfa,	0xf1,	0xd1,	0xaa,	0xba,
     48 	0xbf,	0x2310,	0xac,	0xbd,	0xbc,	0xa1,	0xab,	0xbb,
     49 /*b0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     50 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     51 /*c0*/	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     52 	CIT,	BROM,	NONE,	ITON,	ROM,	SYM,	HEL,	BHEL,
     53 /*d0*/	NONE,	SMALL,	ITOFF,	SUP,	SUB,	NONE,	NONE,	NONE,
     54 	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,	NONE,
     55 /*e0*/	0x3b1,	0xdf,	0x3b3,	0x3c0,	0x3a3,	0x3c3,	0xb5,	0x3c4,
     56 	0x3a6,	0x398,	0x3a9,	0x3b4,	0x221e,	0xd8,	0x3b5,	0x2229,
     57 /*f0*/	0x2261,	0xb1,	0x2265,	0x2264,	0x2320,	0x2321,	0xf7,	0x2248,
     58 	0xb0,	0x2219,	0xb7,	0x221a,	0x207f,	0xb2,	0x220e,	0xa0
     59 };
     60 
     61 static Rune suptab[256];
     62 
     63 static void
     64 initsuptab(void)
     65 {
     66 	suptab['0']= 0x2070;	suptab['1']= 0x2071;	suptab['2']= 0x2072;	suptab['3']= 0x2073;
     67 	suptab['4']= 0x2074;	suptab['5']= 0x2075;	suptab['6']= 0x2076;	suptab['7']= 0x2077;
     68 	suptab['8']= 0x2078;	suptab['9']= 0x2079;	suptab['+']= 0x207a;	suptab['-']= 0x207b;
     69 	suptab['=']= 0x207c;	suptab['(']= 0x207d;	suptab[')']= 0x207e;	suptab['a']= 0xaa;
     70 	suptab['n']= 0x207f;	suptab['o']= 0xba;
     71 }
     72 
     73 static Rune subtab[256];
     74 
     75 static void
     76 initsubtab(void)
     77 {
     78 	subtab['0']= 0x2080;	subtab['1']= 0x2081;	subtab['2']= 0x2082;	subtab['3']= 0x2083;
     79 	subtab['4']= 0x2084;	subtab['5']= 0x2085;	subtab['6']= 0x2086;	subtab['7']= 0x2087;
     80 	subtab['8']= 0x2088;	subtab['9']= 0x2089;	subtab['+']= 0x208a;	subtab['-']= 0x208b;
     81 	subtab['=']= 0x208c;	subtab['(']= 0x208d;	subtab[')']= 0x208e;
     82 }
     83 
     84 #define	GSHORT(p)	(((p)[0]<<8) | (p)[1])
     85 #define	GLONG(p)	(((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])
     86 
     87 static char	cfile[] = "robert/cits.rob";
     88 static char	dfile[] = "robert/defs.rob";
     89 static char	efile[] = "robert/etym.rob";
     90 static char	kfile[] = "robert/_phon";
     91 
     92 static Biobuf *	cb;
     93 static Biobuf *	db;
     94 static Biobuf *	eb;
     95 
     96 static Biobuf *	Bouvrir(char*);
     97 static void	citation(int, int);
     98 static void	robertprintentry(Entry*, Entry*, int);
     99 
    100 void
    101 robertindexentry(Entry e, int cmd)
    102 {
    103 	uchar *p = (uchar *)e.start;
    104 	long ea, el, da, dl, fa;
    105 	Entry def, etym;
    106 
    107 	ea = GLONG(&p[0]);
    108 	el = GSHORT(&p[4]);
    109 	da = GLONG(&p[6]);
    110 	dl = GSHORT(&p[10]);
    111 	fa = GLONG(&p[12]);
    112 	USED(fa);
    113 
    114 	if(db == 0)
    115 		db = Bouvrir(dfile);
    116 	def.start = malloc(dl+1);
    117 	def.end = def.start + dl;
    118 	def.doff = da;
    119 	Bseek(db, da, 0);
    120 	Bread(db, def.start, dl);
    121 	*def.end = 0;
    122 	if(cmd == 'h'){
    123 		robertprintentry(&def, 0, cmd);
    124 	}else{
    125 		if(eb == 0)
    126 			eb = Bouvrir(efile);
    127 		etym.start = malloc(el+1);
    128 		etym.end = etym.start + el;
    129 		etym.doff = ea;
    130 		Bseek(eb, ea, 0);
    131 		Bread(eb, etym.start, el);
    132 		*etym.end = 0;
    133 		robertprintentry(&def, &etym, cmd);
    134 		free(etym.start);
    135 	}
    136 	free(def.start);
    137 }
    138 
    139 static void
    140 robertprintentry(Entry *def, Entry *etym, int cmd)
    141 {
    142 	uchar *p, *pe;
    143 	Rune r; int c, n;
    144 	int baseline = 0;
    145 	int lineno = 0;
    146 	int cit = 0;
    147 
    148 	if(suptab['0'] == 0)
    149 		initsuptab();
    150 	if(subtab['0'] == 0)
    151 		initsubtab();
    152 
    153 	p = (uchar *)def->start;
    154 	pe = (uchar *)def->end;
    155 	while(p < pe){
    156 		if(cmd == 'r'){
    157 			outchar(*p++);
    158 			continue;
    159 		}
    160 		c = *p++;
    161 		switch(r = intab[c]){	/* assign = */
    162 		case BROM:
    163 		case ITON:
    164 		case ROM:
    165 		case SYM:
    166 		case HEL:
    167 		case BHEL:
    168 		case SMALL:
    169 		case ITOFF:
    170 		case NONE:
    171 			if(debug)
    172 				outprint("\\%.2ux", c);
    173 			baseline = 0;
    174 			break;
    175 
    176 		case SUP:
    177 			baseline = 1;
    178 			break;
    179 
    180 		case SUB:
    181 			baseline = -1;
    182 			break;
    183 
    184 		case CIT:
    185 			n = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
    186 			p += 4;
    187 			if(debug)
    188 				outprint("[%d]", n);
    189 			while(*p == ' ' || ('0'<=*p && *p<='9') || *p == '.'){
    190 				if(debug)
    191 					outchar(*p);
    192 				++p;
    193 			}
    194 			++cit;
    195 			outnl(2);
    196 			citation(n, cmd);
    197 			baseline = 0;
    198 			break;
    199 
    200 		case '\n':
    201 			outnl(0);
    202 			baseline = 0;
    203 			++lineno;
    204 			break;
    205 
    206 		default:
    207 			if(baseline > 0 && r < nelem(suptab))
    208 				r = suptab[r];
    209 			else if(baseline < 0 && r < nelem(subtab))
    210 				r = subtab[r];
    211 			if(cit){
    212 				outchar('\n');
    213 				cit = 0;
    214 			}
    215 			outrune(r);
    216 			baseline = 0;
    217 			break;
    218 		}
    219 		if(r == '\n'){
    220 			if(cmd == 'h')
    221 				break;
    222 			if(lineno == 1 && etym)
    223 				robertprintentry(etym, 0, cmd);
    224 		}
    225 	}
    226 	outnl(0);
    227 }
    228 
    229 static void
    230 citation(int addr, int cmd)
    231 {
    232 	Entry cit;
    233 
    234 	if(cb == 0)
    235 		cb = Bouvrir(cfile);
    236 	Bseek(cb, addr, 0);
    237 	cit.start = Brdline(cb, 0xc8);
    238 	cit.end = cit.start + Blinelen(cb) - 1;
    239 	cit.doff = addr;
    240 	*cit.end = 0;
    241 	robertprintentry(&cit, 0, cmd);
    242 }
    243 
    244 long
    245 robertnextoff(long fromoff)
    246 {
    247 	return (fromoff & ~15) + 16;
    248 }
    249 
    250 void
    251 robertprintkey(void)
    252 {
    253 	Biobuf *db;
    254 	char *l;
    255 
    256 	db = Bouvrir(kfile);
    257 	while(l = Brdline(db, '\n'))	/* assign = */
    258 		Bwrite(bout, l, Blinelen(db));
    259 	Bterm(db);
    260 }
    261 
    262 void
    263 robertflexentry(Entry e, int cmd)
    264 {
    265 	uchar *p, *pe;
    266 	Rune r; int c;
    267 	int lineno = 1;
    268 
    269 	p = (uchar *)e.start;
    270 	pe = (uchar *)e.end;
    271 	while(p < pe){
    272 		if(cmd == 'r'){
    273 			Bputc(bout, *p++);
    274 			continue;
    275 		}
    276 		c = *p++;
    277 		r = intab[c];
    278 		if(r == '$')
    279 			r = '\n';
    280 		if(r == '\n'){
    281 			++lineno;
    282 			if(cmd == 'h' && lineno > 2)
    283 				break;
    284 		}
    285 		if(cmd == 'h' && lineno < 2)
    286 			continue;
    287 		if(r > MULTIE){
    288 			if(debug)
    289 				Bprint(bout, "\\%.2ux", c);
    290 			continue;
    291 		}
    292 		if(r < Runeself)
    293 			Bputc(bout, r);
    294 		else
    295 			Bputrune(bout, r);
    296 	}
    297 	outnl(0);
    298 }
    299 
    300 long
    301 robertnextflex(long fromoff)
    302 {
    303 	int c;
    304 
    305 	if(Bseek(bdict, fromoff, 0) < 0)
    306 		return -1;
    307 	while((c = Bgetc(bdict)) >= 0){
    308 		if(c == '$')
    309 			return Boffset(bdict);
    310 	}
    311 	return -1;
    312 }
    313 
    314 static Biobuf *
    315 Bouvrir(char *fichier)
    316 {
    317 	Biobuf *db;
    318 
    319 	fichier = dictfile(fichier);
    320 	db = Bopen(fichier, OREAD);
    321 	if(db == 0){
    322 		fprint(2, "%s: impossible d'ouvrir %s: %r\n", argv0, fichier);
    323 		exits("ouvrir");
    324 	}
    325 	return db;
    326 }