1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-09-27 23:04:13 -04:00
parent fa70c05354
commit 8e18af05b6
84 changed files with 2795 additions and 507 deletions

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.langs.vnts; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
public class Xol_vnt_dir_ {
public static final int Tid__none = 0, Tid__uni = 1, Tid__bi = 2;
public static int Parse(byte[] v) {return hash.Get_as_int_or(v, Tid__none);}
private static final byte[] Bry__none = Bry_.new_a7("disable"), Bry__uni = Bry_.new_a7("unidirectional"), Bry__bi = Bry_.new_a7("bidirectional");
private static final Hash_adp_bry hash = Hash_adp_bry.cs()
.Add_bry_int(Bry__none , Tid__none)
.Add_bry_int(Bry__uni , Tid__uni)
.Add_bry_int(Bry__bi , Tid__bi);
}

View File

@@ -18,27 +18,33 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.langs.vnts; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
import gplx.xowa.langs.vnts.converts.*;
public class Xol_vnt_itm implements GfoInvkAble {
public Xol_vnt_itm(byte[] key, byte[] name, int mask__vnt) {
this.key = key; this.name = name; this.mask__vnt = mask__vnt;
public Xol_vnt_itm(int idx, byte[] key, byte[] name, int mask__vnt) {
this.idx = idx; this.key = key; this.name = name; this.mask__vnt = mask__vnt;
this.convert_wkr = new Xol_convert_wkr(key);
}
public int Idx() {return idx;} private final int idx; // EX: 2
public byte[] Key() {return key;} private final byte[] key; // EX: zh-cn
public byte[] Name() {return name;} private final byte[] name; // EX: 大陆简体
public boolean Visible() {return visible;} private boolean visible = true; // visible in menu
public byte[][] Fallback_ary() {return fallback_ary;} private byte[][] fallback_ary = Bry_.Ary_empty; // EX: zh-hans|zh
public int Dir() {return dir;} private int dir = Xol_vnt_dir_.Tid__bi; // EX: "bidirectional"
public int Mask__vnt() {return mask__vnt;} private final int mask__vnt; // EX: 8
public int Mask__fallbacks() {return mask_fallbacks;} private int mask_fallbacks; // EX: 11 for zh,zh-hans,zh-cn
public byte[][] Convert_ary() {return convert_ary;} private byte[][] convert_ary = Bry_.Ary_empty; // EX: zh-hans|zh-cn
public Xol_convert_wkr Convert_wkr() {return convert_wkr;} private final Xol_convert_wkr convert_wkr;
public void Visible_(boolean v) {this.visible = v;}
public void Convert_ary_(byte[][] v) {convert_ary = v;}
public void Init(int dir, byte[][] fallback_ary) {
this.dir = dir; this.fallback_ary = fallback_ary;
}
public void Mask__fallbacks__calc(Xol_vnt_regy regy, byte[][] ary) {
this.mask_fallbacks = regy.Mask__calc(Bry_.Ary_add(Bry_.Ary(key), ary));// NOTE: must add lang.key which is not part of fallback; EX: "zh-cn" has fallback of "zh-hans", but chain should calc "zh-cn","zh-hans"
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_fallbacks_)) fallback_ary = Bry_split_.Split(m.ReadBry("v"), Byte_ascii.Pipe);
else if (ctx.Match(k, Invk_converts_)) convert_ary = Bry_split_.Split(m.ReadBry("v"), Byte_ascii.Pipe);
else if (ctx.Match(k, Invk_dir_)) dir = Xol_vnt_dir_.Parse(m.ReadBry("v"));
else return GfoInvkAble_.Rv_unhandled;
return this;
} private static final String Invk_fallbacks_ = "fallbacks_", Invk_converts_ = "converts_";
} private static final String Invk_fallbacks_ = "fallbacks_", Invk_converts_ = "converts_", Invk_dir_ = "dir_";
}

View File

