Compare commits
17 Commits
84264e97d4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| b4fdc6e813 | |||
| b22bc95ad5 | |||
| d16b17b4c8 | |||
| d5d3c23f3e | |||
| 032c60e193 | |||
| 5653298bb1 | |||
| 97f897755f | |||
|
|
f5f88e8451 | ||
| db2b3eacad | |||
| 559b82ec9b | |||
|
|
9568893eaf | ||
| 874b941439 | |||
| 72063f84b7 | |||
| 97ae9b1709 | |||
| 436a49c3ca | |||
| e5ce5fd61e | |||
| 8a2ef65379 |
14
Makefile
14
Makefile
@@ -1,12 +1,12 @@
|
|||||||
CC = 9c
|
CC = 9c
|
||||||
LD = 9l
|
LD = 9l
|
||||||
CFLAGS = -Wall -Wextra -O2
|
CFLAGS = -Wall -Wextra -O2 -g
|
||||||
PROG = strans
|
PROG = strans
|
||||||
|
|
||||||
SRCS = $(wildcard *.c)
|
SRCS = $(wildcard *.c)
|
||||||
OBJS = $(SRCS:.c=.o)
|
OBJS = $(SRCS:.c=.o)
|
||||||
|
|
||||||
all: $(PROG)
|
all: $(PROG) xim bench
|
||||||
|
|
||||||
$(PROG): $(OBJS)
|
$(PROG): $(OBJS)
|
||||||
$(LD) -o $@ $(OBJS) -lthread -lString -lbio -lxcb -lm
|
$(LD) -o $@ $(OBJS) -lthread -lString -lbio -lxcb -lm
|
||||||
@@ -15,5 +15,13 @@ $(OBJS): dat.h fn.h ipc.h
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJS) $(PROG)
|
rm -f $(OBJS) $(PROG)
|
||||||
|
make -C xim/ clean
|
||||||
|
make -C bench/ clean
|
||||||
|
|
||||||
.PHONY: all clean
|
xim:
|
||||||
|
make -C xim/
|
||||||
|
|
||||||
|
bench:
|
||||||
|
make -C bench/
|
||||||
|
|
||||||
|
.PHONY: all clean xim bench
|
||||||
|
|||||||
74
README.md
74
README.md
@@ -1,18 +1,70 @@
|
|||||||
# strans
|
# strans
|
||||||
CJK input method
|
|
||||||
|
|
||||||
## Switch Key
|
An input method daemon for CJK text entry on X11.
|
||||||
| Key | Action |
|
|
||||||
|-----|--------|
|
Inspired by 9front's ktrans. Threads communicate via CSP channels.
|
||||||
| Ctrl+N | Hiragana |
|
|
||||||
| Ctrl+K | Katakana |
|
|
||||||
| Ctrl+S | Hangul |
|
|
||||||
| Ctrl+T | English |
|
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- plan9port
|
|
||||||
- libxcb
|
|
||||||
|
|
||||||
## Reference
|
- plan9port
|
||||||
|
- gtk+-3.0 (optional, for GTK IM module)
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
make
|
||||||
|
cd xim && make # XIM adapter
|
||||||
|
cd gtk && make docker && make install # GTK IM module
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
./strans map font &
|
||||||
|
|
||||||
|
For XIM apps:
|
||||||
|
|
||||||
|
./xim/strans-xim &
|
||||||
|
XMODIFIERS=@im=strans xterm
|
||||||
|
|
||||||
|
For GTK apps:
|
||||||
|
|
||||||
|
GTK_IM_MODULE=strans gedit
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Switch input modes with Ctrl + key:
|
||||||
|
|
||||||
|
N Hiragana
|
||||||
|
K Katakana
|
||||||
|
S Hangul
|
||||||
|
T English
|
||||||
|
V Vietnamese (Telex)
|
||||||
|
E Emoji
|
||||||
|
|
||||||
|
Type romanized input. Select candidates with 1-9 or arrow keys.
|
||||||
|
Tab or Enter to commit.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
Four threads communicate via CSP channels:
|
||||||
|
|
||||||
|
- [imthread](strans.c#L271): keystroke processing, transliteration
|
||||||
|
- [dictthread](dict.c#L38): dictionary lookup
|
||||||
|
- [drawthread](win.c#L133): preedit window rendering
|
||||||
|
- [srvthread](srv.c#L42): IPC via unix socket
|
||||||
|
|
||||||
|
Adapters (strans-xim, im-strans.so) bridge X11/GTK events.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
strans.c input method engine
|
||||||
|
dict.c dictionary queries
|
||||||
|
win.c xcb window management
|
||||||
|
font.c truetype rendering (stb_truetype)
|
||||||
|
map/ transliteration tables
|
||||||
|
font/ bundled CJK fonts
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
- https://git.9front.org/plan9front/plan9front/HEAD/info.html
|
- https://git.9front.org/plan9front/plan9front/HEAD/info.html
|
||||||
- https://np.mkv.li/kor/9front-ktrans-%ED%95%9C%EA%B8%80-%EB%98%91%EB%B0%94%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0/
|
- https://np.mkv.li/kor/9front-ktrans-%ED%95%9C%EA%B8%80-%EB%98%91%EB%B0%94%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0/
|
||||||
|
- https://en.wikipedia.org/wiki/Telex_(input_method)
|
||||||
|
- https://gist.github.com/hieuthi/0f5adb7d3f79e7fb67e0e499004bf558
|
||||||
|
|||||||
23
bench.sh
Executable file
23
bench.sh
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
pkill strans
|
||||||
|
pkill strans-xim
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
./strans map font &
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# warm up glyph cache
|
||||||
|
./bench/bench bench/bench.keys 100
|
||||||
|
echo "cache warmed up"
|
||||||
|
|
||||||
|
STRANS_PID=$(pgrep -x strans)
|
||||||
|
perf record -g -o bench/perf.data -p "$STRANS_PID" &
|
||||||
|
PERF_PID=$!
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
./bench/bench bench/bench.keys 100
|
||||||
|
|
||||||
|
kill -INT $PERF_PID
|
||||||
|
wait $PERF_PID 2>/dev/null
|
||||||
|
pkill strans
|
||||||
8
bench/Makefile
Normal file
8
bench/Makefile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
CC = cc
|
||||||
|
CFLAGS = -Wall -O2
|
||||||
|
|
||||||
|
bench: main.c
|
||||||
|
$(CC) $(CFLAGS) -o $@ main.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f bench
|
||||||
BIN
bench/bench
Executable file
BIN
bench/bench
Executable file
Binary file not shown.
30
bench/bench.keys
Normal file
30
bench/bench.keys
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
^ntoukyounotenki^Ryoidesu^R
|
||||||
|
konpyuutanopuroguramu^B^B^Bgramu^R
|
||||||
|
nihongowobenkyoushiteimasu^R
|
||||||
|
sakuranoshanohana^B^B^B^Bhanagasaiteiru^R
|
||||||
|
kaigi^Ekyounokaigi^R
|
||||||
|
ashitahaiitenkininarudeshou^R
|
||||||
|
^sdkssudgktpdy^Rgksrmfekfqnxm^R
|
||||||
|
vmfhrrh^Btprtmxm^Rdufrlavldml^R
|
||||||
|
dmlrlwkekfwprtm^R
|
||||||
|
gksrnl^B^B^Bdlfp^R
|
||||||
|
answkd^Eanswkd^R
|
||||||
|
qkrtlwkf^B^B^Bwkfgkf^R
|
||||||
|
^thello world^R
|
||||||
|
the quick brown fox jumps over the lazy dog^R
|
||||||
|
programming is fun^R
|
||||||
|
^vVietNam^Rxinchaobancokhoekhong^R
|
||||||
|
toidilambaitap^B^B^Bbaitap^R
|
||||||
|
hoctiengviet^R
|
||||||
|
^nkaishanitsuutomeshiteimasu^R
|
||||||
|
tanaboraguukoudesu^B^B^B^B^Bkoudesu^R
|
||||||
|
^srhksrnrdlTkfgkwl^R
|
||||||
|
answkddkssud^B^Bdkssud^R
|
||||||
|
wnsdydgktpdy^R
|
||||||
|
^vtoidenlopcuahang^R
|
||||||
|
motngaymoiconduong^R
|
||||||
|
^thigh performance input method^R
|
||||||
|
^nnyuuryokuhouhou^R
|
||||||
|
tesutonosuuretsu^R
|
||||||
|
^sxkfldzmsdml^R
|
||||||
|
qhfmfjxm^R
|
||||||
168
bench/main.c
Normal file
168
bench/main.c
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Kback = 0xf008,
|
||||||
|
Kret = 0xf00d,
|
||||||
|
Kesc = 0xf01b,
|
||||||
|
Mctrl = 1<<2,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Key Key;
|
||||||
|
struct Key {
|
||||||
|
int k;
|
||||||
|
int mod;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Key *keys;
|
||||||
|
static int nkeys;
|
||||||
|
static int fd;
|
||||||
|
|
||||||
|
static void
|
||||||
|
die(char *msg)
|
||||||
|
{
|
||||||
|
perror(msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addkey(int k, int mod)
|
||||||
|
{
|
||||||
|
static int cap;
|
||||||
|
|
||||||
|
if(nkeys >= cap){
|
||||||
|
cap = cap ? cap * 2 : 256;
|
||||||
|
keys = realloc(keys, cap * sizeof(Key));
|
||||||
|
if(!keys)
|
||||||
|
die("realloc");
|
||||||
|
}
|
||||||
|
keys[nkeys].k = k;
|
||||||
|
keys[nkeys].mod = mod;
|
||||||
|
nkeys++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
loadkeys(char *file)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
f = fopen(file, "r");
|
||||||
|
if(!f)
|
||||||
|
die(file);
|
||||||
|
while((c = fgetc(f)) != EOF){
|
||||||
|
if(c == '\n' || c == '\r')
|
||||||
|
continue;
|
||||||
|
if(c != '^'){
|
||||||
|
addkey(c, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
c = fgetc(f);
|
||||||
|
if(c == EOF)
|
||||||
|
break;
|
||||||
|
switch(c){
|
||||||
|
case 'B':
|
||||||
|
addkey(Kback, 0);
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
addkey(Kret, 0);
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
addkey(Kesc, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
addkey(c, Mctrl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dial(void)
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if(fd < 0)
|
||||||
|
die("socket");
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
snprintf(addr.sun_path, sizeof(addr.sun_path),
|
||||||
|
"/tmp/strans.%d", getuid());
|
||||||
|
if(connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
|
||||||
|
die("connect");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sendkey(int key, int mod)
|
||||||
|
{
|
||||||
|
unsigned char req[4];
|
||||||
|
|
||||||
|
req[0] = 0;
|
||||||
|
req[1] = mod;
|
||||||
|
req[2] = key & 0xff;
|
||||||
|
req[3] = (key >> 8) & 0xff;
|
||||||
|
if(write(fd, req, 4) != 4)
|
||||||
|
die("write");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
readresp(void)
|
||||||
|
{
|
||||||
|
unsigned char buf[256];
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if(read(fd, buf, 2) != 2)
|
||||||
|
return -1;
|
||||||
|
n = buf[1];
|
||||||
|
if(n > 0 && read(fd, buf + 2, n) != n)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double
|
||||||
|
now(void)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
return ts.tv_sec + ts.tv_nsec * 1e-9;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, j, niter;
|
||||||
|
double t0, t1, dt;
|
||||||
|
|
||||||
|
if(argc < 2){
|
||||||
|
fprintf(stderr, "usage: bench file [niter]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadkeys(argv[1]);
|
||||||
|
niter = argc > 2 ? atoi(argv[2]) : 1000;
|
||||||
|
dial();
|
||||||
|
t0 = now();
|
||||||
|
for(i = 0; i < niter; i++)
|
||||||
|
for(j = 0; j < nkeys; j++){
|
||||||
|
sendkey(keys[j].k, keys[j].mod);
|
||||||
|
if(readresp() < 0){
|
||||||
|
fprintf(stderr, "failed at iter %d key %d\n", i, j);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t1 = now();
|
||||||
|
dt = t1 - t0;
|
||||||
|
printf("%d iters x %d keys = %d keys\n", niter, nkeys, niter * nkeys);
|
||||||
|
printf("%.3f ms total, %.3f us/key, %.3f us/iter\n",
|
||||||
|
dt * 1000, dt * 1e6 / (niter * nkeys), dt * 1e6 / niter);
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
bench/perf.data
Normal file
BIN
bench/perf.data
Normal file
Binary file not shown.
BIN
bench/perf.data.old
Normal file
BIN
bench/perf.data.old
Normal file
Binary file not shown.
42
dat.h
42
dat.h
@@ -13,10 +13,12 @@ enum
|
|||||||
LangJP = 0x0e,
|
LangJP = 0x0e,
|
||||||
LangJPK = 0x0b,
|
LangJPK = 0x0b,
|
||||||
LangKO = 0x13,
|
LangKO = 0x13,
|
||||||
|
LangEMOJI = 0x05,
|
||||||
|
LangVI = 0x16,
|
||||||
|
|
||||||
Fontsz = 32,
|
Fontsz = 32,
|
||||||
Fontbase = 4,
|
Fontbase = 4,
|
||||||
Nglyphs = 65536,
|
Nglyphs = 0x20000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@@ -43,7 +45,6 @@ typedef struct Emit Emit;
|
|||||||
struct Emit
|
struct Emit
|
||||||
{
|
{
|
||||||
int eat;
|
int eat;
|
||||||
int flush;
|
|
||||||
Str s;
|
Str s;
|
||||||
Str next;
|
Str next;
|
||||||
Str dict;
|
Str dict;
|
||||||
@@ -56,8 +57,27 @@ struct Hnode
|
|||||||
int next;
|
int next;
|
||||||
char *key;
|
char *key;
|
||||||
int klen;
|
int klen;
|
||||||
char *kana;
|
char *val;
|
||||||
int kanalen;
|
int vlen;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Tnode Tnode;
|
||||||
|
struct Tnode
|
||||||
|
{
|
||||||
|
int child;
|
||||||
|
int sibling;
|
||||||
|
char c;
|
||||||
|
char *val;
|
||||||
|
int vlen;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Trie Trie;
|
||||||
|
struct Trie
|
||||||
|
{
|
||||||
|
int root;
|
||||||
|
Tnode *nodes;
|
||||||
|
int n;
|
||||||
|
int cap;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Hmap Hmap;
|
typedef struct Hmap Hmap;
|
||||||
@@ -77,15 +97,17 @@ struct Lang
|
|||||||
int lang;
|
int lang;
|
||||||
char *mapname;
|
char *mapname;
|
||||||
char *dictname;
|
char *dictname;
|
||||||
Hmap *map;
|
|
||||||
Hmap *dict;
|
|
||||||
Emit (*trans)(Im*, Rune);
|
Emit (*trans)(Im*, Rune);
|
||||||
|
void (*back)(Im*);
|
||||||
|
void (*dictq)(Im*);
|
||||||
|
Trie *map;
|
||||||
|
Hmap *dict;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Im
|
struct Im
|
||||||
{
|
{
|
||||||
Lang *l;
|
Lang *l;
|
||||||
Str line;
|
Str pre;
|
||||||
Str kouho[Maxkouho];
|
Str kouho[Maxkouho];
|
||||||
int nkouho;
|
int nkouho;
|
||||||
int sel;
|
int sel;
|
||||||
@@ -94,8 +116,8 @@ struct Im
|
|||||||
typedef struct Drawcmd Drawcmd;
|
typedef struct Drawcmd Drawcmd;
|
||||||
struct Drawcmd
|
struct Drawcmd
|
||||||
{
|
{
|
||||||
Str preedit;
|
Str pre;
|
||||||
Str kouho[Maxkouho];
|
Str kouho[Maxdisp];
|
||||||
int nkouho;
|
int nkouho;
|
||||||
int sel;
|
int sel;
|
||||||
};
|
};
|
||||||
@@ -112,7 +134,7 @@ typedef struct Dictreq Dictreq;
|
|||||||
struct Dictreq
|
struct Dictreq
|
||||||
{
|
{
|
||||||
Str key;
|
Str key;
|
||||||
Str line;
|
Str pre;
|
||||||
int lang;
|
int lang;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
16
dict.c
16
dict.c
@@ -2,7 +2,7 @@
|
|||||||
#include "fn.h"
|
#include "fn.h"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dictlkup(Dictreq *req, Dictres *res)
|
dictlookup(Dictreq *req, Dictres *res)
|
||||||
{
|
{
|
||||||
Lang *l;
|
Lang *l;
|
||||||
Hmap *dict;
|
Hmap *dict;
|
||||||
@@ -18,10 +18,10 @@ dictlkup(Dictreq *req, Dictres *res)
|
|||||||
if(dict == nil)
|
if(dict == nil)
|
||||||
return;
|
return;
|
||||||
n = hmapget(dict, &req->key);
|
n = hmapget(dict, &req->key);
|
||||||
if(n == nil || n->kanalen == 0)
|
if(n == nil || n->vlen == 0)
|
||||||
return;
|
return;
|
||||||
p = n->kana;
|
p = n->val;
|
||||||
e = p + n->kanalen;
|
e = p + n->vlen;
|
||||||
while(res->nkouho < Maxkouho && p < e){
|
while(res->nkouho < Maxkouho && p < e){
|
||||||
sp = p;
|
sp = p;
|
||||||
while(p < e && *p != ' ')
|
while(p < e && *p != ' ')
|
||||||
@@ -46,14 +46,14 @@ dictthread(void*)
|
|||||||
break;
|
break;
|
||||||
while(channbrecv(dictreqc, &req) > 0)
|
while(channbrecv(dictreqc, &req) > 0)
|
||||||
;
|
;
|
||||||
dictlkup(&req, &res);
|
dictlookup(&req, &res);
|
||||||
res.key = req.line;
|
res.key = req.pre;
|
||||||
chansend(dictresc, &res);
|
chansend(dictresc, &res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hmap*
|
static Hmap*
|
||||||
opendict(char *path)
|
dictopen(char *path)
|
||||||
{
|
{
|
||||||
Hmap *h;
|
Hmap *h;
|
||||||
Biobuf *b;
|
Biobuf *b;
|
||||||
@@ -96,7 +96,7 @@ dictinit(char *dir)
|
|||||||
if(langs[i].dictname == nil)
|
if(langs[i].dictname == nil)
|
||||||
continue;
|
continue;
|
||||||
snprint(path, sizeof(path), "%s/%s.dict", dir, langs[i].dictname);
|
snprint(path, sizeof(path), "%s/%s.dict", dir, langs[i].dictname);
|
||||||
langs[i].dict = opendict(path);
|
langs[i].dict = dictopen(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
13
fn.h
13
fn.h
@@ -12,7 +12,11 @@ Rune slastr(Str*);
|
|||||||
Hmap* hmapalloc(int, int);
|
Hmap* hmapalloc(int, int);
|
||||||
int hmapset(Hmap**, Str*, Str*);
|
int hmapset(Hmap**, Str*, Str*);
|
||||||
Hnode* hmapget(Hmap*, Str*);
|
Hnode* hmapget(Hmap*, Str*);
|
||||||
int mapget(Hmap*, Str*, Str*);
|
int mapget(Trie*, Str*, Str*);
|
||||||
|
|
||||||
|
Trie* trieopen(char*);
|
||||||
|
char* trieget(Trie*, char*, int, int*);
|
||||||
|
int trielookup(Trie*, char*, int, char**, int*);
|
||||||
|
|
||||||
Lang* getlang(int);
|
Lang* getlang(int);
|
||||||
void mapinit(char*);
|
void mapinit(char*);
|
||||||
@@ -22,8 +26,11 @@ void dictthread(void*);
|
|||||||
|
|
||||||
void drawthread(void*);
|
void drawthread(void*);
|
||||||
void imthread(void*);
|
void imthread(void*);
|
||||||
Emit trans(Im*, Rune);
|
Emit transmap(Im*, Rune);
|
||||||
Emit jptrans(Im*, Rune);
|
Emit transko(Im*, Rune);
|
||||||
|
Emit transvi(Im*, Rune);
|
||||||
|
void backko(Im*);
|
||||||
|
void dictsend(Im*, Str*);
|
||||||
|
|
||||||
void srvthread(void*);
|
void srvthread(void*);
|
||||||
|
|
||||||
|
|||||||
92
font.c
92
font.c
@@ -10,9 +10,12 @@ struct Glyph
|
|||||||
int w, h, ox, oy;
|
int w, h, ox, oy;
|
||||||
};
|
};
|
||||||
|
|
||||||
static stbtt_fontinfo font;
|
enum { Maxfonts = 4 };
|
||||||
static uchar *fontdata;
|
|
||||||
static float scale;
|
static stbtt_fontinfo fonts[Maxfonts];
|
||||||
|
static uchar *fontdata[Maxfonts];
|
||||||
|
static float scale[Maxfonts];
|
||||||
|
static int nfonts;
|
||||||
static Glyph cache[Nglyphs];
|
static Glyph cache[Nglyphs];
|
||||||
static u32int blendtab[2][256];
|
static u32int blendtab[2][256];
|
||||||
|
|
||||||
@@ -28,25 +31,64 @@ blend(u32int bg, int a)
|
|||||||
return (r << 16) | (g << 8) | b;
|
return (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
fontinit(char *path)
|
loadfont(char *path)
|
||||||
{
|
{
|
||||||
int fd, a;
|
int fd;
|
||||||
long sz, n;
|
long sz, n;
|
||||||
|
|
||||||
|
if(nfonts >= Maxfonts)
|
||||||
|
die("too many fonts");
|
||||||
fd = open(path, OREAD);
|
fd = open(path, OREAD);
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
die("can't open font: %s", path);
|
die("can't open font: %s", path);
|
||||||
sz = seek(fd, 0, 2);
|
sz = seek(fd, 0, 2);
|
||||||
seek(fd, 0, 0);
|
seek(fd, 0, 0);
|
||||||
fontdata = emalloc(sz);
|
fontdata[nfonts] = emalloc(sz);
|
||||||
n = readn(fd, fontdata, sz);
|
n = readn(fd, fontdata[nfonts], sz);
|
||||||
close(fd);
|
close(fd);
|
||||||
if(n != sz)
|
if(n != sz)
|
||||||
die("can't read font: %s", path);
|
die("can't read font: %s", path);
|
||||||
if(!stbtt_InitFont(&font, fontdata, stbtt_GetFontOffsetForIndex(fontdata, 0)))
|
if(!stbtt_InitFont(&fonts[nfonts], fontdata[nfonts], stbtt_GetFontOffsetForIndex(fontdata[nfonts], 0)))
|
||||||
die("can't init font: %s", path);
|
die("can't init font: %s", path);
|
||||||
scale = stbtt_ScaleForPixelHeight(&font, Fontsz);
|
scale[nfonts] = stbtt_ScaleForPixelHeight(&fonts[nfonts], Fontsz);
|
||||||
|
nfonts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
isfont(char *name)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = strrchr(name, '.');
|
||||||
|
if(p == nil)
|
||||||
|
return 0;
|
||||||
|
return strcmp(p, ".ttf") == 0 || strcmp(p, ".otf") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fontinit(char *dir)
|
||||||
|
{
|
||||||
|
int fd, n, i, a;
|
||||||
|
Dir *d;
|
||||||
|
char path[256];
|
||||||
|
|
||||||
|
fd = open(dir, OREAD);
|
||||||
|
if(fd < 0)
|
||||||
|
die("can't open font dir: %s", dir);
|
||||||
|
n = dirreadall(fd, &d);
|
||||||
|
close(fd);
|
||||||
|
if(n < 0)
|
||||||
|
die("can't read font dir: %s", dir);
|
||||||
|
for(i = 0; i < n; i++){
|
||||||
|
if(isfont(d[i].name)){
|
||||||
|
snprint(path, sizeof path, "%s/%s", dir, d[i].name);
|
||||||
|
loadfont(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(d);
|
||||||
|
if(nfonts == 0)
|
||||||
|
die("no fonts in %s", dir);
|
||||||
for(a = 0; a < 256; a++){
|
for(a = 0; a < 256; a++){
|
||||||
blendtab[0][a] = blend(Colbg, a);
|
blendtab[0][a] = blend(Colbg, a);
|
||||||
blendtab[1][a] = blend(Colsel, a);
|
blendtab[1][a] = blend(Colsel, a);
|
||||||
@@ -57,28 +99,36 @@ void
|
|||||||
putfont(u32int *buf, int w, int h, int px, int py, Rune r)
|
putfont(u32int *buf, int w, int h, int px, int py, Rune r)
|
||||||
{
|
{
|
||||||
Glyph *g;
|
Glyph *g;
|
||||||
int i, j, x, y, a, sel;
|
int i, j, a, sel, f;
|
||||||
|
int y0, j0, j1, x0, i0, i1;
|
||||||
u32int *p;
|
u32int *p;
|
||||||
|
|
||||||
if(r >= Nglyphs)
|
if(r >= Nglyphs)
|
||||||
return;
|
return;
|
||||||
g = &cache[r];
|
g = &cache[r];
|
||||||
if(g->bmp == nil){
|
if(g->bmp == nil){
|
||||||
g->bmp = stbtt_GetCodepointBitmap(&font, scale, scale, r, &g->w, &g->h, &g->ox, &g->oy);
|
for(f = 0; f < nfonts; f++){
|
||||||
|
if(stbtt_FindGlyphIndex(&fonts[f], r) == 0)
|
||||||
|
continue;
|
||||||
|
g->bmp = stbtt_GetCodepointBitmap(&fonts[f], scale[f], scale[f], r, &g->w, &g->h, &g->ox, &g->oy);
|
||||||
|
if(g->bmp != nil)
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(g->bmp == nil)
|
if(g->bmp == nil)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(j = 0; j < g->h; j++){
|
|
||||||
y = py + j + g->oy + Fontsz - Fontbase;
|
y0 = py + g->oy + Fontsz - Fontbase;
|
||||||
if(y < 0 || y >= h)
|
j0 = y0 < 0 ? -y0 : 0;
|
||||||
continue;
|
j1 = y0 + g->h > h ? h - y0 : g->h;
|
||||||
for(i = 0; i < g->w; i++){
|
x0 = px + g->ox;
|
||||||
x = px + i + g->ox;
|
i0 = x0 < 0 ? -x0 : 0;
|
||||||
if(x < 0 || x >= w)
|
i1 = x0 + g->w > w ? w - x0 : g->w;
|
||||||
continue;
|
for(j = j0; j < j1; j++){
|
||||||
|
for(i = i0; i < i1; i++){
|
||||||
a = g->bmp[j * g->w + i];
|
a = g->bmp[j * g->w + i];
|
||||||
if(a > 0){
|
if(a > 0){
|
||||||
p = &buf[y * w + x];
|
p = &buf[(y0 + j) * w + x0 + i];
|
||||||
sel = (*p == Colsel) ? 1 : 0;
|
sel = (*p == Colsel) ? 1 : 0;
|
||||||
*p = blendtab[sel][a];
|
*p = blendtab[sel][a];
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
font/NotoEmoji-Regular.ttf
Normal file
BIN
font/NotoEmoji-Regular.ttf
Normal file
Binary file not shown.
BIN
font/NotoSans-Regular.ttf
Normal file
BIN
font/NotoSans-Regular.ttf
Normal file
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
NotoSansMonoCJKsc-Regular.otf
|
|
||||||
12
hash.c
12
hash.c
@@ -65,7 +65,7 @@ hmapget(Hmap *h, Str *key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
str2dup(Str *s)
|
sdup(Str *s)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
char *p;
|
char *p;
|
||||||
@@ -79,7 +79,7 @@ str2dup(Str *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
hmapset(Hmap **store, Str *key, Str *kana)
|
hmapset(Hmap **store, Str *key, Str *val)
|
||||||
{
|
{
|
||||||
Hnode *n;
|
Hnode *n;
|
||||||
uchar *v;
|
uchar *v;
|
||||||
@@ -116,14 +116,14 @@ hmapset(Hmap **store, Str *key, Str *kana)
|
|||||||
n = (Hnode*)v;
|
n = (Hnode*)v;
|
||||||
replace:
|
replace:
|
||||||
if(n->filled == 0){
|
if(n->filled == 0){
|
||||||
n->key = str2dup(key);
|
n->key = sdup(key);
|
||||||
n->klen = strlen(n->key);
|
n->klen = strlen(n->key);
|
||||||
n->filled = 1;
|
n->filled = 1;
|
||||||
}
|
}
|
||||||
n->next = next;
|
n->next = next;
|
||||||
if(kana->n > 0){
|
if(val->n > 0){
|
||||||
n->kana = str2dup(kana);
|
n->val = sdup(val);
|
||||||
n->kanalen = strlen(n->kana);
|
n->vlen = strlen(n->val);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
80
jp.c
80
jp.c
@@ -1,80 +0,0 @@
|
|||||||
#include "dat.h"
|
|
||||||
#include "fn.h"
|
|
||||||
|
|
||||||
Emit
|
|
||||||
jptrans(Im *im, Rune c)
|
|
||||||
{
|
|
||||||
Emit e;
|
|
||||||
Str key, kana;
|
|
||||||
Hmap *h;
|
|
||||||
Rune last;
|
|
||||||
int hira;
|
|
||||||
|
|
||||||
memset(&e, 0, sizeof(e));
|
|
||||||
h = im->l->map;
|
|
||||||
hira = (im->l->lang == LangJP);
|
|
||||||
key = im->line;
|
|
||||||
sputr(&key, c);
|
|
||||||
if(hmapget(h, &key)){
|
|
||||||
e.eat = 1;
|
|
||||||
e.next = key;
|
|
||||||
mapget(h, &key, &e.dict);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
last = slastr(&im->line);
|
|
||||||
if(last == 0)
|
|
||||||
goto flush;
|
|
||||||
key = im->line;
|
|
||||||
key.n--;
|
|
||||||
if(mapget(h, &key, &kana)){
|
|
||||||
sclear(&key);
|
|
||||||
sputr(&key, last);
|
|
||||||
sputr(&key, c);
|
|
||||||
if(hmapget(h, &key)){
|
|
||||||
e.eat = 1;
|
|
||||||
e.s = kana;
|
|
||||||
sputr(&e.next, last);
|
|
||||||
sputr(&e.next, c);
|
|
||||||
mapget(h, &e.next, &e.dict);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(c == 'n' && last == 'n'){
|
|
||||||
key = im->line;
|
|
||||||
key.n--;
|
|
||||||
if(mapget(h, &key, &kana)){
|
|
||||||
e.eat = 1;
|
|
||||||
e.s = kana;
|
|
||||||
sputr(&e.s, hira ? 0x3093 : 0x30F3);
|
|
||||||
sputr(&e.next, c);
|
|
||||||
mapget(h, &e.next, &e.dict);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(c == last && strchr("kgsztdbpmjfchryw", c)){
|
|
||||||
key = im->line;
|
|
||||||
key.n--;
|
|
||||||
if(mapget(h, &key, &kana)){
|
|
||||||
e.eat = 1;
|
|
||||||
e.s = kana;
|
|
||||||
sputr(&e.s, hira ? 0x3063 : 0x30C3);
|
|
||||||
sputr(&e.next, c);
|
|
||||||
mapget(h, &e.next, &e.dict);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flush:
|
|
||||||
mapget(h, &im->line, &e.s);
|
|
||||||
sclear(&key);
|
|
||||||
sputr(&key, c);
|
|
||||||
if(hmapget(h, &key) == nil){
|
|
||||||
e.flush = 1;
|
|
||||||
sputr(&e.s, c);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
e.eat = 1;
|
|
||||||
sputr(&e.next, c);
|
|
||||||
mapget(h, &e.next, &e.dict);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
321
ko.c
Normal file
321
ko.c
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
#include "dat.h"
|
||||||
|
#include "fn.h"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Sbase = 0xAC00,
|
||||||
|
Jbase = 0x3131,
|
||||||
|
Jrange = 51,
|
||||||
|
Ncho = 19,
|
||||||
|
Njung = 21,
|
||||||
|
Njong = 28,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Rune cho[] = {
|
||||||
|
L'ㄱ', L'ㄲ', L'ㄴ', L'ㄷ', L'ㄸ',
|
||||||
|
L'ㄹ', L'ㅁ', L'ㅂ', L'ㅃ', L'ㅅ',
|
||||||
|
L'ㅆ', L'ㅇ', L'ㅈ', L'ㅉ', L'ㅊ',
|
||||||
|
L'ㅋ', L'ㅌ', L'ㅍ', L'ㅎ',
|
||||||
|
};
|
||||||
|
|
||||||
|
static Rune jung[] = {
|
||||||
|
L'ㅏ', L'ㅐ', L'ㅑ', L'ㅒ', L'ㅓ',
|
||||||
|
L'ㅔ', L'ㅕ', L'ㅖ', L'ㅗ', L'ㅘ',
|
||||||
|
L'ㅙ', L'ㅚ', L'ㅛ', L'ㅜ', L'ㅝ',
|
||||||
|
L'ㅞ', L'ㅟ', L'ㅠ', L'ㅡ', L'ㅢ',
|
||||||
|
L'ㅣ',
|
||||||
|
};
|
||||||
|
|
||||||
|
static Rune jong[] = {
|
||||||
|
0, L'ㄱ', L'ㄲ', L'ㄳ', L'ㄴ',
|
||||||
|
L'ㄵ', L'ㄶ', L'ㄷ', L'ㄹ', L'ㄺ',
|
||||||
|
L'ㄻ', L'ㄼ', L'ㄽ', L'ㄾ', L'ㄿ',
|
||||||
|
L'ㅀ', L'ㅁ', L'ㅂ', L'ㅄ', L'ㅅ',
|
||||||
|
L'ㅆ', L'ㅇ', L'ㅈ', L'ㅊ', L'ㅋ',
|
||||||
|
L'ㅌ', L'ㅍ', L'ㅎ',
|
||||||
|
};
|
||||||
|
|
||||||
|
static int choidx[Jrange] = {
|
||||||
|
[L'ㄱ'-Jbase] = 1, [L'ㄲ'-Jbase] = 2, [L'ㄴ'-Jbase] = 3,
|
||||||
|
[L'ㄷ'-Jbase] = 4, [L'ㄸ'-Jbase] = 5, [L'ㄹ'-Jbase] = 6,
|
||||||
|
[L'ㅁ'-Jbase] = 7, [L'ㅂ'-Jbase] = 8, [L'ㅃ'-Jbase] = 9,
|
||||||
|
[L'ㅅ'-Jbase] = 10, [L'ㅆ'-Jbase] = 11, [L'ㅇ'-Jbase] = 12,
|
||||||
|
[L'ㅈ'-Jbase] = 13, [L'ㅉ'-Jbase] = 14, [L'ㅊ'-Jbase] = 15,
|
||||||
|
[L'ㅋ'-Jbase] = 16, [L'ㅌ'-Jbase] = 17, [L'ㅍ'-Jbase] = 18,
|
||||||
|
[L'ㅎ'-Jbase] = 19,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int jungidx[Jrange] = {
|
||||||
|
[L'ㅏ'-Jbase] = 1, [L'ㅐ'-Jbase] = 2, [L'ㅑ'-Jbase] = 3,
|
||||||
|
[L'ㅒ'-Jbase] = 4, [L'ㅓ'-Jbase] = 5, [L'ㅔ'-Jbase] = 6,
|
||||||
|
[L'ㅕ'-Jbase] = 7, [L'ㅖ'-Jbase] = 8, [L'ㅗ'-Jbase] = 9,
|
||||||
|
[L'ㅘ'-Jbase] = 10, [L'ㅙ'-Jbase] = 11, [L'ㅚ'-Jbase] = 12,
|
||||||
|
[L'ㅛ'-Jbase] = 13, [L'ㅜ'-Jbase] = 14, [L'ㅝ'-Jbase] = 15,
|
||||||
|
[L'ㅞ'-Jbase] = 16, [L'ㅟ'-Jbase] = 17, [L'ㅠ'-Jbase] = 18,
|
||||||
|
[L'ㅡ'-Jbase] = 19, [L'ㅢ'-Jbase] = 20, [L'ㅣ'-Jbase] = 21,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int jongidx[Jrange] = {
|
||||||
|
[L'ㄱ'-Jbase] = 2, [L'ㄲ'-Jbase] = 3, [L'ㄳ'-Jbase] = 4,
|
||||||
|
[L'ㄴ'-Jbase] = 5, [L'ㄵ'-Jbase] = 6, [L'ㄶ'-Jbase] = 7,
|
||||||
|
[L'ㄷ'-Jbase] = 8, [L'ㄹ'-Jbase] = 9, [L'ㄺ'-Jbase] = 10,
|
||||||
|
[L'ㄻ'-Jbase] = 11, [L'ㄼ'-Jbase] = 12, [L'ㄽ'-Jbase] = 13,
|
||||||
|
[L'ㄾ'-Jbase] = 14, [L'ㄿ'-Jbase] = 15, [L'ㅀ'-Jbase] = 16,
|
||||||
|
[L'ㅁ'-Jbase] = 17, [L'ㅂ'-Jbase] = 18, [L'ㅄ'-Jbase] = 19,
|
||||||
|
[L'ㅅ'-Jbase] = 20, [L'ㅆ'-Jbase] = 21, [L'ㅇ'-Jbase] = 22,
|
||||||
|
[L'ㅈ'-Jbase] = 23, [L'ㅊ'-Jbase] = 24, [L'ㅋ'-Jbase] = 25,
|
||||||
|
[L'ㅌ'-Jbase] = 26, [L'ㅍ'-Jbase] = 27, [L'ㅎ'-Jbase] = 28,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define Choidx(r) (choidx[(r) - Jbase] - 1)
|
||||||
|
#define Jungidx(r) (jungidx[(r) - Jbase] - 1)
|
||||||
|
#define Jongidx(r) (jongidx[(r) - Jbase] - 1)
|
||||||
|
|
||||||
|
static Rune jamomap[128] = {
|
||||||
|
['r'] = L'ㄱ', ['R'] = L'ㄲ',
|
||||||
|
['s'] = L'ㄴ', ['S'] = L'ㄴ',
|
||||||
|
['e'] = L'ㄷ', ['E'] = L'ㄸ',
|
||||||
|
['f'] = L'ㄹ', ['F'] = L'ㄹ',
|
||||||
|
['a'] = L'ㅁ', ['A'] = L'ㅁ',
|
||||||
|
['q'] = L'ㅂ', ['Q'] = L'ㅃ',
|
||||||
|
['t'] = L'ㅅ', ['T'] = L'ㅆ',
|
||||||
|
['d'] = L'ㅇ', ['D'] = L'ㅇ',
|
||||||
|
['w'] = L'ㅈ', ['W'] = L'ㅉ',
|
||||||
|
['c'] = L'ㅊ', ['C'] = L'ㅊ',
|
||||||
|
['z'] = L'ㅋ', ['Z'] = L'ㅋ',
|
||||||
|
['x'] = L'ㅌ', ['X'] = L'ㅌ',
|
||||||
|
['v'] = L'ㅍ', ['V'] = L'ㅍ',
|
||||||
|
['g'] = L'ㅎ', ['G'] = L'ㅎ',
|
||||||
|
['k'] = L'ㅏ', ['K'] = L'ㅏ',
|
||||||
|
['o'] = L'ㅐ', ['O'] = L'ㅒ',
|
||||||
|
['i'] = L'ㅑ', ['I'] = L'ㅑ',
|
||||||
|
['j'] = L'ㅓ', ['J'] = L'ㅓ',
|
||||||
|
['p'] = L'ㅔ', ['P'] = L'ㅖ',
|
||||||
|
['u'] = L'ㅕ', ['U'] = L'ㅕ',
|
||||||
|
['h'] = L'ㅗ', ['H'] = L'ㅗ',
|
||||||
|
['y'] = L'ㅛ', ['Y'] = L'ㅛ',
|
||||||
|
['n'] = L'ㅜ', ['N'] = L'ㅜ',
|
||||||
|
['b'] = L'ㅠ', ['B'] = L'ㅠ',
|
||||||
|
['m'] = L'ㅡ', ['M'] = L'ㅡ',
|
||||||
|
['l'] = L'ㅣ', ['L'] = L'ㅣ',
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Cpair Cpair;
|
||||||
|
struct Cpair
|
||||||
|
{
|
||||||
|
Rune b;
|
||||||
|
Rune a;
|
||||||
|
Rune r;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Cpair cvow[] = {
|
||||||
|
{L'ㅗ', L'ㅏ', L'ㅘ'},
|
||||||
|
{L'ㅗ', L'ㅐ', L'ㅙ'},
|
||||||
|
{L'ㅗ', L'ㅣ', L'ㅚ'},
|
||||||
|
{L'ㅜ', L'ㅓ', L'ㅝ'},
|
||||||
|
{L'ㅜ', L'ㅔ', L'ㅞ'},
|
||||||
|
{L'ㅜ', L'ㅣ', L'ㅟ'},
|
||||||
|
{L'ㅡ', L'ㅣ', L'ㅢ'},
|
||||||
|
};
|
||||||
|
|
||||||
|
static Cpair cjong[] = {
|
||||||
|
{L'ㄱ', L'ㅅ', L'ㄳ'},
|
||||||
|
{L'ㄴ', L'ㅈ', L'ㄵ'},
|
||||||
|
{L'ㄴ', L'ㅎ', L'ㄶ'},
|
||||||
|
{L'ㄹ', L'ㄱ', L'ㄺ'},
|
||||||
|
{L'ㄹ', L'ㅁ', L'ㄻ'},
|
||||||
|
{L'ㄹ', L'ㅂ', L'ㄼ'},
|
||||||
|
{L'ㄹ', L'ㅅ', L'ㄽ'},
|
||||||
|
{L'ㄹ', L'ㅌ', L'ㄾ'},
|
||||||
|
{L'ㄹ', L'ㅍ', L'ㄿ'},
|
||||||
|
{L'ㄹ', L'ㅎ', L'ㅀ'},
|
||||||
|
{L'ㅂ', L'ㅅ', L'ㅄ'},
|
||||||
|
};
|
||||||
|
|
||||||
|
static Rune
|
||||||
|
keytojamo(int c)
|
||||||
|
{
|
||||||
|
if(c >= 0 && c < 128)
|
||||||
|
return jamomap[c];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Rune
|
||||||
|
combine(Cpair *t, int n, Rune b, Rune a)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < n; i++)
|
||||||
|
if(t[i].b == b && t[i].a == a)
|
||||||
|
return t[i].r;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
splitpair(Cpair *t, int n, Rune c, Rune *stay, Rune *next)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < n; i++){
|
||||||
|
if(t[i].r == c){
|
||||||
|
*stay = t[i].b;
|
||||||
|
*next = t[i].a;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Rune
|
||||||
|
compose(int c, int j, int jo)
|
||||||
|
{
|
||||||
|
return Sbase + c*Njung*Njong + j*Njong + jo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
decompose(Rune s, int *c, int *j, int *jo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = s - Sbase;
|
||||||
|
*c = i / (Njung * Njong);
|
||||||
|
*j = (i / Njong) % Njung;
|
||||||
|
*jo = i % Njong;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
issyl(Rune r)
|
||||||
|
{
|
||||||
|
return r >= Sbase && r < Sbase + Ncho*Njung*Njong;
|
||||||
|
}
|
||||||
|
|
||||||
|
Emit
|
||||||
|
transko(Im *im, Rune c)
|
||||||
|
{
|
||||||
|
Emit e;
|
||||||
|
Rune jm, jc, last, comb, stay, next;
|
||||||
|
int ci, ji, joi, ni, si, vi;
|
||||||
|
|
||||||
|
memset(&e, 0, sizeof e);
|
||||||
|
jm = keytojamo(c);
|
||||||
|
if(jm == 0){
|
||||||
|
if(im->pre.n > 0){
|
||||||
|
e.s = im->pre;
|
||||||
|
sclear(&im->pre);
|
||||||
|
}
|
||||||
|
sputr(&e.s, c);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
e.eat = 1;
|
||||||
|
last = slastr(&im->pre);
|
||||||
|
if(last == 0){
|
||||||
|
sputr(&e.next, jm);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(!issyl(last)){
|
||||||
|
ci = Choidx(last);
|
||||||
|
ji = Jungidx(jm);
|
||||||
|
if(ci >= 0 && ji >= 0){
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&e.next, compose(ci, ji, 0));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(Jungidx(last) >= 0 && ji >= 0){
|
||||||
|
comb = combine(cvow, nelem(cvow), last, jm);
|
||||||
|
if(comb){
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&e.next, comb);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.s = im->pre;
|
||||||
|
sputr(&e.next, jm);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
decompose(last, &ci, &ji, &joi);
|
||||||
|
if(joi == 0){
|
||||||
|
ni = Jongidx(jm);
|
||||||
|
if(ni > 0){
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&e.next, compose(ci, ji, ni));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
vi = Jungidx(jm);
|
||||||
|
if(vi >= 0){
|
||||||
|
comb = combine(cvow, nelem(cvow), jung[ji], jm);
|
||||||
|
if(comb){
|
||||||
|
ni = Jungidx(comb);
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&e.next, compose(ci, ni, 0));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(joi > 0){
|
||||||
|
comb = combine(cjong, nelem(cjong), jong[joi], jm);
|
||||||
|
if(comb){
|
||||||
|
ni = Jongidx(comb);
|
||||||
|
if(ni > 0){
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&e.next, compose(ci, ji, ni));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vi = Jungidx(jm);
|
||||||
|
if(vi >= 0){
|
||||||
|
jc = jong[joi];
|
||||||
|
if(splitpair(cjong, nelem(cjong), jc, &stay, &next)){
|
||||||
|
si = Jongidx(stay);
|
||||||
|
ni = Choidx(next);
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&e.s, compose(ci, ji, si));
|
||||||
|
sputr(&e.next, compose(ni, vi, 0));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
ni = Choidx(jc);
|
||||||
|
if(ni >= 0){
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&e.s, compose(ci, ji, 0));
|
||||||
|
sputr(&e.next, compose(ni, vi, 0));
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.s = im->pre;
|
||||||
|
sputr(&e.next, jm);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
backko(Im *im)
|
||||||
|
{
|
||||||
|
Rune last;
|
||||||
|
int c, j, jo;
|
||||||
|
Rune stay, next;
|
||||||
|
|
||||||
|
last = slastr(&im->pre);
|
||||||
|
if(!issyl(last)){
|
||||||
|
if(splitpair(cvow, nelem(cvow), last, &stay, &next)){
|
||||||
|
spopr(&im->pre);
|
||||||
|
sputr(&im->pre, stay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
spopr(&im->pre);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
decompose(last, &c, &j, &jo);
|
||||||
|
spopr(&im->pre);
|
||||||
|
if(jo > 0 && splitpair(cjong, nelem(cjong), jong[jo], &stay, &next)){
|
||||||
|
sputr(&im->pre, compose(c, j, Jongidx(stay)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(jo > 0){
|
||||||
|
sputr(&im->pre, compose(c, j, 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(splitpair(cvow, nelem(cvow), jung[j], &stay, &next)){
|
||||||
|
sputr(&im->pre, compose(c, Jungidx(stay), 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sputr(&im->pre, cho[c]);
|
||||||
|
}
|
||||||
8
main.c
8
main.c
@@ -5,7 +5,7 @@ Channel *drawc;
|
|||||||
Channel *keyc;
|
Channel *keyc;
|
||||||
Channel *dictreqc;
|
Channel *dictreqc;
|
||||||
Channel *dictresc;
|
Channel *dictresc;
|
||||||
char *fontpath;
|
char *fontdir;
|
||||||
|
|
||||||
int
|
int
|
||||||
threadmaybackground(void)
|
threadmaybackground(void)
|
||||||
@@ -16,7 +16,7 @@ threadmaybackground(void)
|
|||||||
void
|
void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprint(2, "usage: strans mapdir fontpath\n");
|
fprint(2, "usage: strans mapdir fontdir\n");
|
||||||
threadexitsall("usage");
|
threadexitsall("usage");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,8 +60,8 @@ threadmain(int argc, char **argv)
|
|||||||
if(argc != 3)
|
if(argc != 3)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
fontpath = argv[2];
|
fontdir = argv[2];
|
||||||
drawc = chancreate(sizeof(Drawcmd), 0);
|
drawc = chancreate(sizeof(Drawcmd), 4);
|
||||||
keyc = chancreate(sizeof(Keyreq), 0);
|
keyc = chancreate(sizeof(Keyreq), 0);
|
||||||
dictreqc = chancreate(sizeof(Dictreq), 4);
|
dictreqc = chancreate(sizeof(Dictreq), 4);
|
||||||
dictresc = chancreate(sizeof(Dictres), 0);
|
dictresc = chancreate(sizeof(Dictres), 0);
|
||||||
|
|||||||
179
map/emoji.dict
Normal file
179
map/emoji.dict
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
! ⚠ ≠
|
||||||
|
!! ⚠
|
||||||
|
!= ≠
|
||||||
|
* ★
|
||||||
|
** ★
|
||||||
|
+ ±
|
||||||
|
+- ±
|
||||||
|
- →
|
||||||
|
-> →
|
||||||
|
. · … ÷
|
||||||
|
.. · …
|
||||||
|
... …
|
||||||
|
./ ÷
|
||||||
|
: ☹ ☺
|
||||||
|
:( ☹
|
||||||
|
:) ☺
|
||||||
|
< ← ≤ ≠ ♥
|
||||||
|
<- ←
|
||||||
|
<= ≤
|
||||||
|
<> ≠
|
||||||
|
= ≡ ⇒
|
||||||
|
== ≡
|
||||||
|
=> ⇒
|
||||||
|
> ≥
|
||||||
|
>= ≥
|
||||||
|
^ ⁽ ⁾ ⁺ ⁻ ⁼ ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁱ ⁿ
|
||||||
|
^( ⁽
|
||||||
|
^) ⁾
|
||||||
|
^+ ⁺
|
||||||
|
^- ⁻
|
||||||
|
^= ⁼
|
||||||
|
_ ₍ ₎ ₊ ₋ ₌ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₐ ₑ ₒ ₓ
|
||||||
|
_( ₍
|
||||||
|
_) ₎
|
||||||
|
_+ ₊
|
||||||
|
_- ₋
|
||||||
|
_= ₌
|
||||||
|
~ ≈
|
||||||
|
~= ≈
|
||||||
|
^0 ⁰
|
||||||
|
_0 ₀
|
||||||
|
^1 ¹
|
||||||
|
_1 ₁
|
||||||
|
^2 ²
|
||||||
|
_2 ₂
|
||||||
|
<3 ♥
|
||||||
|
^3 ³
|
||||||
|
_3 ₃
|
||||||
|
^4 ⁴
|
||||||
|
_4 ₄
|
||||||
|
^5 ⁵
|
||||||
|
_5 ₅
|
||||||
|
^6 ⁶
|
||||||
|
_6 ₆
|
||||||
|
^7 ⁷
|
||||||
|
_7 ₇
|
||||||
|
^8 ⁸
|
||||||
|
_8 ₈
|
||||||
|
^9 ⁹
|
||||||
|
_9 ₉
|
||||||
|
_a ₐ
|
||||||
|
a α
|
||||||
|
al α
|
||||||
|
alp α
|
||||||
|
alph α
|
||||||
|
alpha α
|
||||||
|
b β
|
||||||
|
be β
|
||||||
|
bet β
|
||||||
|
beta β
|
||||||
|
c χ
|
||||||
|
ch χ
|
||||||
|
chi χ
|
||||||
|
d ° δ ↓
|
||||||
|
D Δ
|
||||||
|
de ° δ
|
||||||
|
De Δ
|
||||||
|
deg °
|
||||||
|
del δ
|
||||||
|
delt δ
|
||||||
|
delta δ
|
||||||
|
dn ↓
|
||||||
|
_e ₑ
|
||||||
|
e ε η
|
||||||
|
ep ε
|
||||||
|
eps ε
|
||||||
|
et η
|
||||||
|
eta η
|
||||||
|
g γ
|
||||||
|
G Γ
|
||||||
|
ga γ
|
||||||
|
Ga Γ
|
||||||
|
gam γ
|
||||||
|
gamm γ
|
||||||
|
gamma γ
|
||||||
|
^i ⁱ
|
||||||
|
i ∞ ι
|
||||||
|
I ∫
|
||||||
|
II ∫
|
||||||
|
in ∞
|
||||||
|
inf ∞
|
||||||
|
io ι
|
||||||
|
iot ι
|
||||||
|
iota ι
|
||||||
|
k κ
|
||||||
|
ka κ
|
||||||
|
kap κ
|
||||||
|
kapp κ
|
||||||
|
kappa κ
|
||||||
|
l λ
|
||||||
|
L Λ
|
||||||
|
la λ
|
||||||
|
La Λ
|
||||||
|
lam λ
|
||||||
|
lamb λ
|
||||||
|
lambd λ
|
||||||
|
lambda λ
|
||||||
|
m × μ
|
||||||
|
mu × μ
|
||||||
|
mul ×
|
||||||
|
^n ⁿ
|
||||||
|
n ν
|
||||||
|
nu ν
|
||||||
|
_o ₒ
|
||||||
|
o ω ●
|
||||||
|
O Ω
|
||||||
|
om ω
|
||||||
|
Om Ω
|
||||||
|
ome ω
|
||||||
|
omeg ω
|
||||||
|
omega ω
|
||||||
|
oo ●
|
||||||
|
p φ π ψ
|
||||||
|
P Φ Π ∏ Ψ
|
||||||
|
ph φ
|
||||||
|
Ph Φ
|
||||||
|
phi φ
|
||||||
|
pi π
|
||||||
|
Pi Π
|
||||||
|
PP ∏
|
||||||
|
ps ψ
|
||||||
|
Ps Ψ
|
||||||
|
psi ψ
|
||||||
|
r ρ
|
||||||
|
rh ρ
|
||||||
|
rho ρ
|
||||||
|
s σ √
|
||||||
|
S Σ ∑
|
||||||
|
si σ
|
||||||
|
Si Σ
|
||||||
|
sig σ
|
||||||
|
sigm σ
|
||||||
|
sigma σ
|
||||||
|
sq √
|
||||||
|
SS ∑
|
||||||
|
t τ θ
|
||||||
|
T Θ
|
||||||
|
ta τ
|
||||||
|
tau τ
|
||||||
|
th θ
|
||||||
|
Th Θ
|
||||||
|
the θ
|
||||||
|
thet θ
|
||||||
|
theta θ
|
||||||
|
u ↑ υ
|
||||||
|
up ↑ υ
|
||||||
|
ups υ
|
||||||
|
v ✓
|
||||||
|
vv ✓
|
||||||
|
_x ₓ
|
||||||
|
x ξ ✗
|
||||||
|
X Ξ
|
||||||
|
xi ξ
|
||||||
|
Xi Ξ
|
||||||
|
xx ✗
|
||||||
|
z ζ
|
||||||
|
ze ζ
|
||||||
|
zet ζ
|
||||||
|
zeta ζ
|
||||||
179
map/emoji.map
Normal file
179
map/emoji.map
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
! !
|
||||||
|
!! ⚠
|
||||||
|
!= ≠
|
||||||
|
* *
|
||||||
|
** ★
|
||||||
|
+ +
|
||||||
|
+- ±
|
||||||
|
- -
|
||||||
|
-> →
|
||||||
|
. .
|
||||||
|
.. ·
|
||||||
|
... …
|
||||||
|
./ ÷
|
||||||
|
: :
|
||||||
|
:( ☹
|
||||||
|
:) ☺
|
||||||
|
< <
|
||||||
|
<- ←
|
||||||
|
<= ≤
|
||||||
|
<> ≠
|
||||||
|
= =
|
||||||
|
== ≡
|
||||||
|
=> ⇒
|
||||||
|
> >
|
||||||
|
>= ≥
|
||||||
|
^ ^
|
||||||
|
^( ⁽
|
||||||
|
^) ⁾
|
||||||
|
^+ ⁺
|
||||||
|
^- ⁻
|
||||||
|
^= ⁼
|
||||||
|
_ _
|
||||||
|
_( ₍
|
||||||
|
_) ₎
|
||||||
|
_+ ₊
|
||||||
|
_- ₋
|
||||||
|
_= ₌
|
||||||
|
~ ~
|
||||||
|
~= ≈
|
||||||
|
^0 ⁰
|
||||||
|
_0 ₀
|
||||||
|
^1 ¹
|
||||||
|
_1 ₁
|
||||||
|
^2 ²
|
||||||
|
_2 ₂
|
||||||
|
<3 ♥
|
||||||
|
^3 ³
|
||||||
|
_3 ₃
|
||||||
|
^4 ⁴
|
||||||
|
_4 ₄
|
||||||
|
^5 ⁵
|
||||||
|
_5 ₅
|
||||||
|
^6 ⁶
|
||||||
|
_6 ₆
|
||||||
|
^7 ⁷
|
||||||
|
_7 ₇
|
||||||
|
^8 ⁸
|
||||||
|
_8 ₈
|
||||||
|
^9 ⁹
|
||||||
|
_9 ₉
|
||||||
|
_a ₐ
|
||||||
|
a a
|
||||||
|
al al
|
||||||
|
alp alp
|
||||||
|
alph alph
|
||||||
|
alpha α
|
||||||
|
b b
|
||||||
|
be be
|
||||||
|
bet bet
|
||||||
|
beta β
|
||||||
|
c c
|
||||||
|
ch ch
|
||||||
|
chi χ
|
||||||
|
d d
|
||||||
|
D D
|
||||||
|
de de
|
||||||
|
De Δ
|
||||||
|
deg °
|
||||||
|
del del
|
||||||
|
delt delt
|
||||||
|
delta δ
|
||||||
|
dn ↓
|
||||||
|
_e ₑ
|
||||||
|
e e
|
||||||
|
ep ep
|
||||||
|
eps ε
|
||||||
|
et et
|
||||||
|
eta η
|
||||||
|
g g
|
||||||
|
G G
|
||||||
|
ga ga
|
||||||
|
Ga Γ
|
||||||
|
gam gam
|
||||||
|
gamm gamm
|
||||||
|
gamma γ
|
||||||
|
^i ⁱ
|
||||||
|
i i
|
||||||
|
I I
|
||||||
|
II ∫
|
||||||
|
in in
|
||||||
|
inf ∞
|
||||||
|
io io
|
||||||
|
iot iot
|
||||||
|
iota ι
|
||||||
|
k k
|
||||||
|
ka ka
|
||||||
|
kap kap
|
||||||
|
kapp kapp
|
||||||
|
kappa κ
|
||||||
|
l l
|
||||||
|
L L
|
||||||
|
la la
|
||||||
|
La Λ
|
||||||
|
lam lam
|
||||||
|
lamb lamb
|
||||||
|
lambd lambd
|
||||||
|
lambda λ
|
||||||
|
m m
|
||||||
|
mu μ
|
||||||
|
mul ×
|
||||||
|
^n ⁿ
|
||||||
|
n n
|
||||||
|
nu ν
|
||||||
|
_o ₒ
|
||||||
|
o o
|
||||||
|
O O
|
||||||
|
om om
|
||||||
|
Om Ω
|
||||||
|
ome ome
|
||||||
|
omeg omeg
|
||||||
|
omega ω
|
||||||
|
oo ●
|
||||||
|
p p
|
||||||
|
P P
|
||||||
|
ph ph
|
||||||
|
Ph Φ
|
||||||
|
phi φ
|
||||||
|
pi π
|
||||||
|
Pi Π
|
||||||
|
PP ∏
|
||||||
|
ps ps
|
||||||
|
Ps Ψ
|
||||||
|
psi ψ
|
||||||
|
r r
|
||||||
|
rh rh
|
||||||
|
rho ρ
|
||||||
|
s s
|
||||||
|
S S
|
||||||
|
si si
|
||||||
|
Si Σ
|
||||||
|
sig sig
|
||||||
|
sigm sigm
|
||||||
|
sigma σ
|
||||||
|
sq √
|
||||||
|
SS ∑
|
||||||
|
t t
|
||||||
|
T T
|
||||||
|
ta ta
|
||||||
|
tau τ
|
||||||
|
th th
|
||||||
|
Th Θ
|
||||||
|
the the
|
||||||
|
thet thet
|
||||||
|
theta θ
|
||||||
|
u u
|
||||||
|
up ↑
|
||||||
|
ups υ
|
||||||
|
v v
|
||||||
|
vv ✓
|
||||||
|
_x ₓ
|
||||||
|
x x
|
||||||
|
X X
|
||||||
|
xi ξ
|
||||||
|
Xi Ξ
|
||||||
|
xx ✗
|
||||||
|
z z
|
||||||
|
ze ze
|
||||||
|
zet zet
|
||||||
|
zeta ζ
|
||||||
99
map/emoji.src
Normal file
99
map/emoji.src
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
!! ⚠
|
||||||
|
!= ≠
|
||||||
|
** ★
|
||||||
|
+- ±
|
||||||
|
-> →
|
||||||
|
.. ·
|
||||||
|
... …
|
||||||
|
./ ÷
|
||||||
|
:( ☹
|
||||||
|
:) ☺
|
||||||
|
<- ←
|
||||||
|
<= ≤
|
||||||
|
<> ≠
|
||||||
|
== ≡
|
||||||
|
=> ⇒
|
||||||
|
>= ≥
|
||||||
|
^( ⁽
|
||||||
|
^) ⁾
|
||||||
|
^+ ⁺
|
||||||
|
^- ⁻
|
||||||
|
^= ⁼
|
||||||
|
_( ₍
|
||||||
|
_) ₎
|
||||||
|
_+ ₊
|
||||||
|
_- ₋
|
||||||
|
_= ₌
|
||||||
|
~= ≈
|
||||||
|
^0 ⁰
|
||||||
|
_0 ₀
|
||||||
|
^1 ¹
|
||||||
|
_1 ₁
|
||||||
|
^2 ²
|
||||||
|
_2 ₂
|
||||||
|
<3 ♥
|
||||||
|
^3 ³
|
||||||
|
_3 ₃
|
||||||
|
^4 ⁴
|
||||||
|
_4 ₄
|
||||||
|
^5 ⁵
|
||||||
|
_5 ₅
|
||||||
|
^6 ⁶
|
||||||
|
_6 ₆
|
||||||
|
^7 ⁷
|
||||||
|
_7 ₇
|
||||||
|
^8 ⁸
|
||||||
|
_8 ₈
|
||||||
|
^9 ⁹
|
||||||
|
_9 ₉
|
||||||
|
_a ₐ
|
||||||
|
alpha α
|
||||||
|
beta β
|
||||||
|
chi χ
|
||||||
|
deg °
|
||||||
|
delta δ
|
||||||
|
De Δ
|
||||||
|
dn ↓
|
||||||
|
_e ₑ
|
||||||
|
eps ε
|
||||||
|
eta η
|
||||||
|
gamma γ
|
||||||
|
Ga Γ
|
||||||
|
^i ⁱ
|
||||||
|
II ∫
|
||||||
|
inf ∞
|
||||||
|
iota ι
|
||||||
|
kappa κ
|
||||||
|
lambda λ
|
||||||
|
La Λ
|
||||||
|
mul ×
|
||||||
|
mu μ
|
||||||
|
^n ⁿ
|
||||||
|
nu ν
|
||||||
|
omega ω
|
||||||
|
Om Ω
|
||||||
|
oo ●
|
||||||
|
_o ₒ
|
||||||
|
phi φ
|
||||||
|
Ph Φ
|
||||||
|
pi π
|
||||||
|
Pi Π
|
||||||
|
PP ∏
|
||||||
|
psi ψ
|
||||||
|
Ps Ψ
|
||||||
|
rho ρ
|
||||||
|
sigma σ
|
||||||
|
Si Σ
|
||||||
|
sq √
|
||||||
|
SS ∑
|
||||||
|
tau τ
|
||||||
|
theta θ
|
||||||
|
Th Θ
|
||||||
|
up ↑
|
||||||
|
ups υ
|
||||||
|
vv ✓
|
||||||
|
xi ξ
|
||||||
|
Xi Ξ
|
||||||
|
xx ✗
|
||||||
|
_x ₓ
|
||||||
|
zeta ζ
|
||||||
0
map/english.map
Normal file
0
map/english.map
Normal file
382
map/hangul.dict
382
map/hangul.dict
@@ -1,382 +0,0 @@
|
|||||||
;; Korean autocomplete dictionary for ktrans
|
|
||||||
;; Format: prefix completion1 completion2 ...
|
|
||||||
;;
|
|
||||||
;; Initial consonants (초성)
|
|
||||||
ㄱ 가 감사 감사합니다 강남 고마워 고맙습니다 괜찮아 그래 그럼 기다려 가능 가격 가게 가방 가족 간단 갈게 같이 거기 건강 검색 결과 경우 계속 고객 공부 관련 괜찮습니다 교육 구매 그냥 그런데 그리고 근데 금방 기능 기대 기본 길이
|
|
||||||
ㄴ 나 네 내일 너무 노래 누구 뭐 나중에 남자 내용 넣어 놓고 느낌 다음
|
|
||||||
ㄷ 다 대 더 도 동 다시 다음 단어 답변 대단 대화 도움 도착 동생 등록 드릴게요
|
|
||||||
ㄹ 라 로 리 레 뭐라고
|
|
||||||
ㅁ 만 먼저 메시지 모르겠어 모두 뭐 뭐야 뭐라고 뭔가 미안 미안해 문제 문의
|
|
||||||
ㅂ 바로 반갑습니다 방금 방법 별로 보내 보여줘 부탁 부탁드립니다 분명 비밀번호
|
|
||||||
ㅅ 사 사람 사랑 사용 사진 상관없어 생각 서비스 선택 설명 성공 소개 수고 수정 시간 시작 신청 실패 싶어
|
|
||||||
ㅇ 아 아니 아니요 아마 안녕 안녕하세요 알겠습니다 알았어 어디 어떻게 어서오세요 없어 에러 여기 여보세요 연락 열심히 예 오늘 오랜만 오케이 완료 왜 요청 우리 원래 위치 유저 으로 응 이거 이것 이름 이메일 이미 이상 이유 이해 인사 일단 입력 있어
|
|
||||||
ㅈ 자 잘 잘가 잘됐다 잠깐 잠시 저 전화 정말 제가 제발 조금 좀 좋아 좋겠다 주문 주세요 중요 즐거운 지금 직접 진짜 질문 집
|
|
||||||
ㅊ 참 참고 찾아 처리 처음 천만에요 최고 최근 추가 축하 출발 취소
|
|
||||||
ㅋ 카드 커피 컴퓨터 코드 클릭 큰
|
|
||||||
ㅌ 탈퇴 통화 특히
|
|
||||||
ㅍ 파일 편하게 포함 필요 필수
|
|
||||||
ㅎ 하 하나 하루 하세요 하지마 한 한번 항상 해결 해봐 해야 해주세요 핸드폰 행복 확인 회원 회의 휴대폰
|
|
||||||
;;
|
|
||||||
;; Common prefixes (일반 접두어)
|
|
||||||
가 가격 가게 가능 가다 가방 가수 가요 가을 가장 가족 가지
|
|
||||||
간 간단 간식 간장 간호사
|
|
||||||
갈 갈게 갈비 갈색
|
|
||||||
감 감기 감사 감사합니다 감사해요 감자 감정
|
|
||||||
강 강남 강아지 강의 강조
|
|
||||||
같 같아 같아요 같은 같이
|
|
||||||
개 개발 개발자 개선 개인 개정
|
|
||||||
거 거기 거래 거리 거의 거짓말
|
|
||||||
건 건강 건물 건의
|
|
||||||
걱 걱정 걱정마
|
|
||||||
검 검사 검색 검토
|
|
||||||
게 게시판 게임
|
|
||||||
결 결과 결론 결정 결제 결혼
|
|
||||||
경 경기 경험 경우 경제
|
|
||||||
계 계속 계시 계약 계정 계좌 계획
|
|
||||||
고 고객 고급 고기 고등학교 고마워 고맙습니다 고민 고양이 고장
|
|
||||||
곧 곧 곧바로
|
|
||||||
공 공간 공개 공부 공사 공유 공지 공항
|
|
||||||
과 과거 과연 과일 과장 과정
|
|
||||||
관 관계 관련 관리 관심
|
|
||||||
괜 괜찮아 괜찮아요 괜찮습니다
|
|
||||||
교 교사 교수 교육 교통 교환
|
|
||||||
구 구글 구독 구매 구분 구성 구입 구체적
|
|
||||||
국 국가 국내 국민 국어 국제
|
|
||||||
그 그거 그게 그것 그냥 그녀 그니까 그대 그대로 그때 그래 그래도 그래서 그러나 그러니까 그러면 그런 그런데 그럼 그렇게 그리고 그림 그만
|
|
||||||
근 근데 근무 근본 근처
|
|
||||||
글 글 글쎄 글자
|
|
||||||
금 금방 금액 금요일 금지
|
|
||||||
급 급하게 급해
|
|
||||||
기 기간 기능 기다려 기대 기본 기분 기사 기술 기억 기업 기준 기타 기회
|
|
||||||
길 길 길이
|
|
||||||
김 김밥 김치
|
|
||||||
까 까먹었어 까지
|
|
||||||
깜 깜빡 깜짝
|
|
||||||
꼭 꼭
|
|
||||||
끝 끝 끝났어 끝내
|
|
||||||
나 나 나도 나라 나머지 나빠 나오다 나와 나이 나중 나중에
|
|
||||||
날 날씨 날짜
|
|
||||||
남 남기다 남자 남편
|
|
||||||
내 내가 내년 내려 내리다 내용 내일
|
|
||||||
너 너 너무 너희
|
|
||||||
넣 넣다 넣어
|
|
||||||
네 네 네가 네이버
|
|
||||||
넷 넷플릭스
|
|
||||||
노 노래 노력 노트북
|
|
||||||
놀 놀라 놀러
|
|
||||||
농 농담
|
|
||||||
높 높은 높이
|
|
||||||
누 누가 누구 누나
|
|
||||||
눈 눈 눈물
|
|
||||||
뉴 뉴스
|
|
||||||
느 느낌 느린
|
|
||||||
늦 늦게 늦었어
|
|
||||||
다 다 다녀오다 다니다 다른 다르다 다시 다양 다음 다행 다행이다
|
|
||||||
단 단계 단순 단어 단위 단점 단체
|
|
||||||
달 달 달라 달러 달리
|
|
||||||
담 담당 담당자 담배
|
|
||||||
답 답글 답변 답장
|
|
||||||
당 당근 당분간 당신 당연 당장
|
|
||||||
대 대기 대단 대략 대부분 대신 대체 대충 대표 대학 대학교 대화 대해
|
|
||||||
더 더 더욱
|
|
||||||
덕 덕분
|
|
||||||
데 데이터
|
|
||||||
도 도대체 도서관 도시 도와줘 도움 도착 도전
|
|
||||||
독 독서
|
|
||||||
돈 돈
|
|
||||||
동 동네 동생 동시 동안 동영상 동의
|
|
||||||
돼 돼 돼요 됐어
|
|
||||||
되 되게 되다 되면
|
|
||||||
두 두 두고 두번째
|
|
||||||
뒤 뒤 뒤에
|
|
||||||
드 드디어 드라마 드리다 드릴게요 드세요
|
|
||||||
등 등록 등등
|
|
||||||
따 따라 따로
|
|
||||||
딱 딱
|
|
||||||
때 때 때문 때문에
|
|
||||||
또 또 또는 또한
|
|
||||||
똑 똑같이
|
|
||||||
뛰 뛰어
|
|
||||||
라 라면 라이브
|
|
||||||
로 로그인 로그아웃
|
|
||||||
리 리뷰
|
|
||||||
마 마다 마셔 마시다 마음 마지막 마찬가지 마침
|
|
||||||
막 막 막상
|
|
||||||
만 만 만나 만나다 만나서 반가워요 만들다 만약 만원 만큼 만족
|
|
||||||
많 많다 많아 많이
|
|
||||||
말 말 말고 말씀 말야 말이야
|
|
||||||
맛 맛 맛있어 맛있다
|
|
||||||
망 망했다
|
|
||||||
맞 맞아 맞아요 맞춤
|
|
||||||
매 매번 매우 매일 매장
|
|
||||||
머 머리
|
|
||||||
먹 먹고 먹다 먹어
|
|
||||||
먼 먼저
|
|
||||||
멀 멀다 멀리
|
|
||||||
메 메뉴 메모 메시지 메일
|
|
||||||
며 며칠
|
|
||||||
면 면접
|
|
||||||
명 명 명단 명확
|
|
||||||
몇 몇 몇개 몇번
|
|
||||||
모 모두 모든 모르겠어 모르다 모레 모양 모임
|
|
||||||
목 목록 목요일 목적
|
|
||||||
몰 몰라 몰랐어
|
|
||||||
못 못 못하다 못해
|
|
||||||
무 무료 무슨 무엇 무조건
|
|
||||||
문 문서 문의 문자 문제
|
|
||||||
물 물 물건 물론 물어보다
|
|
||||||
뭐 뭐 뭐야 뭐라고 뭔가 뭘
|
|
||||||
미 미국 미래 미리 미안 미안해 미안합니다 미팅
|
|
||||||
믿 믿다 믿어
|
|
||||||
밑 밑에
|
|
||||||
바 바꾸다 바뀌다 바라다 바로 바쁘다 바쁘면
|
|
||||||
박 박사
|
|
||||||
반 반 반갑습니다 반드시 반복
|
|
||||||
받 받다 받아 받았어
|
|
||||||
발 발생 발전 발표
|
|
||||||
밤 밤
|
|
||||||
밥 밥
|
|
||||||
방 방금 방법 방문 방송 방식 방향
|
|
||||||
배 배 배달 배송 배우다
|
|
||||||
백 백 백만
|
|
||||||
버 버그 버리다 버전
|
|
||||||
번 번 번역 번호
|
|
||||||
벌 벌써
|
|
||||||
범 범위
|
|
||||||
법 법
|
|
||||||
별 별로
|
|
||||||
변 변경 변화
|
|
||||||
병 병원
|
|
||||||
보 보고 보고서 보내다 보다 보면 보여줘 보이다 보통 보호
|
|
||||||
복 복사 복잡
|
|
||||||
본 본인
|
|
||||||
봐 봐 봐요 봐줘
|
|
||||||
부 부끄러워 부디 부모님 부분 부장 부족 부탁 부탁드립니다 부탁해
|
|
||||||
분 분 분명 분석 분위기
|
|
||||||
불 불가능 불편 불행
|
|
||||||
비 비교 비밀 비밀번호 비슷 비용
|
|
||||||
빠 빠르게 빠르다 빠른 빨리
|
|
||||||
빼 빼다 빼고
|
|
||||||
사 사고 사람 사랑 사랑해 사무실 사실 사업 사용 사용자 사이 사이트 사장 사전 사진 사회
|
|
||||||
산 산
|
|
||||||
살 살다 살펴보다
|
|
||||||
상 상관 상관없어 상담 상대 상세 상태 상품 상황
|
|
||||||
새 새로 새로운 새벽
|
|
||||||
색 색 색상
|
|
||||||
생 생각 생각해 생기다 생산 생일 생활
|
|
||||||
서 서로 서류 서버 서비스 서울
|
|
||||||
선 선물 선배 선생님 선택
|
|
||||||
설 설명 설정 설치
|
|
||||||
성 성공 성격 성능 성함
|
|
||||||
세 세계 세금 세부 세상 세요
|
|
||||||
소 소개 소리 소비자 소식 소중 소프트웨어
|
|
||||||
속 속도
|
|
||||||
손 손 손님
|
|
||||||
솔 솔직히
|
|
||||||
송 송금
|
|
||||||
쇼 쇼핑
|
|
||||||
수 수 수고 수고하세요 수량 수업 수요일 수정 수준 수출
|
|
||||||
숙 숙제
|
|
||||||
순 순서
|
|
||||||
술 술
|
|
||||||
쉬 쉬다 쉬운 쉽게
|
|
||||||
스 스마트폰 스케줄 스트레스 스타일
|
|
||||||
슬 슬프다
|
|
||||||
시 시 시간 시스템 시작 시장 시험
|
|
||||||
식 식당 식사
|
|
||||||
신 신경 신고 신용 신제품 신청 신호 신뢰 신규
|
|
||||||
실 실례 실수 실제 실패 실행 실험 실화
|
|
||||||
심 심각 심심
|
|
||||||
싶 싶다 싶어 싶으면
|
|
||||||
싸 싸다 싸움
|
|
||||||
쓰 쓰다 쓰레기 쓸
|
|
||||||
씨 씨
|
|
||||||
아 아 아까 아끼다 아니 아니요 아님 아마 아무 아버지 아이 아이디 아직 아침 아파 아프다
|
|
||||||
안 안 안내 안녕 안녕하세요 안되다 안전
|
|
||||||
알 알겠습니다 알겠어 알다 알려줘 알림 알바 알았어
|
|
||||||
앞 앞으로 앞에
|
|
||||||
애 애인
|
|
||||||
야 야
|
|
||||||
약 약 약간 약속
|
|
||||||
얘 얘기
|
|
||||||
어 어 어느 어디 어떤 어떻게 어렵다 어머니 어서 어제 어쩌면 어차피 어플
|
|
||||||
언 언니 언제 언젠가
|
|
||||||
얼 얼굴 얼마 얼마나
|
|
||||||
업 업그레이드 업데이트 업로드 업무 업체
|
|
||||||
없 없다 없어 없으면
|
|
||||||
에 에러
|
|
||||||
여 여기 여러 여름 여보세요 여자 여전히 여행
|
|
||||||
역 역시
|
|
||||||
연 연결 연구 연락 연습 연휴
|
|
||||||
열 열다 열심히
|
|
||||||
영 영상 영수증 영어 영업 영향 영화
|
|
||||||
예 예 예를 들어 예상 예약 예전 예정
|
|
||||||
오 오늘 오다 오래 오랜만 오른쪽 오빠 오전 오케이 오후
|
|
||||||
올 올라가다 올려 올리다 올해
|
|
||||||
와 와 와이파이 왔어
|
|
||||||
완 완료 완벽 완전
|
|
||||||
왜 왜
|
|
||||||
외 외국
|
|
||||||
요 요금 요새 요즘 요청
|
|
||||||
욕 욕
|
|
||||||
용 용 용도
|
|
||||||
우 우리 우선 우연히
|
|
||||||
운 운동 운영 운전
|
|
||||||
울 울다 울어
|
|
||||||
원 원 원래 원인 원하다 원해
|
|
||||||
월 월 월급 월요일
|
|
||||||
웹 웹사이트
|
|
||||||
위 위 위에 위주 위치 위해
|
|
||||||
유 유명 유용 유저 유지 유튜브 유행
|
|
||||||
으 으로 으면
|
|
||||||
은 은 은행
|
|
||||||
을 을
|
|
||||||
음 음 음식 음악
|
|
||||||
응 응 응답
|
|
||||||
의 의견 의미 의문 의사
|
|
||||||
이 이 이거 이것 이곳 이기다 이따 이때 이래 이런 이렇게 이름 이리 이메일 이미 이번 이상 이야기 이용 이유 이제 이전 이쪽 이틀 이해 이해하다
|
|
||||||
인 인간 인기 인사 인스타그램 인정 인증 인터넷 인터뷰
|
|
||||||
일 일 일단 일반 일부 일상 일요일 일을 일자 일정 일찍 일하다
|
|
||||||
읽 읽다 읽어
|
|
||||||
잃 잃다 잃어버리다
|
|
||||||
입 입금 입력 입장 입학
|
|
||||||
있 있다 있어 있으면
|
|
||||||
자 자 자기 자꾸 자다 자동 자료 자세히 자신 자연 자유 자주
|
|
||||||
작 작년 작동 작성 작업 작은 작품
|
|
||||||
잔 잔
|
|
||||||
잘 잘 잘가 잘됐다 잘못 잘하다
|
|
||||||
잠 잠 잠깐 잠시
|
|
||||||
장 장 장기 장난 장소 장점
|
|
||||||
잡 잡다 잡아
|
|
||||||
재 재미 재밌다 재밌어
|
|
||||||
저 저 저거 저기 저녁 저도 저렇게 저번 저장 저희
|
|
||||||
적 적다 적용 적절 적어도
|
|
||||||
전 전 전공 전달 전문 전부 전에 전자 전체 전혀 전화
|
|
||||||
절 절대 절반
|
|
||||||
점 점 점검 점심 점점
|
|
||||||
접 접속 접수 접근
|
|
||||||
정 정기 정도 정리 정말 정보 정상 정신 정식 정확
|
|
||||||
제 제가 제공 제대로 제목 제발 제안 제외 제일 제품
|
|
||||||
젤 젤
|
|
||||||
조 조건 조금 조사 조심 조절 조용 조치
|
|
||||||
존 존경 존재 존중
|
|
||||||
졸 졸려
|
|
||||||
종 종류 종종
|
|
||||||
좀 좀
|
|
||||||
좋 좋겠다 좋다 좋아 좋아요 좋아하다 좋은
|
|
||||||
죄 죄송 죄송합니다
|
|
||||||
주 주 주간 주로 주말 주문 주변 주세요 주소 주요 주의 주인 주제
|
|
||||||
준 준비
|
|
||||||
줄 줄 줄게
|
|
||||||
중 중간 중국 중심 중에 중요
|
|
||||||
즉 즉시
|
|
||||||
즐 즐거운 즐겁다 즐기다
|
|
||||||
증 증가
|
|
||||||
지 지각 지금 지나다 지난 지루 지역 지원 지인 지정 지출
|
|
||||||
직 직업 직원 직장 직접
|
|
||||||
진 진심 진짜 진행
|
|
||||||
질 질문 질서
|
|
||||||
집 집 집중
|
|
||||||
짧 짧은
|
|
||||||
짧 짧다
|
|
||||||
쪽 쪽 쪽으로
|
|
||||||
찍 찍다 찍어
|
|
||||||
차 차 차이 차후
|
|
||||||
참 참 참고 참여 참으로
|
|
||||||
찾 찾고 찾다 찾아 찾으면
|
|
||||||
채 채널 채팅
|
|
||||||
책 책 책임
|
|
||||||
처 처리 처음
|
|
||||||
천 천만에요 천원
|
|
||||||
철 철저
|
|
||||||
첫 첫 첫번째
|
|
||||||
청 청소 청구
|
|
||||||
체 체크 체험
|
|
||||||
초 초 초대 초반 초보
|
|
||||||
최 최고 최근 최대 최소 최선 최신 최적 최종
|
|
||||||
추 추가 추석 추천 추후
|
|
||||||
축 축하 축하드립니다 축하합니다 축하해
|
|
||||||
출 출근 출력 출발 출시 출장
|
|
||||||
충 충분 충전
|
|
||||||
취 취미 취소 취업 취향
|
|
||||||
치 치킨
|
|
||||||
친 친구 친절 친척
|
|
||||||
카 카드 카메라 카카오 카카오톡 카페
|
|
||||||
칼 칼퇴
|
|
||||||
커 커뮤니티 커피 커피숍
|
|
||||||
컨 컨디션 컨텐츠
|
|
||||||
컴 컴퓨터
|
|
||||||
케 케이스
|
|
||||||
코 코드 코로나
|
|
||||||
콘 콘서트 콘텐츠
|
|
||||||
클 클래스 클라이언트 클릭
|
|
||||||
큰 큰 큰일
|
|
||||||
타 타다 타이밍
|
|
||||||
탈 탈퇴
|
|
||||||
테 테스트 테이블
|
|
||||||
토 토요일
|
|
||||||
통 통신 통역 통장 통화
|
|
||||||
투 투자
|
|
||||||
특 특별 특별히 특이 특징 특히
|
|
||||||
틀 틀리다 틀림없이
|
|
||||||
티 티켓 티비
|
|
||||||
파 파악 파일 파티
|
|
||||||
판 판단 판매
|
|
||||||
팔 팔다 팔로우
|
|
||||||
팀 팀 팀장
|
|
||||||
패 패스워드
|
|
||||||
편 편리 편안 편의 편지 편하게 편하다
|
|
||||||
평 평가 평균 평소 평일
|
|
||||||
폰 폰
|
|
||||||
표 표 표시 표현
|
|
||||||
품 품질
|
|
||||||
프 프로그램 프로젝트 프로필
|
|
||||||
플 플랜
|
|
||||||
피 피곤 피드백 피하다
|
|
||||||
필 필수 필요 필요하다
|
|
||||||
하 하 하고 하나 하는 하다 하루 하면 하세요 하지마 하지만
|
|
||||||
한 한 한국 한글 한달 한두 한번 한편 한테
|
|
||||||
할 할 할게 할인
|
|
||||||
함 함께 함수
|
|
||||||
합 합계 합니다 합의
|
|
||||||
항 항목 항상
|
|
||||||
해 해 해결 해도 해봐 해볼게 해서 해야 해요 해외 해주세요
|
|
||||||
핵 핵심
|
|
||||||
행 행동 행복 행사
|
|
||||||
향 향상
|
|
||||||
허 허락
|
|
||||||
현 현금 현상 현재 현황
|
|
||||||
혹 혹시
|
|
||||||
홈 홈페이지
|
|
||||||
화 화 화나다 화요일 화이팅 화인 화장실
|
|
||||||
확 확대 확보 확실 확실히 확인
|
|
||||||
환 환경 환불 환영
|
|
||||||
활 활동 활용
|
|
||||||
회 회 회사 회식 회원 회의
|
|
||||||
효 효과
|
|
||||||
후 후 후기 후에
|
|
||||||
휴 휴가 휴대폰 휴식 휴일
|
|
||||||
흔 흔히
|
|
||||||
힘 힘 힘내 힘들다 힘들어
|
|
||||||
;;
|
|
||||||
;; Common phrases (자주 쓰는 문장)
|
|
||||||
감사합 감사합니다
|
|
||||||
고맙습 고맙습니다
|
|
||||||
고마워 고마워요
|
|
||||||
괜찮습 괜찮습니다
|
|
||||||
반갑습 반갑습니다
|
|
||||||
안녕하 안녕하세요 안녕하십니까
|
|
||||||
알겠습 알겠습니다
|
|
||||||
죄송합 죄송합니다
|
|
||||||
축하합 축하합니다
|
|
||||||
수고하 수고하세요 수고하셨습니다
|
|
||||||
미안합 미안합니다
|
|
||||||
실례합 실례합니다
|
|
||||||
부탁드 부탁드립니다
|
|
||||||
감사해 감사해요
|
|
||||||
고마워 고마워요
|
|
||||||
미안해 미안해요
|
|
||||||
안녕히 안녕히 가세요 안녕히 계세요
|
|
||||||
잘부탁 잘부탁드립니다
|
|
||||||
오랜만 오랜만이에요 오랜만입니다
|
|
||||||
좋은하 좋은하루
|
|
||||||
11212
map/hangul.map
11212
map/hangul.map
File diff suppressed because it is too large
Load Diff
39
map/mkemoji
Executable file
39
map/mkemoji
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
awk '
|
||||||
|
BEGIN { FS = "\t" }
|
||||||
|
/^$/ { next }
|
||||||
|
{
|
||||||
|
key = $1
|
||||||
|
val = $2
|
||||||
|
map[key] = val
|
||||||
|
for(i = 1; i < length(key); i++){
|
||||||
|
p = substr(key, 1, i)
|
||||||
|
if(!(p in map))
|
||||||
|
map[p] = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
for(k in map)
|
||||||
|
print k "\t" map[k]
|
||||||
|
}
|
||||||
|
' $1 | sort -k1,1 > emoji.map
|
||||||
|
|
||||||
|
awk '
|
||||||
|
BEGIN { FS = "\t" }
|
||||||
|
/^$/ { next }
|
||||||
|
{
|
||||||
|
key = $1
|
||||||
|
val = $2
|
||||||
|
for(i = 1; i <= length(key); i++){
|
||||||
|
p = substr(key, 1, i)
|
||||||
|
dict[p] = dict[p] " " val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
for(p in dict){
|
||||||
|
sub(/^ /, "", dict[p])
|
||||||
|
print p "\t" dict[p]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' $1 | sort -k1,1 > emoji.dict
|
||||||
159
map/mktelex.py
Executable file
159
map/mktelex.py
Executable file
@@ -0,0 +1,159 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# tone marks: s=rising f=falling r=hook x=tilde j=dot
|
||||||
|
tone = {
|
||||||
|
's': str.maketrans("aăâeêioôơuưy", "áắấéếíóốớúứý"),
|
||||||
|
'f': str.maketrans("aăâeêioôơuưy", "àằầèềìòồờùừỳ"),
|
||||||
|
'r': str.maketrans("aăâeêioôơuưy", "ảẳẩẻểỉỏổởủửỷ"),
|
||||||
|
'x': str.maketrans("aăâeêioôơuưy", "ãẵẫẽễĩõỗỡũữỹ"),
|
||||||
|
'j': str.maketrans("aăâeêioôơuưy", "ạặậẹệịọộợụựỵ"),
|
||||||
|
}
|
||||||
|
|
||||||
|
# modified vowels: input -> output
|
||||||
|
modvowel = [
|
||||||
|
("aw", "ă"),
|
||||||
|
("aa", "â"),
|
||||||
|
("ee", "ê"),
|
||||||
|
("oo", "ô"),
|
||||||
|
("ow", "ơ"),
|
||||||
|
("uw", "ư"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# modified cons: input -> output
|
||||||
|
modcons = [
|
||||||
|
("dd", "đ"),
|
||||||
|
]
|
||||||
|
|
||||||
|
upper = str.maketrans(
|
||||||
|
"aăâeêioôơuưyđáắấéếíóốớúứýàằầèềìòồờùừỳảẳẩẻểỉỏổởủửỷãẵẫẽễĩõỗỡũữỹạặậẹệịọộợụựỵ",
|
||||||
|
"AĂÂEÊIOÔƠUƯYĐÁẮẤÉẾÍÓỐỚÚỨÝÀẰẦÈỀÌÒỒỜÙỪỲẢẲẨẺỂỈỎỔỞỦỬỶÃẴẪẼỄĨÕỖỠŨỮỸẠẶẬẸỆỊỌỘỢỤỰỴ")
|
||||||
|
|
||||||
|
def addtone(v, t):
|
||||||
|
return v.translate(tone[t])
|
||||||
|
|
||||||
|
def emit(input, output):
|
||||||
|
print(f"{input}\t{output}")
|
||||||
|
def up(s):
|
||||||
|
c = s[0].translate(upper)
|
||||||
|
if c == s[0]:
|
||||||
|
c = s[0].upper()
|
||||||
|
return c + s[1:]
|
||||||
|
print(f"{up(input)}\t{up(output)}")
|
||||||
|
|
||||||
|
def vowel1():
|
||||||
|
for v in "aeiouy":
|
||||||
|
emit(v, v)
|
||||||
|
for t in tone:
|
||||||
|
emit(v+t, addtone(v, t))
|
||||||
|
|
||||||
|
def vowel2():
|
||||||
|
# input, output, vowel
|
||||||
|
tab = [
|
||||||
|
("oa", "oa", "a"), ("oe", "oe", "e"), ("ai", "ai", "a"),
|
||||||
|
("ao", "ao", "a"), ("au", "au", "a"), ("ay", "ay", "a"),
|
||||||
|
("eu", "eu", "e"), ("iu", "iu", "i"), ("oi", "oi", "o"),
|
||||||
|
("ui", "ui", "u"), ("uy", "uy", "y"),
|
||||||
|
("iee", "iê", "ê"), ("yee", "yê", "ê"), ("uoo", "uô", "ô"),
|
||||||
|
("uow", "ươ", "ơ"), ("uaa", "uâ", "â"), ("oaw", "oă", "ă"),
|
||||||
|
("uwa", "ưa", "a"), ("uwow", "ươ", "ơ"),
|
||||||
|
]
|
||||||
|
for i, o, v in tab:
|
||||||
|
emit(i, o)
|
||||||
|
for t in tone:
|
||||||
|
emit(i+t, o.replace(v, addtone(v, t), 1))
|
||||||
|
emit("ie", "ie")
|
||||||
|
emit("ye", "ye")
|
||||||
|
emit("uo", "uo")
|
||||||
|
emit("ua", "ua")
|
||||||
|
|
||||||
|
def vowel3():
|
||||||
|
# input, output, vowel
|
||||||
|
tab = [
|
||||||
|
("ieeu", "iêu", "ê"), ("yeeu", "yêu", "ê"),
|
||||||
|
("uooi", "uôi", "ô"), ("uowi", "ươi", "ơ"),
|
||||||
|
("oai", "oai", "a"), ("oay", "oay", "a"),
|
||||||
|
("uyee", "uyê", "ê"),
|
||||||
|
]
|
||||||
|
for i, o, v in tab:
|
||||||
|
emit(i, o)
|
||||||
|
for t in tone:
|
||||||
|
emit(i+t, o.replace(v, addtone(v, t), 1))
|
||||||
|
emit("uya", "uya")
|
||||||
|
|
||||||
|
def modvowels():
|
||||||
|
for i, o in modvowel:
|
||||||
|
emit(i, o)
|
||||||
|
|
||||||
|
def modconss():
|
||||||
|
for i, o in modcons:
|
||||||
|
emit(i, o)
|
||||||
|
|
||||||
|
def mod1tone():
|
||||||
|
# aw+s -> ắ
|
||||||
|
for i, o in modvowel:
|
||||||
|
for t in tone:
|
||||||
|
emit(i+t, addtone(o, t))
|
||||||
|
|
||||||
|
modvowel = [
|
||||||
|
("aw", "ă"),
|
||||||
|
("aa", "â"),
|
||||||
|
("ee", "ê"),
|
||||||
|
("oo", "ô"),
|
||||||
|
("ow", "ơ"),
|
||||||
|
("uw", "ư"),
|
||||||
|
]
|
||||||
|
def tone1mod():
|
||||||
|
# a+s+w -> ắ
|
||||||
|
for i, o in modvowel:
|
||||||
|
for t in tone:
|
||||||
|
emit(i[0]+t+i[1], addtone(o, t))
|
||||||
|
|
||||||
|
def tone2mod():
|
||||||
|
# ie+s+e -> iế
|
||||||
|
# input, output, vowel, suffix
|
||||||
|
tab = [
|
||||||
|
("ie", "iê", "ê", "e"), ("ye", "yê", "ê", "e"),
|
||||||
|
("uo", "uô", "ô", "o"), ("uo", "ươ", "ơ", "w"),
|
||||||
|
("ua", "uâ", "â", "a"), ("oa", "oă", "ă", "w"),
|
||||||
|
("uwo", "ươ", "ơ", "w"),
|
||||||
|
]
|
||||||
|
for i, o, v, s in tab:
|
||||||
|
for t in tone:
|
||||||
|
emit(i+t+s, o.replace(v, addtone(v, t), 1))
|
||||||
|
|
||||||
|
def escape():
|
||||||
|
# aww -> aw
|
||||||
|
for e in ["aw", "aa", "ee", "oo", "ow", "uw", "dd"]:
|
||||||
|
emit(e+e[-1], e)
|
||||||
|
|
||||||
|
def final():
|
||||||
|
# codas
|
||||||
|
coda = ["c", "m", "n", "p", "t", "ch", "ng", "nh"]
|
||||||
|
# input, output, vowel
|
||||||
|
tab = [
|
||||||
|
("a", "a", "a"), ("e", "e", "e"), ("i", "i", "i"),
|
||||||
|
("o", "o", "o"), ("u", "u", "u"), ("y", "y", "y"),
|
||||||
|
("aw", "ă", "ă"), ("aa", "â", "â"), ("ee", "ê", "ê"),
|
||||||
|
("oo", "ô", "ô"), ("ow", "ơ", "ơ"), ("uw", "ư", "ư"),
|
||||||
|
("iee", "iê", "ê"), ("yee", "yê", "ê"), ("uoo", "uô", "ô"),
|
||||||
|
("uow", "ươ", "ơ"), ("uaa", "uâ", "â"), ("oaw", "oă", "ă"),
|
||||||
|
("ai", "ai", "a"), ("ao", "ao", "a"), ("au", "au", "a"),
|
||||||
|
("ay", "ay", "a"), ("oa", "oa", "a"), ("oi", "oi", "o"),
|
||||||
|
("ui", "ui", "u"), ("uy", "uy", "y"),
|
||||||
|
]
|
||||||
|
for i, o, v in tab:
|
||||||
|
for c in coda:
|
||||||
|
emit(i+c, o+c)
|
||||||
|
for t in tone:
|
||||||
|
emit(i+c+t, o.replace(v, addtone(v, t), 1)+c)
|
||||||
|
|
||||||
|
vowel1()
|
||||||
|
vowel2()
|
||||||
|
vowel3()
|
||||||
|
modvowels()
|
||||||
|
modconss()
|
||||||
|
mod1tone()
|
||||||
|
tone1mod()
|
||||||
|
tone2mod()
|
||||||
|
escape()
|
||||||
|
final()
|
||||||
708
map/telex.map
708
map/telex.map
@@ -1,131 +1,589 @@
|
|||||||
aw ă
|
a a
|
||||||
|
A A
|
||||||
aa â
|
aa â
|
||||||
|
Aa Â
|
||||||
|
aaa aa
|
||||||
|
Aaa Aa
|
||||||
|
aac âc
|
||||||
|
Aac Âc
|
||||||
|
aach âch
|
||||||
|
Aach Âch
|
||||||
|
aam âm
|
||||||
|
Aam Âm
|
||||||
|
aan ân
|
||||||
|
Aan Ân
|
||||||
|
aang âng
|
||||||
|
Aang Âng
|
||||||
|
aanh ânh
|
||||||
|
Aanh Ânh
|
||||||
|
aap âp
|
||||||
|
Aap Âp
|
||||||
|
aat ât
|
||||||
|
Aat Ât
|
||||||
|
ac ac
|
||||||
|
Ac Ac
|
||||||
|
ach ach
|
||||||
|
Ach Ach
|
||||||
|
ai ai
|
||||||
|
Ai Ai
|
||||||
|
aic aic
|
||||||
|
Aic Aic
|
||||||
|
aich aich
|
||||||
|
Aich Aich
|
||||||
|
aim aim
|
||||||
|
Aim Aim
|
||||||
|
ain ain
|
||||||
|
Ain Ain
|
||||||
|
aing aing
|
||||||
|
Aing Aing
|
||||||
|
ainh ainh
|
||||||
|
Ainh Ainh
|
||||||
|
aip aip
|
||||||
|
Aip Aip
|
||||||
|
ait ait
|
||||||
|
Ait Ait
|
||||||
|
am am
|
||||||
|
Am Am
|
||||||
|
an an
|
||||||
|
An An
|
||||||
|
ang ang
|
||||||
|
Ang Ang
|
||||||
|
anh anh
|
||||||
|
Anh Anh
|
||||||
|
ao ao
|
||||||
|
Ao Ao
|
||||||
|
aoc aoc
|
||||||
|
Aoc Aoc
|
||||||
|
aoch aoch
|
||||||
|
Aoch Aoch
|
||||||
|
aom aom
|
||||||
|
Aom Aom
|
||||||
|
aon aon
|
||||||
|
Aon Aon
|
||||||
|
aong aong
|
||||||
|
Aong Aong
|
||||||
|
aonh aonh
|
||||||
|
Aonh Aonh
|
||||||
|
aop aop
|
||||||
|
Aop Aop
|
||||||
|
aot aot
|
||||||
|
Aot Aot
|
||||||
|
ap ap
|
||||||
|
Ap Ap
|
||||||
|
at at
|
||||||
|
At At
|
||||||
|
au au
|
||||||
|
Au Au
|
||||||
|
auc auc
|
||||||
|
Auc Auc
|
||||||
|
auch auch
|
||||||
|
Auch Auch
|
||||||
|
aum aum
|
||||||
|
Aum Aum
|
||||||
|
aun aun
|
||||||
|
Aun Aun
|
||||||
|
aung aung
|
||||||
|
Aung Aung
|
||||||
|
aunh aunh
|
||||||
|
Aunh Aunh
|
||||||
|
aup aup
|
||||||
|
Aup Aup
|
||||||
|
aut aut
|
||||||
|
Aut Aut
|
||||||
|
aw ă
|
||||||
|
Aw Ă
|
||||||
|
awc ăc
|
||||||
|
Awc Ăc
|
||||||
|
awch ăch
|
||||||
|
Awch Ăch
|
||||||
|
awm ăm
|
||||||
|
Awm Ăm
|
||||||
|
awn ăn
|
||||||
|
Awn Ăn
|
||||||
|
awng ăng
|
||||||
|
Awng Ăng
|
||||||
|
awnh ănh
|
||||||
|
Awnh Ănh
|
||||||
|
awp ăp
|
||||||
|
Awp Ăp
|
||||||
|
awt ăt
|
||||||
|
Awt Ăt
|
||||||
|
aww aw
|
||||||
|
Aww Aw
|
||||||
|
ay ay
|
||||||
|
Ay Ay
|
||||||
|
ayc ayc
|
||||||
|
Ayc Ayc
|
||||||
|
aych aych
|
||||||
|
Aych Aych
|
||||||
|
aym aym
|
||||||
|
Aym Aym
|
||||||
|
ayn ayn
|
||||||
|
Ayn Ayn
|
||||||
|
ayng ayng
|
||||||
|
Ayng Ayng
|
||||||
|
aynh aynh
|
||||||
|
Aynh Aynh
|
||||||
|
ayp ayp
|
||||||
|
Ayp Ayp
|
||||||
|
ayt ayt
|
||||||
|
Ayt Ayt
|
||||||
dd đ
|
dd đ
|
||||||
|
Dd Đ
|
||||||
|
ddd dd
|
||||||
|
Ddd Dd
|
||||||
|
ec ec
|
||||||
|
Ec Ec
|
||||||
|
ech ech
|
||||||
|
Ech Ech
|
||||||
|
e e
|
||||||
|
E E
|
||||||
|
eec êc
|
||||||
|
Eec Êc
|
||||||
|
eech êch
|
||||||
|
Eech Êch
|
||||||
ee ê
|
ee ê
|
||||||
|
Ee Ê
|
||||||
|
eee ee
|
||||||
|
Eee Ee
|
||||||
|
eem êm
|
||||||
|
Eem Êm
|
||||||
|
een ên
|
||||||
|
Een Ên
|
||||||
|
eeng êng
|
||||||
|
Eeng Êng
|
||||||
|
eenh ênh
|
||||||
|
Eenh Ênh
|
||||||
|
eep êp
|
||||||
|
Eep Êp
|
||||||
|
eet êt
|
||||||
|
Eet Êt
|
||||||
|
em em
|
||||||
|
Em Em
|
||||||
|
en en
|
||||||
|
En En
|
||||||
|
eng eng
|
||||||
|
Eng Eng
|
||||||
|
enh enh
|
||||||
|
Enh Enh
|
||||||
|
ep ep
|
||||||
|
Ep Ep
|
||||||
|
et et
|
||||||
|
Et Et
|
||||||
|
eu eu
|
||||||
|
Eu Eu
|
||||||
|
ich ich
|
||||||
|
Ich Ich
|
||||||
|
ic ic
|
||||||
|
Ic Ic
|
||||||
|
ieech iêch
|
||||||
|
Ieech Iêch
|
||||||
|
ieec iêc
|
||||||
|
Ieec Iêc
|
||||||
|
iee iê
|
||||||
|
Iee Iê
|
||||||
|
ieem iêm
|
||||||
|
Ieem Iêm
|
||||||
|
ieeng iêng
|
||||||
|
Ieeng Iêng
|
||||||
|
ieenh iênh
|
||||||
|
Ieenh Iênh
|
||||||
|
ieen iên
|
||||||
|
Ieen Iên
|
||||||
|
ieep iêp
|
||||||
|
Ieep Iêp
|
||||||
|
ieet iêt
|
||||||
|
Ieet Iêt
|
||||||
|
ieeu iêu
|
||||||
|
Ieeu Iêu
|
||||||
|
iefe iề
|
||||||
|
Iefe Iề
|
||||||
|
ie ie
|
||||||
|
Ie Ie
|
||||||
|
ieje iệ
|
||||||
|
Ieje Iệ
|
||||||
|
iere iể
|
||||||
|
Iere Iể
|
||||||
|
iese iế
|
||||||
|
Iese Iế
|
||||||
|
iexe iễ
|
||||||
|
Iexe Iễ
|
||||||
|
i i
|
||||||
|
I I
|
||||||
|
im im
|
||||||
|
Im Im
|
||||||
|
ing ing
|
||||||
|
Ing Ing
|
||||||
|
inh inh
|
||||||
|
Inh Inh
|
||||||
|
in in
|
||||||
|
In In
|
||||||
|
ip ip
|
||||||
|
Ip Ip
|
||||||
|
it it
|
||||||
|
It It
|
||||||
|
iu iu
|
||||||
|
Iu Iu
|
||||||
|
oach oach
|
||||||
|
Oach Oach
|
||||||
|
oac oac
|
||||||
|
Oac Oac
|
||||||
|
oafw oằ
|
||||||
|
Oafw Oằ
|
||||||
|
oai oai
|
||||||
|
Oai Oai
|
||||||
|
oajw oặ
|
||||||
|
Oajw Oặ
|
||||||
|
oam oam
|
||||||
|
Oam Oam
|
||||||
|
oang oang
|
||||||
|
Oang Oang
|
||||||
|
oanh oanh
|
||||||
|
Oanh Oanh
|
||||||
|
oan oan
|
||||||
|
Oan Oan
|
||||||
|
oa oa
|
||||||
|
Oa Oa
|
||||||
|
oap oap
|
||||||
|
Oap Oap
|
||||||
|
oarw oẳ
|
||||||
|
Oarw Oẳ
|
||||||
|
oasw oắ
|
||||||
|
Oasw Oắ
|
||||||
|
oat oat
|
||||||
|
Oat Oat
|
||||||
|
oawch oăch
|
||||||
|
Oawch Oăch
|
||||||
|
oawc oăc
|
||||||
|
Oawc Oăc
|
||||||
|
oawm oăm
|
||||||
|
Oawm Oăm
|
||||||
|
oawng oăng
|
||||||
|
Oawng Oăng
|
||||||
|
oawnh oănh
|
||||||
|
Oawnh Oănh
|
||||||
|
oawn oăn
|
||||||
|
Oawn Oăn
|
||||||
|
oaw oă
|
||||||
|
Oaw Oă
|
||||||
|
oawp oăp
|
||||||
|
Oawp Oăp
|
||||||
|
oawt oăt
|
||||||
|
Oawt Oăt
|
||||||
|
oaxw oẵ
|
||||||
|
Oaxw Oẵ
|
||||||
|
oay oay
|
||||||
|
Oay Oay
|
||||||
|
och och
|
||||||
|
Och Och
|
||||||
|
oc oc
|
||||||
|
Oc Oc
|
||||||
|
oe oe
|
||||||
|
Oe Oe
|
||||||
|
oich oich
|
||||||
|
Oich Oich
|
||||||
|
oic oic
|
||||||
|
Oic Oic
|
||||||
|
oim oim
|
||||||
|
Oim Oim
|
||||||
|
oing oing
|
||||||
|
Oing Oing
|
||||||
|
oinh oinh
|
||||||
|
Oinh Oinh
|
||||||
|
oin oin
|
||||||
|
Oin Oin
|
||||||
|
oi oi
|
||||||
|
Oi Oi
|
||||||
|
oip oip
|
||||||
|
Oip Oip
|
||||||
|
oit oit
|
||||||
|
Oit Oit
|
||||||
|
om om
|
||||||
|
Om Om
|
||||||
|
ong ong
|
||||||
|
Ong Ong
|
||||||
|
onh onh
|
||||||
|
Onh Onh
|
||||||
|
on on
|
||||||
|
On On
|
||||||
|
o o
|
||||||
|
O O
|
||||||
|
ooch ôch
|
||||||
|
Ooch Ôch
|
||||||
|
ooc ôc
|
||||||
|
Ooc Ôc
|
||||||
|
oom ôm
|
||||||
|
Oom Ôm
|
||||||
|
oong ông
|
||||||
|
Oong Ông
|
||||||
|
oonh ônh
|
||||||
|
Oonh Ônh
|
||||||
|
oon ôn
|
||||||
|
Oon Ôn
|
||||||
oo ô
|
oo ô
|
||||||
|
Oo Ô
|
||||||
|
ooo oo
|
||||||
|
Ooo Oo
|
||||||
|
oop ôp
|
||||||
|
Oop Ôp
|
||||||
|
oot ôt
|
||||||
|
Oot Ôt
|
||||||
|
op op
|
||||||
|
Op Op
|
||||||
|
ot ot
|
||||||
|
Ot Ot
|
||||||
|
owch ơch
|
||||||
|
Owch Ơch
|
||||||
|
owc ơc
|
||||||
|
Owc Ơc
|
||||||
|
owm ơm
|
||||||
|
Owm Ơm
|
||||||
|
owng ơng
|
||||||
|
Owng Ơng
|
||||||
|
ownh ơnh
|
||||||
|
Ownh Ơnh
|
||||||
|
own ơn
|
||||||
|
Own Ơn
|
||||||
ow ơ
|
ow ơ
|
||||||
|
Ow Ơ
|
||||||
|
owp ơp
|
||||||
|
Owp Ơp
|
||||||
|
owt ơt
|
||||||
|
Owt Ơt
|
||||||
|
oww ow
|
||||||
|
Oww Ow
|
||||||
|
uaach uâch
|
||||||
|
Uaach Uâch
|
||||||
|
uaac uâc
|
||||||
|
Uaac Uâc
|
||||||
|
uaam uâm
|
||||||
|
Uaam Uâm
|
||||||
|
uaang uâng
|
||||||
|
Uaang Uâng
|
||||||
|
uaanh uânh
|
||||||
|
Uaanh Uânh
|
||||||
|
uaan uân
|
||||||
|
Uaan Uân
|
||||||
|
uaap uâp
|
||||||
|
Uaap Uâp
|
||||||
|
uaat uât
|
||||||
|
Uaat Uât
|
||||||
|
uaa uâ
|
||||||
|
Uaa Uâ
|
||||||
|
uafa uầ
|
||||||
|
Uafa Uầ
|
||||||
|
uaja uậ
|
||||||
|
Uaja Uậ
|
||||||
|
uara uẩ
|
||||||
|
Uara Uẩ
|
||||||
|
uasa uấ
|
||||||
|
Uasa Uấ
|
||||||
|
ua ua
|
||||||
|
Ua Ua
|
||||||
|
uaxa uẫ
|
||||||
|
Uaxa Uẫ
|
||||||
|
uch uch
|
||||||
|
Uch Uch
|
||||||
|
uc uc
|
||||||
|
Uc Uc
|
||||||
|
uich uich
|
||||||
|
Uich Uich
|
||||||
|
uic uic
|
||||||
|
Uic Uic
|
||||||
|
uim uim
|
||||||
|
Uim Uim
|
||||||
|
uing uing
|
||||||
|
Uing Uing
|
||||||
|
uinh uinh
|
||||||
|
Uinh Uinh
|
||||||
|
uin uin
|
||||||
|
Uin Uin
|
||||||
|
uip uip
|
||||||
|
Uip Uip
|
||||||
|
uit uit
|
||||||
|
Uit Uit
|
||||||
|
ui ui
|
||||||
|
Ui Ui
|
||||||
|
um um
|
||||||
|
Um Um
|
||||||
|
ung ung
|
||||||
|
Ung Ung
|
||||||
|
unh unh
|
||||||
|
Unh Unh
|
||||||
|
un un
|
||||||
|
Un Un
|
||||||
|
uofo uồ
|
||||||
|
Uofo Uồ
|
||||||
|
uofw ườ
|
||||||
|
Uofw Ườ
|
||||||
|
uojo uộ
|
||||||
|
Uojo Uộ
|
||||||
|
uojw ượ
|
||||||
|
Uojw Ượ
|
||||||
|
uooch uôch
|
||||||
|
Uooch Uôch
|
||||||
|
uooc uôc
|
||||||
|
Uooc Uôc
|
||||||
|
uooi uôi
|
||||||
|
Uooi Uôi
|
||||||
|
uoom uôm
|
||||||
|
Uoom Uôm
|
||||||
|
uoong uông
|
||||||
|
Uoong Uông
|
||||||
|
uoonh uônh
|
||||||
|
Uoonh Uônh
|
||||||
|
uoon uôn
|
||||||
|
Uoon Uôn
|
||||||
|
uoop uôp
|
||||||
|
Uoop Uôp
|
||||||
|
uoot uôt
|
||||||
|
Uoot Uôt
|
||||||
|
uoo uô
|
||||||
|
Uoo Uô
|
||||||
|
uoro uổ
|
||||||
|
Uoro Uổ
|
||||||
|
uorw ưở
|
||||||
|
Uorw Ưở
|
||||||
|
uoso uố
|
||||||
|
Uoso Uố
|
||||||
|
uosw ướ
|
||||||
|
Uosw Ướ
|
||||||
|
uo uo
|
||||||
|
Uo Uo
|
||||||
|
uowch ươch
|
||||||
|
Uowch Ươch
|
||||||
|
uowc ươc
|
||||||
|
Uowc Ươc
|
||||||
|
uowi ươi
|
||||||
|
Uowi Ươi
|
||||||
|
uowm ươm
|
||||||
|
Uowm Ươm
|
||||||
|
uowng ương
|
||||||
|
Uowng Ương
|
||||||
|
uownh ươnh
|
||||||
|
Uownh Ươnh
|
||||||
|
uown ươn
|
||||||
|
Uown Ươn
|
||||||
|
uowp ươp
|
||||||
|
Uowp Ươp
|
||||||
|
uowt ươt
|
||||||
|
Uowt Ươt
|
||||||
|
uow ươ
|
||||||
|
Uow Ươ
|
||||||
|
uoxo uỗ
|
||||||
|
Uoxo Uỗ
|
||||||
|
uoxw ưỡ
|
||||||
|
Uoxw Ưỡ
|
||||||
|
up up
|
||||||
|
Up Up
|
||||||
|
ut ut
|
||||||
|
Ut Ut
|
||||||
|
u u
|
||||||
|
U U
|
||||||
|
uwa ưa
|
||||||
|
Uwa Ưa
|
||||||
|
uwch ưch
|
||||||
|
Uwch Ưch
|
||||||
|
uwc ưc
|
||||||
|
Uwc Ưc
|
||||||
|
uwm ưm
|
||||||
|
Uwm Ưm
|
||||||
|
uwng ưng
|
||||||
|
Uwng Ưng
|
||||||
|
uwnh ưnh
|
||||||
|
Uwnh Ưnh
|
||||||
|
uwn ưn
|
||||||
|
Uwn Ưn
|
||||||
|
uwofw ườ
|
||||||
|
Uwofw Ườ
|
||||||
|
uwojw ượ
|
||||||
|
Uwojw Ượ
|
||||||
|
uworw ưở
|
||||||
|
Uworw Ưở
|
||||||
|
uwosw ướ
|
||||||
|
Uwosw Ướ
|
||||||
|
uwow ươ
|
||||||
|
Uwow Ươ
|
||||||
|
uwoxw ưỡ
|
||||||
|
Uwoxw Ưỡ
|
||||||
|
uwp ưp
|
||||||
|
Uwp Ưp
|
||||||
|
uwt ưt
|
||||||
|
Uwt Ưt
|
||||||
uw ư
|
uw ư
|
||||||
êe ee
|
Uw Ư
|
||||||
âa aa
|
uww uw
|
||||||
đd dd
|
Uww Uw
|
||||||
ôo oo
|
uya uya
|
||||||
Af À
|
Uya Uya
|
||||||
af à
|
uych uych
|
||||||
Ăf Ằ
|
Uych Uych
|
||||||
ăf ằ
|
uyc uyc
|
||||||
Âf Ầ
|
Uyc Uyc
|
||||||
âf ầ
|
uyee uyê
|
||||||
Ef È
|
Uyee Uyê
|
||||||
ef è
|
uym uym
|
||||||
Êf Ề
|
Uym Uym
|
||||||
êf ề
|
uyng uyng
|
||||||
If Ì
|
Uyng Uyng
|
||||||
if ì
|
uynh uynh
|
||||||
Of Ò
|
Uynh Uynh
|
||||||
of ò
|
uyn uyn
|
||||||
Ôf Ồ
|
Uyn Uyn
|
||||||
ôf ồ
|
uyp uyp
|
||||||
Ơf Ờ
|
Uyp Uyp
|
||||||
ơf ờ
|
uyt uyt
|
||||||
Uf Ù
|
Uyt Uyt
|
||||||
uf ù
|
uy uy
|
||||||
Ưf Ừ
|
Uy Uy
|
||||||
ưf ừ
|
ych ych
|
||||||
Yf Ỳ
|
Ych Ych
|
||||||
yf ỳ
|
yc yc
|
||||||
As Á
|
Yc Yc
|
||||||
as á
|
yeech yêch
|
||||||
Ăs Ắ
|
Yeech Yêch
|
||||||
ăs ắ
|
yeec yêc
|
||||||
Âs Ấ
|
Yeec Yêc
|
||||||
âs ấ
|
yeem yêm
|
||||||
Es É
|
Yeem Yêm
|
||||||
es é
|
yeeng yêng
|
||||||
Ês Ế
|
Yeeng Yêng
|
||||||
ês ế
|
yeenh yênh
|
||||||
Is Í
|
Yeenh Yênh
|
||||||
is í
|
yeen yên
|
||||||
Os Ó
|
Yeen Yên
|
||||||
os ó
|
yeep yêp
|
||||||
Ôs Ố
|
Yeep Yêp
|
||||||
ôs ố
|
yeet yêt
|
||||||
Ơs Ớ
|
Yeet Yêt
|
||||||
ơs ớ
|
yeeu yêu
|
||||||
Us Ú
|
Yeeu Yêu
|
||||||
us ú
|
yee yê
|
||||||
Ưs Ứ
|
Yee Yê
|
||||||
ưs ứ
|
yefe yề
|
||||||
Ys Ý
|
Yefe Yề
|
||||||
ys ý
|
yeje yệ
|
||||||
Ar Ả
|
Yeje Yệ
|
||||||
ar ả
|
yere yể
|
||||||
Ăr Ẳ
|
Yere Yể
|
||||||
ăr ẳ
|
yese yế
|
||||||
Âr Ẩ
|
Yese Yế
|
||||||
âr ẩ
|
yexe yễ
|
||||||
Er Ẻ
|
Yexe Yễ
|
||||||
er ẻ
|
ye ye
|
||||||
Êr Ể
|
Ye Ye
|
||||||
êr ể
|
ym ym
|
||||||
Ir Ỉ
|
Ym Ym
|
||||||
ir ỉ
|
yng yng
|
||||||
Or Ỏ
|
Yng Yng
|
||||||
or ỏ
|
ynh ynh
|
||||||
Ôr Ổ
|
Ynh Ynh
|
||||||
ôr ổ
|
yn yn
|
||||||
Ơr Ở
|
Yn Yn
|
||||||
ơr ở
|
yp yp
|
||||||
Ur Ủ
|
Yp Yp
|
||||||
ur ủ
|
yt yt
|
||||||
Ưr Ử
|
Yt Yt
|
||||||
ưr ử
|
y y
|
||||||
Yr Ỷ
|
Y Y
|
||||||
yr ỷ
|
\ \
|
||||||
Ax Ã
|
|
||||||
ax ã
|
|
||||||
Ăx Ẵ
|
|
||||||
ăx ẵ
|
|
||||||
Âx Ẫ
|
|
||||||
âx ẫ
|
|
||||||
Ex Ẽ
|
|
||||||
ex ẽ
|
|
||||||
Êx Ễ
|
|
||||||
êx ễ
|
|
||||||
Ix Ĩ
|
|
||||||
ix ĩ
|
|
||||||
Ox Õ
|
|
||||||
ox õ
|
|
||||||
Ôx Ỗ
|
|
||||||
ôx ỗ
|
|
||||||
Ơx Ỡ
|
|
||||||
ơx ỡ
|
|
||||||
Ux Ũ
|
|
||||||
ux ũ
|
|
||||||
Ưx Ữ
|
|
||||||
ưx ữ
|
|
||||||
Yx Ỹ
|
|
||||||
yx ỹ
|
|
||||||
Aj Ạ
|
|
||||||
aj ạ
|
|
||||||
Ăj Ặ
|
|
||||||
ăj ặ
|
|
||||||
Âj Ậ
|
|
||||||
âj ậ
|
|
||||||
Ej Ẹ
|
|
||||||
ej ẹ
|
|
||||||
Êj Ệ
|
|
||||||
êj ệ
|
|
||||||
Ij Ị
|
|
||||||
ij ị
|
|
||||||
Oj Ọ
|
|
||||||
oj ọ
|
|
||||||
Ôj Ộ
|
|
||||||
ôj ộ
|
|
||||||
Ơj Ợ
|
|
||||||
ơj ợ
|
|
||||||
Uj Ụ
|
|
||||||
uj ụ
|
|
||||||
Ưj Ự
|
|
||||||
ưj ự
|
|
||||||
Yj Ỵ
|
|
||||||
yj ỵ
|
|
||||||
|
|||||||
2
run.sh
2
run.sh
@@ -4,6 +4,6 @@ pkill strans
|
|||||||
pkill strans-xim
|
pkill strans-xim
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
./strans map font/font.otf &
|
./strans map font &
|
||||||
sleep 1
|
sleep 1
|
||||||
xim/strans-xim &
|
xim/strans-xim &
|
||||||
|
|||||||
242
strans.c
242
strans.c
@@ -2,11 +2,21 @@
|
|||||||
#include "fn.h"
|
#include "fn.h"
|
||||||
|
|
||||||
static Im im;
|
static Im im;
|
||||||
|
static void dictqmap(Im*);
|
||||||
|
|
||||||
|
static void
|
||||||
|
backmap(Im *im)
|
||||||
|
{
|
||||||
|
spopr(&im->pre);
|
||||||
|
}
|
||||||
|
|
||||||
Lang langs[] = {
|
Lang langs[] = {
|
||||||
{LangJP, "hira", "kanji", nil, nil, jptrans},
|
{LangEN, "english", nil, transmap, backmap, dictqmap, nil, nil},
|
||||||
{LangJPK, "kata", "kanji", nil, nil, jptrans},
|
{LangJP, "hira", "kanji", transmap, backmap, dictqmap, nil, nil},
|
||||||
{LangKO, "hangul", "hangul", nil, nil, trans},
|
{LangJPK, "kata", "kanji", transmap, backmap, dictqmap, nil, nil},
|
||||||
|
{LangKO, "hangul", nil, transko, backko, dictqmap, nil, nil},
|
||||||
|
{LangEMOJI, "emoji", "emoji", transmap, backmap, dictqmap, nil, nil},
|
||||||
|
{LangVI, "telex", nil, transvi, backmap, dictqmap, nil, nil},
|
||||||
};
|
};
|
||||||
int nlang = nelem(langs);
|
int nlang = nelem(langs);
|
||||||
|
|
||||||
@@ -14,7 +24,7 @@ static void
|
|||||||
clearkouho(void)
|
clearkouho(void)
|
||||||
{
|
{
|
||||||
im.nkouho = 0;
|
im.nkouho = 0;
|
||||||
im.sel = 0;
|
im.sel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -33,41 +43,60 @@ static void
|
|||||||
show(void)
|
show(void)
|
||||||
{
|
{
|
||||||
Drawcmd dc;
|
Drawcmd dc;
|
||||||
int i;
|
int i, first, n;
|
||||||
|
|
||||||
sclear(&dc.preedit);
|
sclear(&dc.pre);
|
||||||
mapget(im.l->map, &im.line, &dc.preedit);
|
if(!mapget(im.l->map, &im.pre, &dc.pre))
|
||||||
dc.nkouho = im.nkouho;
|
dc.pre = im.pre;
|
||||||
dc.sel = im.sel;
|
first = im.sel >= Maxdisp ? im.sel - Maxdisp + 1 : 0;
|
||||||
for(i = 0; i < dc.nkouho; i++)
|
n = im.nkouho - first;
|
||||||
dc.kouho[i] = im.kouho[i];
|
if(n > Maxdisp) n = Maxdisp;
|
||||||
|
dc.nkouho = n;
|
||||||
|
dc.sel = im.sel >= 0 ? im.sel - first : -1;
|
||||||
|
for(i = 0; i < n; i++)
|
||||||
|
dc.kouho[i] = im.kouho[first + i];
|
||||||
chansend(drawc, &dc);
|
chansend(drawc, &dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dictq(void)
|
reset(void)
|
||||||
|
{
|
||||||
|
sclear(&im.pre);
|
||||||
|
clearkouho();
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dictsend(Im *im, Str *key)
|
||||||
{
|
{
|
||||||
Str dict;
|
|
||||||
Dictreq req;
|
Dictreq req;
|
||||||
|
|
||||||
if(!mapget(im.l->map, &im.line, &dict)){
|
req.key = *key;
|
||||||
|
req.lang = im->l->lang;
|
||||||
|
req.pre = im->pre;
|
||||||
|
channbsend(dictreqc, &req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dictqmap(Im *im)
|
||||||
|
{
|
||||||
|
Str dict;
|
||||||
|
|
||||||
|
if(!mapget(im->l->map, &im->pre, &dict)){
|
||||||
clearkouho();
|
clearkouho();
|
||||||
show();
|
show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
req.key = dict;
|
dictsend(im, &dict);
|
||||||
req.lang = im.l->lang;
|
|
||||||
req.line = im.line;
|
|
||||||
channbsend(dictreqc, &req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
checklang(int c)
|
setlang(int c)
|
||||||
{
|
{
|
||||||
Lang *l;
|
Lang *l;
|
||||||
|
|
||||||
l = getlang(c);
|
l = getlang(c);
|
||||||
if(l == nil && c != LangEN)
|
if(l == nil)
|
||||||
return 0;
|
return 0;
|
||||||
im.l = l;
|
im.l = l;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -76,11 +105,13 @@ checklang(int c)
|
|||||||
static void
|
static void
|
||||||
commit(Str *com)
|
commit(Str *com)
|
||||||
{
|
{
|
||||||
Str kana;
|
Str val;
|
||||||
|
|
||||||
if(mapget(im.l->map, &im.line, &kana))
|
if(mapget(im.l->map, &im.pre, &val))
|
||||||
sappend(com, &kana);
|
sappend(com, &val);
|
||||||
sclear(&im.line);
|
else
|
||||||
|
sappend(com, &im.pre);
|
||||||
|
sclear(&im.pre);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -90,18 +121,16 @@ dotrans(Rune c, Str *com)
|
|||||||
Dictreq req;
|
Dictreq req;
|
||||||
|
|
||||||
e = im.l->trans(&im, c);
|
e = im.l->trans(&im, c);
|
||||||
|
|
||||||
if(e.s.n > 0)
|
if(e.s.n > 0)
|
||||||
sappend(com, &e.s);
|
sappend(com, &e.s);
|
||||||
sclear(&im.line);
|
sclear(&im.pre);
|
||||||
sappend(&im.line, &e.next);
|
sappend(&im.pre, &e.next);
|
||||||
if(e.eat && e.dict.n > 0){
|
if(e.eat && e.dict.n > 0){
|
||||||
req.key = e.dict;
|
req.key = e.dict;
|
||||||
req.lang = im.l->lang;
|
req.lang = im.l->lang;
|
||||||
req.line = im.line;
|
req.pre = im.pre;
|
||||||
channbsend(dictreqc, &req);
|
channbsend(dictreqc, &req);
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.eat;
|
return e.eat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,69 +145,52 @@ getlang(int lang)
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
maplookup(Trie *t, Str *key, Str *out)
|
||||||
|
{
|
||||||
|
char buf[256], *v;
|
||||||
|
int klen, vlen;
|
||||||
|
|
||||||
|
if(key->n == 0)
|
||||||
|
return 0;
|
||||||
|
v = nil;
|
||||||
|
vlen = 0;
|
||||||
|
klen = stoutf(key, buf, sizeof(buf));
|
||||||
|
if(!trielookup(t, buf, klen, &v, &vlen))
|
||||||
|
return 0;
|
||||||
|
if(out != nil && v != nil)
|
||||||
|
sinit(out, v, vlen);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Emit
|
Emit
|
||||||
trans(Im *im, Rune c)
|
transmap(Im *im, Rune c)
|
||||||
{
|
{
|
||||||
Emit e = {0};
|
Emit e = {0};
|
||||||
Str key, kana;
|
Str key;
|
||||||
Hmap *h;
|
Trie *t;
|
||||||
Rune last;
|
|
||||||
|
|
||||||
h = im->l->map;
|
t = im->l->map;
|
||||||
key = im->line;
|
key = im->pre;
|
||||||
sputr(&key, c);
|
sputr(&key, c);
|
||||||
if(hmapget(h, &key)){
|
if(maplookup(t, &key, &e.dict)){
|
||||||
e.eat = 1;
|
e.eat = 1;
|
||||||
e.next = key;
|
e.next = key;
|
||||||
mapget(h, &key, &e.dict);
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
if(!mapget(t, &im->pre, &e.s))
|
||||||
last = slastr(&im->line);
|
e.s = im->pre;
|
||||||
if(last == 0)
|
|
||||||
goto flush;
|
|
||||||
|
|
||||||
key = im->line;
|
|
||||||
key.n--;
|
|
||||||
if(mapget(h, &key, &kana)){
|
|
||||||
sclear(&key);
|
|
||||||
sputr(&key, last);
|
|
||||||
sputr(&key, c);
|
|
||||||
if(hmapget(h, &key)){
|
|
||||||
e.eat = 1;
|
|
||||||
e.s = kana;
|
|
||||||
sputr(&e.next, last);
|
|
||||||
sputr(&e.next, c);
|
|
||||||
mapget(h, &e.next, &e.dict);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flush:
|
|
||||||
mapget(h, &im->line, &e.s);
|
|
||||||
|
|
||||||
sclear(&key);
|
sclear(&key);
|
||||||
sputr(&key, c);
|
sputr(&key, c);
|
||||||
if(hmapget(h, &key) == nil){
|
if(!maplookup(t, &key, &e.dict)){
|
||||||
e.flush = 1;
|
|
||||||
sputr(&e.s, c);
|
sputr(&e.s, c);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.eat = 1;
|
e.eat = 1;
|
||||||
sputr(&e.next, c);
|
sputr(&e.next, c);
|
||||||
mapget(h, &e.next, &e.dict);
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
reset(void)
|
|
||||||
{
|
|
||||||
sclear(&im.line);
|
|
||||||
clearkouho();
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
keystroke(u32int ks, u32int mod, Str *com)
|
keystroke(u32int ks, u32int mod, Str *com)
|
||||||
{
|
{
|
||||||
@@ -191,7 +203,7 @@ keystroke(u32int ks, u32int mod, Str *com)
|
|||||||
return 0;
|
return 0;
|
||||||
if(ks == Kdown && im.sel < im.nkouho - 1)
|
if(ks == Kdown && im.sel < im.nkouho - 1)
|
||||||
im.sel++;
|
im.sel++;
|
||||||
if(ks == Kup && im.sel > 0)
|
if(ks == Kup && im.sel >= 0)
|
||||||
im.sel--;
|
im.sel--;
|
||||||
show();
|
show();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -211,7 +223,7 @@ keystroke(u32int ks, u32int mod, Str *com)
|
|||||||
reset();
|
reset();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(im.line.n > 0){
|
if(im.pre.n > 0){
|
||||||
commit(com);
|
commit(com);
|
||||||
reset();
|
reset();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -219,18 +231,18 @@ keystroke(u32int ks, u32int mod, Str *com)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(ks == Kback){
|
if(ks == Kback){
|
||||||
if(im.line.n == 0)
|
if(im.pre.n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
spopr(&im.line);
|
im.l->back(&im);
|
||||||
if(im.line.n == 0){
|
if(im.pre.n == 0){
|
||||||
reset();
|
reset();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
dictq();
|
im.l->dictq(&im);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(ks == Kesc){
|
if(ks == Kesc){
|
||||||
if(im.line.n == 0)
|
if(im.pre.n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
reset();
|
reset();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -244,25 +256,31 @@ keystroke(u32int ks, u32int mod, Str *com)
|
|||||||
reset();
|
reset();
|
||||||
if(ks >= 'a' && ks <= 'z')
|
if(ks >= 'a' && ks <= 'z')
|
||||||
ks -= 'a' - 1;
|
ks -= 'a' - 1;
|
||||||
if(checklang(ks))
|
if(setlang(ks))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(im.l == nil)
|
if(ks == '0' && im.nkouho > 0){
|
||||||
return 0;
|
commit(com);
|
||||||
if(ks > 0x7f || !isalpha(ks)){
|
reset();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(ks > 0x7f || ks == ' '){
|
||||||
commit(com);
|
commit(com);
|
||||||
sputr(com, ks);
|
sputr(com, ks);
|
||||||
reset();
|
reset();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return dotrans(ks, com);
|
dotrans(ks, com);
|
||||||
|
show();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init(void)
|
init(void)
|
||||||
{
|
{
|
||||||
memset(&im, 0, sizeof(im));
|
memset(&im, 0, sizeof(im));
|
||||||
|
im.l = getlang(LangEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -297,7 +315,7 @@ imthread(void*)
|
|||||||
write(kr.fd, out, n);
|
write(kr.fd, out, n);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if(scmp(&res.key, &im.line) == 0){
|
if(scmp(&res.key, &im.pre) == 0){
|
||||||
setkouho(&res);
|
setkouho(&res);
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
@@ -307,57 +325,21 @@ imthread(void*)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mapget(Hmap *h, Str *key, Str *out)
|
mapget(Trie *t, Str *key, Str *out)
|
||||||
{
|
{
|
||||||
Hnode *n;
|
char buf[256], *v;
|
||||||
|
int klen, vlen;
|
||||||
|
|
||||||
if(key->n == 0)
|
if(key->n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
n = hmapget(h, key);
|
klen = stoutf(key, buf, sizeof(buf));
|
||||||
if(n == nil || n->kanalen == 0)
|
v = trieget(t, buf, klen, &vlen);
|
||||||
|
if(v == nil)
|
||||||
return 0;
|
return 0;
|
||||||
sinit(out, n->kana, n->kanalen);
|
sinit(out, v, vlen);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hmap*
|
|
||||||
openmap(char *path)
|
|
||||||
{
|
|
||||||
Hmap *h;
|
|
||||||
Biobuf *b;
|
|
||||||
Str key, val, empty;
|
|
||||||
char *line, *tab;
|
|
||||||
int i, klen;
|
|
||||||
|
|
||||||
b = Bopen(path, OREAD);
|
|
||||||
if(b == nil)
|
|
||||||
die("can't open: %s", path);
|
|
||||||
h = hmapalloc(1024, 0);
|
|
||||||
sclear(&empty);
|
|
||||||
while((line = Brdstr(b, '\n', 1)) != nil){
|
|
||||||
if(line[0] == '\0'){
|
|
||||||
free(line);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
tab = strchr(line, '\t');
|
|
||||||
if(tab == nil || tab[1] == '\0')
|
|
||||||
die("malformed map: %s", path);
|
|
||||||
*tab = '\0';
|
|
||||||
klen = strlen(line);
|
|
||||||
sinit(&key, line, klen);
|
|
||||||
sinit(&val, tab+1, strlen(tab+1));
|
|
||||||
hmapset(&h, &key, &val);
|
|
||||||
for(i = 1; i < klen; i++){
|
|
||||||
sinit(&key, line, i);
|
|
||||||
if(hmapget(h, &key) == nil)
|
|
||||||
hmapset(&h, &key, &empty);
|
|
||||||
}
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
Bterm(b);
|
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mapinit(char *dir)
|
mapinit(char *dir)
|
||||||
{
|
{
|
||||||
@@ -368,7 +350,7 @@ mapinit(char *dir)
|
|||||||
if(langs[i].mapname == nil)
|
if(langs[i].mapname == nil)
|
||||||
continue;
|
continue;
|
||||||
snprint(path, sizeof(path), "%s/%s.map", dir, langs[i].mapname);
|
snprint(path, sizeof(path), "%s/%s.map", dir, langs[i].mapname);
|
||||||
langs[i].map = openmap(path);
|
langs[i].map = trieopen(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
130
trie.c
Normal file
130
trie.c
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#include "dat.h"
|
||||||
|
#include "fn.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
newnode(Trie *t)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(t->n >= t->cap){
|
||||||
|
t->cap *= 2;
|
||||||
|
t->nodes = erealloc(t->nodes, t->cap * sizeof(Tnode));
|
||||||
|
}
|
||||||
|
i = t->n++;
|
||||||
|
memset(&t->nodes[i], 0, sizeof(Tnode));
|
||||||
|
t->nodes[i].child = -1;
|
||||||
|
t->nodes[i].sibling = -1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
find(Trie *t, int ni, char c)
|
||||||
|
{
|
||||||
|
int pi;
|
||||||
|
|
||||||
|
for(pi = t->nodes[ni].child; pi >= 0; pi = t->nodes[pi].sibling)
|
||||||
|
if(t->nodes[pi].c == c)
|
||||||
|
return pi;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
add(Trie *t, int ni, char c)
|
||||||
|
{
|
||||||
|
int pi;
|
||||||
|
|
||||||
|
pi = newnode(t);
|
||||||
|
t->nodes[pi].c = c;
|
||||||
|
t->nodes[pi].sibling = t->nodes[ni].child;
|
||||||
|
t->nodes[ni].child = pi;
|
||||||
|
return pi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
insert(Trie *t, char *key, int klen, char *val, int vlen)
|
||||||
|
{
|
||||||
|
int ni, ci;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ni = t->root;
|
||||||
|
for(i = 0; i < klen; i++){
|
||||||
|
ci = find(t, ni, key[i]);
|
||||||
|
if(ci < 0)
|
||||||
|
ci = add(t, ni, key[i]);
|
||||||
|
ni = ci;
|
||||||
|
}
|
||||||
|
t->nodes[ni].val = val;
|
||||||
|
t->nodes[ni].vlen = vlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
Trie*
|
||||||
|
trieopen(char *path)
|
||||||
|
{
|
||||||
|
Trie *t;
|
||||||
|
Biobuf *b;
|
||||||
|
char *line, *tab, *key, *val;
|
||||||
|
int klen, vlen;
|
||||||
|
|
||||||
|
b = Bopen(path, OREAD);
|
||||||
|
if(b == nil)
|
||||||
|
die("can't open: %s", path);
|
||||||
|
t = emalloc(sizeof(*t));
|
||||||
|
t->cap = 1024;
|
||||||
|
t->nodes = emalloc(t->cap * sizeof(Tnode));
|
||||||
|
t->n = 0;
|
||||||
|
t->root = newnode(t);
|
||||||
|
while((line = Brdstr(b, '\n', 1)) != nil){
|
||||||
|
if(line[0] == '\0'){
|
||||||
|
free(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tab = strchr(line, '\t');
|
||||||
|
if(tab == nil || tab[1] == '\0')
|
||||||
|
die("malformed map: %s", path);
|
||||||
|
*tab = '\0';
|
||||||
|
key = line;
|
||||||
|
klen = tab - line;
|
||||||
|
val = tab + 1;
|
||||||
|
vlen = strlen(val);
|
||||||
|
insert(t, key, klen, val, vlen);
|
||||||
|
}
|
||||||
|
Bterm(b);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
trieget(Trie *t, char *key, int klen, int *vlen)
|
||||||
|
{
|
||||||
|
int ni;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ni = t->root;
|
||||||
|
for(i = 0; i < klen; i++){
|
||||||
|
ni = find(t, ni, key[i]);
|
||||||
|
if(ni < 0)
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
if(t->nodes[ni].val == nil)
|
||||||
|
return nil;
|
||||||
|
*vlen = t->nodes[ni].vlen;
|
||||||
|
return t->nodes[ni].val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
trielookup(Trie *t, char *key, int klen, char **val, int *vlen)
|
||||||
|
{
|
||||||
|
int ni;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ni = t->root;
|
||||||
|
for(i = 0; i < klen; i++){
|
||||||
|
ni = find(t, ni, key[i]);
|
||||||
|
if(ni < 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(val != nil && t->nodes[ni].val != nil){
|
||||||
|
*val = t->nodes[ni].val;
|
||||||
|
*vlen = t->nodes[ni].vlen;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
148
vi.c
Normal file
148
vi.c
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#include "dat.h"
|
||||||
|
#include "fn.h"
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
Rune base;
|
||||||
|
Rune tone[5]; /* s f r x j */
|
||||||
|
} vitone[] = {
|
||||||
|
{L'a', {L'á', L'à', L'ả', L'ã', L'ạ'}},
|
||||||
|
{L'â', {L'ấ', L'ầ', L'ẩ', L'ẫ', L'ậ'}},
|
||||||
|
{L'ă', {L'ắ', L'ằ', L'ẳ', L'ẵ', L'ặ'}},
|
||||||
|
{L'e', {L'é', L'è', L'ẻ', L'ẽ', L'ẹ'}},
|
||||||
|
{L'ê', {L'ế', L'ề', L'ể', L'ễ', L'ệ'}},
|
||||||
|
{L'i', {L'í', L'ì', L'ỉ', L'ĩ', L'ị'}},
|
||||||
|
{L'o', {L'ó', L'ò', L'ỏ', L'õ', L'ọ'}},
|
||||||
|
{L'ô', {L'ố', L'ồ', L'ổ', L'ỗ', L'ộ'}},
|
||||||
|
{L'ơ', {L'ớ', L'ờ', L'ở', L'ỡ', L'ợ'}},
|
||||||
|
{L'u', {L'ú', L'ù', L'ủ', L'ũ', L'ụ'}},
|
||||||
|
{L'ư', {L'ứ', L'ừ', L'ử', L'ữ', L'ự'}},
|
||||||
|
{L'y', {L'ý', L'ỳ', L'ỷ', L'ỹ', L'ỵ'}},
|
||||||
|
{L'A', {L'Á', L'À', L'Ả', L'Ã', L'Ạ'}},
|
||||||
|
{L'Â', {L'Ấ', L'Ầ', L'Ẩ', L'Ẫ', L'Ậ'}},
|
||||||
|
{L'Ă', {L'Ắ', L'Ằ', L'Ẳ', L'Ẵ', L'Ặ'}},
|
||||||
|
{L'E', {L'É', L'È', L'Ẻ', L'Ẽ', L'Ẹ'}},
|
||||||
|
{L'Ê', {L'Ế', L'Ề', L'Ể', L'Ễ', L'Ệ'}},
|
||||||
|
{L'I', {L'Í', L'Ì', L'Ỉ', L'Ĩ', L'Ị'}},
|
||||||
|
{L'O', {L'Ó', L'Ò', L'Ỏ', L'Õ', L'Ọ'}},
|
||||||
|
{L'Ô', {L'Ố', L'Ồ', L'Ổ', L'Ỗ', L'Ộ'}},
|
||||||
|
{L'Ơ', {L'Ớ', L'Ờ', L'Ở', L'Ỡ', L'Ợ'}},
|
||||||
|
{L'U', {L'Ú', L'Ù', L'Ủ', L'Ũ', L'Ụ'}},
|
||||||
|
{L'Ư', {L'Ứ', L'Ừ', L'Ử', L'Ữ', L'Ự'}},
|
||||||
|
{L'Y', {L'Ý', L'Ỳ', L'Ỷ', L'Ỹ', L'Ỵ'}},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tonetab[128] = {
|
||||||
|
['s'] = 1, ['f'] = 2, ['r'] = 3, ['x'] = 4, ['j'] = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define Istone(c) ((c) < 128 && tonetab[(c)] > 0)
|
||||||
|
#define Toneidx(c) (tonetab[(c)] - 1)
|
||||||
|
|
||||||
|
static int
|
||||||
|
isvowel(Rune c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < nelem(vitone); i++)
|
||||||
|
if(vitone[i].base == c)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Rune
|
||||||
|
removetone(Rune c)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for(i = 0; i < nelem(vitone); i++){
|
||||||
|
if(vitone[i].base == c)
|
||||||
|
return c;
|
||||||
|
for(j = 0; j < 5; j++)
|
||||||
|
if(vitone[i].tone[j] == c)
|
||||||
|
return vitone[i].base;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Rune
|
||||||
|
applytone(Rune c, int tidx)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Rune base;
|
||||||
|
|
||||||
|
base = removetone(c);
|
||||||
|
for(i = 0; i < nelem(vitone); i++)
|
||||||
|
if(vitone[i].base == base)
|
||||||
|
return vitone[i].tone[tidx];
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Emit
|
||||||
|
transvi(Im *im, Rune c)
|
||||||
|
{
|
||||||
|
Emit e;
|
||||||
|
Str mapped, pre;
|
||||||
|
int i, tidx, vi, last, penult;
|
||||||
|
Rune v, b1, b2;
|
||||||
|
|
||||||
|
if(!Istone(c) && c != 'z')
|
||||||
|
return transmap(im, c);
|
||||||
|
|
||||||
|
memset(&e, 0, sizeof e);
|
||||||
|
if(im->pre.n == 0){
|
||||||
|
sputr(&e.s, c);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(im->pre.r[im->pre.n - 1] == '\\'){
|
||||||
|
pre = im->pre;
|
||||||
|
pre.n--;
|
||||||
|
if(!mapget(im->l->map, &pre, &mapped))
|
||||||
|
mapped = pre;
|
||||||
|
sputr(&mapped, c);
|
||||||
|
e.eat = 1;
|
||||||
|
e.s = mapped;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(!mapget(im->l->map, &im->pre, &mapped))
|
||||||
|
mapped = im->pre;
|
||||||
|
last = -1;
|
||||||
|
penult = -1;
|
||||||
|
for(i = 0; i < mapped.n; i++){
|
||||||
|
v = removetone(mapped.r[i]);
|
||||||
|
if(isvowel(v)){
|
||||||
|
penult = last;
|
||||||
|
last = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vi = -1;
|
||||||
|
if(last >= 0){
|
||||||
|
if(last < mapped.n - 1 || penult < 0)
|
||||||
|
vi = last;
|
||||||
|
else{
|
||||||
|
b1 = removetone(mapped.r[penult]);
|
||||||
|
b2 = removetone(mapped.r[last]);
|
||||||
|
if((b1 == 'o' || b1 == 'O') && (b2 == 'a' || b2 == 'A' || b2 == 'e' || b2 == 'E'))
|
||||||
|
vi = last;
|
||||||
|
else if((b1 == 'u' || b1 == 'U') && (b2 == 'y' || b2 == 'Y'))
|
||||||
|
vi = last;
|
||||||
|
else
|
||||||
|
vi = penult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(vi < 0){
|
||||||
|
e.eat = 1;
|
||||||
|
e.s = mapped;
|
||||||
|
sputr(&e.s, c);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c == 'z')
|
||||||
|
mapped.r[vi] = removetone(mapped.r[vi]);
|
||||||
|
else{
|
||||||
|
tidx = Toneidx(c);
|
||||||
|
mapped.r[vi] = applytone(mapped.r[vi], tidx);
|
||||||
|
}
|
||||||
|
e.eat = 1;
|
||||||
|
e.next = mapped;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
25
win.c
25
win.c
@@ -6,7 +6,7 @@ enum {
|
|||||||
Asciitofull = 0xFEE0,
|
Asciitofull = 0xFEE0,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern char *fontpath;
|
extern char *fontdir;
|
||||||
|
|
||||||
static xcb_connection_t *conn;
|
static xcb_connection_t *conn;
|
||||||
static xcb_screen_t *scr;
|
static xcb_screen_t *scr;
|
||||||
@@ -52,7 +52,7 @@ wininit(void)
|
|||||||
gc = xcb_generate_id(conn);
|
gc = xcb_generate_id(conn);
|
||||||
xcb_create_gc(conn, gc, win, 0, nil);
|
xcb_create_gc(conn, gc, win, 0, nil);
|
||||||
img = emalloc(Imgw * Imgh * sizeof(img[0]));
|
img = emalloc(Imgw * Imgh * sizeof(img[0]));
|
||||||
fontinit(fontpath);
|
fontinit(fontdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -71,9 +71,11 @@ drawkouho(Drawcmd *dc, int first, int n, int w, int h)
|
|||||||
Str *s;
|
Str *s;
|
||||||
|
|
||||||
memset(img, (uchar)Colbg, w * h * sizeof(u32int));
|
memset(img, (uchar)Colbg, w * h * sizeof(u32int));
|
||||||
drawstr(img, 0, 0, dc->preedit.r, dc->preedit.n, w, h);
|
drawstr(img, 0, 0, dc->pre.r, dc->pre.n, w, h);
|
||||||
sely = Fontsz + (dc->sel - first) * Fontsz;
|
if(dc->sel >= 0){
|
||||||
|
sely = Fontsz + dc->sel * Fontsz;
|
||||||
memset(img + sely * w, (uchar)Colsel, Fontsz * w * sizeof(u32int));
|
memset(img + sely * w, (uchar)Colsel, Fontsz * w * sizeof(u32int));
|
||||||
|
}
|
||||||
for(i = 0, y = Fontsz; i < n; i++, y += Fontsz){
|
for(i = 0, y = Fontsz; i < n; i++, y += Fontsz){
|
||||||
s = &dc->kouho[first+i];
|
s = &dc->kouho[first+i];
|
||||||
putfont(img, w, h, 0, y, '1' + i + Asciitofull);
|
putfont(img, w, h, 0, y, '1' + i + Asciitofull);
|
||||||
@@ -99,17 +101,16 @@ winhide(void)
|
|||||||
static void
|
static void
|
||||||
winshow(Drawcmd *dc)
|
winshow(Drawcmd *dc)
|
||||||
{
|
{
|
||||||
int px, py, w, h, i, n, first, maxw;
|
int px, py, w, h, i, n, maxw;
|
||||||
u32int vals[4];
|
u32int vals[4];
|
||||||
xcb_query_pointer_reply_t *ptr;
|
xcb_query_pointer_reply_t *ptr;
|
||||||
xcb_query_pointer_cookie_t cookie;
|
xcb_query_pointer_cookie_t cookie;
|
||||||
|
|
||||||
cookie = xcb_query_pointer(conn, scr->root);
|
cookie = xcb_query_pointer(conn, scr->root);
|
||||||
first = dc->sel >= Maxdisp ? dc->sel - Maxdisp + 1 : 0;
|
n = dc->nkouho;
|
||||||
n = min(dc->nkouho - first, Maxdisp);
|
maxw = dc->pre.n;
|
||||||
maxw = dc->preedit.n;
|
|
||||||
for(i = 0; i < n; i++)
|
for(i = 0; i < n; i++)
|
||||||
maxw = max(maxw, dc->kouho[first+i].n);
|
maxw = max(maxw, dc->kouho[i].n);
|
||||||
ptr = xcb_query_pointer_reply(conn, cookie, nil);
|
ptr = xcb_query_pointer_reply(conn, cookie, nil);
|
||||||
if(ptr == nil)
|
if(ptr == nil)
|
||||||
die("xcb_query_pointer");
|
die("xcb_query_pointer");
|
||||||
@@ -125,7 +126,7 @@ winshow(Drawcmd *dc)
|
|||||||
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||||
vals);
|
vals);
|
||||||
xcb_map_window(conn, win);
|
xcb_map_window(conn, win);
|
||||||
drawkouho(dc, first, n, w, h);
|
drawkouho(dc, 0, n, w, h);
|
||||||
putimage(w, h);
|
putimage(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +138,9 @@ drawthread(void*)
|
|||||||
threadsetname("draw");
|
threadsetname("draw");
|
||||||
wininit();
|
wininit();
|
||||||
while(chanrecv(drawc, &dc) > 0){
|
while(chanrecv(drawc, &dc) > 0){
|
||||||
if(dc.nkouho == 0 && dc.preedit.n == 0)
|
while(channbrecv(drawc, &dc) > 0)
|
||||||
|
;
|
||||||
|
if(dc.nkouho == 0 && dc.pre.n == 0)
|
||||||
winhide();
|
winhide();
|
||||||
else
|
else
|
||||||
winshow(&dc);
|
winshow(&dc);
|
||||||
|
|||||||
Reference in New Issue
Block a user