plan9fox/sys/src/cmd/dict/robert.c

315 lines
6.7 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <u.h>
#include <libc.h>
#include <bio.h>
#include "dict.h"
/*
* Robert Électronique.
*/
enum
{
CIT = MULTIE+1, /* citation ptr followed by long int and ascii label */
BROM, /* bold roman */
ITON, /* start italic */
ROM, /* roman */
SYM, /* symbol font? */
HEL, /* helvetica */
BHEL, /* helvetica bold */
SMALL, /* smaller? */
ITOFF, /* end italic */
SUP, /* following character is superscript */
SUB /* following character is subscript */
};
static Rune intab[256] = {
/*0*/ /*1*/ /*2*/ /*3*/ /*4*/ /*5*/ /*6*/ /*7*/
/*00*/ NONE, L'', L'', L'', L'', L'', L'', L'',
0x25d8, L'ʘ', L'\n', L'', L'', L'', 0x266b, L'',
/*10*/ L'', L'', L'', L'', L'', L'§', L'', L'',
L'', L'', L'', L'', L'', L'', 0x25b4, 0x25be,
/*20*/ L' ', L'!', L'"', L'#', L'$', L'%', L'&', L''',
L'(', L')', L'*', L'+', L',', L'-', L'.', L'/',
/*30*/ L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
L'8', L'9', L':', L';', L'<', L'=', L'>', L'?',
/*40*/ L'@', L'A', L'B', L'C', L'D', L'E', L'F', L'G',
L'H', L'I', L'J', L'K', L'L', L'M', L'N', L'O',
/*50*/ L'P', L'Q', L'R', L'S', L'T', L'U', L'V', L'W',
L'X', L'Y', L'Z', L'[', L'\\', L']', L'^', L'_',
/*60*/ L'`', L'a', L'b', L'c', L'd', L'e', L'f', L'g',
L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o',
/*70*/ L'p', L'q', L'r', L's', L't', L'u', L'v', L'w',
L'x', L'y', L'z', L'{', L'|', L'}', L'~', L'',
/*80*/ L'Ç', L'ü', L'é', L'â', L'ä', L'à', L'å', L'ç',
L'ê', L'ë', L'è', L'ï', L'î', L'ì', L'Ä', L'Å',
/*90*/ L'É', L'æ', L'Æ', L'ô', L'ö', L'ò', L'û', L'ù',
L'ÿ', L'Ö', L'Ü', L'¢', L'£', L'¥', L'', L'ʃ',
/*a0*/ L'á', L'í', L'ó', L'ú', L'ñ', L'Ñ', L'ª', L'º',
L'¿', L'', L'¬', L'½', L'¼', L'¡', L'«', L'»',
/*b0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
/*c0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
CIT, BROM, NONE, ITON, ROM, SYM, HEL, BHEL,
/*d0*/ NONE, SMALL, ITOFF, SUP, SUB, NONE, NONE, NONE,
NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE,
/*e0*/ L'α', L'ß', L'γ', L'π', L'Σ', L'σ', L'µ', L'τ',
L'Φ', L'Θ', L'Ω', L'δ', L'', L'Ø', L'ε', L'',
/*f0*/ L'', L'±', L'', L'', L'', L'', L'÷', L'',
L'°', L'', L'·', L'', L'', L'²', L'', L' ',
};
static Rune suptab[] = {
['0'] L'', ['1'] L'¹', ['2'] L'²', ['3'] L'³',
['4'] L'', ['5'] L'', ['6'] L'', ['7'] L'',
['8'] L'', ['9'] L'', ['+'] L'', ['-'] L'',
['='] L'', ['('] L'', [')'] L'', ['a'] L'ª',
['n'] L'', ['o'] L'º'
};
static Rune subtab[] = {
['0'] L'', ['1'] L'', ['2'] L'', ['3'] L'',
['4'] L'', ['5'] L'', ['6'] L'', ['7'] L'',
['8'] L'', ['9'] L'', ['+'] L'', ['-'] L'',
['='] L'', ['('] L'', [')'] L''
};
#define GSHORT(p) (((p)[0]<<8) | (p)[1])
#define GLONG(p) (((p)[0]<<24) | ((p)[1]<<16) | ((p)[2]<<8) | (p)[3])
static char cfile[] = "/lib/dict/robert/cits.rob";
static char dfile[] = "/lib/dict/robert/defs.rob";
static char efile[] = "/lib/dict/robert/etym.rob";
static char kfile[] = "/lib/dict/robert/_phon";
static Biobuf * cb;
static Biobuf * db;
static Biobuf * eb;
static Biobuf * Bouvrir(char*);
static void citation(int, int);
static void robertprintentry(Entry*, Entry*, int);
void
robertindexentry(Entry e, int cmd)
{
uchar *p = (uchar *)e.start;
long ea, el, da, dl, fa;
Entry def, etym;
ea = GLONG(&p[0]);
el = GSHORT(&p[4]);
da = GLONG(&p[6]);
dl = GSHORT(&p[10]);
fa = GLONG(&p[12]);
USED(fa);
if(db == 0)
db = Bouvrir(dfile);
if((def.start = malloc(dl+1)) == nil)
sysfatal("malloc: %r");
def.end = def.start + dl;
def.doff = da;
Bseek(db, da, 0);
Bread(db, def.start, dl);
*def.end = 0;
if(cmd == 'h'){
robertprintentry(&def, 0, cmd);
}else{
if(eb == 0)
eb = Bouvrir(efile);
if((etym.start = malloc(el+1)) == nil)
sysfatal("malloc: %r");
etym.end = etym.start + el;
etym.doff = ea;
Bseek(eb, ea, 0);
Bread(eb, etym.start, el);
*etym.end = 0;
robertprintentry(&def, &etym, cmd);
free(etym.start);
}
free(def.start);
}
static void
robertprintentry(Entry *def, Entry *etym, int cmd)
{
uchar *p, *pe;
Rune r; int c, n;
int baseline = 0;
int lineno = 0;
int cit = 0;
p = (uchar *)def->start;
pe = (uchar *)def->end;
while(p < pe){
if(cmd == 'r'){
outchar(*p++);
continue;
}
c = *p++;
switch(r = intab[c]){ /* assign = */
case BROM:
case ITON:
case ROM:
case SYM:
case HEL:
case BHEL:
case SMALL:
case ITOFF:
case NONE:
if(debug)
outprint("\\%.2ux", c);
baseline = 0;
break;
case SUP:
baseline = 1;
break;
case SUB:
baseline = -1;
break;
case CIT:
n = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
p += 4;
if(debug)
outprint("[%d]", n);
while(*p == ' ' || ('0'<=*p && *p<='9') || *p == '.'){
if(debug)
outchar(*p);
++p;
}
++cit;
outnl(2);
citation(n, cmd);
baseline = 0;
break;
case '\n':
outnl(0);
baseline = 0;
++lineno;
break;
default:
if(baseline > 0 && r < nelem(suptab))
r = suptab[r];
else if(baseline < 0 && r < nelem(subtab))
r = subtab[r];
if(cit){
outchar('\n');
cit = 0;
}
outrune(r);
baseline = 0;
break;
}
if(r == '\n'){
if(cmd == 'h')
break;
if(lineno == 1 && etym)
robertprintentry(etym, 0, cmd);
}
}
outnl(0);
}
static void
citation(int addr, int cmd)
{
Entry cit;
if(cb == 0)
cb = Bouvrir(cfile);
Bseek(cb, addr, 0);
cit.start = Brdline(cb, 0xc8);
cit.end = cit.start + Blinelen(cb) - 1;
cit.doff = addr;
*cit.end = 0;
robertprintentry(&cit, 0, cmd);
}
long
robertnextoff(long fromoff)
{
return (fromoff & ~15) + 16;
}
void
robertprintkey(void)
{
Biobuf *db;
char *l;
db = Bouvrir(kfile);
while(l = Brdline(db, '\n')) /* assign = */
Bwrite(bout, l, Blinelen(db));
Bterm(db);
}
void
robertflexentry(Entry e, int cmd)
{
uchar *p, *pe;
Rune r; int c;
int lineno = 1;
p = (uchar *)e.start;
pe = (uchar *)e.end;
while(p < pe){
if(cmd == 'r'){
Bputc(bout, *p++);
continue;
}
c = *p++;
r = intab[c];
if(r == '$')
r = '\n';
if(r == '\n'){
++lineno;
if(cmd == 'h' && lineno > 2)
break;
}
if(cmd == 'h' && lineno < 2)
continue;
if(r > MULTIE){
if(debug)
Bprint(bout, "\\%.2ux", c);
continue;
}
if(r < Runeself)
Bputc(bout, r);
else
Bputrune(bout, r);
}
outnl(0);
}
long
robertnextflex(long fromoff)
{
int c;
if(Bseek(bdict, fromoff, 0) < 0)
return -1;
while((c = Bgetc(bdict)) >= 0){
if(c == '$')
return Boffset(bdict);
}
return -1;
}
static Biobuf *
Bouvrir(char *fichier)
{
Biobuf *db;
db = Bopen(fichier, OREAD);
if(db == 0){
fprint(2, "%s: impossible d'ouvrir %s: %r\n", argv0, fichier);
exits("ouvrir");
}
return db;
}