@@ -18,8 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.langs.vnts; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
import gplx.xowa.parsers.vnts.*;
class Xol_vnt_itm_sorter__rule implements gplx.lists.ComparerAble {
private Ordered_hash hash;
public void Sort(Ordered_hash hash, Xop_vnt_rule_tkn[] ary) {
private Hash_adp hash;
public void Sort(Hash_adp hash, Xop_vnt_rule_tkn[] ary) {
synchronized (hash) {
this.hash = hash;
Array_.Sort(ary, this);

View File

@@ -19,17 +19,20 @@ package gplx.xowa.langs.vnts; import gplx.*; import gplx.xowa.*; import gplx.xow
import gplx.core.btries.*;
import gplx.xowa.parsers.vnts.*;
public class Xol_vnt_regy {
private final Ordered_hash hash = Ordered_hash_.new_bry_(); private int hash_len;
private final Hash_adp_bry hash = Hash_adp_bry.ci_a7(); private int hash_len;
private final List_adp list = List_adp_.new_();
public Btrie_slim_mgr Trie() {return trie;} private final Btrie_slim_mgr trie = Btrie_slim_mgr.ci_a7();
public int Len() {return hash.Count();}
public boolean Has(byte[] k) {return hash.Has(k);}
public Xol_vnt_itm Get_at(int i) {return (Xol_vnt_itm)hash.Get_at(i);}
public Xol_vnt_itm Get_at(int i) {return (Xol_vnt_itm)list.Get_at(i);}
public Xol_vnt_itm Get_by(byte[] k) {return (Xol_vnt_itm)hash.Get_by(k);}
public void Clear() {hash.Clear(); trie.Clear(); hash_len = 0;}
public Xol_vnt_itm Get_by(byte[] s, int b, int e) {return (Xol_vnt_itm)hash.Get_by_mid(s, b, e);}
public void Clear() {hash.Clear(); list.Clear(); trie.Clear(); hash_len = 0;}
public Xol_vnt_itm Add(byte[] key, byte[] name) {
int mask = gplx.core.brys.Bit_.Get_flag(hash_len);
Xol_vnt_itm itm = new Xol_vnt_itm(key, name, mask);
Xol_vnt_itm itm = new Xol_vnt_itm(hash_len, key, name, mask);
hash.Add(key, itm);
list.Add(itm);
trie.Add_obj(key, itm);
hash_len = hash.Count();
return itm;
@@ -41,15 +44,15 @@ public class Xol_vnt_regy {
byte[] key = ary[i];
Xol_vnt_itm itm = (Xol_vnt_itm)hash.Get_by(key); if (itm == null) continue; // handle bad vnt from user input; EX: -{zh;bad|text}-
int itm_mask = itm.Mask__vnt();
rv = rv == 0 ? itm_mask : Enm_.Flip_int(true, rv, itm_mask);
rv = rv == 0 ? itm_mask : Bitmask_.Flip_int(true, rv, itm_mask);
}
return rv;
}
public boolean Mask__match_any(int lhs, int rhs) { // EX: match "zh-cn|zh-hans|zh-hant" against "zh|zh-hans|zh-hant"
for (int i = 0; i < hash_len; ++i) {
int mask = gplx.core.brys.Bit_.Get_flag(i); // 1,2,4,8
if (Enm_.Has_int(lhs, mask)) { // lhs has mask; EX: for lhs=6, mask=1 -> 'n'; mask=2 -> 'y'
if (Enm_.Has_int(rhs, mask)) // if rhs does not have mask, return false;
if (Bitmask_.Has_int(lhs, mask)) { // lhs has mask; EX: for lhs=6, mask=1 -> 'n'; mask=2 -> 'y'
if (Bitmask_.Has_int(rhs, mask)) // if rhs does not have mask, return false;
return true;
}
}

View File

@@ -0,0 +1,63 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.langs.vnts; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
import gplx.xowa.parsers.vnts.*;
public class Xol_vnt_regy_fxt {
private final Xol_vnt_regy mgr = new_chinese();
public String[] Make_lang_chain_cn() {return String_.Ary("zh-cn", "zh-hans", "zh-hant", "zh");}
public void Test_match_any(boolean expd, String[] lang_chain, String[]... vnt_chain_ary) {
int len = vnt_chain_ary.length;
int lang_flag = mgr.Mask__calc(Bry_.Ary(lang_chain));
for (int i = 0; i < len; ++i) {
String[] vnt_chain = vnt_chain_ary[i]; // EX: -{zh;zh-hans;zh-hant}-
int vnt_flag = mgr.Mask__calc(Bry_.Ary(vnt_chain));
Tfds.Eq(expd, mgr.Mask__match_any(vnt_flag, lang_flag), String_.Concat_with_str(";", vnt_chain) + "<>" + String_.Concat_with_str(";", lang_chain));
}
}
public void Test_calc(String[] ary, int expd) {
Tfds.Eq(expd, mgr.Mask__calc(Bry_.Ary(ary)));
}
public void Test_sort(String[] vnt_ary, String[] expd) {
int vnt_len = vnt_ary.length;
Xop_vnt_rule_tkn[] rule_ary = new Xop_vnt_rule_tkn[vnt_len];
for (int i = 0; i < vnt_len; ++i)
rule_ary[i] = new Xop_vnt_rule_tkn(Bry_.Empty, Bry_.new_u8(vnt_ary[i]), gplx.xowa.parsers.Xop_tkn_itm_.Ary_empty);
mgr.Mask__sort(rule_ary);
for (int i = 0; i < vnt_len; ++i)
vnt_ary[i] = String_.new_u8(rule_ary[i].Rule_lang());
Tfds.Eq_ary_str(expd, vnt_ary);
}
public static Xol_vnt_regy new_chinese() { // REF.MW:/languages/classes/LanguageZh.php|LanguageZh|__construct
Xol_vnt_regy rv = new Xol_vnt_regy();
new_chinese_vnt(rv, "zh" , Xol_vnt_dir_.Tid__none, "zh-hans", "zh-hant", "zh-cn", "zh-tw", "zh-hk", "zh-sg", "zh-mo", "zh-my");
new_chinese_vnt(rv, "zh-hans" , Xol_vnt_dir_.Tid__uni , "zh-cn", "zh-sg", "zh-my");
new_chinese_vnt(rv, "zh-hant" , Xol_vnt_dir_.Tid__uni , "zh-tw", "zh-hk", "zh-mo");
new_chinese_vnt(rv, "zh-cn" , Xol_vnt_dir_.Tid__bi , "zh-hans", "zh-sg", "zh-my");
new_chinese_vnt(rv, "zh-hk" , Xol_vnt_dir_.Tid__bi , "zh-hant", "zh-mo", "zh-tw");
new_chinese_vnt(rv, "zh-my" , Xol_vnt_dir_.Tid__bi , "zh-hans", "zh-sg", "zh-cn");
new_chinese_vnt(rv, "zh-mo" , Xol_vnt_dir_.Tid__bi , "zh-hant", "zh-hk", "zh-tw");
new_chinese_vnt(rv, "zh-sg" , Xol_vnt_dir_.Tid__bi , "zh-hans", "zh-cn", "zh-my");
new_chinese_vnt(rv, "zh-tw" , Xol_vnt_dir_.Tid__bi , "zh-hant", "zh-hk", "zh-mo");
return rv;
}
private static void new_chinese_vnt(Xol_vnt_regy regy, String key, int dir, String... fallbacks) {
byte[] key_bry = Bry_.new_u8(key);
Xol_vnt_itm itm = regy.Add(key_bry, Bry_.Ucase__all(key_bry));
itm.Init(dir, Bry_.Ary(fallbacks));
}
}

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.langs.vnts; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
import org.junit.*; import gplx.xowa.parsers.vnts.*;
import org.junit.*;
public class Xol_vnt_regy_tst {
private final Xol_vnt_regy_fxt fxt = new Xol_vnt_regy_fxt();
@Test public void Calc() {
@@ -51,34 +51,3 @@ public class Xol_vnt_regy_tst {
fxt.Test_sort(String_.Ary("zh", "zh-hans", "zh-cn" ) , String_.Ary("zh-cn", "zh-hans", "zh"));
}
}
class Xol_vnt_regy_fxt {
private final Xol_vnt_regy mgr = new Xol_vnt_regy();
public Xol_vnt_regy_fxt() {
String[] ary = Xop_vnt_parser_fxt.Vnts_chinese;
for (String itm : ary)
mgr.Add(Bry_.new_u8(itm), Bry_.Empty);
}
public String[] Make_lang_chain_cn() {return String_.Ary("zh-cn", "zh-hans", "zh-hant", "zh");}
public void Test_match_any(boolean expd, String[] lang_chain, String[]... vnt_chain_ary) {
int len = vnt_chain_ary.length;
int lang_flag = mgr.Mask__calc(Bry_.Ary(lang_chain));
for (int i = 0; i < len; ++i) {
String[] vnt_chain = vnt_chain_ary[i]; // EX: -{zh;zh-hans;zh-hant}-
int vnt_flag = mgr.Mask__calc(Bry_.Ary(vnt_chain));
Tfds.Eq(expd, mgr.Mask__match_any(vnt_flag, lang_flag), String_.Concat_with_str(";", vnt_chain) + "<>" + String_.Concat_with_str(";", lang_chain));
}
}
public void Test_calc(String[] ary, int expd) {
Tfds.Eq(expd, mgr.Mask__calc(Bry_.Ary(ary)));
}
public void Test_sort(String[] vnt_ary, String[] expd) {
int vnt_len = vnt_ary.length;
Xop_vnt_rule_tkn[] rule_ary = new Xop_vnt_rule_tkn[vnt_len];
for (int i = 0; i < vnt_len; ++i)
rule_ary[i] = new Xop_vnt_rule_tkn(Bry_.Empty, Bry_.new_u8(vnt_ary[i]), gplx.xowa.parsers.Xop_tkn_itm_.Ary_empty);
mgr.Mask__sort(rule_ary);
for (int i = 0; i < vnt_len; ++i)
vnt_ary[i] = String_.new_u8(rule_ary[i].Rule_lang());
Tfds.Eq_ary_str(expd, vnt_ary);
}
}

View File

@@ -44,10 +44,11 @@ public class Xol_convert_mgr {
if (new_wkr_idx == -1) throw Err_.new_("lang.vnt", "unknown vnt", "key", cur_vnt);
this.cur_wkr_idx = new_wkr_idx;
}
public byte[] Convert_text(Xowe_wiki wiki, byte[] src) {return Convert_text(wiki, src, 0, src.length);}
public byte[] Convert_text(Xowe_wiki wiki, byte[] src, int bgn, int end) {
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001();
Xol_convert_wkr converter = wkr_ary[cur_wkr_idx];
public byte[] Convert_text(byte[] src) {return Convert_text(src, 0, src.length);}
public byte[] Convert_text(byte[] src, int bgn, int end) {return Convert_text(cur_wkr_idx, src, bgn, end);}
public byte[] Convert_text(int vnt_idx, byte[] src, int bgn, int end) {
Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_m001();
Xol_convert_wkr converter = wkr_ary[vnt_idx];
converter.Convert_text(tmp_bfr, src, bgn, end);
return tmp_bfr.To_bry_and_rls();
}

View File

@@ -21,6 +21,8 @@ public class Xol_convert_wkr {
private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs();
public Xol_convert_wkr(byte[] key) {this.key = key;}
public byte[] Key() {return key;} private final byte[] key;
public void Add(byte[] src, byte[] trg) {trie.Add_obj(src, trg);}
public void Del(byte[] src) {trie.Del(src);}
public boolean Convert_text(Bry_bfr bfr, byte[] src) {return Convert_text(bfr, src, 0, src.length);}
public boolean Convert_text(Bry_bfr bfr, byte[] src, int bgn, int end) {
int pos = bgn;
@@ -47,7 +49,7 @@ public class Xol_convert_wkr {
pos = trie.Match_pos();
}
}
if (!matched) bfr.Add(src); // no convert; make sure to add back src, else bfr will be blank
if (!matched) bfr.Add_mid(src, bgn, end); // no convert; make sure to add back src, else bfr will be blank
return matched;
}
public void Rebuild(Xol_convert_regy regy, byte[][] ary) {