1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2025-06-13 12:54:14 +00:00
gnosygnu_xowa/400_xowa/src/gplx/gfui/Gfui_bnd_parser.java

331 lines
13 KiB
Java

/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.gfui; import gplx.*;
import gplx.core.bits.*;
public class Gfui_bnd_parser {
private Bry_bfr tmp_bfr = Bry_bfr_.Reset(32);
private Hash_adp_bry
gfui_regy = Hash_adp_bry.ci_a7()
, norm_regy = Hash_adp_bry.ci_a7()
;
private static final Gfui_bnd_tkn
Itm_sym_plus = new_sym_(Gfui_bnd_tkn.Tid_sym_plus , new byte[] {Byte_ascii.Plus})
, Itm_sym_pipe = new_sym_(Gfui_bnd_tkn.Tid_sym_pipe , new byte[] {Byte_ascii.Pipe})
, Itm_sym_comma = new_sym_(Gfui_bnd_tkn.Tid_sym_comma , new byte[] {Byte_ascii.Comma})
// , Itm_sym_ws = new_sym_(Gfui_bnd_tkn.Tid_sym_ws , Bry_.Empty)
, Itm_sym_eos = new_sym_(Gfui_bnd_tkn.Tid_sym_eos , Bry_.Empty)
;
private static final Gfui_bnd_tkn[] Mod_ary = new Gfui_bnd_tkn[]
{ null
, new_mod_(Gfui_bnd_tkn.Tid_mod_c , "mod.c" , "Ctrl")
, new_mod_(Gfui_bnd_tkn.Tid_mod_a , "mod.a" , "Alt")
, new_mod_(Gfui_bnd_tkn.Tid_mod_ca , "mod.ca" , "Ctrl + Alt")
, new_mod_(Gfui_bnd_tkn.Tid_mod_s , "mod.s" , "Shift")
, new_mod_(Gfui_bnd_tkn.Tid_mod_cs , "mod.cs" , "Ctrl + Shift")
, new_mod_(Gfui_bnd_tkn.Tid_mod_as , "mod.as" , "Alt + Shift")
, new_mod_(Gfui_bnd_tkn.Tid_mod_cas , "mod.cas" , "Ctrl + Alt + Shift")
};
private byte[] src; private int src_len;
private List_adp tkns = List_adp_.New(); private int mod_val = Mod_val_null;
public String Xto_norm(String src_str) {return Convert(Bool_.Y, src_str);}
public String Xto_gfui(String src_str) {return Convert(Bool_.N, src_str);}
private String Convert(boolean src_is_gfui, String src_str) {
this.src = Bry_.new_u8(src_str); this.src_len = src.length;
tkns.Clear(); mod_val = Mod_val_null;
int pos = 0; int itm_bgn = -1, itm_end = -1; boolean is_numeric = false;
while (pos <= src_len) { // loop over bytes and break up tkns by symbols
byte b = pos == src_len ? Byte_ascii.Nl: src[pos]; // treat eos as "\n" for purpose of separating tokens
Gfui_bnd_tkn sym_tkn = null;
switch (b) {
case Byte_ascii.Plus: // simultaneous; EX: Ctrl + S
sym_tkn = Itm_sym_plus;
break;
case Byte_ascii.Pipe: // alternate; EX: Ctrl + S | Ctrl + Alt + s
sym_tkn = Itm_sym_pipe;
break;
case Byte_ascii.Comma: // chorded; EX: Ctrl + S, Ctrl + T
sym_tkn = Itm_sym_comma;
break;
case Byte_ascii.Nl: // eos: process anything in bfr
sym_tkn = Itm_sym_eos;
break;
case Byte_ascii.Space:
if (itm_bgn != -1) // if word started, " " ends word; EX: "Ctrl + A"; " +" ends "Ctrl"
itm_end = pos;
++pos;
continue;
case Byte_ascii.Hash:
if (is_numeric) throw Err_.new_wo_type("multiple numeric symbols in keycode");
is_numeric = true;
++pos;
continue;
default: // letter / number; continue
if (itm_bgn == -1) // no word started; start it
itm_bgn = pos;
++pos;
continue;
}
if (itm_end == -1) // end not set by space; char before symbol is end
itm_end = pos;
Process_sym(src_is_gfui, is_numeric, sym_tkn, itm_bgn, itm_end);
is_numeric = false;
if (sym_tkn.Tid() == Gfui_bnd_tkn.Tid_sym_eos)
break;
else
++pos;
itm_bgn = itm_end = -1;
}
int tkns_len = tkns.Count();
for (int i = 0; i < tkns_len; i++) {
Gfui_bnd_tkn tkn = (Gfui_bnd_tkn)tkns.Get_at(i);
tkn.Write(tmp_bfr, !src_is_gfui);
}
return tmp_bfr.To_str_and_clear();
}
private void Process_sym(boolean src_is_gfui, boolean is_numeric, Gfui_bnd_tkn sym_tkn, int itm_bgn, int itm_end) {
Hash_adp_bry regy = src_is_gfui ? gfui_regy : norm_regy;
Gfui_bnd_tkn tkn = null;
if (is_numeric) { // EX: "key.#10" or "#10"
int tkn_bgn = itm_bgn;
if (src_is_gfui) { // remove "key." in "key.#10"
tkn_bgn = Bry_find_.Move_fwd(src, Byte_ascii.Dot, itm_bgn, itm_end);
if (tkn_bgn == -1) throw Err_.new_wo_type("invalid keycode.dot", "keycode", Bry_.Mid(src, tkn_bgn, itm_end));
++tkn_bgn; // skip #
}
int keycode = Bry_.To_int_or(src, tkn_bgn, itm_end, -1); if (keycode == -1) throw Err_.new_wo_type("invalid keycode", "keycode", Bry_.Mid(src, tkn_bgn, itm_end));
tkn = new Gfui_bnd_tkn(Gfui_bnd_tkn.Tid_key, keycode, Bry_.Empty, Bry_.Empty);
}
else
tkn = (Gfui_bnd_tkn)regy.Get_by_mid(src, itm_bgn, itm_end);
if (tkn == null) return;
int mod_adj = Mod_val_null;
switch (tkn.Tid()) {
case Gfui_bnd_tkn.Tid_mod_c: mod_adj = Gfui_bnd_tkn.Tid_mod_c; break;
case Gfui_bnd_tkn.Tid_mod_a: mod_adj = Gfui_bnd_tkn.Tid_mod_a; break;
case Gfui_bnd_tkn.Tid_mod_s: mod_adj = Gfui_bnd_tkn.Tid_mod_s; break;
case Gfui_bnd_tkn.Tid_mod_cs: mod_adj = Gfui_bnd_tkn.Tid_mod_cs; break;
case Gfui_bnd_tkn.Tid_mod_as: mod_adj = Gfui_bnd_tkn.Tid_mod_as; break;
case Gfui_bnd_tkn.Tid_mod_ca: mod_adj = Gfui_bnd_tkn.Tid_mod_ca; break;
case Gfui_bnd_tkn.Tid_mod_cas: mod_adj = Gfui_bnd_tkn.Tid_mod_cas; break;
case Gfui_bnd_tkn.Tid_key: break;
default: throw Err_.new_unhandled(tkn.Tid());
}
switch (sym_tkn.Tid()) {
case Gfui_bnd_tkn.Tid_sym_plus: // EX: Ctrl + A
if (mod_adj != Mod_val_null) { // if mod, just update mod_val and exit
mod_val = Bitmask_.Flip_int(true, mod_val, mod_adj);
return;
}
break;
}
if (mod_val != Mod_val_null) { // modifier exists; add tkn
tkns.Add(Mod_ary[mod_val]);
tkns.Add(Itm_sym_plus);
mod_val = Mod_val_null;
}
tkns.Add(tkn); // add word
if (sym_tkn.Tid() != Gfui_bnd_tkn.Tid_sym_eos)
tkns.Add(sym_tkn);
}
private Gfui_bnd_parser Init_en() {
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_c);
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_a);
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_s);
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_ca);
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_cs);
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_as);
Init_itm_mod(Gfui_bnd_tkn.Tid_mod_cas);
Init_itm(Gfui_bnd_tkn.Tid_mod_c, "key.ctrl", "Ctrl");
Init_itm(Gfui_bnd_tkn.Tid_mod_a, "key.alt", "Atl");
Init_itm(Gfui_bnd_tkn.Tid_mod_s, "key.shift", "Shift");
Init_itm("key.a", "A");
Init_itm("key.b", "B");
Init_itm("key.c", "C");
Init_itm("key.d", "D");
Init_itm("key.e", "E");
Init_itm("key.f", "F");
Init_itm("key.g", "G");
Init_itm("key.h", "H");
Init_itm("key.i", "I");
Init_itm("key.j", "J");
Init_itm("key.k", "K");
Init_itm("key.l", "L");
Init_itm("key.m", "M");
Init_itm("key.n", "N");
Init_itm("key.o", "O");
Init_itm("key.p", "P");
Init_itm("key.q", "Q");
Init_itm("key.r", "R");
Init_itm("key.s", "S");
Init_itm("key.t", "T");
Init_itm("key.u", "U");
Init_itm("key.v", "V");
Init_itm("key.w", "W");
Init_itm("key.x", "X");
Init_itm("key.y", "Y");
Init_itm("key.z", "Z");
Init_itm("key.d0", "0");
Init_itm("key.d1", "1");
Init_itm("key.d2", "2");
Init_itm("key.d3", "3");
Init_itm("key.d4", "4");
Init_itm("key.d5", "5");
Init_itm("key.d6", "6");
Init_itm("key.d7", "7");
Init_itm("key.d8", "8");
Init_itm("key.d9", "9");
Init_itm("key.f1", "F1");
Init_itm("key.f2", "F2");
Init_itm("key.f3", "F3");
Init_itm("key.f4", "F4");
Init_itm("key.f5", "F5");
Init_itm("key.f6", "F6");
Init_itm("key.f7", "F7");
Init_itm("key.f8", "F8");
Init_itm("key.f9", "F9");
Init_itm("key.f10", "F10");
Init_itm("key.f11", "F11");
Init_itm("key.f12", "F12");
Init_itm("key.none", "None");
Init_itm("key.back", "Backspace");
Init_itm("key.tab", "Tab");
Init_itm("key.clear", "Clear");
Init_itm("key.enter", "Enter");
Init_itm("key.shiftKey", "ShiftKey");
Init_itm("key.ctrlKey", "CtrlKey");
Init_itm("key.altKey", "AltKey");
Init_itm("key.pause", "Pause");
Init_itm("key.capsLock", "CapsLock");
Init_itm("key.escape", "Escape");
Init_itm("key.space", "Space");
Init_itm("key.pageUp", "PageUp");
Init_itm("key.pageDown", "PageDown");
Init_itm("key.end", "End");
Init_itm("key.home", "Home");
Init_itm("key.left", "Left");
Init_itm("key.up", "Up");
Init_itm("key.right", "Right");
Init_itm("key.down", "Down");
Init_itm("key.printScreen", "PrintScreen");
Init_itm("key.insert", "Insert");
Init_itm("key.delete", "Delete");
Init_itm("key.numLock", "NumLock");
Init_itm("key.scrollLock", "ScrollLock");
Init_itm("key.semicolon", "Semicolon");
Init_itm("key.equal", "Equal");
Init_itm("key.comma", "Comma");
Init_itm("key.minus", "Minus");
Init_itm("key.period", "Period");
Init_itm("key.slash", "Slash");
Init_itm("key.tick", "Tick");
Init_itm("key.openBracket", "OpenBracket");
Init_itm("key.backslash", "Backslash");
Init_itm("key.closeBracket", "CloseBracket");
Init_itm("key.quote", "Quote");
Init_itm("mouse.middle", "Middle Click");
Init_itm("mouse.left", "Left Click");
Init_itm("mouse.right", "Right Click");
Init_itm("key.numpad_0", "Numpad 0");
Init_itm("key.numpad_1", "Numpad 1");
Init_itm("key.numpad_2", "Numpad 2");
Init_itm("key.numpad_3", "Numpad 3");
Init_itm("key.numpad_4", "Numpad 4");
Init_itm("key.numpad_5", "Numpad 5");
Init_itm("key.numpad_6", "Numpad 6");
Init_itm("key.numpad_7", "Numpad 7");
Init_itm("key.numpad_8", "Numpad 8");
Init_itm("key.numpad_9", "Numpad 9");
Init_itm("key.numpad_multiply", "Numpad Multiply");
Init_itm("key.numpad_add", "Numpad Add");
Init_itm("key.numpad_subtract", "Numpad Subtract");
Init_itm("key.numpad_decimal", "Numpad Decimal");
Init_itm("key.numpad_divide", "Numpad Divide");
Init_itm("key.numpad_enter", "Numpad Enter");
return this;
}
private void Init_itm(String gfui, String norm) {Init_itm(Gfui_bnd_tkn.Tid_key, gfui, norm);}
private void Init_itm_mod(int tid) {
Gfui_bnd_tkn itm = Mod_ary[tid];
gfui_regy.Add(itm.Bry_gfui(), itm);
norm_regy.Add(itm.Bry_norm(), itm);
}
private void Init_itm(byte tid, String gfui, String norm) {
byte[] gfui_bry = Bry_.new_u8(gfui);
byte[] norm_bry = Bry_.new_u8(norm);
Gfui_bnd_tkn itm = new Gfui_bnd_tkn(tid, Gfui_bnd_tkn.Keycode_null, gfui_bry, norm_bry);
gfui_regy.Add(gfui_bry, itm);
norm_regy.Add_if_dupe_use_1st(norm_bry, itm);
}
private static final int Mod_val_null = 0;
public static Gfui_bnd_parser new_en_() {return new Gfui_bnd_parser().Init_en();} Gfui_bnd_parser() {}
private static Gfui_bnd_tkn new_sym_(byte tid, byte[] bry) {return new Gfui_bnd_tkn(tid, Gfui_bnd_tkn.Keycode_null, bry, bry);}
private static Gfui_bnd_tkn new_mod_(byte tid, String gfui, String norm) {return new Gfui_bnd_tkn(tid, Gfui_bnd_tkn.Keycode_null, Bry_.new_a7(gfui), Bry_.new_a7(norm));}
}
class Gfui_bnd_tkn {
public Gfui_bnd_tkn(byte tid, int keycode, byte[] gfui, byte[] norm) {
this.tid = tid; this.keycode = keycode; ; this.bry_gfui = gfui; this.bry_norm = norm;
}
public byte Tid() {return tid;} private final byte tid;
public int Keycode() {return keycode;} private final int keycode;
public byte[] Bry_gfui() {return bry_gfui;} private final byte[] bry_gfui;
public byte[] Bry_norm() {return bry_norm;} private final byte[] bry_norm;
public void Write(Bry_bfr bfr, boolean src_is_gfui) {
if (keycode != Gfui_bnd_tkn.Keycode_null) {
if (src_is_gfui)
bfr.Add(Bry_key_prefix);
bfr.Add_byte(Byte_ascii.Hash).Add_int_variable(keycode);
return;
}
byte[] bry = src_is_gfui ? bry_gfui : bry_norm;
switch (tid) {
case Tid_mod_c: case Tid_mod_a: case Tid_mod_s:
case Tid_mod_ca: case Tid_mod_cs: case Tid_mod_as: case Tid_mod_cas:
bfr.Add(bry);
break;
case Tid_sym_plus:
if (!src_is_gfui)
bfr.Add_byte_space();
bfr.Add(bry);
if (!src_is_gfui)
bfr.Add_byte_space();
break;
case Tid_sym_pipe:
if (!src_is_gfui)
bfr.Add_byte_space();
bfr.Add(bry);
if (!src_is_gfui)
bfr.Add_byte_space();
break;
case Tid_sym_comma:
bfr.Add(bry);
if (!src_is_gfui)
bfr.Add_byte_space();
break;
case Tid_key:
bfr.Add(bry);
break;
}
}
public static final byte
Tid_mod_c = 1 , Tid_mod_a = 2 , Tid_mod_s = 4
, Tid_mod_ca = 3 , Tid_mod_cs = 5 , Tid_mod_as = 6, Tid_mod_cas = 7
, Tid_sym_plus = 8 , Tid_sym_pipe = 9 , Tid_sym_comma = 10, Tid_sym_eos = 11
, Tid_key = 12
;
public static final int Keycode_null = 0;
private static final byte[] Bry_key_prefix = Bry_.new_a7("key.");
}