mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v2.7.2.1
This commit is contained in:
118
400_xowa/src/gplx/xowa/langs/Xoa_lang_mgr.java
Normal file
118
400_xowa/src/gplx/xowa/langs/Xoa_lang_mgr.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
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; import gplx.*; import gplx.xowa.*;
|
||||
import gplx.intl.*;
|
||||
import gplx.xowa.apps.fsys.*; import gplx.xowa.bldrs.langs.*; import gplx.xowa.langs.vnts.*;
|
||||
public class Xoa_lang_mgr implements GfoInvkAble {
|
||||
private final Xoa_fsys_mgr fsys_mgr; private final Gfo_msg_log msg_log; private final Xol_lang lang_en;
|
||||
private final Ordered_hash hash = Ordered_hash_.new_bry_(); private final Hash_adp_bry fallback_regy = Hash_adp_bry.cs_();
|
||||
public Xoa_lang_mgr(Xoae_app app) {
|
||||
this.fsys_mgr = app.Fsys_mgr(); this.msg_log = app.Msg_log();
|
||||
mw_converter = new Xobc_utl_make_lang(this, fsys_mgr, msg_log);
|
||||
lang_en = Lang_en_make(this); this.Add(lang_en);
|
||||
}
|
||||
public void Clear() {hash.Clear();}
|
||||
public int Len() {return hash.Count();}
|
||||
public void Add(Xol_lang itm) {hash.Add(itm.Key_bry(), itm);}
|
||||
public Xol_lang Get_at(int i) {return (Xol_lang)hash.Get_at(i);}
|
||||
public Xol_lang Get_by_key(byte[] key) {return (Xol_lang)hash.Get_by(key);}
|
||||
public Xol_lang Get_by_key_or_load(byte[] key) {return Get_by_key_or_new(key).Init_by_load_assert();}
|
||||
public Xol_lang Get_by_key_or_new(byte[] key) {
|
||||
Xol_lang rv = Get_by_key(key);
|
||||
if (rv == null) {
|
||||
rv = new Xol_lang(this, key);
|
||||
this.Add(rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Hash_adp_bry Fallback_regy() {return fallback_regy;}
|
||||
public Xol_lang Lang_en() {return lang_en;}
|
||||
public Xobc_utl_make_lang Mw_converter() {return mw_converter;} private Xobc_utl_make_lang mw_converter;
|
||||
public Cfg_nde_root Groups() {return groups;} Cfg_nde_root groups = new Cfg_nde_root().Root_(new Xoac_lang_grp(Bry_.Empty), Xoac_lang_grp.Make_grp, Bry_.Ary_empty);
|
||||
public byte[] Default_lang() {return default_lang;} private byte[] default_lang = Xol_lang_.Key_en;
|
||||
private void Load_lang(byte[] bry) {this.Get_by_key_or_new(bry).Init_by_load();}
|
||||
public void Local_set_bulk(byte[] src) { // NOTE: setting local lang names/grps on app level; may need to move to user level or wiki level (for groups) later
|
||||
int len = src.length;
|
||||
int pos = 0, fld_bgn = 0, fld_idx = 0;
|
||||
byte[] code = Bry_.Empty, name = Bry_.Empty;
|
||||
Xol_csv_parser csv_parser = Xol_csv_parser._;
|
||||
while (true) {
|
||||
boolean last = pos == len;
|
||||
byte b = last ? Byte_ascii.Nl : src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Pipe:
|
||||
switch (fld_idx) {
|
||||
case 0: code = csv_parser.Load(src, fld_bgn, pos); break;
|
||||
case 1: name = csv_parser.Load(src, fld_bgn, pos); break;
|
||||
default: throw Exc_.new_unhandled(fld_idx);
|
||||
}
|
||||
fld_bgn = pos + 1;
|
||||
++fld_idx;
|
||||
break;
|
||||
case Byte_ascii.Nl:
|
||||
byte[] grp = csv_parser.Load(src, fld_bgn, pos);
|
||||
Xol_lang_itm itm = Xol_lang_itm_.Get_by_key(code);
|
||||
itm.Localized_name_(name, grp);
|
||||
fld_bgn = pos + 1;
|
||||
fld_idx = 0;
|
||||
break;
|
||||
}
|
||||
if (last) break;
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
public void Bld_xowa() {
|
||||
Xol_mw_lang_parser lang_parser = new Xol_mw_lang_parser(msg_log);
|
||||
lang_parser.Bld_all(this, fsys_mgr);
|
||||
}
|
||||
public Ordered_hash Xto_hash(byte[] raw) {
|
||||
byte[][] keys = Bry_.Split(raw, Byte_ascii.Tilde);
|
||||
int len = keys.length;
|
||||
Ordered_hash langs = Ordered_hash_.new_();
|
||||
Cfg_nde_root lang_root = groups;
|
||||
for (int i = 0; i < len; i++) {
|
||||
byte[] key = keys[i];
|
||||
Cfg_nde_obj lang_grp = lang_root.Grps_get(key);
|
||||
if (lang_grp == null) {
|
||||
Xol_lang_itm itm = Xol_lang_itm_.Get_by_key(key);
|
||||
if (itm == null) throw Exc_.new_("unknown lang group or key", "key", String_.new_u8(key));
|
||||
langs.Add(key, Xoac_lang_grp.Regy_get_or_new(key));
|
||||
}
|
||||
else
|
||||
Cfg_nde_obj_.Fill_recurse(langs, lang_grp);
|
||||
}
|
||||
return langs;
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_get)) return Get_by_key_or_new(m.ReadBry("key"));
|
||||
else if (ctx.Match(k, Invk_groups)) return groups;
|
||||
else if (ctx.Match(k, Invk_local_set_bulk)) Local_set_bulk(m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_load_lang)) Load_lang(m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_mediawiki_converter))return mw_converter;
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
private static final String Invk_get = "get", Invk_local_set_bulk = "local_set_bulk", Invk_load_lang = "load_lang", Invk_groups = "groups", Invk_mediawiki_converter = "mediawiki_converter";
|
||||
public static final byte[] Fallback_false = Bry_.new_a7("false");
|
||||
public static Xol_lang Lang_en_make(Xoa_lang_mgr lang_mgr) {
|
||||
Xol_lang rv = new Xol_lang(lang_mgr, Xol_lang_.Key_en);
|
||||
Xol_lang_.Lang_init(rv);
|
||||
rv.Evt_lang_changed();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
36
400_xowa/src/gplx/xowa/langs/Xol_func_name_itm.java
Normal file
36
400_xowa/src/gplx/xowa/langs/Xol_func_name_itm.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
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; import gplx.*; import gplx.xowa.*;
|
||||
public class Xol_func_name_itm {
|
||||
public byte Tid() {return tid;} private byte tid = Xot_defn_.Tid_null;
|
||||
public Xot_defn Func() {return func;} private Xot_defn func = Xot_defn_.Null;
|
||||
public void Func_set(Xot_defn v, int colon_pos) {
|
||||
if (tid == Xot_defn_.Tid_null) tid = Xot_defn_.Tid_func; // only set tid if subst did not set it
|
||||
this.func = v;
|
||||
this.colon_pos = colon_pos;
|
||||
}
|
||||
public int Colon_pos() {return colon_pos;} private int colon_pos = -1;
|
||||
public int Subst_bgn() {return subst_bgn;} private int subst_bgn = -1;
|
||||
public int Subst_end() {return subst_end;} private int subst_end = -1;
|
||||
public void Subst_set_(byte tid, int bgn, int end) {this.tid = tid; this.subst_bgn = bgn; this.subst_end = end;}
|
||||
public void Clear() {
|
||||
tid = Xot_defn_.Tid_null;
|
||||
func = Xot_defn_.Null;
|
||||
colon_pos = subst_bgn = subst_end = -1;
|
||||
}
|
||||
}
|
||||
117
400_xowa/src/gplx/xowa/langs/Xol_func_name_regy.java
Normal file
117
400_xowa/src/gplx/xowa/langs/Xol_func_name_regy.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
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; import gplx.*; import gplx.xowa.*;
|
||||
import gplx.core.btries.*; import gplx.intl.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
public class Xol_func_name_regy {
|
||||
private final Xoa_lang_mgr lang_mgr; private final Xol_lang lang;
|
||||
private final Xol_func_name_itm finder = new Xol_func_name_itm();
|
||||
private final Btrie_slim_mgr cs_trie = Btrie_slim_mgr.cs_(), ci_trie = Btrie_slim_mgr.ci_utf_8_();
|
||||
public Xol_func_name_regy(Xoa_lang_mgr lang_mgr, Xol_lang lang) {this.lang_mgr = lang_mgr; this.lang = lang;}
|
||||
public void Evt_lang_changed(Xol_lang lang) {
|
||||
Xol_kwd_mgr kwd_mgr = lang.Kwd_mgr();
|
||||
ci_trie.Clear(); cs_trie.Clear();
|
||||
int[] kwd_ary = Pf_func_.Ary_get(!lang.Kwd_mgr__strx());
|
||||
int len = kwd_ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int id = kwd_ary[i];
|
||||
Xol_kwd_grp list = kwd_mgr.Get_at(id);
|
||||
if (list == null) {
|
||||
if (Env_.Mode_testing())
|
||||
continue; // TEST: allows partial parsing of $magicWords
|
||||
else
|
||||
list = lang_mgr.Lang_en().Kwd_mgr().Get_at(id); // get from fallback language; TODO: allow other fallback langs besides "English"
|
||||
}
|
||||
Reg_defn(kwd_mgr, id, Pf_func_.Get_prototype(id));
|
||||
}
|
||||
}
|
||||
public void Reg_defn(Xol_kwd_mgr kwd_mgr, int id, Xot_defn defn) {
|
||||
Xol_kwd_grp grp = kwd_mgr.Get_at(id); if (grp == null) return;
|
||||
Xol_kwd_itm[] itms = grp.Itms(); if (itms == null) return;
|
||||
int itms_len = itms.length;
|
||||
for (int i = 0; i < itms_len; i++) {
|
||||
byte[] name = itms[i].Val();
|
||||
this.Add(name, grp.Case_match(), defn.Clone(id, name));
|
||||
}
|
||||
}
|
||||
private void Add(byte[] ary, boolean case_match, Xot_defn func) {
|
||||
if (case_match)
|
||||
cs_trie.Add_obj(ary, func);
|
||||
else {
|
||||
byte[] lower_ary = lang.Case_mgr().Case_build_lower(ary, 0, ary.length);
|
||||
ci_trie.Add_obj(lower_ary, func);
|
||||
}
|
||||
}
|
||||
public Xol_func_name_itm Find_defn(byte[] src, int txt_bgn, int txt_end) {
|
||||
finder.Clear();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (txt_bgn == txt_end) return finder; // NOTE: true when tmpl_name is either not loaded, or doesn't exist
|
||||
Xot_defn func = Match_bgn(src, txt_bgn, txt_end);
|
||||
if (func == null) return finder; // NOTE: null when tmpl_name is either not loaded, or doesn't exist
|
||||
byte[] func_name = func.Name();
|
||||
int match_pos = func_name.length + txt_bgn;
|
||||
byte defn_tid = func.Defn_tid();
|
||||
switch (defn_tid) {
|
||||
case Xot_defn_.Tid_func:
|
||||
if (match_pos == txt_end) // next char is ws (b/c match_pos == txt_end)
|
||||
finder.Func_set(func, -1);
|
||||
else if (src[match_pos] == Pf_func_.Name_dlm) // next char is :
|
||||
finder.Func_set(func, match_pos);
|
||||
else { // func is close, but not quite: ex: #ifx: or padlefts:
|
||||
return finder;
|
||||
}
|
||||
break;
|
||||
case Xot_defn_.Tid_safesubst:
|
||||
case Xot_defn_.Tid_subst:
|
||||
finder.Subst_set_(defn_tid, txt_bgn, match_pos);
|
||||
if (match_pos < txt_end) txt_bgn = Bry_finder.Find_fwd_while_not_ws(src, match_pos, txt_end);
|
||||
break;
|
||||
case Xot_defn_.Tid_raw:
|
||||
case Xot_defn_.Tid_msg:
|
||||
case Xot_defn_.Tid_msgnw:
|
||||
finder.Subst_set_(defn_tid, txt_bgn, match_pos);
|
||||
if (match_pos + 1 < txt_end) // +1 to include ":" (keyword id "raw", not "raw:")
|
||||
txt_bgn = Bry_finder.Find_fwd_while_not_ws(src, match_pos + 1, txt_end);
|
||||
break;
|
||||
default: return finder;
|
||||
}
|
||||
}
|
||||
return finder;
|
||||
}
|
||||
private Xot_defn Match_bgn(byte[] src, int bgn, int end) {
|
||||
Object cs_obj = cs_trie.Match_bgn(src, bgn, end);
|
||||
Xot_defn rv = null;
|
||||
if (cs_obj != null) { // match found for cs; could be false_match; EX: NAME"+"SPACE and NAME"+"SPACENUMBER
|
||||
rv = (Xot_defn)cs_obj;
|
||||
if (rv.Name().length == end - bgn) // func_name matches cur_name; DATE:2013-04-15
|
||||
return rv;
|
||||
// else {} // func_name doesn't match cur_name; continue below; EX: NAME"+"SPACENUMBER passed in and matches NAME"+"SPACE (which is cs); note that NAME"+"SPACENUMBER only exists in ci
|
||||
}
|
||||
LowerAry(src, bgn, end);
|
||||
byte[] ary = lang.Case_mgr().Case_build_lower(lower_ary, 0, end - bgn);
|
||||
Xot_defn rv_alt = (Xot_defn)ci_trie.Match_bgn(ary, 0, end - bgn);
|
||||
return (rv != null && rv_alt == null)
|
||||
? rv // name not found in ci, but name was found in cs; return cs; handles NAME"+"SPACENUMBER
|
||||
: rv_alt; // else return rv_alt
|
||||
}
|
||||
private void LowerAry(byte[] src, int bgn, int end) {
|
||||
int len = end - bgn;
|
||||
if (len > lower_ary_len) {lower_ary = new byte[len]; lower_ary_len = len;}
|
||||
lower_ary_len = len;
|
||||
Array_.CopyTo(src, bgn, lower_ary, 0, len);
|
||||
} byte[] lower_ary = new byte[255]; int lower_ary_len = 255;
|
||||
}
|
||||
28
400_xowa/src/gplx/xowa/langs/Xol_lang_itm.java
Normal file
28
400_xowa/src/gplx/xowa/langs/Xol_lang_itm.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
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; import gplx.*; import gplx.xowa.*;
|
||||
public class Xol_lang_itm {
|
||||
public Xol_lang_itm(int id, byte[] key, byte[] canonical_name) {this.id = id; this.key = key; this.canonical_name = canonical_name; this.localized_name = canonical_name;}
|
||||
public int Id() {return id;} private final int id; // EX: 1
|
||||
public byte[] Key() {return key;} private final byte[] key; // EX: de
|
||||
public byte[] Canonical_name() {return canonical_name;} private final byte[] canonical_name; // EX: Deutsch
|
||||
public byte[] Localized_name() {return localized_name;} private byte[] localized_name; // EX: German if usr.lang == English
|
||||
public void Localized_name_(byte[] v, byte[] localized_grp) {// NOTE: localized_grp preserved for historical reasons; should be removed; WHEN: refactor Xol_lang_itm_parser
|
||||
if (Bry_.Len_gt_0(v)) this.localized_name = v;
|
||||
}
|
||||
}
|
||||
948
400_xowa/src/gplx/xowa/langs/Xol_lang_itm_.java
Normal file
948
400_xowa/src/gplx/xowa/langs/Xol_lang_itm_.java
Normal file
@@ -0,0 +1,948 @@
|
||||
/*
|
||||
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; import gplx.*; import gplx.xowa.*;
|
||||
import gplx.lists.*;
|
||||
public class Xol_lang_itm_ {
|
||||
public static final byte[] Key__unknown = Bry_.Empty;
|
||||
public static final ComparerAble Comparer_key = new Xol_lang_itm_comparer();
|
||||
public static final int
|
||||
Id__intl = -2
|
||||
, Id__unknown = -1
|
||||
, Id_en = 0
|
||||
, Id_aa = 1
|
||||
, Id_ab = 2
|
||||
, Id_ace = 3
|
||||
, Id_ady_cyrl = 4
|
||||
, Id_aeb = 5
|
||||
, Id_af = 6
|
||||
, Id_ak = 7
|
||||
, Id_akz = 8
|
||||
, Id_aln = 9
|
||||
, Id_als = 10
|
||||
, Id_am = 11
|
||||
, Id_an = 12
|
||||
, Id_ang = 13
|
||||
, Id_anp = 14
|
||||
, Id_ar = 15
|
||||
, Id_arc = 16
|
||||
, Id_arn = 17
|
||||
, Id_aro = 18
|
||||
, Id_arq = 19
|
||||
, Id_ary = 20
|
||||
, Id_arz = 21
|
||||
, Id_as = 22
|
||||
, Id_ase = 23
|
||||
, Id_ast = 24
|
||||
, Id_av = 25
|
||||
, Id_avk = 26
|
||||
, Id_awa = 27
|
||||
, Id_ay = 28
|
||||
, Id_az = 29
|
||||
, Id_azb = 30
|
||||
, Id_ba = 31
|
||||
, Id_ban = 32
|
||||
, Id_bar = 33
|
||||
, Id_bat_smg = 34
|
||||
, Id_bbc = 35
|
||||
, Id_bbc_latn = 36
|
||||
, Id_bcc = 37
|
||||
, Id_bcl = 38
|
||||
, Id_be = 39
|
||||
, Id_be_tarask = 40
|
||||
, Id_be_x_old = 41
|
||||
, Id_bew = 42
|
||||
, Id_bg = 43
|
||||
, Id_bgn = 44
|
||||
, Id_bh = 45
|
||||
, Id_bho = 46
|
||||
, Id_bi = 47
|
||||
, Id_bjn = 48
|
||||
, Id_bm = 49
|
||||
, Id_bn = 50
|
||||
, Id_bo = 51
|
||||
, Id_bpy = 52
|
||||
, Id_bqi = 53
|
||||
, Id_br = 54
|
||||
, Id_brh = 55
|
||||
, Id_bs = 56
|
||||
, Id_bto = 57
|
||||
, Id_bug = 58
|
||||
, Id_bxr = 59
|
||||
, Id_ca = 60
|
||||
, Id_cbk_zam = 61
|
||||
, Id_cdo = 62
|
||||
, Id_ce = 63
|
||||
, Id_ceb = 64
|
||||
, Id_ch = 65
|
||||
, Id_chm = 66
|
||||
, Id_cho = 67
|
||||
, Id_chr = 68
|
||||
, Id_chy = 69
|
||||
, Id_ckb = 70
|
||||
, Id_co = 71
|
||||
, Id_cps = 72
|
||||
, Id_cr = 73
|
||||
, Id_crh = 74
|
||||
, Id_crh_cyrl = 75
|
||||
, Id_crh_latn = 76
|
||||
, Id_cs = 77
|
||||
, Id_csb = 78
|
||||
, Id_cu = 79
|
||||
, Id_cv = 80
|
||||
, Id_cy = 81
|
||||
, Id_da = 82
|
||||
, Id_de = 83
|
||||
, Id_de_at = 84
|
||||
, Id_de_ch = 85
|
||||
, Id_de_formal = 86
|
||||
, Id_diq = 87
|
||||
, Id_dsb = 88
|
||||
, Id_dtp = 89
|
||||
, Id_dv = 90
|
||||
, Id_dz = 91
|
||||
, Id_ee = 92
|
||||
, Id_egl = 93
|
||||
, Id_el = 94
|
||||
, Id_eml = 95
|
||||
, Id_en_ca = 96
|
||||
, Id_en_gb = 97
|
||||
, Id_en_rtl = 98
|
||||
, Id_enrtl = 99
|
||||
, Id_eo = 100
|
||||
, Id_es = 101
|
||||
, Id_es_formal = 102
|
||||
, Id_esu = 103
|
||||
, Id_et = 104
|
||||
, Id_eu = 105
|
||||
, Id_ext = 106
|
||||
, Id_fa = 107
|
||||
, Id_ff = 108
|
||||
, Id_fi = 109
|
||||
, Id_fit = 110
|
||||
, Id_fiu_vro = 111
|
||||
, Id_fj = 112
|
||||
, Id_fo = 113
|
||||
, Id_fr = 114
|
||||
, Id_frc = 115
|
||||
, Id_frp = 116
|
||||
, Id_frr = 117
|
||||
, Id_fur = 118
|
||||
, Id_fy = 119
|
||||
, Id_ga = 120
|
||||
, Id_gag = 121
|
||||
, Id_gan = 122
|
||||
, Id_gan_hans = 123
|
||||
, Id_gan_hant = 124
|
||||
, Id_gd = 125
|
||||
, Id_gl = 126
|
||||
, Id_glk = 127
|
||||
, Id_gn = 128
|
||||
, Id_gom = 129
|
||||
, Id_gom_deva = 130
|
||||
, Id_gom_latn = 131
|
||||
, Id_got = 132
|
||||
, Id_grc = 133
|
||||
, Id_gsw = 134
|
||||
, Id_gu = 135
|
||||
, Id_guc = 136
|
||||
, Id_gv = 137
|
||||
, Id_ha = 138
|
||||
, Id_hak = 139
|
||||
, Id_haw = 140
|
||||
, Id_he = 141
|
||||
, Id_hi = 142
|
||||
, Id_hif = 143
|
||||
, Id_hif_latn = 144
|
||||
, Id_hil = 145
|
||||
, Id_ho = 146
|
||||
, Id_hr = 147
|
||||
, Id_hrx = 148
|
||||
, Id_hsb = 149
|
||||
, Id_hsn = 150
|
||||
, Id_ht = 151
|
||||
, Id_hu = 152
|
||||
, Id_hu_formal = 153
|
||||
, Id_hy = 154
|
||||
, Id_hz = 155
|
||||
, Id_ia = 156
|
||||
, Id_id = 157
|
||||
, Id_ie = 158
|
||||
, Id_ig = 159
|
||||
, Id_ii = 160
|
||||
, Id_ik = 161
|
||||
, Id_ike_cans = 162
|
||||
, Id_ike_latn = 163
|
||||
, Id_ilo = 164
|
||||
, Id_inh = 165
|
||||
, Id_io = 166
|
||||
, Id_is = 167
|
||||
, Id_it = 168
|
||||
, Id_iu = 169
|
||||
, Id_izh = 170
|
||||
, Id_ja = 171
|
||||
, Id_jam = 172
|
||||
, Id_jbo = 173
|
||||
, Id_jut = 174
|
||||
, Id_jv = 175
|
||||
, Id_ka = 176
|
||||
, Id_kaa = 177
|
||||
, Id_kab = 178
|
||||
, Id_kbd = 179
|
||||
, Id_kbd_cyrl = 180
|
||||
, Id_kg = 181
|
||||
, Id_khw = 182
|
||||
, Id_ki = 183
|
||||
, Id_kiu = 184
|
||||
, Id_kj = 185
|
||||
, Id_kk = 186
|
||||
, Id_kk_arab = 187
|
||||
, Id_kk_cn = 188
|
||||
, Id_kk_cyrl = 189
|
||||
, Id_kk_kz = 190
|
||||
, Id_kk_latn = 191
|
||||
, Id_kk_tr = 192
|
||||
, Id_kl = 193
|
||||
, Id_km = 194
|
||||
, Id_kn = 195
|
||||
, Id_ko = 196
|
||||
, Id_ko_kp = 197
|
||||
, Id_koi = 198
|
||||
, Id_kr = 199
|
||||
, Id_krc = 200
|
||||
, Id_kri = 201
|
||||
, Id_krj = 202
|
||||
, Id_krl = 203
|
||||
, Id_ks = 204
|
||||
, Id_ks_arab = 205
|
||||
, Id_ks_deva = 206
|
||||
, Id_ksh = 207
|
||||
, Id_ku = 208
|
||||
, Id_ku_arab = 209
|
||||
, Id_ku_latn = 210
|
||||
, Id_kv = 211
|
||||
, Id_kw = 212
|
||||
, Id_ky = 213
|
||||
, Id_la = 214
|
||||
, Id_lad = 215
|
||||
, Id_lb = 216
|
||||
, Id_lbe = 217
|
||||
, Id_lez = 218
|
||||
, Id_lfn = 219
|
||||
, Id_lg = 220
|
||||
, Id_li = 221
|
||||
, Id_lij = 222
|
||||
, Id_liv = 223
|
||||
, Id_lmo = 224
|
||||
, Id_ln = 225
|
||||
, Id_lo = 226
|
||||
, Id_loz = 227
|
||||
, Id_lrc = 228
|
||||
, Id_lt = 229
|
||||
, Id_ltg = 230
|
||||
, Id_lus = 231
|
||||
, Id_luz = 232
|
||||
, Id_lv = 233
|
||||
, Id_lzh = 234
|
||||
, Id_lzz = 235
|
||||
, Id_mai = 236
|
||||
, Id_map_bms = 237
|
||||
, Id_mdf = 238
|
||||
, Id_mg = 239
|
||||
, Id_mh = 240
|
||||
, Id_mhr = 241
|
||||
, Id_mi = 242
|
||||
, Id_mic = 243
|
||||
, Id_min = 244
|
||||
, Id_mk = 245
|
||||
, Id_ml = 246
|
||||
, Id_mn = 247
|
||||
, Id_mnc = 248
|
||||
, Id_mo = 249
|
||||
, Id_mr = 250
|
||||
, Id_mrj = 251
|
||||
, Id_ms = 252
|
||||
, Id_mt = 253
|
||||
, Id_mui = 254
|
||||
, Id_mus = 255
|
||||
, Id_mwl = 256
|
||||
, Id_mwv = 257
|
||||
, Id_my = 258
|
||||
, Id_myv = 259
|
||||
, Id_mzn = 260
|
||||
, Id_na = 261
|
||||
, Id_nah = 262
|
||||
, Id_nan = 263
|
||||
, Id_nap = 264
|
||||
, Id_nb = 265
|
||||
, Id_nds = 266
|
||||
, Id_nds_nl = 267
|
||||
, Id_ne = 268
|
||||
, Id_new = 269
|
||||
, Id_ng = 270
|
||||
, Id_niu = 271
|
||||
, Id_nl = 272
|
||||
, Id_nl_informal = 273
|
||||
, Id_nn = 274
|
||||
, Id_no = 275
|
||||
, Id_nov = 276
|
||||
, Id_nrm = 277
|
||||
, Id_nso = 278
|
||||
, Id_nv = 279
|
||||
, Id_ny = 280
|
||||
, Id_oc = 281
|
||||
, Id_om = 282
|
||||
, Id_or = 283
|
||||
, Id_os = 284
|
||||
, Id_pa = 285
|
||||
, Id_pag = 286
|
||||
, Id_pam = 287
|
||||
, Id_pap = 288
|
||||
, Id_pbb = 289
|
||||
, Id_pcd = 290
|
||||
, Id_pdc = 291
|
||||
, Id_pdt = 292
|
||||
, Id_pfl = 293
|
||||
, Id_pi = 294
|
||||
, Id_pih = 295
|
||||
, Id_pl = 296
|
||||
, Id_pms = 297
|
||||
, Id_pnb = 298
|
||||
, Id_pnt = 299
|
||||
, Id_ppl = 300
|
||||
, Id_prg = 301
|
||||
, Id_ps = 302
|
||||
, Id_pt = 303
|
||||
, Id_pt_br = 304
|
||||
, Id_qqq = 305
|
||||
, Id_qu = 306
|
||||
, Id_qug = 307
|
||||
, Id_rap = 308
|
||||
, Id_rgn = 309
|
||||
, Id_rif = 310
|
||||
, Id_rm = 311
|
||||
, Id_rmf = 312
|
||||
, Id_rmy = 313
|
||||
, Id_rn = 314
|
||||
, Id_ro = 315
|
||||
, Id_roa_rup = 316
|
||||
, Id_roa_tara = 317
|
||||
, Id_ru = 318
|
||||
, Id_rue = 319
|
||||
, Id_rup = 320
|
||||
, Id_ruq = 321
|
||||
, Id_ruq_cyrl = 322
|
||||
, Id_ruq_latn = 323
|
||||
, Id_rw = 324
|
||||
, Id_ryu = 325
|
||||
, Id_sa = 326
|
||||
, Id_sah = 327
|
||||
, Id_sat = 328
|
||||
, Id_saz = 329
|
||||
, Id_sc = 330
|
||||
, Id_scn = 331
|
||||
, Id_sco = 332
|
||||
, Id_sd = 333
|
||||
, Id_sdc = 334
|
||||
, Id_sdh = 335
|
||||
, Id_se = 336
|
||||
, Id_sei = 337
|
||||
, Id_ses = 338
|
||||
, Id_sg = 339
|
||||
, Id_sgs = 340
|
||||
, Id_sh = 341
|
||||
, Id_shi = 342
|
||||
, Id_shn = 343
|
||||
, Id_si = 344
|
||||
, Id_simple = 345
|
||||
, Id_sk = 346
|
||||
, Id_sl = 347
|
||||
, Id_sli = 348
|
||||
, Id_sly = 349
|
||||
, Id_sm = 350
|
||||
, Id_sma = 351
|
||||
, Id_sn = 352
|
||||
, Id_so = 353
|
||||
, Id_sq = 354
|
||||
, Id_sr = 355
|
||||
, Id_sr_ec = 356
|
||||
, Id_sr_el = 357
|
||||
, Id_srn = 358
|
||||
, Id_ss = 359
|
||||
, Id_st = 360
|
||||
, Id_stq = 361
|
||||
, Id_su = 362
|
||||
, Id_sv = 363
|
||||
, Id_sw = 364
|
||||
, Id_sxu = 365
|
||||
, Id_szl = 366
|
||||
, Id_ta = 367
|
||||
, Id_tcy = 368
|
||||
, Id_te = 369
|
||||
, Id_test = 370
|
||||
, Id_tet = 371
|
||||
, Id_tg = 372
|
||||
, Id_tg_cyrl = 373
|
||||
, Id_tg_latn = 374
|
||||
, Id_th = 375
|
||||
, Id_ti = 376
|
||||
, Id_tk = 377
|
||||
, Id_tl = 378
|
||||
, Id_tly = 379
|
||||
, Id_tn = 380
|
||||
, Id_to = 381
|
||||
, Id_tokipona = 382
|
||||
, Id_tp = 383
|
||||
, Id_tpi = 384
|
||||
, Id_tr = 385
|
||||
, Id_tru = 386
|
||||
, Id_ts = 387
|
||||
, Id_tt = 388
|
||||
, Id_tt_cyrl = 389
|
||||
, Id_tt_latn = 390
|
||||
, Id_ttt = 391
|
||||
, Id_tum = 392
|
||||
, Id_tw = 393
|
||||
, Id_ty = 394
|
||||
, Id_tyv = 395
|
||||
, Id_tzm = 396
|
||||
, Id_udm = 397
|
||||
, Id_ug = 398
|
||||
, Id_ug_arab = 399
|
||||
, Id_ug_latn = 400
|
||||
, Id_uk = 401
|
||||
, Id_ur = 402
|
||||
, Id_uz = 403
|
||||
, Id_ve = 404
|
||||
, Id_vec = 405
|
||||
, Id_vep = 406
|
||||
, Id_vi = 407
|
||||
, Id_vls = 408
|
||||
, Id_vmf = 409
|
||||
, Id_vo = 410
|
||||
, Id_vot = 411
|
||||
, Id_vro = 412
|
||||
, Id_wa = 413
|
||||
, Id_war = 414
|
||||
, Id_wo = 415
|
||||
, Id_wuu = 416
|
||||
, Id_xal = 417
|
||||
, Id_xh = 418
|
||||
, Id_xmf = 419
|
||||
, Id_yi = 420
|
||||
, Id_yo = 421
|
||||
, Id_yue = 422
|
||||
, Id_za = 423
|
||||
, Id_zea = 424
|
||||
, Id_zh = 425
|
||||
, Id_zh_classical = 426
|
||||
, Id_zh_cn = 427
|
||||
, Id_zh_hans = 428
|
||||
, Id_zh_hant = 429
|
||||
, Id_zh_hk = 430
|
||||
, Id_zh_min_nan = 431
|
||||
, Id_zh_mo = 432
|
||||
, Id_zh_my = 433
|
||||
, Id_zh_sg = 434
|
||||
, Id_zh_tw = 435
|
||||
, Id_zh_yue = 436
|
||||
, Id_zu = 437
|
||||
;
|
||||
public static final int Id__max = 438;
|
||||
public static Hash_adp_bry Regy() {
|
||||
if (regy == null) {
|
||||
// NOTE: any parenthetical String below will have an "unseen" character of "\xE2\x80\xAA" at the begining and "\xE2\x80\xAC" at the end. They are responsible for parentheses-orientation in RTL langs.
|
||||
regy = Hash_adp_bry.ci_ascii_(); // ASCII:lang_code; NOTE: must be ci; EX: {{#languages:FR}}
|
||||
Regy_add(regy, Id_en, "en", "English");
|
||||
Regy_add(regy, Id_aa, "aa", "Qafár af");
|
||||
Regy_add(regy, Id_ab, "ab", "Аҧсуа");
|
||||
Regy_add(regy, Id_ace, "ace", "Acèh");
|
||||
Regy_add(regy, Id_ady_cyrl, "ady-cyrl", "West Circassian (Cyrillic)");
|
||||
Regy_add(regy, Id_aeb, "aeb", "زَوُن");
|
||||
Regy_add(regy, Id_af, "af", "Afrikaans");
|
||||
Regy_add(regy, Id_ak, "ak", "Akan");
|
||||
Regy_add(regy, Id_akz, "akz", "Alibamu");
|
||||
Regy_add(regy, Id_aln, "aln", "Gegë");
|
||||
Regy_add(regy, Id_als, "als", "Alemannisch");
|
||||
Regy_add(regy, Id_am, "am", "አማርኛ");
|
||||
Regy_add(regy, Id_an, "an", "Aragonés");
|
||||
Regy_add(regy, Id_ang, "ang", "Ænglisc");
|
||||
Regy_add(regy, Id_anp, "anp", "अङ्गिका");
|
||||
Regy_add(regy, Id_ar, "ar", "العربية");
|
||||
Regy_add(regy, Id_arc, "arc", "ܐܪܡܝܐ");
|
||||
Regy_add(regy, Id_arn, "arn", "Mapudungun");
|
||||
Regy_add(regy, Id_aro, "aro", "Araona");
|
||||
Regy_add(regy, Id_arq, "arq", "Algerian Arabic");
|
||||
Regy_add(regy, Id_ary, "ary", "Maġribi");
|
||||
Regy_add(regy, Id_arz, "arz", "مصرى");
|
||||
Regy_add(regy, Id_as, "as", "অসমীয়া");
|
||||
Regy_add(regy, Id_ase, "ase", "American Sign Language");
|
||||
Regy_add(regy, Id_ast, "ast", "Asturianu");
|
||||
Regy_add(regy, Id_av, "av", "Авар");
|
||||
Regy_add(regy, Id_avk, "avk", "Kotava");
|
||||
Regy_add(regy, Id_awa, "awa", "Awadhi");
|
||||
Regy_add(regy, Id_ay, "ay", "Aymar aru");
|
||||
Regy_add(regy, Id_az, "az", "Azərbaycanca");
|
||||
Regy_add(regy, Id_azb, "azb", "South Azerbaijani");
|
||||
Regy_add(regy, Id_ba, "ba", "Башҡортса");
|
||||
Regy_add(regy, Id_ban, "ban", "ᬩᬲᬩᬮᬶ");
|
||||
Regy_add(regy, Id_bar, "bar", "Boarisch");
|
||||
Regy_add(regy, Id_bat_smg, "bat-smg", "Žemaitėška");
|
||||
Regy_add(regy, Id_bbc, "bbc", "Batak Toba");
|
||||
Regy_add(regy, Id_bbc_latn, "bbc-latn", "Batak Toba (Latin)");
|
||||
Regy_add(regy, Id_bcc, "bcc", "بلوچی مکرانی");
|
||||
Regy_add(regy, Id_bcl, "bcl", "Bikol Central");
|
||||
Regy_add(regy, Id_be, "be", "Беларуская");
|
||||
Regy_add(regy, Id_be_tarask, "be-tarask", "Беларуская (тарашкевіца)");
|
||||
Regy_add(regy, Id_be_x_old, "be-x-old", "Беларуская (тарашкевіца)");
|
||||
Regy_add(regy, Id_bew, "bew", "Betawi");
|
||||
Regy_add(regy, Id_bg, "bg", "Български");
|
||||
Regy_add(regy, Id_bgn, "bgn", "Balochi");
|
||||
Regy_add(regy, Id_bh, "bh", "भोजपुरी");
|
||||
Regy_add(regy, Id_bho, "bho", "भोजपुरी");
|
||||
Regy_add(regy, Id_bi, "bi", "Bislama");
|
||||
Regy_add(regy, Id_bjn, "bjn", "Bahasa Banjar");
|
||||
Regy_add(regy, Id_bm, "bm", "Bamanankan");
|
||||
Regy_add(regy, Id_bn, "bn", "বাংলা");
|
||||
Regy_add(regy, Id_bo, "bo", "བོད་ཡིག");
|
||||
Regy_add(regy, Id_bpy, "bpy", "ইমার ঠার/বিষ্ণুপ্রিয়া মণিপুরী");
|
||||
Regy_add(regy, Id_bqi, "bqi", "بختياري");
|
||||
Regy_add(regy, Id_br, "br", "Brezhoneg");
|
||||
Regy_add(regy, Id_brh, "brh", "Bráhuí");
|
||||
Regy_add(regy, Id_bs, "bs", "Bosanski");
|
||||
Regy_add(regy, Id_bto, "bto", "Rinconada Bikol");
|
||||
Regy_add(regy, Id_bug, "bug", "ᨅᨔ ᨕᨘᨁᨗ");
|
||||
Regy_add(regy, Id_bxr, "bxr", "Буряад");
|
||||
Regy_add(regy, Id_ca, "ca", "Català");
|
||||
Regy_add(regy, Id_cbk_zam, "cbk-zam", "Chavacano de Zamboanga");
|
||||
Regy_add(regy, Id_cdo, "cdo", "Mìng-dĕ̤ng-ngṳ̄");
|
||||
Regy_add(regy, Id_ce, "ce", "Нохчийн");
|
||||
Regy_add(regy, Id_ceb, "ceb", "Cebuano");
|
||||
Regy_add(regy, Id_ch, "ch", "Chamoru");
|
||||
Regy_add(regy, Id_chm, "chm", "Mari");
|
||||
Regy_add(regy, Id_cho, "cho", "Choctaw");
|
||||
Regy_add(regy, Id_chr, "chr", "ᏣᎳᎩ");
|
||||
Regy_add(regy, Id_chy, "chy", "Tsetsêhestâhese");
|
||||
Regy_add(regy, Id_ckb, "ckb", "کوردی");
|
||||
Regy_add(regy, Id_co, "co", "Corsu");
|
||||
Regy_add(regy, Id_cps, "cps", "Capiceño");
|
||||
Regy_add(regy, Id_cr, "cr", "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ");
|
||||
Regy_add(regy, Id_crh, "crh", "Qırımtatarca");
|
||||
Regy_add(regy, Id_crh_cyrl, "crh-cyrl", "Къырымтатарджа (Кирилл)");
|
||||
Regy_add(regy, Id_crh_latn, "crh-latn", "Qırımtatarca (Latin)");
|
||||
Regy_add(regy, Id_cs, "cs", "Česky");
|
||||
Regy_add(regy, Id_csb, "csb", "Kaszëbsczi");
|
||||
Regy_add(regy, Id_cu, "cu", "Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ");
|
||||
Regy_add(regy, Id_cv, "cv", "Чӑвашла");
|
||||
Regy_add(regy, Id_cy, "cy", "Cymraeg");
|
||||
Regy_add(regy, Id_da, "da", "Dansk");
|
||||
Regy_add(regy, Id_de, "de", "Deutsch");
|
||||
Regy_add(regy, Id_de_at, "de-at", "Österreichisches Deutsch");
|
||||
Regy_add(regy, Id_de_ch, "de-ch", "Schweizer Hochdeutsch");
|
||||
Regy_add(regy, Id_de_formal, "de-formal", "Deutsch (Sie-Form)");
|
||||
Regy_add(regy, Id_diq, "diq", "Zazaki");
|
||||
Regy_add(regy, Id_dsb, "dsb", "Dolnoserbski");
|
||||
Regy_add(regy, Id_dtp, "dtp", "Dusun Bundu-liwan");
|
||||
Regy_add(regy, Id_dv, "dv", "ދިވެހިބަސް");
|
||||
Regy_add(regy, Id_dz, "dz", "ཇོང་ཁ");
|
||||
Regy_add(regy, Id_ee, "ee", "Eʋegbe");
|
||||
Regy_add(regy, Id_egl, "egl", "Emiliàn");
|
||||
Regy_add(regy, Id_el, "el", "Ελληνικά");
|
||||
Regy_add(regy, Id_eml, "eml", "Emiliàn e rumagnòl");
|
||||
Regy_add(regy, Id_en_ca, "en-ca", "Canadian English");
|
||||
Regy_add(regy, Id_en_gb, "en-gb", "British English");
|
||||
Regy_add(regy, Id_en_rtl, "en-rtl", "English rtl");
|
||||
Regy_add(regy, Id_enrtl, "enrtl", "English (right to left)");
|
||||
Regy_add(regy, Id_eo, "eo", "Esperanto");
|
||||
Regy_add(regy, Id_es, "es", "Español");
|
||||
Regy_add(regy, Id_es_formal, "es-formal", "Spanish (formal)");
|
||||
Regy_add(regy, Id_esu, "esu", "Yuk'ip");
|
||||
Regy_add(regy, Id_et, "et", "Eesti");
|
||||
Regy_add(regy, Id_eu, "eu", "Euskara");
|
||||
Regy_add(regy, Id_ext, "ext", "Estremeñu");
|
||||
Regy_add(regy, Id_fa, "fa", "فارسی");
|
||||
Regy_add(regy, Id_ff, "ff", "Fulfulde");
|
||||
Regy_add(regy, Id_fi, "fi", "Suomi");
|
||||
Regy_add(regy, Id_fit, "fit", "meänkieli");
|
||||
Regy_add(regy, Id_fiu_vro, "fiu-vro", "Võro");
|
||||
Regy_add(regy, Id_fj, "fj", "Na Vosa Vakaviti");
|
||||
Regy_add(regy, Id_fo, "fo", "Føroyskt");
|
||||
Regy_add(regy, Id_fr, "fr", "Français");
|
||||
Regy_add(regy, Id_frc, "frc", "Français cadien");
|
||||
Regy_add(regy, Id_frp, "frp", "Arpetan");
|
||||
Regy_add(regy, Id_frr, "frr", "Nordfriisk");
|
||||
Regy_add(regy, Id_fur, "fur", "Furlan");
|
||||
Regy_add(regy, Id_fy, "fy", "Frysk");
|
||||
Regy_add(regy, Id_ga, "ga", "Gaeilge");
|
||||
Regy_add(regy, Id_gag, "gag", "Gagauz");
|
||||
Regy_add(regy, Id_gan, "gan", "贛語");
|
||||
Regy_add(regy, Id_gan_hans, "gan-hans", "赣语(简体)");
|
||||
Regy_add(regy, Id_gan_hant, "gan-hant", "贛語(繁體)");
|
||||
Regy_add(regy, Id_gd, "gd", "Gàidhlig");
|
||||
Regy_add(regy, Id_gl, "gl", "Galego");
|
||||
Regy_add(regy, Id_glk, "glk", "گیلکی");
|
||||
Regy_add(regy, Id_gn, "gn", "Avañe'ẽ");
|
||||
Regy_add(regy, Id_gom, "gom", "कोंकणी");
|
||||
Regy_add(regy, Id_gom_deva, "gom-deva", "Konkani");
|
||||
Regy_add(regy, Id_gom_latn, "gom-latn", "कोंकणी (Latin)");
|
||||
Regy_add(regy, Id_got, "got", "𐌲𐌿𐍄𐌹𐍃𐌺");
|
||||
Regy_add(regy, Id_grc, "grc", "Ἀρχαία ἑλληνικὴ");
|
||||
Regy_add(regy, Id_gsw, "gsw", "Alemannisch");
|
||||
Regy_add(regy, Id_gu, "gu", "ગુજરાતી");
|
||||
Regy_add(regy, Id_guc, "guc", "Wayuu");
|
||||
Regy_add(regy, Id_gv, "gv", "Gaelg");
|
||||
Regy_add(regy, Id_ha, "ha", "هَوُسَ");
|
||||
Regy_add(regy, Id_hak, "hak", "Hak-kâ-fa");
|
||||
Regy_add(regy, Id_haw, "haw", "Hawai`i");
|
||||
Regy_add(regy, Id_he, "he", "עברית");
|
||||
Regy_add(regy, Id_hi, "hi", "हिन्दी");
|
||||
Regy_add(regy, Id_hif, "hif", "Fiji Hindi");
|
||||
Regy_add(regy, Id_hif_latn, "hif-latn", "Fiji Hindi");
|
||||
Regy_add(regy, Id_hil, "hil", "Ilonggo");
|
||||
Regy_add(regy, Id_ho, "ho", "Hiri Motu");
|
||||
Regy_add(regy, Id_hr, "hr", "Hrvatski");
|
||||
Regy_add(regy, Id_hrx, "hrx", "Hunsriker");
|
||||
Regy_add(regy, Id_hsb, "hsb", "Hornjoserbsce");
|
||||
Regy_add(regy, Id_hsn, "hsn", "Xiang");
|
||||
Regy_add(regy, Id_ht, "ht", "Kreyòl ayisyen");
|
||||
Regy_add(regy, Id_hu, "hu", "Magyar");
|
||||
Regy_add(regy, Id_hu_formal, "hu-formal", "Magyar (formal)");
|
||||
Regy_add(regy, Id_hy, "hy", "Հայերեն");
|
||||
Regy_add(regy, Id_hz, "hz", "Otsiherero");
|
||||
Regy_add(regy, Id_ia, "ia", "Interlingua");
|
||||
Regy_add(regy, Id_id, "id", "Bahasa Indonesia");
|
||||
Regy_add(regy, Id_ie, "ie", "Interlingue");
|
||||
Regy_add(regy, Id_ig, "ig", "Igbo");
|
||||
Regy_add(regy, Id_ii, "ii", "ꆇꉙ");
|
||||
Regy_add(regy, Id_ik, "ik", "Iñupiak");
|
||||
Regy_add(regy, Id_ike_cans, "ike-cans", "ᐃᓄᒃᑎᑐᑦ");
|
||||
Regy_add(regy, Id_ike_latn, "ike-latn", "inuktitut");
|
||||
Regy_add(regy, Id_ilo, "ilo", "Ilokano");
|
||||
Regy_add(regy, Id_inh, "inh", "ГІалгІай Ğalğaj");
|
||||
Regy_add(regy, Id_io, "io", "Ido");
|
||||
Regy_add(regy, Id_is, "is", "Íslenska");
|
||||
Regy_add(regy, Id_it, "it", "Italiano");
|
||||
Regy_add(regy, Id_iu, "iu", "ᐃᓄᒃᑎᑐᑦ/inuktitut");
|
||||
Regy_add(regy, Id_izh, "izh", "Ingrian");
|
||||
Regy_add(regy, Id_ja, "ja", "日本語");
|
||||
Regy_add(regy, Id_jam, "jam", "Patois");
|
||||
Regy_add(regy, Id_jbo, "jbo", "Lojban");
|
||||
Regy_add(regy, Id_jut, "jut", "Jysk");
|
||||
Regy_add(regy, Id_jv, "jv", "Basa Jawa");
|
||||
Regy_add(regy, Id_ka, "ka", "ქართული");
|
||||
Regy_add(regy, Id_kaa, "kaa", "Qaraqalpaqsha");
|
||||
Regy_add(regy, Id_kab, "kab", "Taqbaylit");
|
||||
Regy_add(regy, Id_kbd, "kbd", "Къэбэрдеибзэ / Qabardjajəbza");
|
||||
Regy_add(regy, Id_kbd_cyrl, "kbd-cyrl", "къэбэрдеибзэ");
|
||||
Regy_add(regy, Id_kg, "kg", "Kongo");
|
||||
Regy_add(regy, Id_khw, "khw", "کھوار");
|
||||
Regy_add(regy, Id_ki, "ki", "Gĩkũyũ");
|
||||
Regy_add(regy, Id_kiu, "kiu", "Kırmancki");
|
||||
Regy_add(regy, Id_kj, "kj", "Kwanyama");
|
||||
Regy_add(regy, Id_kk, "kk", "Қазақша");
|
||||
Regy_add(regy, Id_kk_arab, "kk-arab", "قازاقشا (تٴوتە)");
|
||||
Regy_add(regy, Id_kk_cn, "kk-cn", "قازاقشا (جۇنگو)");
|
||||
Regy_add(regy, Id_kk_cyrl, "kk-cyrl", "Қазақша (кирил)");
|
||||
Regy_add(regy, Id_kk_kz, "kk-kz", "Қазақша (Қазақстан)");
|
||||
Regy_add(regy, Id_kk_latn, "kk-latn", "Qazaqşa (latın)");
|
||||
Regy_add(regy, Id_kk_tr, "kk-tr", "Qazaqşa (Türkïya)");
|
||||
Regy_add(regy, Id_kl, "kl", "Kalaallisut");
|
||||
Regy_add(regy, Id_km, "km", "ភាសាខ្មែរ");
|
||||
Regy_add(regy, Id_kn, "kn", "ಕನ್ನಡ");
|
||||
Regy_add(regy, Id_ko, "ko", "한국어");
|
||||
Regy_add(regy, Id_ko_kp, "ko-kp", "한국어 (조선)");
|
||||
Regy_add(regy, Id_koi, "koi", "Перем Коми");
|
||||
Regy_add(regy, Id_kr, "kr", "Kanuri");
|
||||
Regy_add(regy, Id_krc, "krc", "Къарачай-Малкъар");
|
||||
Regy_add(regy, Id_kri, "kri", "Krio");
|
||||
Regy_add(regy, Id_krj, "krj", "Kinaray-a");
|
||||
Regy_add(regy, Id_krl, "krl", "Karelian");
|
||||
Regy_add(regy, Id_ks, "ks", "कश्मीरी - (كشميري)");
|
||||
Regy_add(regy, Id_ks_arab, "ks-arab", "کٲشُر");
|
||||
Regy_add(regy, Id_ks_deva, "ks-deva", "कॉशुर");
|
||||
Regy_add(regy, Id_ksh, "ksh", "Ripoarisch");
|
||||
Regy_add(regy, Id_ku, "ku", "Kurdî");
|
||||
Regy_add(regy, Id_ku_arab, "ku-arab", "كوردي (عەرەبی)");
|
||||
Regy_add(regy, Id_ku_latn, "ku-latn", "Kurdî (latînî)");
|
||||
Regy_add(regy, Id_kv, "kv", "Коми");
|
||||
Regy_add(regy, Id_kw, "kw", "Kernowek");
|
||||
Regy_add(regy, Id_ky, "ky", "Кыргызча");
|
||||
Regy_add(regy, Id_la, "la", "Latina");
|
||||
Regy_add(regy, Id_lad, "lad", "Ladino");
|
||||
Regy_add(regy, Id_lb, "lb", "Lëtzebuergesch");
|
||||
Regy_add(regy, Id_lbe, "lbe", "Лакку");
|
||||
Regy_add(regy, Id_lez, "lez", "Лезги");
|
||||
Regy_add(regy, Id_lfn, "lfn", "Lingua Franca Nova");
|
||||
Regy_add(regy, Id_lg, "lg", "Luganda");
|
||||
Regy_add(regy, Id_li, "li", "Limburgs");
|
||||
Regy_add(regy, Id_lij, "lij", "Líguru");
|
||||
Regy_add(regy, Id_liv, "liv", "Līvõ kēļ");
|
||||
Regy_add(regy, Id_lmo, "lmo", "Lumbaart");
|
||||
Regy_add(regy, Id_ln, "ln", "Lingála");
|
||||
Regy_add(regy, Id_lo, "lo", "ລາວ");
|
||||
Regy_add(regy, Id_loz, "loz", "Silozi");
|
||||
Regy_add(regy, Id_lrc, "lrc", "لوری");
|
||||
Regy_add(regy, Id_lt, "lt", "Lietuvių");
|
||||
Regy_add(regy, Id_ltg, "ltg", "Latgaļu");
|
||||
Regy_add(regy, Id_lus, "lus", "Mizo ţawng");
|
||||
Regy_add(regy, Id_luz, "luz", "Luri");
|
||||
Regy_add(regy, Id_lv, "lv", "Latviešu");
|
||||
Regy_add(regy, Id_lzh, "lzh", "文言");
|
||||
Regy_add(regy, Id_lzz, "lzz", "Lazuri");
|
||||
Regy_add(regy, Id_mai, "mai", "मैथिली");
|
||||
Regy_add(regy, Id_map_bms, "map-bms", "Basa Banyumasan");
|
||||
Regy_add(regy, Id_mdf, "mdf", "Мокшень");
|
||||
Regy_add(regy, Id_mg, "mg", "Malagasy");
|
||||
Regy_add(regy, Id_mh, "mh", "Ebon");
|
||||
Regy_add(regy, Id_mhr, "mhr", "Олык Марий");
|
||||
Regy_add(regy, Id_mi, "mi", "Māori");
|
||||
Regy_add(regy, Id_mic, "mic", "Mi'kmaq");
|
||||
Regy_add(regy, Id_min, "min", "Baso Minangkabau");
|
||||
Regy_add(regy, Id_mk, "mk", "Македонски");
|
||||
Regy_add(regy, Id_ml, "ml", "മലയാളം");
|
||||
Regy_add(regy, Id_mn, "mn", "Монгол");
|
||||
Regy_add(regy, Id_mnc, "mnc", "Manchu");
|
||||
Regy_add(regy, Id_mo, "mo", "Молдовеняскэ");
|
||||
Regy_add(regy, Id_mr, "mr", "मराठी");
|
||||
Regy_add(regy, Id_mrj, "mrj", "Кырык мары");
|
||||
Regy_add(regy, Id_ms, "ms", "Bahasa Melayu");
|
||||
Regy_add(regy, Id_mt, "mt", "Malti");
|
||||
Regy_add(regy, Id_mui, "mui", "Musi");
|
||||
Regy_add(regy, Id_mus, "mus", "Mvskoke");
|
||||
Regy_add(regy, Id_mwl, "mwl", "Mirandés");
|
||||
Regy_add(regy, Id_mwv, "mwv", "Behase Mentawei");
|
||||
Regy_add(regy, Id_my, "my", "Burmese");
|
||||
Regy_add(regy, Id_myv, "myv", "Эрзянь");
|
||||
Regy_add(regy, Id_mzn, "mzn", "مازِرونی");
|
||||
Regy_add(regy, Id_na, "na", "Dorerin Naoero");
|
||||
Regy_add(regy, Id_nah, "nah", "Nāhuatl");
|
||||
Regy_add(regy, Id_nan, "nan", "Bân-lâm-gú");
|
||||
Regy_add(regy, Id_nap, "nap", "Nnapulitano");
|
||||
Regy_add(regy, Id_nb, "nb", "Norsk (bokmål)");
|
||||
Regy_add(regy, Id_nds, "nds", "Plattdüütsch");
|
||||
Regy_add(regy, Id_nds_nl, "nds-nl", "Nedersaksisch");
|
||||
Regy_add(regy, Id_ne, "ne", "नेपाली");
|
||||
Regy_add(regy, Id_new, "new", "नेपाल भाषा");
|
||||
Regy_add(regy, Id_ng, "ng", "Oshiwambo");
|
||||
Regy_add(regy, Id_niu, "niu", "Niuē");
|
||||
Regy_add(regy, Id_nl, "nl", "Nederlands");
|
||||
Regy_add(regy, Id_nl_informal, "nl-informal", "Nederlands (informeel)");
|
||||
Regy_add(regy, Id_nn, "nn", "Norsk (nynorsk)");
|
||||
Regy_add(regy, Id_no, "no", "Norsk (bokmål)");
|
||||
Regy_add(regy, Id_nov, "nov", "Novial");
|
||||
Regy_add(regy, Id_nrm, "nrm", "Nouormand");
|
||||
Regy_add(regy, Id_nso, "nso", "Sesotho sa Leboa");
|
||||
Regy_add(regy, Id_nv, "nv", "Diné bizaad");
|
||||
Regy_add(regy, Id_ny, "ny", "Chi-Chewa");
|
||||
Regy_add(regy, Id_oc, "oc", "Occitan");
|
||||
Regy_add(regy, Id_om, "om", "Oromoo");
|
||||
Regy_add(regy, Id_or, "or", "ଓଡ଼ିଆ");
|
||||
Regy_add(regy, Id_os, "os", "Иронау");
|
||||
Regy_add(regy, Id_pa, "pa", "ਪੰਜਾਬੀ");
|
||||
Regy_add(regy, Id_pag, "pag", "Pangasinan");
|
||||
Regy_add(regy, Id_pam, "pam", "Kapampangan");
|
||||
Regy_add(regy, Id_pap, "pap", "Papiamentu");
|
||||
Regy_add(regy, Id_pbb, "pbb", "Páez");
|
||||
Regy_add(regy, Id_pcd, "pcd", "Picard");
|
||||
Regy_add(regy, Id_pdc, "pdc", "Deitsch");
|
||||
Regy_add(regy, Id_pdt, "pdt", "Plautdietsch");
|
||||
Regy_add(regy, Id_pfl, "pfl", "Pälzisch");
|
||||
Regy_add(regy, Id_pi, "pi", "पािऴ");
|
||||
Regy_add(regy, Id_pih, "pih", "Norfuk / Pitkern");
|
||||
Regy_add(regy, Id_pl, "pl", "Polski");
|
||||
Regy_add(regy, Id_pms, "pms", "Piemontèis");
|
||||
Regy_add(regy, Id_pnb, "pnb", "پنجابی");
|
||||
Regy_add(regy, Id_pnt, "pnt", "Ποντιακά");
|
||||
Regy_add(regy, Id_ppl, "ppl", "Pipil");
|
||||
Regy_add(regy, Id_prg, "prg", "Prūsiskan");
|
||||
Regy_add(regy, Id_ps, "ps", "پښتو");
|
||||
Regy_add(regy, Id_pt, "pt", "Português");
|
||||
Regy_add(regy, Id_pt_br, "pt-br", "Português do Brasil");
|
||||
Regy_add(regy, Id_qqq, "qqq", "MediaWiki sample");
|
||||
Regy_add(regy, Id_qu, "qu", "Runa Simi");
|
||||
Regy_add(regy, Id_qug, "qug", "Runa shimi");
|
||||
Regy_add(regy, Id_rap, "rap", "Rapa Nui");
|
||||
Regy_add(regy, Id_rgn, "rgn", "Rumagnôl");
|
||||
Regy_add(regy, Id_rif, "rif", "Tarifit");
|
||||
Regy_add(regy, Id_rm, "rm", "Rumantsch");
|
||||
Regy_add(regy, Id_rmf, "rmf", "Finnish Kalo");
|
||||
Regy_add(regy, Id_rmy, "rmy", "Romani");
|
||||
Regy_add(regy, Id_rn, "rn", "Kirundi");
|
||||
Regy_add(regy, Id_ro, "ro", "Română");
|
||||
Regy_add(regy, Id_roa_rup, "roa-rup", "Armãneashce");
|
||||
Regy_add(regy, Id_roa_tara, "roa-tara", "Tarandíne");
|
||||
Regy_add(regy, Id_ru, "ru", "Русский");
|
||||
Regy_add(regy, Id_rue, "rue", "Русиньскый");
|
||||
Regy_add(regy, Id_rup, "rup", "Armãneașce");
|
||||
Regy_add(regy, Id_ruq, "ruq", "Vlăheşte");
|
||||
Regy_add(regy, Id_ruq_cyrl, "ruq-cyrl", "Влахесте");
|
||||
Regy_add(regy, Id_ruq_latn, "ruq-latn", "Vlăheşte");
|
||||
Regy_add(regy, Id_rw, "rw", "Kinyarwanda");
|
||||
Regy_add(regy, Id_ryu, "ryu", "Okinawan");
|
||||
Regy_add(regy, Id_sa, "sa", "संस्कृत");
|
||||
Regy_add(regy, Id_sah, "sah", "Саха тыла");
|
||||
Regy_add(regy, Id_sat, "sat", "Santali");
|
||||
Regy_add(regy, Id_saz, "saz", "Saurashtra");
|
||||
Regy_add(regy, Id_sc, "sc", "Sardu");
|
||||
Regy_add(regy, Id_scn, "scn", "Sicilianu");
|
||||
Regy_add(regy, Id_sco, "sco", "Scots");
|
||||
Regy_add(regy, Id_sd, "sd", "سنڌي");
|
||||
Regy_add(regy, Id_sdc, "sdc", "Sassaresu");
|
||||
Regy_add(regy, Id_sdh, "sdh", "Southern Kurdish");
|
||||
Regy_add(regy, Id_se, "se", "Sámegiella");
|
||||
Regy_add(regy, Id_sei, "sei", "Cmique Itom");
|
||||
Regy_add(regy, Id_ses, "ses", "Songhay");
|
||||
Regy_add(regy, Id_sg, "sg", "Sängö");
|
||||
Regy_add(regy, Id_sgs, "sgs", "Žemaitėška");
|
||||
Regy_add(regy, Id_sh, "sh", "Srpskohrvatski / Српскохрватски");
|
||||
Regy_add(regy, Id_shi, "shi", "Tašlḥiyt");
|
||||
Regy_add(regy, Id_shn, "shn", "Shan");
|
||||
Regy_add(regy, Id_si, "si", "Sinhalese");
|
||||
Regy_add(regy, Id_simple, "simple", "Simple English");
|
||||
Regy_add(regy, Id_sk, "sk", "Slovenčina");
|
||||
Regy_add(regy, Id_sl, "sl", "Slovenščina");
|
||||
Regy_add(regy, Id_sli, "sli", "Schläsch");
|
||||
Regy_add(regy, Id_sly, "sly", "Selayar");
|
||||
Regy_add(regy, Id_sm, "sm", "Gagana Samoa");
|
||||
Regy_add(regy, Id_sma, "sma", "Åarjelsaemien");
|
||||
Regy_add(regy, Id_sn, "sn", "chiShona");
|
||||
Regy_add(regy, Id_so, "so", "Soomaaliga");
|
||||
Regy_add(regy, Id_sq, "sq", "Shqip");
|
||||
Regy_add(regy, Id_sr, "sr", "Српски / Srpski");
|
||||
Regy_add(regy, Id_sr_ec, "sr-ec", "Српски (ћирилица)");
|
||||
Regy_add(regy, Id_sr_el, "sr-el", "Srpski (latinica)");
|
||||
Regy_add(regy, Id_srn, "srn", "Sranantongo");
|
||||
Regy_add(regy, Id_ss, "ss", "SiSwati");
|
||||
Regy_add(regy, Id_st, "st", "Sesotho");
|
||||
Regy_add(regy, Id_stq, "stq", "Seeltersk");
|
||||
Regy_add(regy, Id_su, "su", "Basa Sunda");
|
||||
Regy_add(regy, Id_sv, "sv", "Svenska");
|
||||
Regy_add(regy, Id_sw, "sw", "Kiswahili");
|
||||
Regy_add(regy, Id_sxu, "sxu", "Saxon, Upper");
|
||||
Regy_add(regy, Id_szl, "szl", "Ślůnski");
|
||||
Regy_add(regy, Id_ta, "ta", "தமிழ்");
|
||||
Regy_add(regy, Id_tcy, "tcy", "ತುಳು");
|
||||
Regy_add(regy, Id_te, "te", "తెలుగు");
|
||||
Regy_add(regy, Id_test, "test", "MediaWiki test");
|
||||
Regy_add(regy, Id_tet, "tet", "Tetun");
|
||||
Regy_add(regy, Id_tg, "tg", "Тоҷикӣ");
|
||||
Regy_add(regy, Id_tg_cyrl, "tg-cyrl", "Тоҷикӣ");
|
||||
Regy_add(regy, Id_tg_latn, "tg-latn", "tojikī");
|
||||
Regy_add(regy, Id_th, "th", "ไทย");
|
||||
Regy_add(regy, Id_ti, "ti", "ትግርኛ");
|
||||
Regy_add(regy, Id_tk, "tk", "Türkmençe");
|
||||
Regy_add(regy, Id_tl, "tl", "Tagalog");
|
||||
Regy_add(regy, Id_tly, "tly", "толышә зывон");
|
||||
Regy_add(regy, Id_tn, "tn", "Setswana");
|
||||
Regy_add(regy, Id_to, "to", "lea faka-Tonga");
|
||||
Regy_add(regy, Id_tokipona, "tokipona", "Toki Pona");
|
||||
Regy_add(regy, Id_tp, "tp", "Toki Pona (deprecated:tokipona)");
|
||||
Regy_add(regy, Id_tpi, "tpi", "Tok Pisin");
|
||||
Regy_add(regy, Id_tr, "tr", "Türkçe");
|
||||
Regy_add(regy, Id_tru, "tru", "Ṫuroyo");
|
||||
Regy_add(regy, Id_ts, "ts", "Xitsonga");
|
||||
Regy_add(regy, Id_tt, "tt", "Татарча/Tatarça");
|
||||
Regy_add(regy, Id_tt_cyrl, "tt-cyrl", "Татарча");
|
||||
Regy_add(regy, Id_tt_latn, "tt-latn", "Tatarça");
|
||||
Regy_add(regy, Id_ttt, "ttt", "Tat, Muslim");
|
||||
Regy_add(regy, Id_tum, "tum", "chiTumbuka");
|
||||
Regy_add(regy, Id_tw, "tw", "Twi");
|
||||
Regy_add(regy, Id_ty, "ty", "Reo Mā`ohi");
|
||||
Regy_add(regy, Id_tyv, "tyv", "Тыва дыл");
|
||||
Regy_add(regy, Id_tzm, "tzm", "ⵜⴰⵎⴰⵣⵉⵖⵜ");
|
||||
Regy_add(regy, Id_udm, "udm", "Удмурт");
|
||||
Regy_add(regy, Id_ug, "ug", "ئۇيغۇرچە / Uyghurche");
|
||||
Regy_add(regy, Id_ug_arab, "ug-arab", "ئۇيغۇرچە");
|
||||
Regy_add(regy, Id_ug_latn, "ug-latn", "Uyghurche");
|
||||
Regy_add(regy, Id_uk, "uk", "Українська");
|
||||
Regy_add(regy, Id_ur, "ur", "اردو");
|
||||
Regy_add(regy, Id_uz, "uz", "O'zbek");
|
||||
Regy_add(regy, Id_ve, "ve", "Tshivenda");
|
||||
Regy_add(regy, Id_vec, "vec", "Vèneto");
|
||||
Regy_add(regy, Id_vep, "vep", "Vepsan kel'");
|
||||
Regy_add(regy, Id_vi, "vi", "Tiếng Việt");
|
||||
Regy_add(regy, Id_vls, "vls", "West-Vlams");
|
||||
Regy_add(regy, Id_vmf, "vmf", "Mainfränkisch");
|
||||
Regy_add(regy, Id_vo, "vo", "Volapük");
|
||||
Regy_add(regy, Id_vot, "vot", "Vaďďa");
|
||||
Regy_add(regy, Id_vro, "vro", "Võro");
|
||||
Regy_add(regy, Id_wa, "wa", "Walon");
|
||||
Regy_add(regy, Id_war, "war", "Winaray");
|
||||
Regy_add(regy, Id_wo, "wo", "Wolof");
|
||||
Regy_add(regy, Id_wuu, "wuu", "吴语");
|
||||
Regy_add(regy, Id_xal, "xal", "Хальмг");
|
||||
Regy_add(regy, Id_xh, "xh", "isiXhosa");
|
||||
Regy_add(regy, Id_xmf, "xmf", "მარგალური");
|
||||
Regy_add(regy, Id_yi, "yi", "ייִדיש");
|
||||
Regy_add(regy, Id_yo, "yo", "Yorùbá");
|
||||
Regy_add(regy, Id_yue, "yue", "粵語");
|
||||
Regy_add(regy, Id_za, "za", "Vahcuengh");
|
||||
Regy_add(regy, Id_zea, "zea", "Zeêuws");
|
||||
Regy_add(regy, Id_zh, "zh", "中文");
|
||||
Regy_add(regy, Id_zh_classical, "zh-classical", "文言");
|
||||
Regy_add(regy, Id_zh_cn, "zh-cn", "中文(中国大陆)");
|
||||
Regy_add(regy, Id_zh_hans, "zh-hans", "中文(简体)");
|
||||
Regy_add(regy, Id_zh_hant, "zh-hant", "中文(繁體)");
|
||||
Regy_add(regy, Id_zh_hk, "zh-hk", "中文(香港)");
|
||||
Regy_add(regy, Id_zh_min_nan, "zh-min-nan", "Bân-lâm-gú");
|
||||
Regy_add(regy, Id_zh_mo, "zh-mo", "中文(澳門)");
|
||||
Regy_add(regy, Id_zh_my, "zh-my", "中文(马来西亚)");
|
||||
Regy_add(regy, Id_zh_sg, "zh-sg", "中文(新加坡)");
|
||||
Regy_add(regy, Id_zh_tw, "zh-tw", "中文(台灣)");
|
||||
Regy_add(regy, Id_zh_yue, "zh-yue", "粵語");
|
||||
Regy_add(regy, Id_zu, "zu", "isiZulu");
|
||||
}
|
||||
return regy;
|
||||
}
|
||||
private static Hash_adp_bry regy; private static final Xol_lang_itm[] langs = new Xol_lang_itm[Id__max];
|
||||
private static void Regy_add(Hash_adp_bry regy, int id, String code_str, String canonical) {
|
||||
byte[] code = Bry_.new_a7(code_str); // ASCII:lang_code should always be ASCII
|
||||
Xol_lang_itm itm = new Xol_lang_itm(id, code, Bry_.new_u8(canonical));
|
||||
langs[id] = itm;
|
||||
regy.Add(code, itm);
|
||||
}
|
||||
public static Xol_lang_itm Get_by_key_or_en(byte[] key) {
|
||||
if (regy == null) Regy();
|
||||
Xol_lang_itm lang_itm = (Xol_lang_itm)regy.Get_by_bry(key);
|
||||
if (lang_itm == null) lang_itm = (Xol_lang_itm)regy.Get_by_bry(Xol_lang_.Key_en);
|
||||
return lang_itm;
|
||||
}
|
||||
public static Xol_lang_itm Get_by_key(byte[] key) {return Get_by_key(key, 0, key.length);}
|
||||
public static Xol_lang_itm Get_by_key(byte[] key, int bgn, int end) {
|
||||
if (regy == null) Regy();
|
||||
return (Xol_lang_itm)regy.Get_by_mid(key, bgn, end);
|
||||
}
|
||||
public static Xol_lang_itm Get_by_key_or_intl(byte[] key) {return Get_by_key_or_intl(key, 0, key.length);}
|
||||
public static Xol_lang_itm Get_by_key_or_intl(byte[] key, int bgn, int end) {
|
||||
Xol_lang_itm rv = Get_by_key_or_null(key, bgn, end);
|
||||
return rv == null ? Intl : rv;
|
||||
}
|
||||
public static Xol_lang_itm Get_by_key_or_null(byte[] key, int bgn, int end) {
|
||||
if (regy == null) Regy();
|
||||
return (Xol_lang_itm)regy.Get_by_mid(key, bgn, end);
|
||||
}
|
||||
public static Xol_lang_itm Get_by_id(int id) {if (regy == null) Regy(); return langs[id];}
|
||||
public static boolean Exists(byte[] key) {return Get_by_key(key) != null;} // Language.php!isSupportedLanguage
|
||||
public static final Xol_lang_itm Intl = new Xol_lang_itm(Xol_lang_itm_.Id__intl, Bry_.Empty, Bry_.Empty); // intended for international wikis like commons, wikidata, etc..
|
||||
}
|
||||
class Xol_lang_itm_comparer implements ComparerAble {
|
||||
public int compare(Object lhsObj, Object rhsObj) {
|
||||
Xol_lang_itm lhs = (Xol_lang_itm)lhsObj;
|
||||
Xol_lang_itm rhs = (Xol_lang_itm)rhsObj;
|
||||
return Bry_.Compare(lhs.Key(), rhs.Key());
|
||||
}
|
||||
}
|
||||
93
400_xowa/src/gplx/xowa/langs/cases/Xol_case_itm.java
Normal file
93
400_xowa/src/gplx/xowa/langs/cases/Xol_case_itm.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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.cases; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.primitives.*;
|
||||
import gplx.intl.*;
|
||||
public interface Xol_case_itm extends Gfo_case_itm {
|
||||
byte Tid();
|
||||
byte[] Src_ary();
|
||||
byte[] Trg_ary();
|
||||
void Case_build_upper(Bry_bfr bfr);
|
||||
void Case_build_lower(Bry_bfr bfr);
|
||||
void Case_reuse_upper(byte[] ary, int bgn, int len);
|
||||
void Case_reuse_lower(byte[] ary, int bgn, int len);
|
||||
Xol_case_itm Clone();
|
||||
}
|
||||
class Xol_case_itm_byt implements Xol_case_itm {
|
||||
public Xol_case_itm_byt(byte tid, byte src_byte, byte trg_byte) {
|
||||
this.tid = tid; this.src_byte = src_byte; this.trg_byte = trg_byte; this.src_ary = new byte[] {src_byte}; this.trg_ary = new byte[] {trg_byte};
|
||||
switch (tid) {
|
||||
case Xol_case_itm_.Tid_both:
|
||||
case Xol_case_itm_.Tid_upper: upper_byte = trg_byte; lower_byte = src_byte; break;
|
||||
case Xol_case_itm_.Tid_lower: upper_byte = src_byte; lower_byte = trg_byte; break;
|
||||
}
|
||||
}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Src_ary() {return src_ary;} private byte[] src_ary;
|
||||
public byte[] Trg_ary() {return trg_ary;} private byte[] trg_ary;
|
||||
public byte Src_byte() {return src_byte;} private byte src_byte;
|
||||
public byte Trg_byte() {return trg_byte;} private byte trg_byte;
|
||||
public void Case_build_upper(Bry_bfr bfr) {bfr.Add_byte(upper_byte);} private byte upper_byte;
|
||||
public void Case_build_lower(Bry_bfr bfr) {bfr.Add_byte(lower_byte);} private byte lower_byte;
|
||||
public void Case_reuse_upper(byte[] ary, int bgn, int len) {ary[bgn] = upper_byte;}
|
||||
public void Case_reuse_lower(byte[] ary, int bgn, int len) {ary[bgn] = lower_byte;}
|
||||
public Xol_case_itm Clone() {return new Xol_case_itm_byt(tid, src_byte, trg_byte);}
|
||||
public int Utf8_id_lower() {return lower_byte;}
|
||||
public boolean Eq_lo(Gfo_case_itm trg_obj) {
|
||||
Xol_case_itm_byt trg_itm = (Xol_case_itm_byt)trg_obj;
|
||||
return lower_byte == trg_itm.lower_byte;
|
||||
}
|
||||
public int Hashcode_lo() {return lower_byte;}
|
||||
public int Len_lo() {return 1;}
|
||||
public byte[] Asymmetric_bry() {return null;}
|
||||
}
|
||||
class Xol_case_itm_bry implements Xol_case_itm {
|
||||
public Xol_case_itm_bry(byte tid, byte[] src_ary, byte[] trg_ary) {
|
||||
this.tid = tid; this.src_ary = src_ary; this.trg_ary = trg_ary;
|
||||
switch (tid) {
|
||||
case Xol_case_itm_.Tid_both: upper_ary = trg_ary; lower_ary = src_ary; break;
|
||||
case Xol_case_itm_.Tid_upper: upper_ary = trg_ary; lower_ary = src_ary; asymmetric_bry = src_ary; break;
|
||||
case Xol_case_itm_.Tid_lower: upper_ary = src_ary; lower_ary = trg_ary; asymmetric_bry = trg_ary; break;
|
||||
}
|
||||
len_lo = lower_ary.length;
|
||||
utf8_id_lo = Utf16_.Decode_to_int(lower_ary, 0);
|
||||
hashcode_ci_lo = Bry_obj_ref.CalcHashCode(lower_ary, 0, len_lo);
|
||||
}
|
||||
public byte Tid() {return tid;} public Xol_case_itm_bry Tid_(byte v) {tid = v; return this;} private byte tid;
|
||||
public byte[] Src_ary() {return src_ary;} private byte[] src_ary;
|
||||
public byte[] Trg_ary() {return trg_ary;} private byte[] trg_ary;
|
||||
public void Case_build_upper(Bry_bfr bfr) {bfr.Add(upper_ary);} private byte[] upper_ary;
|
||||
public void Case_build_lower(Bry_bfr bfr) {bfr.Add(lower_ary);} private byte[] lower_ary;
|
||||
public void Case_reuse_upper(byte[] ary, int bgn, int len) { // ASSUME: upper/lower have same width; i.e.: upper'ing a character doesn't go from a 2-width byte to a 3-width byte
|
||||
for (int i = 0; i < len; i++)
|
||||
ary[i + bgn] = upper_ary[i];
|
||||
}
|
||||
public void Case_reuse_lower(byte[] ary, int bgn, int len) { // ASSUME: upper/lower have same width; i.e.: upper'ing a character doesn't go from a 2-width byte to a 3-width byte
|
||||
for (int i = 0; i < len; i++)
|
||||
ary[i + bgn] = lower_ary[i];
|
||||
}
|
||||
public Xol_case_itm Clone() {return new Xol_case_itm_bry(tid, src_ary, trg_ary);}
|
||||
public int Len_lo() {return len_lo;} private int len_lo;
|
||||
public int Utf8_id_lo() {return utf8_id_lo;} private int utf8_id_lo;
|
||||
public boolean Eq_lo(Gfo_case_itm trg_obj) {
|
||||
Xol_case_itm_bry trg_itm = (Xol_case_itm_bry)trg_obj;
|
||||
return utf8_id_lo == trg_itm.utf8_id_lo;
|
||||
}
|
||||
public byte[] Asymmetric_bry() {return asymmetric_bry;} private byte[] asymmetric_bry;
|
||||
public int Hashcode_lo() {return hashcode_ci_lo;} private int hashcode_ci_lo;
|
||||
}
|
||||
148
400_xowa/src/gplx/xowa/langs/cases/Xol_case_itm_.java
Normal file
148
400_xowa/src/gplx/xowa/langs/cases/Xol_case_itm_.java
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
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.cases; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_case_itm_ {
|
||||
public static final byte Tid_both = 0, Tid_upper = 1, Tid_lower = 2;
|
||||
public static Xol_case_itm new_(int tid, String src_str, String trg_str) {return new_((byte)tid, Bry_.new_u8(src_str), Bry_.new_u8(trg_str));}
|
||||
public static Xol_case_itm new_(byte tid, byte[] src, byte[] trg) {
|
||||
if (src.length == 1 && trg.length == 1)
|
||||
return new Xol_case_itm_byt(tid, src[0], trg[0]);
|
||||
else
|
||||
return new Xol_case_itm_bry(tid, src, trg);
|
||||
}
|
||||
public static Xol_case_itm[] parse_xo_(byte[] src) {
|
||||
List_adp list = List_adp_.new_();
|
||||
int src_len = src.length, src_pos = 0, fld_bgn = 0, fld_idx = 0;
|
||||
byte cur_cmd = Byte_.Zero;
|
||||
byte[] cur_lhs = null;
|
||||
Xol_csv_parser csv_parser = Xol_csv_parser._;
|
||||
while (true) {
|
||||
boolean last = src_pos == src_len;
|
||||
byte b = last ? Byte_ascii.Nl : src[src_pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Pipe:
|
||||
switch (fld_idx) {
|
||||
case 0:
|
||||
boolean fail = true;
|
||||
if (src_pos - fld_bgn == 1) {
|
||||
byte cmd_byte = src[src_pos - 1];
|
||||
cur_cmd = Byte_.Zero;
|
||||
switch (cmd_byte) {
|
||||
case Byte_ascii.Num_0: cur_cmd = Xol_case_itm_.Tid_both; fail = false; break;
|
||||
case Byte_ascii.Num_1: cur_cmd = Xol_case_itm_.Tid_upper; fail = false; break;
|
||||
case Byte_ascii.Num_2: cur_cmd = Xol_case_itm_.Tid_lower; fail = false; break;
|
||||
}
|
||||
}
|
||||
if (fail) throw Exc_.new_("cmd is invalid", "cmd", String_.new_u8(src, fld_bgn, src_pos));
|
||||
break;
|
||||
case 1: cur_lhs = csv_parser.Load(src, fld_bgn, src_pos); break;
|
||||
}
|
||||
++fld_idx;
|
||||
fld_bgn = src_pos + 1;
|
||||
break;
|
||||
case Byte_ascii.Nl:
|
||||
if (!(fld_idx == 0 && fld_bgn == src_pos)) {
|
||||
byte[] cur_rhs = csv_parser.Load(src, fld_bgn, src_pos);
|
||||
Xol_case_itm itm = Xol_case_itm_.new_(cur_cmd, cur_lhs, cur_rhs);
|
||||
list.Add(itm);
|
||||
}
|
||||
cur_cmd = Byte_.Zero;
|
||||
cur_lhs = null;
|
||||
fld_idx = 0;
|
||||
fld_bgn = src_pos + 1;
|
||||
break;
|
||||
}
|
||||
if (last) break;
|
||||
++src_pos;
|
||||
}
|
||||
return (Xol_case_itm[])list.To_ary(Xol_case_itm.class);
|
||||
}
|
||||
public static Xol_case_itm[] parse_mw_(byte[] raw) {
|
||||
Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
int pos = 0;
|
||||
pos = parse_mw_grp(hash, raw, Bool_.Y, pos);
|
||||
pos = parse_mw_grp(hash, raw, Bool_.N, pos);
|
||||
return (Xol_case_itm[])hash.To_ary(Xol_case_itm.class);
|
||||
}
|
||||
private static int parse_mw_grp(Ordered_hash hash, byte[] raw, boolean section_is_upper, int find_bgn) {
|
||||
byte[] find = section_is_upper ? parse_mw_upper : parse_mw_lower;
|
||||
int raw_len = raw.length;
|
||||
int pos = Bry_finder.Find_fwd(raw, find, find_bgn); if (pos == Bry_.NotFound) throw Exc_.new_("could not find section name", "name", String_.new_u8(find));
|
||||
pos = Bry_finder.Find_fwd(raw, Byte_ascii.Curly_bgn, pos, raw_len); if (pos == Bry_.NotFound) throw Exc_.new_("could not find '{' after section name", "name", String_.new_u8(find));
|
||||
int itm_bgn = 0;
|
||||
boolean quote_off = true, itm_is_first = true;
|
||||
byte[] cur_lhs = Bry_.Empty;
|
||||
boolean loop = true;
|
||||
while (loop) {
|
||||
if (pos >= raw_len) break;
|
||||
byte b = raw[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Quote:
|
||||
if (quote_off) {
|
||||
itm_bgn = pos + 1;
|
||||
quote_off = false;
|
||||
}
|
||||
else {
|
||||
if (itm_is_first) {
|
||||
cur_lhs = Bry_.Mid(raw, itm_bgn, pos);
|
||||
itm_is_first = false;
|
||||
}
|
||||
else {
|
||||
byte[] cur_rhs = Bry_.Mid(raw, itm_bgn, pos);
|
||||
byte[] upper = null, lower = null; byte tid = Byte_.Zero, rev_tid = Byte_.Zero;
|
||||
if (section_is_upper) {
|
||||
upper = cur_rhs;
|
||||
lower = cur_lhs;
|
||||
tid = Xol_case_itm_.Tid_upper;
|
||||
rev_tid = Xol_case_itm_.Tid_lower;
|
||||
}
|
||||
else {
|
||||
upper = cur_lhs;
|
||||
lower = cur_rhs;
|
||||
tid = Xol_case_itm_.Tid_lower;
|
||||
rev_tid = Xol_case_itm_.Tid_upper;
|
||||
}
|
||||
Xol_case_itm_bry itm = (Xol_case_itm_bry)hash.Get_by(upper);
|
||||
if (itm == null) {
|
||||
itm = new Xol_case_itm_bry(tid, upper, lower);
|
||||
hash.Add(upper, itm);
|
||||
}
|
||||
else {
|
||||
if (itm.Tid() == rev_tid && Bry_.Eq(itm.Src_ary(), upper) && Bry_.Eq(itm.Trg_ary(), lower))
|
||||
itm.Tid_(Xol_case_itm_.Tid_both);
|
||||
else {
|
||||
itm = new Xol_case_itm_bry(tid, cur_lhs, cur_rhs);
|
||||
byte[] add_key = Bry_.Add(section_is_upper ? Bry_upper : Bry_lower, Bry_pipe, upper, Bry_pipe, lower);
|
||||
hash.Add(add_key, itm);
|
||||
}
|
||||
}
|
||||
itm_is_first = true;
|
||||
}
|
||||
quote_off = true;
|
||||
}
|
||||
break;
|
||||
case Byte_ascii.Curly_end:
|
||||
loop = false;
|
||||
break;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
return pos;
|
||||
} private static final byte[] parse_mw_upper= Bry_.new_a7("wikiUpperChars"), parse_mw_lower= Bry_.new_a7("wikiLowerChars"), Bry_upper = Bry_.new_a7("upper"), Bry_lower = Bry_.new_a7("lower"), Bry_pipe = Bry_.new_a7("|");
|
||||
static final String GRP_KEY = "xowa.langs.case_parser";
|
||||
}
|
||||
136
400_xowa/src/gplx/xowa/langs/cases/Xol_case_mgr.java
Normal file
136
400_xowa/src/gplx/xowa/langs/cases/Xol_case_mgr.java
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
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.cases; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.btries.*; import gplx.intl.*;
|
||||
public class Xol_case_mgr implements GfoInvkAble, Gfo_case_mgr {
|
||||
private Bry_bfr tmp_bfr = Bry_bfr.new_(); private Btrie_fast_mgr upper_trie = Btrie_fast_mgr.cs_(), lower_trie = Btrie_fast_mgr.cs_(); private Xol_case_itm[] itms;
|
||||
public Xol_case_mgr(byte tid) {this.tid = tid;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public Gfo_case_itm Get_or_null(byte bgn_byte, byte[] src, int bgn, int end) {
|
||||
Object rv = lower_trie.Match_bgn_w_byte(bgn_byte, src, bgn, end);
|
||||
return rv == null
|
||||
? (Gfo_case_itm)upper_trie.Match_bgn_w_byte(bgn_byte, src, bgn, end)
|
||||
: (Gfo_case_itm)rv;
|
||||
}
|
||||
public void Clear() {upper_trie.Clear(); lower_trie.Clear();}
|
||||
public boolean Match_any_exists(byte b, byte[] src, int bgn_pos, int end_pos) {
|
||||
return upper_trie.Match_bgn_w_byte(b, src, bgn_pos, end_pos) != null
|
||||
|| lower_trie.Match_bgn_w_byte(b, src, bgn_pos, end_pos) != null
|
||||
;
|
||||
}
|
||||
public Object Match_upper(byte b, byte[] src, int bgn_pos, int end_pos) {return upper_trie.Match_bgn_w_byte(b, src, bgn_pos, end_pos);}
|
||||
public void Add_bulk(byte[] raw) {Add_bulk(Xol_case_itm_.parse_xo_(raw));}
|
||||
public Xol_case_mgr Add_bulk(Xol_case_itm[] ary) {
|
||||
itms = ary;
|
||||
int itms_len = itms.length;
|
||||
for (int i = 0; i < itms_len; i++) {
|
||||
Xol_case_itm itm = itms[i];
|
||||
switch (itm.Tid()) {
|
||||
case Xol_case_itm_.Tid_both:
|
||||
upper_trie.Add(itm.Src_ary(), itm);
|
||||
lower_trie.Add(itm.Trg_ary(), itm);
|
||||
break;
|
||||
case Xol_case_itm_.Tid_upper:
|
||||
upper_trie.Add(itm.Src_ary(), itm);
|
||||
break;
|
||||
case Xol_case_itm_.Tid_lower:
|
||||
lower_trie.Add(itm.Src_ary(), itm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public byte[] Case_reuse_upper(byte[] src, int bgn, int end) {return Case_reuse(Bool_.Y, src, bgn, end);}
|
||||
public byte[] Case_reuse_lower(byte[] src, int bgn, int end) {return Case_reuse(Bool_.N, src, bgn, end);}
|
||||
public byte[] Case_reuse(boolean upper, byte[] src, int bgn, int end) {
|
||||
int pos = bgn;
|
||||
tmp_bfr.Clear();
|
||||
Btrie_fast_mgr trie = upper ? upper_trie : lower_trie;
|
||||
while (true) {
|
||||
if (pos >= end) break;
|
||||
byte b = src[pos];
|
||||
int b_len = gplx.intl.Utf8_.Len_of_char_by_1st_byte(b);
|
||||
Object o = trie.Match_bgn_w_byte(b, src, pos, end); // NOTE: used to be (b, src, bgn, end) which would never case correctly; DATE:2013-12-25
|
||||
if (o != null && pos < end) { // pos < end used for casing 1st letter only; upper_1st will pass end of 1
|
||||
Xol_case_itm itm = (Xol_case_itm)o;
|
||||
if (upper)
|
||||
itm.Case_reuse_upper(src, pos, b_len);
|
||||
else
|
||||
itm.Case_reuse_lower(src, pos, b_len);
|
||||
}
|
||||
else {} // noop
|
||||
pos += b_len;
|
||||
}
|
||||
return src;
|
||||
}
|
||||
public byte[] Case_reuse_1st_upper(byte[] src) { // NOTE: optimized version called by Frame_ttl; DATE:2014-06-21
|
||||
int src_len = src.length;
|
||||
if (src_len == 0) return src; // empty bry
|
||||
byte b = src[0];
|
||||
int b_len = gplx.intl.Utf8_.Len_of_char_by_1st_byte(b);
|
||||
Object o = upper_trie.Match_bgn_w_byte(b, src, 0, b_len);
|
||||
if (o == null) return src; // 1st letter is not a lower case char (either num, symbol, or upper)
|
||||
Xol_case_itm itm = (Xol_case_itm)o;
|
||||
itm.Case_build_upper(tmp_bfr);
|
||||
int pos = upper_trie.Match_pos();
|
||||
tmp_bfr.Add_mid(src, pos, src_len);
|
||||
return tmp_bfr.Xto_bry_and_clear();
|
||||
}
|
||||
public byte[] Case_build_upper(byte[] src) {return Case_build_upper(src, 0, src.length);}
|
||||
public byte[] Case_build_upper(byte[] src, int bgn, int end) {return Case_build(Bool_.Y, src, bgn, end);}
|
||||
public byte[] Case_build_lower(byte[] src) {return Case_build_lower(src, 0, src.length);}
|
||||
public byte[] Case_build_lower(byte[] src, int bgn, int end) {return Case_build(Bool_.N, src, bgn, end);}
|
||||
public byte[] Case_build(boolean upper, byte[] src, int bgn, int end) {
|
||||
int pos = bgn;
|
||||
tmp_bfr.Clear();
|
||||
Btrie_fast_mgr trie = upper ? upper_trie : lower_trie;
|
||||
while (true) {
|
||||
if (pos >= end) break;
|
||||
byte b = src[pos];
|
||||
int b_len = gplx.intl.Utf8_.Len_of_char_by_1st_byte(b);
|
||||
Object o = trie.Match_bgn_w_byte(b, src, pos, end); // NOTE: used to be (b, src, bgn, end) which would never case correctly; DATE:2013-12-25
|
||||
if (o != null && pos < end) { // pos < end used for casing 1st letter only; upper_1st will pass end of 1
|
||||
Xol_case_itm itm = (Xol_case_itm)o;
|
||||
if (upper)
|
||||
itm.Case_build_upper(tmp_bfr);
|
||||
else
|
||||
itm.Case_build_lower(tmp_bfr);
|
||||
}
|
||||
else {
|
||||
tmp_bfr.Add_mid(src, pos, pos + b_len);
|
||||
}
|
||||
pos += b_len;
|
||||
}
|
||||
return tmp_bfr.Xto_bry_and_clear();
|
||||
}
|
||||
public byte[] Case_build_1st_upper(Bry_bfr bfr, byte[] src, int bgn, int end) {return Case_build_1st(bfr, Bool_.Y, src, bgn, end);}
|
||||
public byte[] Case_build_1st_lower(Bry_bfr bfr, byte[] src, int bgn, int end) {return Case_build_1st(bfr, Bool_.N, src, bgn, end);}
|
||||
public byte[] Case_build_1st(Bry_bfr bfr, boolean upper, byte[] src, int bgn, int end) {
|
||||
if (bgn == end) return Bry_.Empty; // upper "" -> ""
|
||||
int b_len = gplx.intl.Utf8_.Len_of_char_by_1st_byte(src[bgn]);
|
||||
bfr.Add(Case_build(upper, src, bgn, bgn + b_len));
|
||||
bfr.Add_mid(src, bgn + b_len, end);
|
||||
return bfr.Xto_bry_and_clear();
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_add_bulk)) Add_bulk(m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_clear)) throw Exc_.new_unimplemented();
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_clear = "clear", Invk_add_bulk = "add_bulk";
|
||||
}
|
||||
1123
400_xowa/src/gplx/xowa/langs/cases/Xol_case_mgr_.java
Normal file
1123
400_xowa/src/gplx/xowa/langs/cases/Xol_case_mgr_.java
Normal file
File diff suppressed because it is too large
Load Diff
151
400_xowa/src/gplx/xowa/langs/cases/Xol_case_mgr_tst.java
Normal file
151
400_xowa/src/gplx/xowa/langs/cases/Xol_case_mgr_tst.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
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.cases; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import org.junit.*; import gplx.core.strings.*;
|
||||
public class Xol_case_mgr_tst {
|
||||
@Before public void init() {fxt.Clear();} private Xol_case_mgr_fxt fxt = new Xol_case_mgr_fxt();
|
||||
@Test public void Mw_parse() {
|
||||
fxt.parse_mw__tst(fxt.itm_both_("A", "a"), fxt.itm_both_("B", "b"));
|
||||
}
|
||||
@Test public void Xo_parse() {
|
||||
fxt.parse_xo__tst(fxt.Init_ltrs_raw(), fxt.itm_both_("a", "A"), fxt.itm_upper_("b", "B"), fxt.itm_lower_("C", "c"));
|
||||
}
|
||||
@Test public void Upper_a() {fxt.Init_ltrs().Upper("aAaz", "AAAz");}
|
||||
@Test public void Upper_ab() {fxt.Init_ltrs().Upper("abac", "ABAc");}
|
||||
@Test public void Lower_a() {fxt.Init_ltrs().Lower("aAaZ", "aaaZ");}
|
||||
@Test public void Lower_ac() {fxt.Init_ltrs().Lower("ABAC", "aBac");}
|
||||
@Test public void Upper_1st() {
|
||||
fxt.Init_ltrs_universal();
|
||||
fxt.Test_reuse_1st_upper("a", "A");
|
||||
fxt.Test_reuse_1st_upper("abc", "Abc");
|
||||
fxt.Test_reuse_1st_upper("");
|
||||
fxt.Test_reuse_1st_upper("Abc");
|
||||
fxt.Test_reuse_1st_upper("é", "É");
|
||||
fxt.Test_reuse_1st_upper("É");
|
||||
fxt.Lower("Ι", "ι"); // PURPOSE:test reversal; PAGE:en.d:ἀρχιερεύς DATE:2014-09-02
|
||||
}
|
||||
// @Test public void Hack() {
|
||||
// Xol_case_itm[] ary = Xol_case_mgr_.Utf_8;
|
||||
// Bry_bfr bfr = Bry_bfr.new_();
|
||||
// for (int i = 0; i < ary.length; i++) {
|
||||
// Xol_case_itm itm = ary[i];
|
||||
// bfr.Add_str_a7("xo|");
|
||||
// bfr.Add_bry_comma(itm.Src_ary()).Add_byte_pipe();
|
||||
// bfr.Add_bry_comma(itm.Trg_ary()).Add_byte_nl();
|
||||
// }
|
||||
// Io_mgr.I.SaveFilStr("C:\\test1.txt", bfr.Xto_str_and_clear());
|
||||
// }
|
||||
}
|
||||
class Xol_case_mgr_fxt {
|
||||
private Xol_case_mgr case_mgr = Xol_case_mgr_.new_(); private String_bldr sb = String_bldr_.new_();
|
||||
public void Clear() {case_mgr.Clear();}
|
||||
public Xol_case_itm_bry itm_both_(String src, String trg) {return new Xol_case_itm_bry(Xol_case_itm_.Tid_both , Bry_.new_u8(src), Bry_.new_u8(trg));}
|
||||
public Xol_case_itm_bry itm_upper_(String src, String trg) {return new Xol_case_itm_bry(Xol_case_itm_.Tid_upper, Bry_.new_u8(src), Bry_.new_u8(trg));}
|
||||
public Xol_case_itm_bry itm_lower_(String src, String trg) {return new Xol_case_itm_bry(Xol_case_itm_.Tid_lower, Bry_.new_u8(src), Bry_.new_u8(trg));}
|
||||
public String Init_ltrs_raw() {
|
||||
return String_.Concat_lines_nl
|
||||
( "0|a|A"
|
||||
, "1|b|B"
|
||||
, "2|C|c"
|
||||
);
|
||||
}
|
||||
public Xol_case_mgr_fxt Init_ltrs() {
|
||||
case_mgr = Xol_case_mgr_.new_();
|
||||
case_mgr.Add_bulk(Bry_.new_u8(Init_ltrs_raw()));
|
||||
return this;
|
||||
}
|
||||
public Xol_case_mgr_fxt Init_ltrs_universal() {
|
||||
case_mgr = Xol_case_mgr_.Utf8();
|
||||
return this;
|
||||
}
|
||||
public Xol_case_mgr_fxt Upper(String raw_str, String expd) {return Case_build(Bool_.Y, raw_str, expd);}
|
||||
public Xol_case_mgr_fxt Lower(String raw_str, String expd) {return Case_build(Bool_.N, raw_str, expd);}
|
||||
public Xol_case_mgr_fxt Case_build(boolean upper, String raw_str, String expd) {
|
||||
byte[] raw = Bry_.new_u8(raw_str);
|
||||
byte[] actl = case_mgr.Case_build(upper, raw, 0, raw.length);
|
||||
Tfds.Eq(expd, String_.new_u8(actl));
|
||||
return this;
|
||||
}
|
||||
public void parse_xo__tst(String raw, Xol_case_itm_bry... expd) {
|
||||
Tfds.Eq_str_lines(Xto_str(expd), Xto_str(Xol_case_itm_.parse_xo_(Bry_.new_u8(raw))));
|
||||
}
|
||||
public void parse_mw__tst(Xol_case_itm_bry... expd) {
|
||||
String raw = raw_(expd);
|
||||
Xol_case_itm[] actl = Xol_case_itm_.parse_mw_(Bry_.new_u8(raw));
|
||||
Tfds.Eq_str_lines(Xto_str(expd), Xto_str(actl));
|
||||
}
|
||||
public String Xto_str(Xol_case_itm[] ary) {
|
||||
int ary_len = ary.length;
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
Xol_case_itm itm = ary[i];
|
||||
sb.Add(Byte_.Xto_str(itm.Tid())).Add_char_pipe().Add(String_.new_u8(itm.Src_ary())).Add_char_pipe().Add(String_.new_u8(itm.Trg_ary())).Add_char_nl();
|
||||
}
|
||||
return sb.Xto_str_and_clear();
|
||||
}
|
||||
public String raw_(Xol_case_itm_bry[] itms) {
|
||||
int itms_len = itms.length;
|
||||
uppers_list.Clear(); lowers_list.Clear();
|
||||
for (int i = 0; i < itms_len; i++) {
|
||||
Xol_case_itm_bry itm = itms[i];
|
||||
String src = String_.new_u8(itm.Src_ary());
|
||||
String trg = String_.new_u8(itm.Trg_ary());
|
||||
switch (itm.Tid()) {
|
||||
case Xol_case_itm_.Tid_both:
|
||||
uppers_list.Add(trg); uppers_list.Add(src);
|
||||
lowers_list.Add(src); lowers_list.Add(trg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return raw_str_(uppers_list.To_str_ary(), lowers_list.To_str_ary());
|
||||
} List_adp uppers_list = List_adp_.new_(), lowers_list = List_adp_.new_();
|
||||
String raw_str_(String[] uppers, String[] lowers) {
|
||||
sb.Add("a:2:{s:14:\"wikiUpperChars\";a:1046:{");
|
||||
raw_ary(sb, uppers);
|
||||
sb.Add("}");
|
||||
sb.Add("s:14:\"wikiLowerChars\";a:1038:{");
|
||||
raw_ary(sb, lowers);
|
||||
sb.Add("}}");
|
||||
return sb.Xto_str_and_clear();
|
||||
}
|
||||
private void raw_ary(String_bldr sb, String[] ary) {
|
||||
int ary_len = ary.length;
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
String itm = ary[i];
|
||||
int itm_len = String_.Len(itm);
|
||||
sb.Add_fmt("s:{0}:\"{1}\";", itm_len, itm);
|
||||
}
|
||||
}
|
||||
public void Test_reuse_1st_upper(String raw) {Test_reuse_1st_upper(raw, null, Bool_.Y);}
|
||||
public void Test_reuse_1st_upper(String raw, String expd) {Test_reuse_1st_upper(raw, expd, Bool_.N);}
|
||||
private void Test_reuse_1st_upper(String raw, String expd, boolean expd_is_same) {
|
||||
byte[] raw_bry = Bry_.new_u8(raw);
|
||||
byte[] actl_bry = case_mgr.Case_reuse_1st_upper(raw_bry);
|
||||
String actl_str = String_.new_u8(actl_bry);
|
||||
boolean actl_is_same = Object_.Eq(raw_bry, actl_bry); // pointers will be same if no change
|
||||
if (expd_is_same) {
|
||||
Tfds.Eq_true(actl_is_same, "expd should be same: " + actl_str);
|
||||
}
|
||||
else {
|
||||
Tfds.Eq_true(!actl_is_same, "expd should not be same: " + actl_str);
|
||||
Tfds.Eq(expd, actl_str, expd);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
a:2:{s:14:"wikiUpperChars";a:1046:{s:1:"a";s:1:"A";s:1:"b";}s:14:"wikiLowerChars";a:1038:{s:1:"A";s:1:"a";s:1:"B";}}
|
||||
*/
|
||||
64
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_grp.java
Normal file
64
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_grp.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
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.cnvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.intl.*;
|
||||
public class Xol_cnv_grp implements GfoInvkAble {
|
||||
private Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
public Xol_cnv_grp(byte[] key) {this.key = key;}
|
||||
public byte[] Key() {return key;} private byte[] key;
|
||||
public int Len() {return hash.Count();}
|
||||
public Xol_cnv_itm Get_at(int i) {return (Xol_cnv_itm)hash.Get_at(i);}
|
||||
public void Add(byte[] src, byte[] trg) {
|
||||
hash.Add_if_dupe_use_nth(src, new Xol_cnv_itm(src, trg));
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_add_bulk)) Add_bulk(hash, m.ReadBry("v"));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_add_bulk = "add_bulk";
|
||||
public static void Add_bulk(Ordered_hash hash, byte[] raw) { // COPY:add_bulk
|
||||
int len = raw.length;
|
||||
int pos = 0, fld_bgn = 0, fld_idx = 0;
|
||||
byte[] src = Bry_.Empty, trg = Bry_.Empty;
|
||||
Xol_csv_parser csv_parser = Xol_csv_parser._;
|
||||
while (true) {
|
||||
boolean last = pos == len;
|
||||
byte b = last ? Byte_ascii.Nl : raw[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Pipe:
|
||||
switch (fld_idx) {
|
||||
case 0: src = csv_parser.Load(raw, fld_bgn, pos); break;
|
||||
default: throw Exc_.new_unhandled(fld_idx);
|
||||
}
|
||||
fld_bgn = pos + 1;
|
||||
++fld_idx;
|
||||
break;
|
||||
case Byte_ascii.Nl:
|
||||
if (fld_bgn < pos) { // guard against trailing new lines
|
||||
trg = csv_parser.Load(raw, fld_bgn, pos);
|
||||
hash.Add_if_dupe_use_nth(src, new Xol_cnv_itm(src, trg));
|
||||
}
|
||||
fld_bgn = pos + 1;
|
||||
fld_idx = 0;
|
||||
break;
|
||||
}
|
||||
if (last) break;
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_itm.java
Normal file
23
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_itm.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
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.cnvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_cnv_itm {
|
||||
public Xol_cnv_itm(byte[] src, byte[] trg) {this.src = src; this.trg = trg;}
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public byte[] Trg() {return trg;} private byte[] trg;
|
||||
}
|
||||
38
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_mgr.java
Normal file
38
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_mgr.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
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.cnvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.xowa.apps.fsys.*;
|
||||
public class Xol_cnv_mgr implements GfoInvkAble {
|
||||
private Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
public Xol_cnv_mgr(Xol_lang lang) {}//this.lang = lang;} private Xol_lang lang;
|
||||
public Xol_cnv_grp Get_or_null(byte[] key) {return (Xol_cnv_grp)hash.Get_by(key);}
|
||||
public Xol_cnv_grp Get_or_make(byte[] key) {
|
||||
Xol_cnv_grp rv = (Xol_cnv_grp)hash.Get_by(key);
|
||||
if (rv == null) {
|
||||
rv = new Xol_cnv_grp(key);
|
||||
hash.Add(key, rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_get)) return Get_or_make(m.ReadBry("v"));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
} private static final String Invk_get = "get";
|
||||
public static Io_url Bld_url(Xoa_fsys_mgr app_fsys_mgr, String lang) {return Bld_url(app_fsys_mgr.Cfg_lang_core_dir(), lang);}
|
||||
public static Io_url Bld_url(Io_url dir, String lang) {return dir.GenSubFil_nest("variants", lang + ".gfs");}
|
||||
}
|
||||
89
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_mgr_tst.java
Normal file
89
400_xowa/src/gplx/xowa/langs/cnvs/Xol_cnv_mgr_tst.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
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.cnvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.langs.vnts.*; import gplx.xowa.wikis.data.tbls.*;
|
||||
public class Xol_cnv_mgr_tst {
|
||||
private Xol_cnv_mgr_fxt fxt = new Xol_cnv_mgr_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Basic() {
|
||||
fxt.Parser_fxt().Init_page_create("Template:Test_x1", "val");
|
||||
fxt.Parser_fxt().Test_parse_tmpl_str_test("{{Test_x0}}", "{{test}}", "val");
|
||||
}
|
||||
@Test public void Upper_1st() { // PURPOSE: convert should call Xoa_ttl.parse_(), which will upper 1st letter; EX:{{jez-eng|sense}} -> Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
|
||||
fxt.Parser_fxt().Init_page_create("Template:X1", "val");
|
||||
fxt.Parser_fxt().Test_parse_tmpl_str_test("{{x0}}", "{{test}}", "val");
|
||||
}
|
||||
@Test public void Redlink() { // PURPOSE: check redlink's Convert_ttl(Xowe_wiki wiki, Xoa_ttl ttl); DATE:2014-07-06
|
||||
fxt.Parser_fxt().Init_page_create("Template:Test_x1", "val");
|
||||
fxt.Test_convert_by_ttl("zh", "Template:Test_x0", Bool_.Y); // Template:Test_xo should not be parsed to Template:Template:Test_x0; EX:Шаблон:Šablon:Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
|
||||
fxt.Test_convert_by_ttl("zh", "Template:Test_x1", Bool_.N); // note that convert of trg should not find title;
|
||||
fxt.Test_convert_by_ttl("zh", "Template:Test_x2", Bool_.N); // test that non-convert characters return false
|
||||
}
|
||||
@Test public void Pfunc() {
|
||||
fxt.Parser_fxt().Init_defn_clear();
|
||||
fxt.Parser_fxt().Init_page_create("Test_x1");
|
||||
fxt.Test_parse("{{#ifexist:Test_x0|y|n}}", "y");
|
||||
}
|
||||
}
|
||||
class Xol_cnv_mgr_fxt {
|
||||
public Xoae_app App() {return app;} private Xoae_app app;
|
||||
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
|
||||
public Xop_fxt Parser_fxt() {return parser_fxt;} private Xop_fxt parser_fxt;
|
||||
public void Clear() {
|
||||
app = Xoa_app_fxt.app_();
|
||||
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(Bry_.new_u8("zh"));
|
||||
Xol_lang_.Lang_init(lang);
|
||||
Init_cnv(app, "zh", "zh-hant", KeyVal_.new_("x0", "x1"));
|
||||
lang.Vnt_mgr().Enabled_(true);
|
||||
lang.Vnt_mgr().Convert_ttl_init();
|
||||
wiki = Xoa_app_fxt.wiki_(app, "zh.wikipedia.org", lang);
|
||||
parser_fxt = new Xop_fxt(app, wiki);
|
||||
}
|
||||
public static void Init_cnv(Xoae_app app, String lang_key, String vnt_key, KeyVal... ary) {
|
||||
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(Bry_.new_a7(lang_key));
|
||||
Xol_cnv_grp grp = lang.Cnv_mgr().Get_or_make(Bry_.new_a7(vnt_key));
|
||||
int ary_len = ary.length;
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
KeyVal itm = ary[i];
|
||||
grp.Add(Bry_.new_u8(itm.Key()), Bry_.new_u8(itm.Val_to_str_or_empty()));
|
||||
}
|
||||
Xol_vnt_itm vnt_itm = lang.Vnt_mgr().Get_or_new(Bry_.new_a7(vnt_key));
|
||||
vnt_itm.Convert_ary_(Bry_.Ary(vnt_key));
|
||||
vnt_itm.Converter().Rebuild();
|
||||
}
|
||||
// public void Test_convert(String lang, String vnt, String raw, String expd) {
|
||||
// Xol_cnv_grp convert_grp = app.Lang_mgr().Get_by_key_or_new(Bry_.new_a7(lang)).Cnv_mgr().Get_or_new(Bry_.new_a7(vnt));
|
||||
// Bry_bfr bfr = Bry_bfr.new_();
|
||||
// boolean converted = convert_grp.Convert_to_bfr(bfr, Bry_.new_u8(raw));
|
||||
// String actl = converted ? bfr.Xto_str_and_clear() : raw;
|
||||
// Tfds.Eq(expd, actl);
|
||||
// }
|
||||
public void Test_parse(String raw, String expd) {
|
||||
parser_fxt.Test_parse_page_all_str(raw, expd);
|
||||
}
|
||||
public void Test_convert_by_ttl(String lang_key, String raw, boolean expd) {
|
||||
Xol_lang lang = app.Lang_mgr().Get_by_key_or_new(Bry_.new_a7(lang_key));
|
||||
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_u8(raw));
|
||||
Xowd_page_itm page = lang.Vnt_mgr().Convert_ttl(wiki, ttl);
|
||||
if (expd)
|
||||
Tfds.Eq_true(page.Exists());
|
||||
else
|
||||
Tfds.Eq_null(page);
|
||||
}
|
||||
}
|
||||
141
400_xowa/src/gplx/xowa/langs/cnvs/Xol_mw_parse_tst.java
Normal file
141
400_xowa/src/gplx/xowa/langs/cnvs/Xol_mw_parse_tst.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
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.cnvs; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import org.junit.*;
|
||||
import gplx.php.*;
|
||||
public class Xol_mw_parse_tst {
|
||||
private Xol_mw_parse_fxt fxt = new Xol_mw_parse_fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Test_convert("$zh2Hant = array('a' => 'A', 'b' => 'B',);", String_.Concat_lines_nl
|
||||
( "// zh_zh-hant"
|
||||
, "app.langs.get('zh').converts.get('zh-hant').add_bulk("
|
||||
, "<:['"
|
||||
, "a|A"
|
||||
, "b|B"
|
||||
, "']:>"
|
||||
, ");"
|
||||
));
|
||||
}
|
||||
// @Test public void Run() {
|
||||
// Io_url src_dir = Io_url_.new_dir_("C:\\xowa\\bin\\any\\xowa\\lang\\mediawiki\\converts\\");
|
||||
// Io_url trg_dir = Io_url_.new_dir_("C:\\xowa\\bin\\any\\xowa\\lang\\");
|
||||
// fxt.Test_run(src_dir, trg_dir);
|
||||
// }
|
||||
}
|
||||
class Xol_mw_parse_grp {
|
||||
public byte[] Lng() {return lng;} public Xol_mw_parse_grp Lng_(byte[] v) {lng = v; return this;} private byte[] lng;
|
||||
public byte[] Vnt() {return vnt;} public Xol_mw_parse_grp Vnt_(byte[] v) {vnt = v; return this;} private byte[] vnt;
|
||||
public Xol_mw_parse_itm[] Itms() {return itms;} public Xol_mw_parse_grp Itms_(Xol_mw_parse_itm[] v) {itms = v; return this;} private Xol_mw_parse_itm[] itms;
|
||||
public void Write_as_gfs(Bry_bfr bfr) {
|
||||
int itms_len = itms.length;
|
||||
Write_bgn(bfr);
|
||||
for (int i = 0; i < itms_len; i++) {
|
||||
Xol_mw_parse_itm itm = (Xol_mw_parse_itm)itms[i];
|
||||
Write_itm(bfr, itm);
|
||||
}
|
||||
Write_end(bfr);
|
||||
}
|
||||
private void Write_bgn(Bry_bfr bfr) {
|
||||
bfr.Add_str_a7("// ").Add(lng).Add_str("_").Add(vnt).Add_byte_nl();
|
||||
bfr.Add_str_a7("app.langs.get('");
|
||||
bfr.Add(lng);
|
||||
bfr.Add_str_a7("').converts.get('");
|
||||
bfr.Add(vnt);
|
||||
bfr.Add_str_a7("').add_bulk(");
|
||||
bfr.Add_byte_nl().Add_str("<:['").Add_byte_nl();
|
||||
}
|
||||
private void Write_itm(Bry_bfr bfr, Xol_mw_parse_itm itm) {
|
||||
bfr.Add(itm.Src());
|
||||
bfr.Add_byte_pipe();
|
||||
bfr.Add(itm.Trg());
|
||||
bfr.Add_byte_nl();
|
||||
}
|
||||
private void Write_end(Bry_bfr bfr) {
|
||||
bfr.Add_str_a7("']:>").Add_byte_nl();
|
||||
bfr.Add_str_a7(");").Add_byte_nl();
|
||||
}
|
||||
}
|
||||
class Xol_mw_parse_itm {
|
||||
public Xol_mw_parse_itm(byte[] src, byte[] trg) {this.src = src; this.trg = trg;}
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public byte[] Trg() {return trg;} private byte[] trg;
|
||||
}
|
||||
class Xol_mw_parse_fxt {
|
||||
public void Test_convert(String mw, String expd) {
|
||||
Xol_mw_parse_grp[] actl_ary = Parse(Bry_.new_u8(mw));
|
||||
Bry_bfr bfr = Bry_bfr.new_();
|
||||
actl_ary[0].Write_as_gfs(bfr);
|
||||
Tfds.Eq_str_lines(expd, bfr.Xto_str());
|
||||
}
|
||||
public void Test_run(Io_url src_dir, Io_url trg_dir) {
|
||||
Bry_bfr bfr = Bry_bfr.new_();
|
||||
Io_url[] fils = Io_mgr.I.QueryDir_fils(src_dir);
|
||||
int fils_len = fils.length;
|
||||
for (int i = 0; i < fils_len; i++) {
|
||||
Io_url fil = fils[i];
|
||||
byte[] src = Io_mgr.I.LoadFilBry(fil);
|
||||
Xol_mw_parse_grp[] itms = Parse(src);
|
||||
int itms_len = itms.length;
|
||||
String lang_name = String_.Lower(String_.Mid(fil.NameOnly(), 0, 2)); // ZhConversion.php -> Zh
|
||||
for (int j = 0; j < itms_len; j++) {
|
||||
Xol_mw_parse_grp itm = itms[j];
|
||||
itm.Write_as_gfs(bfr);
|
||||
}
|
||||
Io_url trg_fil = Xol_cnv_mgr.Bld_url(trg_dir, lang_name);
|
||||
Io_mgr.I.SaveFilBry(trg_fil, bfr.Xto_bry_and_clear());
|
||||
}
|
||||
}
|
||||
public Xol_mw_parse_grp[] Parse(byte[] src) {
|
||||
List_adp list = List_adp_.new_();
|
||||
Php_parser parser = new Php_parser();
|
||||
Gfo_msg_log msg_log = new Gfo_msg_log("xowa");
|
||||
Php_evaluator evaluator = new Php_evaluator(msg_log);
|
||||
parser.Parse_tkns(src, evaluator);
|
||||
Php_line[] lines = (Php_line[])evaluator.List().To_ary(Php_line.class);
|
||||
int lines_len = lines.length;
|
||||
for (int i = 0; i < lines_len; i++) {
|
||||
Php_line_assign line = (Php_line_assign)lines[i];
|
||||
Xol_mw_parse_grp grp = Parse_grp(line);
|
||||
list.Add(grp);
|
||||
}
|
||||
return (Xol_mw_parse_grp[])list.To_ary(Xol_mw_parse_grp.class);
|
||||
}
|
||||
private List_adp tmp_itm_list = List_adp_.new_();
|
||||
private Xol_mw_parse_grp Parse_grp(Php_line_assign line) {
|
||||
Xol_mw_parse_grp grp = new Xol_mw_parse_grp();
|
||||
byte[] key = line.Key().Val_obj_bry(); // EX: "zh2Hant"
|
||||
key = Bry_.Lower_ascii(key); // EX: "zh2hant"
|
||||
byte[][] parts = Bry_.Split(key, Byte_ascii.Num_2); // EX: "zh", "hant"
|
||||
byte[] src = parts[0];
|
||||
byte[] trg = Bry_.Add(parts[0], new byte[] {Byte_ascii.Dash}, parts[1]);
|
||||
grp.Lng_(src).Vnt_(trg);
|
||||
Parse_itms(line, grp);
|
||||
return grp;
|
||||
}
|
||||
private void Parse_itms(Php_line_assign line, Xol_mw_parse_grp grp) {
|
||||
Php_itm_ary ary = (Php_itm_ary)line.Val();
|
||||
tmp_itm_list.Clear();
|
||||
int subs_len = ary.Subs_len();
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Php_itm_kv kv = (Php_itm_kv)ary.Subs_get(i);
|
||||
Xol_mw_parse_itm itm = new Xol_mw_parse_itm(kv.Key().Val_obj_bry(), kv.Val().Val_obj_bry());
|
||||
tmp_itm_list.Add(itm);
|
||||
}
|
||||
grp.Itms_((Xol_mw_parse_itm[])tmp_itm_list.To_ary(Xol_mw_parse_itm.class));
|
||||
}
|
||||
}
|
||||
28
400_xowa/src/gplx/xowa/langs/durations/Xol_duration_itm.java
Normal file
28
400_xowa/src/gplx/xowa/langs/durations/Xol_duration_itm.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
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.durations; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_duration_itm {
|
||||
public Xol_duration_itm(byte tid, String name_str, long seconds) {
|
||||
this.tid = tid; this.seconds = seconds;
|
||||
this.name_str = name_str; this.name_bry = Bry_.new_a7(name_str);
|
||||
}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Name_bry() {return name_bry;} private byte[] name_bry;
|
||||
public String Name_str() {return name_str;} private String name_str;
|
||||
public long Seconds() {return seconds;} private long seconds;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
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.durations; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_duration_itm_ {
|
||||
private static final Hash_adp_bry regy = Hash_adp_bry.ci_ascii_(); // ASCII:MW.consts
|
||||
public static final byte
|
||||
Tid_millenia = 0
|
||||
, Tid_centuries = 1
|
||||
, Tid_decades = 2
|
||||
, Tid_years = 3
|
||||
, Tid_weeks = 4
|
||||
, Tid_days = 5
|
||||
, Tid_hours = 6
|
||||
, Tid_minutes = 7
|
||||
, Tid_seconds = 8
|
||||
;
|
||||
public static final Xol_duration_itm
|
||||
Itm_millenia = new_(Tid_millenia , "millenia" , 31556952000L)
|
||||
, Itm_centuries = new_(Tid_centuries , "centuries" , 3155695200L)
|
||||
, Itm_decades = new_(Tid_decades , "decades" , 315569520L)
|
||||
, Itm_years = new_(Tid_years , "years" , 31556952L) // 86400 * (365 + (24 * 3 + 25) / 400)
|
||||
, Itm_weeks = new_(Tid_weeks , "weeks" , 604800L)
|
||||
, Itm_days = new_(Tid_days , "days" , 86400L)
|
||||
, Itm_hours = new_(Tid_hours , "hours" , 3600L)
|
||||
, Itm_minutes = new_(Tid_minutes , "minutes" , 60L)
|
||||
, Itm_seconds = new_(Tid_seconds , "seconds" , 1L)
|
||||
;
|
||||
private static Xol_duration_itm new_(byte tid, String name, long factor) {
|
||||
Xol_duration_itm rv = new Xol_duration_itm(tid, name, factor);
|
||||
regy.Add(rv.Name_bry(), rv);
|
||||
return rv;
|
||||
}
|
||||
public static final Xol_duration_itm[] Ary_default = new Xol_duration_itm[]
|
||||
{ Itm_millenia
|
||||
, Itm_centuries
|
||||
, Itm_decades
|
||||
, Itm_years
|
||||
, Itm_weeks
|
||||
, Itm_days
|
||||
, Itm_hours
|
||||
, Itm_minutes
|
||||
, Itm_seconds
|
||||
};
|
||||
public static Xol_duration_itm[] Xto_itm_ary(KeyVal[] kv_ary) {
|
||||
if (kv_ary == null) return Xol_duration_itm_.Ary_default;
|
||||
List_adp rv = List_adp_.new_();
|
||||
int len = kv_ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
KeyVal kv = kv_ary[i];
|
||||
String name = kv.Val_to_str_or_empty();
|
||||
Xol_duration_itm itm = (Xol_duration_itm)regy.Get_by(Bry_.new_u8(name));
|
||||
if (itm != null)
|
||||
rv.Add(itm);
|
||||
}
|
||||
return (Xol_duration_itm[])rv.To_ary(Xol_duration_itm.class);
|
||||
}
|
||||
}
|
||||
class Xol_duration_itm_sorter implements gplx.lists.ComparerAble {
|
||||
public int compare(Object lhsObj, Object rhsObj) {
|
||||
Xol_duration_itm lhs = (Xol_duration_itm)lhsObj;
|
||||
Xol_duration_itm rhs = (Xol_duration_itm)rhsObj;
|
||||
return -Long_.Compare(lhs.Seconds(), rhs.Seconds()); // - to sort from largest to smallest
|
||||
}
|
||||
public static final Xol_duration_itm_sorter _ = new Xol_duration_itm_sorter(); Xol_duration_itm_sorter() {}
|
||||
}
|
||||
90
400_xowa/src/gplx/xowa/langs/durations/Xol_duration_mgr.java
Normal file
90
400_xowa/src/gplx/xowa/langs/durations/Xol_duration_mgr.java
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
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.durations; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_duration_mgr {
|
||||
private Xol_msg_itm[] interval_msgs = null;
|
||||
public Xol_duration_mgr(Xol_lang lang) {this.lang = lang;} private Xol_lang lang;
|
||||
private Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
|
||||
public Xol_interval_itm[] Get_duration_intervals(long seconds, Xol_duration_itm[] intervals) {
|
||||
if (intervals == null) intervals = Xol_duration_itm_.Ary_default;
|
||||
Array_.Sort(intervals, Xol_duration_itm_sorter._);
|
||||
int intervals_len = intervals.length;
|
||||
long val = seconds;
|
||||
List_adp rv = List_adp_.new_();
|
||||
for (int i = 0; i < intervals_len; i++) {
|
||||
Xol_duration_itm itm = intervals[i];
|
||||
long itm_seconds = itm.Seconds();
|
||||
val = seconds / itm_seconds;
|
||||
if ( val > 0
|
||||
|| (i == intervals_len - 1 && rv.Count() == 0) // always add one seg; EX: 40 seconds, but minutes requested -> 0 minutes; DATE:2014-05-10
|
||||
) {
|
||||
seconds -= val * itm_seconds;
|
||||
rv.Add(new Xol_interval_itm(itm, val));
|
||||
}
|
||||
}
|
||||
return (Xol_interval_itm[])rv.To_ary(Xol_interval_itm.class);
|
||||
}
|
||||
public byte[] Format_durations(Xop_ctx ctx, long seconds, Xol_duration_itm[] ary) {
|
||||
if (interval_msgs == null) Format_durations_init();
|
||||
Xol_interval_itm[] intervals = Get_duration_intervals(seconds, ary);
|
||||
int intervals_len = intervals.length;
|
||||
byte[][] msgs_ary = new byte[intervals_len][];
|
||||
for (int i = 0; i < intervals_len; i++) {
|
||||
Xol_interval_itm interval = intervals[i];
|
||||
Xol_msg_itm msg_itm = interval_msgs[interval.Duration_itm().Tid()];
|
||||
byte[] msg_bry = msg_itm.Fmt(tmp_bfr, interval.Val());
|
||||
msg_bry = ctx.Wiki().Parser().Parse_text_to_html(ctx, msg_bry);
|
||||
msgs_ary[i] = msg_bry;
|
||||
}
|
||||
return List_to_str(msgs_ary);
|
||||
}
|
||||
private byte[] Msg_and, Msg_word_separator, Msg_comma_separator;
|
||||
private void Format_durations_init() {
|
||||
Xol_msg_mgr msg_mgr = lang.Msg_mgr();
|
||||
int len = Xol_duration_itm_.Ary_default.length;
|
||||
interval_msgs = new Xol_msg_itm[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xol_duration_itm itm = Xol_duration_itm_.Ary_default[i];
|
||||
byte[] msg_key = Bry_.Add(Bry_duration, itm.Name_bry());
|
||||
interval_msgs[i] = msg_mgr.Itm_by_key_or_new(msg_key);
|
||||
}
|
||||
} private static final byte[] Bry_duration = Bry_.new_a7("duration-");
|
||||
private void List_to_str_init() {
|
||||
Xol_msg_mgr msg_mgr = lang.Msg_mgr();
|
||||
Msg_and = msg_mgr.Val_by_str_or_empty("and");
|
||||
Msg_word_separator = msg_mgr.Val_by_str_or_empty("word-separator");
|
||||
Msg_comma_separator = msg_mgr.Val_by_str_or_empty("comma-separator");
|
||||
}
|
||||
|
||||
public byte[] List_to_str(byte[][] segs_ary) {
|
||||
int len = segs_ary.length;
|
||||
switch (len) {
|
||||
case 0: return Bry_.Empty;
|
||||
case 1: return segs_ary[0];
|
||||
default:
|
||||
if (Msg_and == null) List_to_str_init();
|
||||
int last_idx = len - 1;
|
||||
for (int i = 0; i < last_idx; i++) {
|
||||
if (i != 0) tmp_bfr.Add(Msg_comma_separator);
|
||||
tmp_bfr.Add(segs_ary[i]);
|
||||
}
|
||||
tmp_bfr.Add(Msg_and).Add(Msg_word_separator).Add(segs_ary[last_idx]);
|
||||
return tmp_bfr.Xto_bry_and_clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
32
400_xowa/src/gplx/xowa/langs/durations/Xol_interval_itm.java
Normal file
32
400_xowa/src/gplx/xowa/langs/durations/Xol_interval_itm.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
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.durations; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_interval_itm {
|
||||
public Xol_interval_itm(Xol_duration_itm duration_itm, long val) {this.duration_itm = duration_itm; this.val = val;}
|
||||
public Xol_duration_itm Duration_itm() {return duration_itm;} private Xol_duration_itm duration_itm;
|
||||
public long Val() {return val;} private long val;
|
||||
public static KeyVal[] Xto_kv_ary(Xol_interval_itm[] ary) {
|
||||
int len = ary.length;
|
||||
KeyVal[] rv = new KeyVal[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xol_interval_itm itm = ary[i];
|
||||
rv[i] = KeyVal_.new_(itm.Duration_itm().Name_str(), (int)itm.Val()); // double for scribunto
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
21
400_xowa/src/gplx/xowa/langs/genders/Xol_gender.java
Normal file
21
400_xowa/src/gplx/xowa/langs/genders/Xol_gender.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
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.genders; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public interface Xol_gender {
|
||||
byte[] Gender_eval(int gender, byte[] when_m, byte[] when_f, byte[] when_u);
|
||||
}
|
||||
34
400_xowa/src/gplx/xowa/langs/genders/Xol_gender_.java
Normal file
34
400_xowa/src/gplx/xowa/langs/genders/Xol_gender_.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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.genders; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.primitives.*; import gplx.core.btries.*;
|
||||
public class Xol_gender_ {
|
||||
public static Xol_gender new_by_lang_id(int lang_id) {return Xol_gender__basic.I;}
|
||||
public static final int Tid_male = 0, Tid_female = 1, Tid_unknown = 2;
|
||||
}
|
||||
class Xol_gender__basic implements Xol_gender {
|
||||
public byte[] Gender_eval(int gender, byte[] when_m, byte[] when_f, byte[] when_u) {
|
||||
switch (gender) {
|
||||
case Xol_gender_.Tid_male: return when_m;
|
||||
case Xol_gender_.Tid_female: return when_f;
|
||||
case Xol_gender_.Tid_unknown: return when_u;
|
||||
default: throw Exc_.new_unimplemented();
|
||||
}
|
||||
}
|
||||
public static final Xol_gender__basic I = new Xol_gender__basic(); Xol_gender__basic() {}
|
||||
}
|
||||
21
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar.java
Normal file
21
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
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.grammars; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public interface Xol_grammar {
|
||||
boolean Grammar_eval(Bry_bfr bfr, Xol_lang lang, byte[] word, byte[] type);
|
||||
}
|
||||
55
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar_.java
Normal file
55
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar_.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
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.grammars; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.primitives.*; import gplx.core.btries.*;
|
||||
public class Xol_grammar_ {
|
||||
public static final byte Tid__max = 9;
|
||||
public static final byte Tid_genitive = 0, Tid_elative = 1, Tid_partitive = 2, Tid_illative = 3, Tid_inessive = 4, Tid_accusative = 5, Tid_instrumental = 6, Tid_prepositional = 7, Tid_dative = 8, Tid_unknown = Byte_.Max_value_127;
|
||||
private static final Btrie_slim_mgr Tid_trie = Btrie_slim_mgr.ci_ascii_() // NOTE:ci.ascii:MW kwds
|
||||
.Add_str_byte("genitive", Tid_genitive)
|
||||
.Add_str_byte("elative", Tid_elative)
|
||||
.Add_str_byte("partitive", Tid_partitive)
|
||||
.Add_str_byte("illative", Tid_illative)
|
||||
.Add_str_byte("inessive", Tid_inessive)
|
||||
.Add_str_byte("accusative", Tid_accusative)
|
||||
.Add_str_byte("instrumental", Tid_instrumental)
|
||||
.Add_str_byte("prepositional", Tid_prepositional)
|
||||
.Add_str_byte("dative", Tid_dative)
|
||||
;
|
||||
public static byte Tid_of_type(byte[] v) {
|
||||
if (Bry_.Len_eq_0(v)) return Tid_unknown;
|
||||
Object o = Xol_grammar_.Tid_trie.Match_exact(v, 0, v.length);
|
||||
return o == null ? Tid_unknown : ((Byte_obj_val)o).Val();
|
||||
}
|
||||
public static Xol_grammar new_by_lang_id(int lang_id) {
|
||||
switch (lang_id) {
|
||||
case Xol_lang_itm_.Id_fi: return new Xol_grammar_fi();
|
||||
case Xol_lang_itm_.Id_ru: return new Xol_grammar_ru();
|
||||
case Xol_lang_itm_.Id_pl: return Xol_grammar__noop._;
|
||||
default: return Xol_grammar__unimplemented._;
|
||||
}
|
||||
}
|
||||
}
|
||||
class Xol_grammar__unimplemented implements Xol_grammar {
|
||||
public boolean Grammar_eval(Bry_bfr bfr, Xol_lang lang, byte[] word, byte[] type) {return false;}
|
||||
public static final Xol_grammar__unimplemented _ = new Xol_grammar__unimplemented(); Xol_grammar__unimplemented() {}
|
||||
}
|
||||
class Xol_grammar__noop implements Xol_grammar {
|
||||
public boolean Grammar_eval(Bry_bfr bfr, Xol_lang lang, byte[] word, byte[] type) {bfr.Add(word); return true;}
|
||||
public static final Xol_grammar__noop _ = new Xol_grammar__noop(); Xol_grammar__noop() {}
|
||||
}
|
||||
80
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar_fi.java
Normal file
80
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar_fi.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
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.grammars; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.primitives.*; import gplx.core.btries.*;
|
||||
public class Xol_grammar_fi implements Xol_grammar {
|
||||
public boolean Vowel_harmony(byte[] word, int word_len) {
|
||||
// $aou = preg_match( '/[aou][^äöy]*$/i', $word );
|
||||
boolean aou_found = false;
|
||||
for (int i = 0; i < word_len; i++) {
|
||||
byte b = word[i];
|
||||
Object o = trie_vh.Match_bgn_w_byte(b, word, i, word_len);
|
||||
if (o != null) {
|
||||
byte vh_type = ((Byte_obj_val)o).Val();
|
||||
if (vh_type == Trie_vh_back)
|
||||
aou_found = true;
|
||||
else
|
||||
aou_found = false;
|
||||
}
|
||||
}
|
||||
return aou_found;
|
||||
}
|
||||
public boolean Grammar_eval(Bry_bfr bfr, Xol_lang lang, byte[] word, byte[] type) {
|
||||
if (Bry_.Len_eq_0(word)) return true; // empty_string returns ""
|
||||
byte tid = Xol_grammar_.Tid_of_type(type);
|
||||
if (tid == Xol_grammar_.Tid_unknown) {bfr.Add(word); return true;} // unknown type returns word
|
||||
// PHP: if (isset($wgGrammarForms['fi'][$case][$word])){ return $wgGrammarForms['fi'][$case][$word];
|
||||
if (manual_regy == null) {
|
||||
manual_regy = new Xol_grammar_manual_regy()
|
||||
.Itms_add(Xol_grammar_.Tid_elative, "Wikiuutiset", "Wikiuutisista");
|
||||
}
|
||||
byte[] manual_repl = manual_regy.Itms_get(tid, word);
|
||||
if (manual_repl != null) {
|
||||
bfr.Add(manual_repl);
|
||||
return true;
|
||||
}
|
||||
bfr.Add(word); // NOTE: preemptively add word now; the rest of this function takes "word" and adds other letters to it;
|
||||
int word_len = word.length;
|
||||
byte[] lower = lang.Case_mgr().Case_build_lower(word, 0, word_len);
|
||||
boolean aou = Vowel_harmony(lower, word_len);
|
||||
// PHP: if ( preg_match( '/wiki$/i', $word ) ) $aou = false;
|
||||
if (aou && Bry_.Has_at_end(lower, Xoa_url_parser.Bry_wiki_name))
|
||||
aou = false;
|
||||
// PHP: if ( preg_match( '/[bcdfghjklmnpqrstvwxz]$/i', $word ) ) $word .= 'i';
|
||||
switch (lower[word_len - 1]) {
|
||||
case Byte_ascii.Ltr_b: case Byte_ascii.Ltr_c: case Byte_ascii.Ltr_d: case Byte_ascii.Ltr_f: case Byte_ascii.Ltr_g:
|
||||
case Byte_ascii.Ltr_h: case Byte_ascii.Ltr_j: case Byte_ascii.Ltr_k: case Byte_ascii.Ltr_l: case Byte_ascii.Ltr_m:
|
||||
case Byte_ascii.Ltr_n: case Byte_ascii.Ltr_p: case Byte_ascii.Ltr_q: case Byte_ascii.Ltr_r: case Byte_ascii.Ltr_s:
|
||||
case Byte_ascii.Ltr_t: case Byte_ascii.Ltr_v: case Byte_ascii.Ltr_w: case Byte_ascii.Ltr_x: case Byte_ascii.Ltr_z:
|
||||
bfr.Add_byte(Byte_ascii.Ltr_i);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tid) {
|
||||
case Xol_grammar_.Tid_genitive: bfr.Add_byte(Byte_ascii.Ltr_n); break; // case 'genitive': $word .= 'n';
|
||||
case Xol_grammar_.Tid_elative: bfr.Add(aou ? Bry_sta_y : Bry_sta_n); break; // case 'elative': $word .= ( $aou ? 'sta' : 'stä' );
|
||||
case Xol_grammar_.Tid_partitive: bfr.Add(aou ? Bry_a_y : Bry_a_n); break; // case 'partitive': $word .= ( $aou ? 'a' : 'ä' );
|
||||
case Xol_grammar_.Tid_inessive: bfr.Add(aou ? Bry_ssa_y : Bry_ssa_n); break; // case 'inessive': $word .= ( $aou ? 'ssa' : 'ssä' );
|
||||
case Xol_grammar_.Tid_illative: bfr.Add_byte(word[word_len - 1]).Add_byte(Byte_ascii.Ltr_n); break;// # Double the last letter and add 'n'
|
||||
}
|
||||
return true;
|
||||
} static Xol_grammar_manual_regy manual_regy;
|
||||
private static final byte[] Bry_sta_y = Bry_.new_a7("sta"), Bry_sta_n = Bry_.new_u8("stä"), Bry_a_y = Bry_.new_a7("a"), Bry_a_n = Bry_.new_u8("ä"), Bry_ssa_y = Bry_.new_a7("ssa"), Bry_ssa_n = Bry_.new_u8("ssä");
|
||||
static final byte Trie_vh_back = 0, Trie_vh_front = 1;
|
||||
private static Btrie_slim_mgr trie_vh = Btrie_slim_mgr.cs_().Add_str_byte__many(Trie_vh_back, "a", "o", "u").Add_str_byte__many(Trie_vh_front, "ä", "ö", "y");
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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.grammars; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_grammar_manual_regy {
|
||||
private Hash_adp_bry[] ary = new Hash_adp_bry[Xol_grammar_.Tid__max];
|
||||
public byte[] Itms_get(byte type_tid, byte[] word) {
|
||||
Hash_adp_bry hash = ary[type_tid]; if (hash == null) return null;
|
||||
return (byte[])hash.Get_by_bry(word);
|
||||
}
|
||||
public Xol_grammar_manual_regy Itms_add(byte type_tid, String orig, String repl) {
|
||||
Hash_adp_bry hash = ary[type_tid];
|
||||
if (hash == null) {
|
||||
hash = Hash_adp_bry.ci_ascii_(); // ASCII:currently only being used for Wikiuutiset; DATE:2014-07-07
|
||||
ary[type_tid] = hash;
|
||||
}
|
||||
hash.Add_str_obj(orig, Bry_.new_a7(repl));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
73
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar_ru.java
Normal file
73
400_xowa/src/gplx/xowa/langs/grammars/Xol_grammar_ru.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
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.grammars; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.btries.*;
|
||||
public class Xol_grammar_ru implements Xol_grammar {
|
||||
static final byte Genitive_null = 0, Genitive_bnkn = 1, Genitive_Bnkn = 26, Genitive_b = 3, Genitive_nr = 4, Genitive_ka = 5, Genitive_tn = 6, Genitive_abl = 7, Genitive_hnk = 8;
|
||||
private static Btrie_bwd_mgr Genitive_trie;
|
||||
private static Btrie_bwd_mgr genitive_trie_() {
|
||||
Btrie_bwd_mgr rv = new Btrie_bwd_mgr(false);
|
||||
genitive_trie_add(rv, Genitive_bnkn, "вики", null);
|
||||
genitive_trie_add(rv, Genitive_Bnkn, "Вики", null);
|
||||
genitive_trie_add(rv, Genitive_b, "ь", "я");
|
||||
genitive_trie_add(rv, Genitive_nr, "ия", "ии");
|
||||
genitive_trie_add(rv, Genitive_ka, "ка", "ки");
|
||||
genitive_trie_add(rv, Genitive_tn, "ти", "тей");
|
||||
genitive_trie_add(rv, Genitive_abl, "ды", "дов");
|
||||
genitive_trie_add(rv, Genitive_hnk , "ник", "ника");
|
||||
return rv;
|
||||
}
|
||||
private static void genitive_trie_add(Btrie_bwd_mgr trie, byte tid, String find_str, String repl_str) {
|
||||
byte[] find_bry = Bry_.new_u8(find_str);
|
||||
byte[] repl_bry = repl_str == null ? null : Bry_.new_u8(repl_str);
|
||||
Xol_grammar_ru_genitive_itm itm = new Xol_grammar_ru_genitive_itm(tid, find_bry, repl_bry);
|
||||
trie.Add(find_bry, itm);
|
||||
}
|
||||
public boolean Grammar_eval(Bry_bfr bfr, Xol_lang lang, byte[] word, byte[] type) {
|
||||
if (Bry_.Len_eq_0(word)) return true; // empty_string returns ""
|
||||
byte tid = Xol_grammar_.Tid_of_type(type);
|
||||
switch (tid) {
|
||||
case Xol_grammar_.Tid_genitive: {
|
||||
if (Genitive_trie == null) Genitive_trie = genitive_trie_();
|
||||
Object o = Genitive_trie.Match_bgn(word, word.length - 1, -1);
|
||||
if (o != null) {
|
||||
Xol_grammar_ru_genitive_itm itm = (Xol_grammar_ru_genitive_itm)o;
|
||||
if (!itm.Repl_is_noop()) {
|
||||
bfr.Add_mid(word, 0, Genitive_trie.Match_pos() + 1);
|
||||
bfr.Add(itm.Repl());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Xol_grammar_.Tid_dative: break;
|
||||
case Xol_grammar_.Tid_accusative: break;
|
||||
case Xol_grammar_.Tid_instrumental: break;
|
||||
case Xol_grammar_.Tid_prepositional:break;
|
||||
}
|
||||
bfr.Add(word);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
class Xol_grammar_ru_genitive_itm {
|
||||
public Xol_grammar_ru_genitive_itm(byte tid, byte[] find, byte[] repl) {this.tid = tid; this.find = find; this.repl = repl;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Find() {return find;} private byte[] find;
|
||||
public byte[] Repl() {return repl;} private byte[] repl;
|
||||
public boolean Repl_is_noop() {return repl == null;}
|
||||
}
|
||||
134
400_xowa/src/gplx/xowa/langs/msgs/Xol_msg_mgr_.java
Normal file
134
400_xowa/src/gplx/xowa/langs/msgs/Xol_msg_mgr_.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
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.msgs; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.php.*;
|
||||
public class Xol_msg_mgr_ {
|
||||
// public static String Get_msg_val_gui_or_null(Xol_lang lang, byte[] pre, byte[] key, byte[] suf) {
|
||||
// String rv = Get_msg_val_gui_or_null(lang, pre, key, suf);
|
||||
// return rv == null ? "<" + String_.new_u8(Bry_.Add(pre, key, suf)) + ">" : rv;
|
||||
// }
|
||||
public static String Get_msg_val_gui_or_empty(Xoa_lang_mgr lang_mgr, Xol_lang lang, byte[] pre, byte[] key, byte[] suf) { // get from lang, else get from en; does not use get_msg_val to skip db lookups; should only be used for gui; DATE:2014-05-28
|
||||
String rv = Get_msg_val_gui_or_null(lang_mgr, lang, pre, key, suf);
|
||||
return rv == null ? "" : rv;
|
||||
}
|
||||
public static String Get_msg_val_gui_or(Xoa_lang_mgr lang_mgr, Xol_lang lang, byte[] pre, byte[] key, byte[] suf, String or) {
|
||||
String rv = Get_msg_val_gui_or_null(lang_mgr, lang, pre, key, suf);
|
||||
return rv == null ? or : rv;
|
||||
}
|
||||
public static String Get_msg_val_gui_or_null(Xoa_lang_mgr lang_mgr, Xol_lang lang, byte[] pre, byte[] key, byte[] suf) { // get from lang, else get from en; does not use get_msg_val to skip db lookups; should only be used for gui; DATE:2014-05-28
|
||||
byte[] msg_key = Bry_.Add(pre, key, suf);
|
||||
Xol_msg_itm msg_itm = lang.Msg_mgr().Itm_by_key_or_null(msg_key);
|
||||
if (msg_itm == null)
|
||||
msg_itm = lang_mgr.Lang_en().Msg_mgr().Itm_by_key_or_null(msg_key);
|
||||
return msg_itm == null ? null : String_.new_u8(msg_itm.Val());
|
||||
}
|
||||
public static byte[] Get_msg_val(Xowe_wiki wiki, Xol_lang lang, byte[] msg_key, byte[][] fmt_args) {
|
||||
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512();
|
||||
Xol_msg_itm msg_itm = Get_msg_itm(tmp_bfr, wiki, lang, msg_key);
|
||||
byte[] rv = Get_msg_val(tmp_bfr, wiki, msg_itm, fmt_args);
|
||||
tmp_bfr.Mkr_rls();
|
||||
return rv;
|
||||
} private static final byte[] Missing_bry = Bry_.new_a7("$"), Slash_bry = new byte[] {Byte_ascii.Slash};
|
||||
public static byte[] Get_msg_val(Bry_bfr tmp_bfr, Xowe_wiki wiki, Xol_msg_itm msg_itm, byte[][] fmt_args) {
|
||||
byte[] msg_val = msg_itm.Val();
|
||||
boolean has_fmt = msg_itm.Has_fmt_arg(), has_tmpl = msg_itm.Has_tmpl_txt();
|
||||
if (!has_fmt && !has_tmpl) // no fmt or tmpl; just add val
|
||||
return msg_val;
|
||||
if (has_fmt) { // fmt exists; fmt first (before tmpl text); EX: Expression error: Unrecognised word "~{0}"
|
||||
Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_().Missing_bgn_(Missing_bry).Missing_end_(Bry_.Empty).Missing_adj_(1);
|
||||
tmp_fmtr.Fmt_(msg_val);
|
||||
tmp_fmtr.Bld_bfr(tmp_bfr, fmt_args);
|
||||
msg_val = tmp_bfr.Xto_bry_and_clear();
|
||||
}
|
||||
if (has_tmpl) {
|
||||
Xop_ctx sub_ctx = Xop_ctx.new_sub_(wiki); Xop_tkn_mkr tkn_mkr = sub_ctx.Tkn_mkr();
|
||||
Xop_root_tkn sub_root = tkn_mkr.Root(msg_val);
|
||||
msg_val = wiki.Parser().Parse_text_to_wtxt(sub_root, sub_ctx, tkn_mkr, msg_val);
|
||||
}
|
||||
return msg_val;
|
||||
}
|
||||
public static Xol_msg_itm Get_msg_itm(Bry_bfr tmp_bfr, Xowe_wiki wiki, Xol_lang lang, byte[] msg_key) {
|
||||
byte[] msg_key_sub_root = msg_key;
|
||||
int slash_pos = Bry_finder.Find_bwd(msg_key, Byte_ascii.Slash);
|
||||
if (slash_pos != Bry_.NotFound) { // key is of format "key/lang"; EX: "January/en"
|
||||
int msg_key_len = msg_key.length;
|
||||
if (slash_pos != msg_key_len) { // get text after slash; EX: "en"
|
||||
Object o = Xol_lang_itm_.Regy().Get_by_mid(msg_key, slash_pos + 1, msg_key_len);
|
||||
if (o != null) { // text is known lang_code;
|
||||
Xol_lang_itm lang_itm = (Xol_lang_itm)o;
|
||||
lang = wiki.Appe().Lang_mgr().Get_by_key_or_new(lang_itm.Key()); // set lang
|
||||
}
|
||||
msg_key_sub_root = Bry_.Mid(msg_key, 0, slash_pos); // set msg to "a" (discarding "/b")
|
||||
}
|
||||
}
|
||||
Xol_msg_itm msg_in_wiki = wiki.Msg_mgr().Get_or_null(msg_key); // check wiki; used to be check lang, but Search_mediawiki should never be toggled on lang; DATE:2014-05-13
|
||||
if (msg_in_wiki != null) return msg_in_wiki; // NOTE: all new msgs will Search_mediawiki once; EX: de.w:{{int:Autosumm-replace}}; DATE:2013-01-25
|
||||
msg_in_wiki = wiki.Msg_mgr().Get_or_make(msg_key);
|
||||
Xoae_page msg_page = Get_msg_itm_from_db(wiki, lang, msg_key, msg_key_sub_root);
|
||||
byte[] msg_val = Bry_.Empty;
|
||||
if (msg_page.Missing()) { // [[MediaWiki:key/fallback]] still not found; search "lang.gfs";
|
||||
Xol_msg_itm msg_in_lang = Get_msg_itm_from_gfs(wiki, lang, msg_key_sub_root);
|
||||
if (msg_in_lang == null) {
|
||||
msg_val = tmp_bfr.Add_byte(Byte_ascii.Lt).Add(msg_key).Add_byte(Byte_ascii.Gt).Xto_bry_and_clear(); // set val to <msg_key>
|
||||
msg_in_wiki.Src_(Xol_msg_itm.Src_missing);
|
||||
}
|
||||
else {
|
||||
msg_val = msg_in_lang.Val();
|
||||
msg_in_wiki.Src_(Xol_msg_itm.Src_lang);
|
||||
}
|
||||
}
|
||||
else { // page found; dump entire contents
|
||||
msg_val = gplx.xowa.apps.Xoa_gfs_php_mgr.Xto_gfs(tmp_bfr, msg_page.Data_raw()); // note that MediaWiki msg's use php arg format ($1); xowa.gfs msgs are already converted
|
||||
msg_in_wiki.Src_(Xol_msg_itm.Src_wiki);
|
||||
}
|
||||
Xol_msg_itm_.update_val_(msg_in_wiki, msg_val);
|
||||
return msg_in_wiki;
|
||||
}
|
||||
private static Xoae_page Get_msg_itm_from_db(Xowe_wiki wiki, Xol_lang lang, byte[] msg_key, byte[] msg_key_sub_root) {
|
||||
byte[] ns_bry = wiki.Ns_mgr().Ns_mediawiki().Name_db_w_colon();
|
||||
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.Add(ns_bry, msg_key)); // ttl="MediaWiki:msg_key"; note that there may be "/lang"; EX:pl.d:Wikislownik:Bar/Archiwum_6 and newarticletext/pl
|
||||
Xoae_page rv = ttl == null ? Xoae_page.Empty : wiki.Data_mgr().Get_page_from_msg(ttl);
|
||||
if (rv.Missing()) { // [[MediaWiki:key]] not found; search for [[MediaWiki:key/fallback]]
|
||||
byte[][] fallback_ary = lang.Fallback_bry_ary();
|
||||
int fallback_ary_len = fallback_ary.length;
|
||||
for (int i = 0; i < fallback_ary_len; i++) {
|
||||
byte[] fallback = fallback_ary[i];
|
||||
ttl = Xoa_ttl.parse_(wiki, Bry_.Add(ns_bry, msg_key_sub_root, Slash_bry, fallback)); // ttl="MediaWiki:msg_key/fallback"
|
||||
rv = ttl == null ? Xoae_page.Empty : wiki.Data_mgr().Get_page_from_msg(ttl);
|
||||
if (!rv.Missing()) break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
private static Xol_msg_itm Get_msg_itm_from_gfs(Xowe_wiki wiki, Xol_lang lang, byte[] msg_key_sub_root) {
|
||||
Xol_msg_itm rv = lang.Msg_mgr().Itm_by_key_or_null(msg_key_sub_root); // NOTE: should always be msg_key_sub_root; EX: "msg/lang" will never be in lang.gfs
|
||||
if (rv == null) { // msg not found; check fallbacks; note that this is different from MW b/c when MW constructs a lang, it automatically adds all fallback msgs to the current lang
|
||||
byte[][] fallback_ary = lang.Fallback_bry_ary();
|
||||
int fallback_ary_len = fallback_ary.length;
|
||||
Xoa_lang_mgr lang_mgr = wiki.Appe().Lang_mgr();
|
||||
for (int i = 0; i < fallback_ary_len; i++) {
|
||||
byte[] fallback = fallback_ary[i];
|
||||
Xol_lang fallback_lang = lang_mgr.Get_by_key(fallback);
|
||||
if (fallback_lang == null) continue; // NOTE: en has fallback of "false"; ignore bad fallbacks;
|
||||
rv = fallback_lang.Msg_mgr().Itm_by_key_or_null(msg_key_sub_root);
|
||||
if (rv != null) break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
204
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_fmtr_base.java
Normal file
204
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_fmtr_base.java
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.primitives.*; import gplx.core.btries.*;
|
||||
public class Xol_num_fmtr_base implements GfoInvkAble {
|
||||
private Btrie_fast_mgr dlm_trie = Btrie_fast_mgr.cs_();
|
||||
private Xol_num_grp[] grp_ary = Xol_num_grp.Ary_empty; int grp_ary_len;
|
||||
private Gfo_num_fmt_wkr[] cache; int cache_len = 16;
|
||||
private Bry_bfr tmp = Bry_bfr.new_();
|
||||
public boolean Standard() {return standard;} private boolean standard = true;
|
||||
public byte[] Dec_dlm() {return dec_dlm;} public Xol_num_fmtr_base Dec_dlm_(byte[] v) {this.dec_dlm = v; dlm_trie.Add_bry_bval(v, Raw_tid_dec); return this;} private byte[] dec_dlm = Dec_dlm_default;
|
||||
private byte[] grp_dlm;
|
||||
public byte[] Raw(byte tid, byte[] src) {
|
||||
int src_len = src.length;
|
||||
for (int i = 0; i < src_len; i++) {
|
||||
byte b = src[i];
|
||||
Object o = dlm_trie.Match_bgn(src, i, src_len);
|
||||
if (o == null)
|
||||
tmp.Add_byte(b);
|
||||
else {
|
||||
byte dlm_tid = ((Byte_obj_val)o).Val();
|
||||
int dlm_match_pos = dlm_trie.Match_pos();
|
||||
switch (dlm_tid) {
|
||||
case Raw_tid_dec:
|
||||
if (tid == Tid_raw)
|
||||
tmp.Add_byte(Byte_ascii.Dot); // NOTE: dec_dlm is always outputted as dot, not regional dec_spr; EX: for dewiki, 12,34 -> 12.34
|
||||
else
|
||||
tmp.Add(dec_dlm);
|
||||
break;
|
||||
case Raw_tid_grp: {
|
||||
if (tid == Tid_raw) {} // never add grp_sep for raw
|
||||
else // add raw grp_spr
|
||||
tmp.Add_mid(src, i, dlm_match_pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = dlm_match_pos - 1; // NOTE: handle multi-byte delims
|
||||
}
|
||||
}
|
||||
return tmp.Xto_bry_and_clear();
|
||||
}
|
||||
public byte[] Fmt(int val) {return Fmt(Bry_.new_a7(Int_.Xto_str(val)));}
|
||||
public byte[] Fmt(byte[] src) { // SEE: DOC_1:Fmt
|
||||
int src_len = src.length;
|
||||
int num_bgn = -1, dec_pos = -1;
|
||||
for (int i = 0; i < src_len; i++) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
|
||||
if (dec_pos == -1) { // no decimal seen
|
||||
if (num_bgn == -1) // num_bgn hasn't started
|
||||
num_bgn = i; // set num_bgn
|
||||
}
|
||||
else // decimal seen; add rest of src literally
|
||||
tmp.Add_byte(b);
|
||||
break;
|
||||
default: // non-number; includes alpha chars, as well as ".", "," and other potential separators
|
||||
if (num_bgn != -1) { // number started; format group; EX: 1234. -> 1,234.
|
||||
Gfo_num_fmt_wkr wkr = Get_or_new(i - num_bgn);
|
||||
wkr.Fmt(src, num_bgn, i, tmp);
|
||||
num_bgn = dec_pos = -1; // reset vars
|
||||
if (b == Byte_ascii.Dot // current char is "."; NOTE: all languages treat "." as decimal separator for parse; EX: for de, "1.23" is "1,23" DATE:2013-10-21
|
||||
//|| Bry_.Has_at_bgn(src, dec_dlm, i, src_len)
|
||||
) { // current char is languages's decimal delimiter; note this can be "," or any other multi-byte separator
|
||||
dec_pos = i;
|
||||
// i += dec_dlm.length - 1;
|
||||
tmp.Add(dec_dlm);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (b == Byte_ascii.Comma)
|
||||
tmp.Add(grp_dlm);
|
||||
else
|
||||
tmp.Add_byte(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (num_bgn != -1) { // digits left unprocessed
|
||||
Gfo_num_fmt_wkr wkr = Get_or_new(src_len - num_bgn);
|
||||
wkr.Fmt(src, num_bgn, src_len, tmp);
|
||||
}
|
||||
return tmp.Xto_bry_and_clear();
|
||||
}
|
||||
private Gfo_num_fmt_wkr Get_or_new(int src_len) {
|
||||
Gfo_num_fmt_wkr rv = null;
|
||||
if (src_len < cache_len) {
|
||||
rv = cache[src_len];
|
||||
if (rv != null) return rv;
|
||||
}
|
||||
rv = new Gfo_num_fmt_wkr(grp_ary, grp_ary_len, src_len);
|
||||
if (src_len < cache_len) cache[src_len] = rv;
|
||||
return rv;
|
||||
}
|
||||
public Xol_num_grp Grps_get_last() {return grp_ary[grp_ary_len - 1];}
|
||||
public Xol_num_grp Grps_get(int i) {return grp_ary[i];}
|
||||
public int Grps_len() {return grp_ary_len;}
|
||||
public void Grps_add(Xol_num_grp dat_itm) {
|
||||
standard = false;
|
||||
this.grp_ary = (Xol_num_grp[])Array_.Resize(grp_ary, grp_ary_len + 1);
|
||||
grp_ary[grp_ary_len] = dat_itm;
|
||||
grp_ary_len = grp_ary.length;
|
||||
for (int i = 0; i < grp_ary_len; i++) {
|
||||
Xol_num_grp itm = grp_ary[i];
|
||||
byte[] itm_dlm = itm.Dlm();
|
||||
Object o = dlm_trie.Match_exact(itm_dlm, 0, itm_dlm.length); // check for existing Object
|
||||
if (o == null) {
|
||||
dlm_trie.Add_bry_bval(itm_dlm, Raw_tid_grp);
|
||||
grp_dlm = itm_dlm;
|
||||
}
|
||||
}
|
||||
}
|
||||
public Xol_num_fmtr_base Clear() {
|
||||
this.grp_ary = Xol_num_grp.Ary_empty;
|
||||
grp_ary_len = 0;
|
||||
cache = new Gfo_num_fmt_wkr[cache_len];
|
||||
dlm_trie.Clear();
|
||||
return this;
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_dec_dlm_)) this.Dec_dlm_(m.ReadBry("v")); // NOTE: must call mutator
|
||||
else if (ctx.Match(k, Invk_clear)) this.Clear();
|
||||
else if (ctx.Match(k, Invk_grps_add)) this.Grps_add(new Xol_num_grp(m.ReadBry("dlm"), m.ReadInt("digits"), m.ReadYn("repeat")));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
public static final String Invk_dec_dlm_ = "dec_dlm_", Invk_clear = "clear", Invk_grps_add = "grps_add";
|
||||
private static final byte Raw_tid_dec = 0, Raw_tid_grp = 1;
|
||||
private static final byte[] Dec_dlm_default = new byte[] {Byte_ascii.Dot};
|
||||
public static final byte[] Grp_dlm_default = new byte[] {Byte_ascii.Comma};
|
||||
public static final byte Tid_format = 0, Tid_raw = 1, Tid_nosep = 2;
|
||||
}
|
||||
class Gfo_num_fmt_wkr {
|
||||
public void Fmt(byte[] src, int bgn, int end, Bry_bfr bb) {
|
||||
if (itm_max == 0) {bb.Add_mid(src, bgn, end); return;}; // NOTE: small numbers (<=3) will have a 0-len ary
|
||||
int cur_idx = itm_max - 1;
|
||||
Gfo_num_fmt_bldr cur = itm_ary[cur_idx];
|
||||
int cur_pos = cur.Pos();
|
||||
for (int i = bgn; i < end; i++) {
|
||||
if (i == cur_pos + bgn) {
|
||||
cur.Gen(bb);
|
||||
if (cur_idx > 0) cur = itm_ary[--cur_idx];
|
||||
cur_pos = cur.Pos();
|
||||
}
|
||||
bb.Add_byte(src[i]);
|
||||
}
|
||||
}
|
||||
public Gfo_num_fmt_wkr(Xol_num_grp[] grp_ary, int grp_ary_len, int src_len) {
|
||||
itm_ary = new Gfo_num_fmt_bldr[src_len]; // default to src_len; will resize below;
|
||||
int src_pos = src_len, dat_idx = 0, dat_repeat = -1;
|
||||
while (true) {
|
||||
if (dat_idx == grp_ary_len) dat_idx = dat_repeat; // no more itms left; return to repeat
|
||||
Xol_num_grp dat = grp_ary[dat_idx];
|
||||
src_pos -= dat.Digits();
|
||||
if (src_pos < 1) break; // no more digits needed; stop
|
||||
byte[] dat_dlm = dat.Dlm();
|
||||
itm_ary[itm_max++] = dat_dlm.length == 1 ? new Gfo_num_fmt_bldr_one(src_pos, dat_dlm[0]) : (Gfo_num_fmt_bldr)new Gfo_num_fmt_bldr_many(src_pos, dat_dlm);
|
||||
if (dat.Repeat() && dat_repeat == -1) dat_repeat = dat_idx;
|
||||
++dat_idx;
|
||||
}
|
||||
itm_ary = (Gfo_num_fmt_bldr[])Array_.Resize(itm_ary, itm_max);
|
||||
}
|
||||
private Gfo_num_fmt_bldr[] itm_ary; private int itm_max;
|
||||
}
|
||||
interface Gfo_num_fmt_bldr {
|
||||
int Pos();
|
||||
void Gen(Bry_bfr bb);
|
||||
}
|
||||
class Gfo_num_fmt_bldr_one implements Gfo_num_fmt_bldr {
|
||||
public int Pos() {return pos;} private int pos;
|
||||
public void Gen(Bry_bfr bb) {bb.Add_byte(b);}
|
||||
public Gfo_num_fmt_bldr_one(int pos, byte b) {this.pos = pos; this.b = b;} private byte b;
|
||||
}
|
||||
class Gfo_num_fmt_bldr_many implements Gfo_num_fmt_bldr {
|
||||
public int Pos() {return pos;} private int pos;
|
||||
public void Gen(Bry_bfr bb) {bb.Add(ary);}
|
||||
public Gfo_num_fmt_bldr_many(int pos, byte[] ary) {this.pos = pos; this.ary = ary;} private byte[] ary;
|
||||
}
|
||||
/*
|
||||
DOC_1:Fmt
|
||||
. mediawiki does the following (from Language.php|commafy
|
||||
.. split the number by digitGoupingPattern: ###,###,### -> 3,3,3
|
||||
.. use regx to search for number groups
|
||||
.. for each number group, format with "," and "."
|
||||
.. replace final result with languages's decimal / grouping entry from separatorTransformTable
|
||||
. XOWA does the following
|
||||
.. iterate over bytes until non-number reached
|
||||
.. take all seen numbers and format according to lang
|
||||
*/
|
||||
118
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_fmtr_base_tst.java
Normal file
118
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_fmtr_base_tst.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import org.junit.*;
|
||||
public class Xol_num_fmtr_base_tst {
|
||||
Xol_num_fmtr_base mgr = new Xol_num_fmtr_base();
|
||||
@Before public void init() {mgr.Clear();}
|
||||
@Test public void Outliers() {
|
||||
ini_(".", dat_(",", 3));
|
||||
tst_Fmt("1234a1234" , "1,234a1,234");
|
||||
tst_Fmt("1234abc1234" , "1,234abc1,234");
|
||||
tst_Fmt("1234,1234" , "1,234,1,234");
|
||||
tst_Fmt("1234.1234" , "1,234.1234");
|
||||
tst_Fmt("1234." , "1,234.");
|
||||
tst_Fmt("1234.1234.1234.1234" , "1,234.1234.1234.1234");
|
||||
tst_Fmt("-1234567" , "-1,234,567");
|
||||
tst_Fmt("1,234,567" , "1,234,567");
|
||||
}
|
||||
@Test public void English() {
|
||||
ini_(".", dat_(",", 3));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1,234");
|
||||
tst_Fmt("12345678" , "12,345,678");
|
||||
tst_Fmt("12345678901234567890" , "12,345,678,901,234,567,890");
|
||||
tst_Raw("1,234.12" , "1234.12");
|
||||
}
|
||||
@Test public void French() {
|
||||
ini_(",", dat_(" ", 3));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1 234");
|
||||
tst_Fmt("12345678" , "12 345 678");
|
||||
tst_Fmt("12345678901234567890" , "12 345 678 901 234 567 890");
|
||||
tst_Fmt("1234,5678" , "1 234 5 678"); // NOTE: nbsp here; also, nbsp is repeated. see dewiki and {{formatnum:1234,56}}
|
||||
}
|
||||
@Test public void Croatia() {
|
||||
ini_(",", dat_(".", 3), dat_(",", 3));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1.234");
|
||||
tst_Fmt("12345678" , "12,345.678");
|
||||
tst_Fmt("12345678901234567890" , "12,345.678,901.234,567.890");
|
||||
}
|
||||
@Test public void Mexico() {
|
||||
ini_(".", dat_(",", 3, false), dat_("'", 3, false), dat_(",", 3));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1,234");
|
||||
tst_Fmt("12345678" , "12'345,678");
|
||||
tst_Fmt("12345678901234567890" , "12,345,678,901,234'567,890");
|
||||
tst_Raw("12'345,678.90" , "12345678.90");
|
||||
}
|
||||
@Test public void China() {
|
||||
ini_(".", dat_(",", 4));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1234");
|
||||
tst_Fmt("12345678" , "1234,5678");
|
||||
tst_Fmt("12345678901234567890" , "1234,5678,9012,3456,7890");
|
||||
}
|
||||
@Test public void Hindi() {
|
||||
ini_(".", dat_(",", 3, false), dat_(",", 2));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1,234");
|
||||
tst_Fmt("12345678" , "1,23,45,678");
|
||||
tst_Fmt("12345678901234567890" , "1,23,45,67,89,01,23,45,67,890");
|
||||
}
|
||||
@Test public void India() {
|
||||
ini_(".", dat_(",", 3), dat_(",", 2), dat_(",", 2));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1,234");
|
||||
tst_Fmt("12345678" , "1,23,45,678");
|
||||
tst_Fmt("12345678901234567890" , "1,23,456,78,90,123,45,67,890");
|
||||
}
|
||||
@Test public void MiddleDot() {
|
||||
ini_("·", dat_("·", 3));
|
||||
tst_Fmt("123" , "123");
|
||||
tst_Fmt("1234" , "1·234");
|
||||
tst_Fmt("12345678" , "12·345·678");
|
||||
tst_Fmt("12345678901234567890" , "12·345·678·901·234·567·890");
|
||||
tst_Fmt("1234·5678" , "1·234·5·678");// NOTE: middle-dot is repeated. see dewiki and {{formatnum:1234,5678}}
|
||||
tst_Raw("1234·5678" , "1234.5678");
|
||||
}
|
||||
Xol_num_grp dat_(String dlm, int digits) {return new Xol_num_grp(Bry_.new_u8(dlm), digits, true);}
|
||||
Xol_num_grp dat_(String dlm, int digits, boolean repeat) {return new Xol_num_grp(Bry_.new_u8(dlm), digits, repeat);}
|
||||
private void tst_Fmt(String val, String expd) {Tfds.Eq(expd, String_.new_u8(mgr.Fmt(Bry_.new_u8(val))));}
|
||||
private void tst_Raw(String val, String expd) {Tfds.Eq(expd, String_.new_u8(mgr.Raw(Xol_num_fmtr_base.Tid_raw, Bry_.new_u8(val))));}
|
||||
private void ini_(String dec_dlm, Xol_num_grp... ary) {
|
||||
mgr.Dec_dlm_(Bry_.new_u8(dec_dlm));
|
||||
int ary_len = ary.length;
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
mgr.Grps_add(ary[i]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
'france' ' 3#' ',0%' // 1 234 567,89
|
||||
'spain' '.3#' "'0%" // 1.234.567'89
|
||||
'germany' '.3#' ",0%" // 1.234.567,89
|
||||
'italy' ''3#' ",0%" // 1'234'567,89
|
||||
'en-us' ',3#' '.0%' // 1,234,567.89
|
||||
'en-sa' ',3#' '\u00120%' // 1,234,567·89
|
||||
'croatia' ',3#*' '.3#*' ',0%' // 1,234.567,890.123,45
|
||||
'china' ',4$' // 123,4567.89
|
||||
'mexico' ',3#*' "'3#" ',3#' // 1'234,567.89
|
||||
'hindi' ",2#*" ',3#' // 1,23,45,678.9
|
||||
'india' ',2#*' ',2#*' ',3#*' // 1,245,67,89,012
|
||||
*/
|
||||
26
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_grp.java
Normal file
26
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_grp.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_num_grp {
|
||||
public Xol_num_grp(byte[] dlm, int digits, boolean repeat) {this.dlm = dlm; this.digits = digits; this.repeat = repeat;}
|
||||
public byte[] Dlm() {return dlm;} private byte[] dlm;
|
||||
public int Digits() {return digits;} private int digits;
|
||||
public boolean Repeat() {return repeat;} private boolean repeat;
|
||||
public static final Xol_num_grp[] Ary_empty = new Xol_num_grp[0];
|
||||
public static final Xol_num_grp Default = new Xol_num_grp(new byte[] {Byte_ascii.Comma}, 3, true);
|
||||
}
|
||||
81
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_grp_fmtr.java
Normal file
81
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_grp_fmtr.java
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_num_grp_fmtr {
|
||||
public boolean Mode_is_regx() {return digit_grouping_pattern == null || Bry_.Eq(digit_grouping_pattern, Digit_grouping_pattern_normal);}
|
||||
public byte[] Digit_grouping_pattern() {return digit_grouping_pattern;} public void Digit_grouping_pattern_(byte[] v) {digit_grouping_pattern = v;} private byte[] digit_grouping_pattern;
|
||||
public void Clear() {digit_grouping_pattern = null;}
|
||||
public byte[] Fmt_regx(Bry_bfr bfr, byte[] src) {// NOTE: specific code to handle preg_replace( '/(\d{3})(?=\d)(?!\d*\.)/', '$1,', strrev( $number ) ) );"; DATE:2014-04-15
|
||||
int src_len = src.length;
|
||||
int bgn = 0;
|
||||
int pos = bgn;
|
||||
boolean dirty = false;
|
||||
int grp_len = 3;
|
||||
while (true) {
|
||||
if (pos == src_len) break;
|
||||
byte b = src[pos];
|
||||
switch (b) {
|
||||
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
|
||||
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9: {
|
||||
int num_end = Bry_finder.Find_fwd_while_num(src, pos, src_len);
|
||||
int num_len = num_end - pos;
|
||||
if (num_len > grp_len) {
|
||||
if (!dirty) {
|
||||
bfr.Add_mid(src, bgn, pos);
|
||||
dirty = true;
|
||||
}
|
||||
Fmt_grp(bfr, src, pos, num_end, num_len, grp_len);
|
||||
}
|
||||
else {
|
||||
if (dirty)
|
||||
bfr.Add_mid(src, pos, num_end);
|
||||
}
|
||||
pos = num_end;
|
||||
break;
|
||||
}
|
||||
case Byte_ascii.Dot: {
|
||||
int num_end = Bry_finder.Find_fwd_while_num(src, pos + 1, src_len); // +1 to skip dot
|
||||
if (dirty)
|
||||
bfr.Add_mid(src, pos, num_end);
|
||||
pos = num_end;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (dirty)
|
||||
bfr.Add_byte(b);
|
||||
++pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dirty ? bfr.Xto_bry_and_clear() : src;
|
||||
}
|
||||
private void Fmt_grp(Bry_bfr bfr, byte[] src, int bgn, int end, int len, int grp_len) {
|
||||
int seg_0 = bgn + (len % grp_len); // 5 digit number will have seg_0 of 2; 12345 -> 12,345
|
||||
for (int i = bgn; i < end; i++) {
|
||||
if ( i != bgn // never format at bgn; necessary for even multiples of grp_len (6, 9)
|
||||
&& ( i == seg_0 // seg_0
|
||||
|| (i - seg_0) % grp_len == 0 // seg_n
|
||||
)
|
||||
) {
|
||||
bfr.Add_byte(Byte_ascii.Comma); // MW: hard-coded
|
||||
}
|
||||
bfr.Add_byte(src[i]);
|
||||
}
|
||||
}
|
||||
private static final byte[] Digit_grouping_pattern_normal = Bry_.new_a7("###,###,###");
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import org.junit.*;
|
||||
public class Xol_num_grp_fmtr_tst {
|
||||
@Before public void init() {fxt.Reset();} private Xol_num_grp_fmtr_fxt fxt = new Xol_num_grp_fmtr_fxt();
|
||||
@Test public void Num() {
|
||||
fxt.Test_fmt_regx("" , "");
|
||||
fxt.Test_fmt_regx("1" , "1");
|
||||
fxt.Test_fmt_regx("12" , "12");
|
||||
fxt.Test_fmt_regx("123" , "123");
|
||||
fxt.Test_fmt_regx("1234" , "1,234");
|
||||
fxt.Test_fmt_regx("12345" , "12,345");
|
||||
fxt.Test_fmt_regx("123456" , "123,456");
|
||||
fxt.Test_fmt_regx("1234567" , "1,234,567");
|
||||
fxt.Test_fmt_regx("1234567890" , "1,234,567,890");
|
||||
}
|
||||
@Test public void Dec() {
|
||||
fxt.Test_fmt_regx("1.9876" , "1.9876");
|
||||
fxt.Test_fmt_regx("1234.9876" , "1,234.9876");
|
||||
}
|
||||
@Test public void Neg() {
|
||||
fxt.Test_fmt_regx("-1234.5678" , "-1,234.5678");
|
||||
}
|
||||
@Test public void Char() {
|
||||
fxt.Test_fmt_regx("1,234" , "1,234");
|
||||
fxt.Test_fmt_regx("1a2345" , "1a2,345");
|
||||
fxt.Test_fmt_regx("1234a5678b2345c.3456d7890e3210.f5432", "1,234a5,678b2,345c.3456d7,890e3,210.f5,432");
|
||||
}
|
||||
}
|
||||
class Xol_num_grp_fmtr_fxt {
|
||||
private Xol_num_grp_fmtr grouper = new Xol_num_grp_fmtr();
|
||||
private Bry_bfr bfr = Bry_bfr.new_();
|
||||
public void Reset() {}
|
||||
public void Test_fmt_regx(String raw, String expd) {
|
||||
byte[] actl = grouper.Fmt_regx(bfr, Bry_.new_a7(raw));
|
||||
Tfds.Eq(expd, String_.new_u8(actl));
|
||||
}
|
||||
}
|
||||
73
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_mgr.java
Normal file
73
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_mgr.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_num_mgr implements GfoInvkAble {
|
||||
private boolean digits_translate;
|
||||
protected Bry_bfr tmp_bfr = Bry_bfr.reset_(32);
|
||||
private static final byte[] Comma_bry = Bry_.new_a7(",");
|
||||
public Xol_num_grp_fmtr Num_grp_fmtr() {return num_grp_fmtr;} private Xol_num_grp_fmtr num_grp_fmtr = new Xol_num_grp_fmtr();
|
||||
public Xol_transform_mgr Separators_mgr() {return separators_mgr;} private Xol_transform_mgr separators_mgr = new Xol_transform_mgr();
|
||||
public Xol_transform_mgr Digits_mgr() {return digits_mgr;} private Xol_transform_mgr digits_mgr = new Xol_transform_mgr();
|
||||
public byte[] Raw(byte[] num) {
|
||||
if (digits_translate)
|
||||
num = digits_mgr.Replace(tmp_bfr, num, false);
|
||||
num = separators_mgr.Replace(tmp_bfr, num, false);
|
||||
num = Bry_.Replace_safe(tmp_bfr, num, Comma_bry, Bry_.Empty);
|
||||
return num;
|
||||
}
|
||||
public byte[] Format_num_no_separators(byte[] num) {return Format_num(num, true);}
|
||||
public byte[] Format_num(int val) {return Format_num(Bry_.new_a7(Int_.Xto_str(val)));}
|
||||
public byte[] Format_num(byte[] num) {return Format_num(num, false);}
|
||||
public byte[] Format_num(byte[] num, boolean skip_commafy) {
|
||||
if (!skip_commafy) {
|
||||
num = Commafy(num);
|
||||
num = separators_mgr.Replace(tmp_bfr, num, true);
|
||||
}
|
||||
if (digits_translate)
|
||||
num = digits_mgr.Replace(tmp_bfr, num, true);
|
||||
return num;
|
||||
}
|
||||
@gplx.Virtual public byte[] Commafy(byte[] num_bry) {
|
||||
if (num_bry == null) return Bry_.Empty; // MW: if ( $number === null ) return '';
|
||||
if (num_grp_fmtr.Mode_is_regx())
|
||||
return num_grp_fmtr.Fmt_regx(tmp_bfr, num_bry);
|
||||
else // NOTE: for now, return same as ###,###,###; only affects 12 languages; current implementation is bad; https://bugzilla.wikimedia.org/show_bug.cgi?id=63977
|
||||
return num_grp_fmtr.Fmt_regx(tmp_bfr, num_bry);
|
||||
}
|
||||
public Xol_num_mgr Clear() {
|
||||
digits_mgr.Clear();
|
||||
separators_mgr.Clear();
|
||||
num_grp_fmtr.Clear();
|
||||
return this;
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_clear)) this.Clear();
|
||||
else if (ctx.Match(k, Invk_separators)) return separators_mgr;
|
||||
else if (ctx.Match(k, Invk_digits)) {digits_translate = true; return digits_mgr;} // NOTE: only langes with a digit_transform_table will call digits; DATE:2014-05-28
|
||||
else if (ctx.Match(k, Invk_digit_grouping_pattern)) return String_.new_u8(num_grp_fmtr.Digit_grouping_pattern());
|
||||
else if (ctx.Match(k, Invk_digit_grouping_pattern_)) num_grp_fmtr.Digit_grouping_pattern_(m.ReadBry("v"));
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
public static final String Invk_clear = "clear", Invk_separators = "separators"
|
||||
, Invk_digits = "digits", Invk_digit_grouping_pattern = "digit_grouping_pattern", Invk_digit_grouping_pattern_ = "digit_grouping_pattern_";
|
||||
public static final byte[]
|
||||
Separators_key__grp = new byte[]{Byte_ascii.Comma}
|
||||
, Separators_key__dec = new byte[]{Byte_ascii.Dot}
|
||||
;
|
||||
}
|
||||
40
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_mgr_.java
Normal file
40
400_xowa/src/gplx/xowa/langs/numbers/Xol_num_mgr_.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_num_mgr_ {
|
||||
public static Xol_num_mgr new_by_lang_id(int lang_id) {
|
||||
switch (lang_id) {
|
||||
case Xol_lang_itm_.Id_be_tarask:
|
||||
case Xol_lang_itm_.Id_bg:
|
||||
case Xol_lang_itm_.Id_ru:
|
||||
case Xol_lang_itm_.Id_pl:
|
||||
case Xol_lang_itm_.Id_uk:
|
||||
case Xol_lang_itm_.Id_es:
|
||||
case Xol_lang_itm_.Id_et:
|
||||
case Xol_lang_itm_.Id_hy:
|
||||
case Xol_lang_itm_.Id_kaa:
|
||||
case Xol_lang_itm_.Id_kk_cyrl:
|
||||
case Xol_lang_itm_.Id_ksh:
|
||||
// case Xol_lang_itm_.Id_ku_ku:
|
||||
return new Xol_num_mgr__commafy_5();
|
||||
case Xol_lang_itm_.Id_km:
|
||||
case Xol_lang_itm_.Id_my: return new Xol_num_mgr__noop();
|
||||
default: return new Xol_num_mgr();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
class Xol_num_mgr__commafy_5 extends Xol_num_mgr { @Override public byte[] Commafy(byte[] num) {
|
||||
if (Bry_.Len_eq_0(num)) return num; // bounds check
|
||||
int num_len = num.length;
|
||||
int num_bgn = 0;
|
||||
byte b = num[num_bgn];
|
||||
if (b == Byte_ascii.Dash) {
|
||||
if (num_len == 1) return num; // bounds check
|
||||
b = num[++num_bgn]; // skip negative sign
|
||||
}
|
||||
if (Byte_ascii.Is_num(b)) { // check for preg_match( '/^-?\d{1,4}(\.\d+)?$/', $_ )
|
||||
int num_end = Bry_finder.Find_fwd_while_num(num, num_bgn, num_len);
|
||||
if (num_end - num_bgn < 5) { // 1-4 digits
|
||||
if (num_end == num_len) return num; // no decimal; exit
|
||||
b = num[num_end];
|
||||
if ( b == Byte_ascii.Dot
|
||||
&& num_end != num_len - 1) { // if dot at end, then no match on above regx; fall-thru to below
|
||||
num_end = Bry_finder.Find_fwd_while_num(num, num_end + 1, num_len);
|
||||
if (num_end == num_len) return num; // only numbers after dot; matches regx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.Num_grp_fmtr().Fmt_regx(tmp_bfr, num); // otherwise do default grouping; '/(\d{3})(?=\d)(?!\d*\.)/', '$1,'
|
||||
}
|
||||
}
|
||||
class Xol_num_mgr__noop extends Xol_num_mgr { @Override public byte[] Commafy(byte[] num) {return num;}
|
||||
}
|
||||
54
400_xowa/src/gplx/xowa/langs/numbers/Xol_transform_mgr.java
Normal file
54
400_xowa/src/gplx/xowa/langs/numbers/Xol_transform_mgr.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
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.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import gplx.core.btries.*;
|
||||
public class Xol_transform_mgr implements GfoInvkAble {
|
||||
private Btrie_fast_mgr trie_k_to_v = Btrie_fast_mgr.cs_();
|
||||
private Btrie_fast_mgr trie_v_to_k = Btrie_fast_mgr.cs_();
|
||||
private Ordered_hash hash = Ordered_hash_.new_bry_();
|
||||
private boolean empty = true;
|
||||
public void Clear() {hash.Clear(); trie_k_to_v.Clear(); trie_v_to_k.Clear(); empty = true;}
|
||||
public int Len() {return hash.Count();}
|
||||
public KeyVal Get_at(int i) {return (KeyVal)hash.Get_at(i);}
|
||||
public byte[] Get_val_or_self(byte[] k) { // NOTE: return self; note that MW defaults "." and "," to self, even though MessagesLa.php only specifies ","; i.e.: always return something for "."; DATE:2014-05-13
|
||||
KeyVal kv = (KeyVal)hash.Get_by(k);
|
||||
return kv == null ? k : (byte[])kv.Val();
|
||||
}
|
||||
public Xol_transform_mgr Set(byte[] k, byte[] v) {
|
||||
trie_k_to_v.Add(k, v);
|
||||
trie_v_to_k.Add(v, k);
|
||||
KeyVal kv = KeyVal_.new_(String_.new_u8(k), v);
|
||||
hash.Del(k);
|
||||
hash.Add(k, kv);
|
||||
empty = false;
|
||||
return this;
|
||||
}
|
||||
public byte[] Replace(Bry_bfr tmp_bfr, byte[] src, boolean k_to_v) {
|
||||
if (empty || src == null) return src;
|
||||
int src_len = src.length; if (src_len == 0) return src;
|
||||
Btrie_fast_mgr trie = k_to_v ? trie_k_to_v : trie_v_to_k;
|
||||
return trie.Replace(tmp_bfr, src, 0, src_len);
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_set)) Set(m.ReadBry("k"), m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_clear)) Clear();
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
public static final String Invk_set = "set", Invk_clear = "clear";
|
||||
}
|
||||
21
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural.java
Normal file
21
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural.java
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
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.plurals; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public interface Xol_plural {
|
||||
byte[] Plural_eval(Xol_lang lang, int count, byte[][] words);
|
||||
}
|
||||
44
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural_.java
Normal file
44
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural_.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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.plurals; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_plural_ {
|
||||
public static Xol_plural new_by_lang_id(int lang_id) {
|
||||
switch (lang_id) {
|
||||
case Xol_lang_itm_.Id_ru: return Xol_plural_ru._;
|
||||
default: return Xol_plural__default._;
|
||||
}
|
||||
}
|
||||
public static byte[][] Fill_ary(byte[][] words, int words_len, int reqd_len) {// convert words to an ary of at least reqd_len where new entries are filled with last item; EX: {"a", "b"}, 3 -> {"a", "b", "b"}
|
||||
byte[][] rv = new byte[reqd_len][];
|
||||
byte[] last = words[words_len - 1];
|
||||
for (int i = 0; i < reqd_len; i++)
|
||||
rv[i] = i < words_len ? words[i] : last;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
class Xol_plural__default implements Xol_plural {
|
||||
public byte[] Plural_eval(Xol_lang lang, int count, byte[][] forms) {
|
||||
int forms_len = forms.length;
|
||||
switch (forms_len) {
|
||||
case 0: return Bry_.Empty; // forms is empty; do nothing
|
||||
case 1: return forms[0]; // only one word specified; use it; REF.MW:$pluralForm = min( $pluralForm, count( $forms ) - 1 );
|
||||
default: return count == 1 ? forms[0] : forms[1]; // TODO: incorporate plurals.xml logic
|
||||
}
|
||||
}
|
||||
public static final Xol_plural__default _ = new Xol_plural__default(); Xol_plural__default() {}
|
||||
}
|
||||
40
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural_ru.java
Normal file
40
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural_ru.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.plurals; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
public class Xol_plural_ru implements Xol_plural {
|
||||
public byte[] Plural_eval(Xol_lang lang, int count, byte[][] forms) {
|
||||
int forms_len = forms.length;
|
||||
switch (forms_len) {
|
||||
case 0: return null; // forms is empty; do nothing
|
||||
case 2: return count == 1 ? forms[0] : forms[1];
|
||||
default: { // either 1, 3, or >3;
|
||||
if (forms_len == 1) forms = Xol_plural_.Fill_ary(forms, forms_len, 3);
|
||||
if (count > 10 && ((count % 100) / 10) == 1)
|
||||
return forms[2];
|
||||
else {
|
||||
switch (count % 10) {
|
||||
case 1: return forms[0];
|
||||
case 2: case 3: case 4: return forms[1];
|
||||
default: return forms[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static final Xol_plural_ru _ = new Xol_plural_ru(); Xol_plural_ru() {}
|
||||
}
|
||||
35
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural_ru_tst.java
Normal file
35
400_xowa/src/gplx/xowa/langs/plurals/Xol_plural_ru_tst.java
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
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.plurals; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*;
|
||||
import org.junit.*;
|
||||
public class Xol_plural_ru_tst {
|
||||
@Test public void Plural() {
|
||||
Tst(1, String_.Ary_empty, null); // 0 forms
|
||||
Tst(1, String_.Ary("a", "b"), "a"); // 2 forms; singluar
|
||||
Tst(2, String_.Ary("a", "b"), "b"); // 2 forms; plural
|
||||
Tst(111, String_.Ary("a", "b", "c"), "c"); // 3 forms; (count % 100) / 10 == 0; should not return "a"
|
||||
Tst(1, String_.Ary("a", "b", "c"), "a"); // 3 forms; count % 10 == 1
|
||||
Tst(2, String_.Ary("a", "b", "c"), "b"); // 3 forms; count % 10 == (2, 3, 4)
|
||||
Tst(5, String_.Ary("a", "b", "c"), "c"); // 3 forms; count % 10 != (1, 2, 3, 4)
|
||||
Tst(5, String_.Ary("a"), "a"); // 1 form; count % 10 != (1, 2, 3, 4); but only 1 element, so take 1st
|
||||
}
|
||||
private void Tst(int count, String[] forms, String expd) {
|
||||
byte[] actl = Xol_plural_ru._.Plural_eval(null, count, Bry_.Ary(forms));
|
||||
Tfds.Eq_bry(Bry_.new_a7(expd), actl);
|
||||
}
|
||||
}
|
||||
74
400_xowa/src/gplx/xowa/langs/vnts/Xol_vnt_converter.java
Normal file
74
400_xowa/src/gplx/xowa/langs/vnts/Xol_vnt_converter.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
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.core.btries.*; import gplx.intl.*;
|
||||
import gplx.xowa.langs.cnvs.*;
|
||||
public class Xol_vnt_converter {
|
||||
private Btrie_slim_mgr trie = Btrie_slim_mgr.cs_();
|
||||
public Xol_vnt_converter(Xol_vnt_itm owner) {this.owner = owner;}
|
||||
public byte[] Owner_key() {return owner.Key();}
|
||||
public Xol_vnt_itm Owner() {return owner;} private Xol_vnt_itm owner;
|
||||
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;
|
||||
boolean matched = false;
|
||||
while (pos < end) {
|
||||
byte b = src[pos];
|
||||
Object o = trie.Match_bgn_w_byte(b, src, pos, end);
|
||||
if (o == null) { // no match; skip to next char
|
||||
int char_len = Utf8_.Len_of_char_by_1st_byte(b); // NOTE: must increment by char_len, not +1
|
||||
if (matched) {
|
||||
if (char_len == 1)
|
||||
bfr.Add_byte(b);
|
||||
else
|
||||
bfr.Add_mid(src, pos, pos + char_len);
|
||||
}
|
||||
pos += char_len;
|
||||
}
|
||||
else {
|
||||
if (!matched) {
|
||||
bfr.Add_mid(src, bgn, pos); // add everything up to pos
|
||||
matched = true;
|
||||
}
|
||||
bfr.Add((byte[])o);
|
||||
pos = trie.Match_pos();
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
public void Rebuild() {Clear(); Build();}
|
||||
private void Clear() {trie.Clear();}
|
||||
private void Build() {
|
||||
Xol_lang lang = owner.Lang();
|
||||
byte[][] convert_ary = owner.Convert_ary();
|
||||
int convert_ary_len = convert_ary.length;
|
||||
for (int i = 0; i < convert_ary_len; i++) {
|
||||
byte[] convert_grp_key = convert_ary[i];
|
||||
Xol_cnv_grp convert_grp = lang.Cnv_mgr().Get_or_null(convert_grp_key);
|
||||
if (convert_grp == null) continue; // vnts may not have convert mapping; EX: zh-my
|
||||
Build_grp(convert_grp);
|
||||
}
|
||||
}
|
||||
private void Build_grp(Xol_cnv_grp convert_grp) {
|
||||
int len = convert_grp.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xol_cnv_itm convert_itm = convert_grp.Get_at(i);
|
||||
trie.Add_obj(convert_itm.Src(), convert_itm.Trg()); // NOTE: for dupes, latest value wins
|
||||
}
|
||||
}
|
||||
}
|
||||
40
400_xowa/src/gplx/xowa/langs/vnts/Xol_vnt_itm.java
Normal file
40
400_xowa/src/gplx/xowa/langs/vnts/Xol_vnt_itm.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.intl.*;
|
||||
import gplx.xowa.langs.cnvs.*;
|
||||
public class Xol_vnt_itm implements GfoInvkAble {
|
||||
public Xol_vnt_itm(Xol_vnt_mgr owner, byte[] key) {
|
||||
this.owner = owner;
|
||||
this.lang = owner.Lang(); this.key = key;
|
||||
converter = new Xol_vnt_converter(this);
|
||||
}
|
||||
public Xol_vnt_mgr Owner() {return owner;} private Xol_vnt_mgr owner;
|
||||
public Xol_lang Lang() {return lang;} private Xol_lang lang;
|
||||
public Xol_vnt_converter Converter() {return converter;} private Xol_vnt_converter converter;
|
||||
public byte[] Key() {return key;} private byte[] key;
|
||||
public byte[][] Fallback_ary() {return fallback_ary;} private byte[][] fallback_ary = Bry_.Ary_empty;
|
||||
public byte[][] Convert_ary() {return convert_ary;} private byte[][] convert_ary = Bry_.Ary_empty;
|
||||
public void Convert_ary_(byte[][] v) {convert_ary = v;}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_fallbacks_)) fallback_ary = Bry_.Split(m.ReadBry("v"), Byte_ascii.Pipe);
|
||||
else if (ctx.Match(k, Invk_converts_)) {convert_ary = Bry_.Split(m.ReadBry("v"), Byte_ascii.Pipe); converter.Rebuild();} // setting converts will always force rebuild
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_fallbacks_ = "fallbacks_", Invk_converts_ = "converts_";
|
||||
}
|
||||
105
400_xowa/src/gplx/xowa/langs/vnts/Xol_vnt_mgr.java
Normal file
105
400_xowa/src/gplx/xowa/langs/vnts/Xol_vnt_mgr.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
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.wikis.data.tbls.*;
|
||||
public class Xol_vnt_mgr implements GfoInvkAble {
|
||||
private Ordered_hash vnts = Ordered_hash_.new_bry_();
|
||||
private int converter_ary_len; private Ordered_hash tmp_page_list = Ordered_hash_.new_bry_();
|
||||
public Xol_vnt_mgr(Xol_lang lang) {this.lang = lang;}
|
||||
public Xol_vnt_converter[] Converter_ary() {return converter_ary;} private Xol_vnt_converter[] converter_ary;
|
||||
public Xolg_vnt_grp Vnt_grp() {return vnt_grp;} private Xolg_vnt_grp vnt_grp = new Xolg_vnt_grp();
|
||||
public Xolg_vnt_grp_fmtr Vnt_mnu_fmtr() {return vnt_mnu_fmtr;} private Xolg_vnt_grp_fmtr vnt_mnu_fmtr = new Xolg_vnt_grp_fmtr();
|
||||
public Xol_lang Lang() {return lang;} private Xol_lang lang;
|
||||
public byte[] Cur_vnt() {return cur_vnt;} public Xol_vnt_mgr Cur_vnt_(byte[] v) {cur_vnt = v; return this;} private byte[] cur_vnt = Bry_.Empty;
|
||||
public boolean Enabled() {return enabled;} public void Enabled_(boolean v) {this.enabled = v;} private boolean enabled = false;
|
||||
public String Html_style() {return html_style;} private String html_style = "";
|
||||
public void Init_by_wiki(Xowe_wiki wiki) {
|
||||
if (!enabled) return;
|
||||
Xop_vnt_lxr_.set_(wiki);
|
||||
// VNT
|
||||
// vnt_grp.Add(new Xolg_vnt_itm(Bry_.new_u8("zh-hans"), Bry_.new_u8("Simplified")));
|
||||
// vnt_grp.Add(new Xolg_vnt_itm(Bry_.new_u8("zh-hant"), Bry_.new_u8("Traditional")));
|
||||
// vnt_grp.Add(new Xolg_vnt_itm(Bry_.new_u8("zh-cn"), Bry_.new_u8("China")));
|
||||
// vnt_grp.Add(new Xolg_vnt_itm(Bry_.new_u8("zh-hk"), Bry_.new_u8("Hong Kong")));
|
||||
// vnt_grp.Add(new Xolg_vnt_itm(Bry_.new_u8("zh-mo"), Bry_.new_u8("Macau")));
|
||||
// vnt_grp.Add(new Xolg_vnt_itm(Bry_.new_u8("zh-sg"), Bry_.new_u8("Singapore")));
|
||||
// vnt_grp.Add(new Xolg_vnt_itm(Bry_.new_u8("zh-tw"), Bry_.new_u8("Taiwan")));
|
||||
}
|
||||
public Xol_vnt_itm Get_or_new(byte[] key) {
|
||||
Xol_vnt_itm rv = (Xol_vnt_itm)vnts.Get_by(key);
|
||||
if (rv == null) {
|
||||
rv = new Xol_vnt_itm(this, key);
|
||||
vnts.Add(key, rv);
|
||||
enabled = true; // mark enabled if any vnts have been added
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public void Convert_ttl_init() {
|
||||
int vnts_len = vnts.Count();
|
||||
converter_ary_len = vnts_len;
|
||||
converter_ary = new Xol_vnt_converter[vnts_len];
|
||||
for (int i = 0; i < vnts_len; i++) {
|
||||
Xol_vnt_itm itm = (Xol_vnt_itm)vnts.Get_at(i);
|
||||
converter_ary[i] = itm.Converter();
|
||||
if (i == 0) cur_vnt = itm.Key(); // default to 1st item
|
||||
}
|
||||
}
|
||||
public Xowd_page_itm Convert_ttl(Xowe_wiki wiki, Xoa_ttl ttl) {return Convert_ttl(wiki, ttl.Ns(), ttl.Page_db());} // NOTE: not Full_db as ttl.Ns is passed; EX:Шаблон:Šablon:Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
|
||||
public Xowd_page_itm Convert_ttl(Xowe_wiki wiki, Xow_ns ns, byte[] ttl_bry) {
|
||||
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512();
|
||||
Xowd_page_itm rv = Convert_ttl(wiki, tmp_bfr, ns, ttl_bry);
|
||||
tmp_bfr.Mkr_rls();
|
||||
return rv;
|
||||
}
|
||||
public Xowd_page_itm Convert_ttl(Xowe_wiki wiki, Bry_bfr tmp_bfr, Xow_ns ns, byte[] ttl_bry) { // REF.MW:LanguageConverter.php|findVariantLink
|
||||
int converted = Convert_ttl_convert(wiki, tmp_bfr, ns, ttl_bry); // convert ttl for each vnt
|
||||
if (converted == 0) return Xowd_page_itm.Null; // ttl_bry has no conversions; exit;
|
||||
wiki.Db_mgr().Load_mgr().Load_by_ttls(Cancelable_.Never, tmp_page_list, true, 0, converted);
|
||||
for (int i = 0; i < converted; i++) {
|
||||
Xowd_page_itm page = (Xowd_page_itm)tmp_page_list.Get_at(i);
|
||||
if (page.Exists()) return page; // return 1st found page
|
||||
}
|
||||
return Xowd_page_itm.Null;
|
||||
}
|
||||
private int Convert_ttl_convert(Xowe_wiki wiki, Bry_bfr tmp_bfr, Xow_ns ns, byte[] ttl_bry) {
|
||||
tmp_page_list.Clear();
|
||||
int rv = 0;
|
||||
for (int i = 0; i < converter_ary_len; i++) { // convert ttl for each variant
|
||||
Xol_vnt_converter converter = converter_ary[i];
|
||||
tmp_bfr.Clear();
|
||||
if (!converter.Convert_text(tmp_bfr, ttl_bry)) continue; // ttl is not converted for variant; ignore
|
||||
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ns.Id(), tmp_bfr.Xto_bry_and_clear()); // NOTE: must convert to ttl in order to upper 1st letter; EX:{{jez-eng|sense}} -> Jez-eng; PAGE:sr.w:ДНК DATE:2014-07-06
|
||||
if (ttl == null) continue;
|
||||
Xowd_page_itm page = new Xowd_page_itm();
|
||||
page.Ttl_(ns, ttl.Page_db());
|
||||
byte[] converted_ttl = page.Ttl_full_db();
|
||||
if (tmp_page_list.Has(converted_ttl)) continue;
|
||||
tmp_page_list.Add(converted_ttl, page);
|
||||
++rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_get)) return Get_or_new(m.ReadBry("v"));
|
||||
else if (ctx.Match(k, Invk_init_end)) Convert_ttl_init();
|
||||
else if (ctx.Match(k, Invk_cur_vnt_)) cur_vnt = m.ReadBry("v");
|
||||
else if (ctx.Match(k, Invk_html_style_)) html_style = m.ReadStr("v");
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
} private static final String Invk_get = "get", Invk_init_end = "init_end", Invk_cur_vnt_ = "cur_vnt_", Invk_html_style_ = "html_style_";
|
||||
}
|
||||
25
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_grp.java
Normal file
25
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_grp.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
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 Xolg_vnt_grp {
|
||||
private final List_adp list = List_adp_.new_();
|
||||
public byte[] Text() {return text;} public void Text_(byte[] v) {text = v;} private byte[] text;
|
||||
public int Len() {return list.Count();}
|
||||
public Xolg_vnt_itm Get_at(int i) {return (Xolg_vnt_itm)list.Get_at(i);}
|
||||
public void Add(Xolg_vnt_itm itm) {list.Add(itm);}
|
||||
}
|
||||
58
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_grp_fmtr.java
Normal file
58
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_grp_fmtr.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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 Xolg_vnt_grp_fmtr implements Bry_fmtr_arg {
|
||||
private Xolg_vnt_grp grp;
|
||||
private Xolg_vnt_itm_fmtr itm_fmtr = new Xolg_vnt_itm_fmtr();
|
||||
public void Init(Xolg_vnt_grp grp, byte[] page_href, byte[] page_vnt) {
|
||||
this.grp = grp;
|
||||
itm_fmtr.Init(grp, page_href, page_vnt);
|
||||
}
|
||||
public void XferAry(Bry_bfr bfr, int idx) {
|
||||
fmtr.Bld_bfr_many(bfr, grp.Text(), itm_fmtr);
|
||||
}
|
||||
private static final Bry_fmtr fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
|
||||
( " <div id='p-variants' role='navigation' class='vectorMenu' aria-labelledby='p-variants-label'>"
|
||||
, " <h3 id='p-variants-label'><span>~{grp_text}</span><a href='#'></a></h3>"
|
||||
, " <div class='menu'>"
|
||||
, " <ul>~{itms}"
|
||||
, " </ul>"
|
||||
, " </div>"
|
||||
, " </div>"
|
||||
), "grp_text", "itms"
|
||||
);
|
||||
}
|
||||
class Xolg_vnt_itm_fmtr implements Bry_fmtr_arg {
|
||||
private Xolg_vnt_grp grp; private byte[] page_href, page_vnt;
|
||||
public void Init(Xolg_vnt_grp grp, byte[] page_href, byte[] page_vnt) {this.grp = grp; this.page_href = page_href; this.page_vnt = page_vnt;}
|
||||
public void XferAry(Bry_bfr bfr, int idx) {
|
||||
int len = grp.Len();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
Xolg_vnt_itm itm = grp.Get_at(i);
|
||||
boolean itm_is_selected = Bry_.Eq(itm.Key(), page_vnt);
|
||||
byte[] itm_cls_selected = itm_is_selected ? Itm_cls_selected_y : Bry_.Empty;
|
||||
fmtr.Bld_bfr_many(bfr, i, itm_cls_selected, itm.Key(), itm.Text(), page_href);
|
||||
}
|
||||
}
|
||||
private static final byte[] Itm_cls_selected_y = Bry_.new_a7(" class='selected'");
|
||||
private static final Bry_fmtr fmtr = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
|
||||
( ""
|
||||
, " <li id='ca-varlang-~{itm_idx}'~{itm_cls_selected}><a href='/wiki/~{itm_href}?xowa_vnt=~{itm_lang}' lang='~{itm_lang}' hreflang='~{itm_lang}'>~{itm_text}</a></li>"
|
||||
), "itm_idx", "itm_cls_selected", "itm_lang", "itm_text", "itm_href"
|
||||
);
|
||||
}
|
||||
68
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_grp_fmtr_tst.java
Normal file
68
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_grp_fmtr_tst.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
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 org.junit.*;
|
||||
public class Xolg_vnt_grp_fmtr_tst {
|
||||
@Before public void init() {fxt.Clear();} private final Xolg_vnt_grp_fmtr_fxt fxt = new Xolg_vnt_grp_fmtr_fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Test_to_str("Earth", "zh-hk", String_.Concat_lines_nl_skip_last
|
||||
( " <div id='p-variants' role='navigation' class='vectorMenu' aria-labelledby='p-variants-label'>"
|
||||
, " <h3 id='p-variants-label'><span>Choose lang</span><a href='#'></a></h3>"
|
||||
, " <div class='menu'>"
|
||||
, " <ul>"
|
||||
, " <li id='ca-varlang-0'><a href='/wiki/Earth?xowa_vnt=zh-hans' lang='zh-hans' hreflang='zh-hans'>Simplified</a></li>"
|
||||
, " <li id='ca-varlang-1'><a href='/wiki/Earth?xowa_vnt=zh-hant' lang='zh-hant' hreflang='zh-hant'>Traditional</a></li>"
|
||||
, " <li id='ca-varlang-2'><a href='/wiki/Earth?xowa_vnt=zh-cn' lang='zh-cn' hreflang='zh-cn'>China</a></li>"
|
||||
, " <li id='ca-varlang-3' class='selected'><a href='/wiki/Earth?xowa_vnt=zh-hk' lang='zh-hk' hreflang='zh-hk'>Hong Kong</a></li>"
|
||||
, " <li id='ca-varlang-4'><a href='/wiki/Earth?xowa_vnt=zh-mo' lang='zh-mo' hreflang='zh-mo'>Macau</a></li>"
|
||||
, " <li id='ca-varlang-5'><a href='/wiki/Earth?xowa_vnt=zh-sg' lang='zh-sg' hreflang='zh-sg'>Singapore</a></li>"
|
||||
, " <li id='ca-varlang-6'><a href='/wiki/Earth?xowa_vnt=zh-tw' lang='zh-tw' hreflang='zh-tw'>Taiwan</a></li>"
|
||||
, " </ul>"
|
||||
, " </div>"
|
||||
, " </div>"
|
||||
));
|
||||
}
|
||||
}
|
||||
class Xolg_vnt_grp_fmtr_fxt {
|
||||
private Xolg_vnt_grp vnt_grp;
|
||||
public void Clear() {
|
||||
this.Init_grp("Choose lang", "zh-hans", "Simplified", "zh-hant", "Traditional", "zh-cn", "China", "zh-hk", "Hong Kong", "zh-mo", "Macau", "zh-sg", "Singapore", "zh-tw", "Taiwan");
|
||||
}
|
||||
public void Init_grp(String text, String... langs) {
|
||||
vnt_grp = new Xolg_vnt_grp();
|
||||
vnt_grp.Text_(Bry_.new_u8(text));
|
||||
int len = langs.length;
|
||||
String lang_code = "";
|
||||
for (int i = 0; i < len; ++i) {
|
||||
String lang = langs[i];
|
||||
if (i % 2 == 0)
|
||||
lang_code = lang;
|
||||
else {
|
||||
Xolg_vnt_itm itm = new Xolg_vnt_itm(Bry_.new_u8(lang_code), Bry_.new_u8(lang));
|
||||
vnt_grp.Add(itm);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Test_to_str(String page_href, String selected_vnt, String expd) {
|
||||
Xolg_vnt_grp_fmtr vnt_grp_fmtr = new Xolg_vnt_grp_fmtr();
|
||||
Bry_bfr bfr = Bry_bfr.new_();
|
||||
vnt_grp_fmtr.Init(vnt_grp, Bry_.new_u8(page_href), Bry_.new_u8(selected_vnt));
|
||||
vnt_grp_fmtr.XferAry(bfr, 0);
|
||||
Tfds.Eq_str_lines(expd, bfr.Xto_str_and_clear());
|
||||
}
|
||||
}
|
||||
23
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_itm.java
Normal file
23
400_xowa/src/gplx/xowa/langs/vnts/Xolg_vnt_itm.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
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 Xolg_vnt_itm {
|
||||
public Xolg_vnt_itm(byte[] key, byte[] text) {this.key = key; this.text = text;}
|
||||
public byte[] Key() {return key;} private final byte[] key;
|
||||
public byte[] Text() {return text;} private final byte[] text;
|
||||
}
|
||||
22
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_eqgt_tkn.java
Normal file
22
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_eqgt_tkn.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
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 Xop_vnt_eqgt_tkn extends Xop_tkn_itm_base {
|
||||
public Xop_vnt_eqgt_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_vnt_eqgt;}
|
||||
}
|
||||
124
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_flag.java
Normal file
124
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_flag.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
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.core.btries.*;
|
||||
public class Xop_vnt_flag {
|
||||
public Xop_vnt_flag(byte tid) {this.tid = tid; this.langs = Bry_.Ary_empty;}
|
||||
public Xop_vnt_flag(byte tid, byte[][] langs) {this.tid = tid; this.langs = langs;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[][] Langs() {return langs;} private byte[][] langs;
|
||||
}
|
||||
class Xop_vnt_flag_ {
|
||||
public static final Xop_vnt_flag[] Ary_empty = new Xop_vnt_flag[0];
|
||||
public static final byte
|
||||
Tid_unknown = 0
|
||||
, Tid_show = 1 // EX: -{S|zh-hans:A;zh-hant:B}- -> "A"
|
||||
, Tid_all = 2 // EX: -{+|zh-hans:A;zh-hant:B}- -> "A"
|
||||
, Tid_err = 3 // EX: -{E|zh-hans:A;zh-hant:B}- -> "A"
|
||||
, Tid_add = 4 // add and output; EX: -{A|zh-hans:A;zh-hant:B}- -> "A"
|
||||
, Tid_title = 5 // page_title; EX: -{T|zh-hans:A;zh-hant:B}- -> ""
|
||||
, Tid_raw = 6 // raw: no convert; EX: -{R|zh-hans:A;zh-hant:B}- -> "zh-hans:A;zh-hant:B"
|
||||
, Tid_descrip = 7 // describe; EX: -{D|zh-hans:A;zh-hant:B}- -> "简体:A;繁體:B;" (简体=Simplified;繁體=Traditional)
|
||||
, Tid_del = 8 // remove; EX: -{-|zh-hans:A;zh-hant:B}- -> ""
|
||||
, Tid_macro = 9 // macro; EX: -{H|zh-hans:A;zh-hant:B}- -> ""
|
||||
, Tid_name = 10 // EX: -{N|zh-hans:A;zh-hant:B}- -> ""
|
||||
, Tid_lang = 11 // EX: -{zh-hant|B}- -> "B"
|
||||
;
|
||||
public static String Xto_name(byte tid) {
|
||||
switch (tid) {
|
||||
case Tid_unknown: return "unknown";
|
||||
case Tid_show : return "show";
|
||||
case Tid_all : return "all";
|
||||
case Tid_err : return "err";
|
||||
case Tid_add : return "add";
|
||||
case Tid_title : return "title";
|
||||
case Tid_raw : return "raw";
|
||||
case Tid_descrip: return "descrip";
|
||||
case Tid_del : return "del";
|
||||
case Tid_macro : return "macro";
|
||||
case Tid_name : return "name";
|
||||
case Tid_lang : return "lang";
|
||||
default : throw Exc_.new_unhandled(tid);
|
||||
}
|
||||
}
|
||||
public static final byte Tid__max = 12;
|
||||
public static final byte
|
||||
Key_show = Byte_ascii.Ltr_S
|
||||
, Key_all = Byte_ascii.Plus
|
||||
, Key_err = Byte_ascii.Ltr_E
|
||||
, Key_add = Byte_ascii.Ltr_A
|
||||
, Key_title = Byte_ascii.Ltr_T
|
||||
, Key_raw = Byte_ascii.Ltr_R
|
||||
, Key_descrip = Byte_ascii.Ltr_D
|
||||
, Key_del = Byte_ascii.Dash
|
||||
, Key_macro = Byte_ascii.Ltr_H
|
||||
, Key_name = Byte_ascii.Ltr_N
|
||||
;
|
||||
public static final Xop_vnt_flag
|
||||
Flag_unknown = new Xop_vnt_flag(Tid_unknown)
|
||||
, Flag_show = new Xop_vnt_flag(Tid_show)
|
||||
, Flag_all = new Xop_vnt_flag(Tid_all)
|
||||
, Flag_err = new Xop_vnt_flag(Tid_err)
|
||||
, Flag_add = new Xop_vnt_flag(Tid_add)
|
||||
, Flag_title = new Xop_vnt_flag(Tid_title)
|
||||
, Flag_raw = new Xop_vnt_flag(Tid_raw)
|
||||
, Flag_descrip = new Xop_vnt_flag(Tid_descrip)
|
||||
, Flag_del = new Xop_vnt_flag(Tid_del)
|
||||
, Flag_macro = new Xop_vnt_flag(Tid_macro)
|
||||
, Flag_name = new Xop_vnt_flag(Tid_name)
|
||||
;
|
||||
public static final Btrie_fast_mgr Trie = Btrie_fast_mgr.ci_ascii_() // NOTE: match either lc or uc; EX: -{D}- or -{d}-; // NOTE:ci.ascii:MW_const.en; flag keys; EX: -{S|a}-
|
||||
.Add(Byte_ascii.Ltr_S , Xop_vnt_flag_.Flag_show)
|
||||
.Add(Byte_ascii.Plus , Xop_vnt_flag_.Flag_all)
|
||||
.Add(Byte_ascii.Ltr_E , Xop_vnt_flag_.Flag_err)
|
||||
.Add(Byte_ascii.Ltr_A , Xop_vnt_flag_.Flag_add)
|
||||
.Add(Byte_ascii.Ltr_T , Xop_vnt_flag_.Flag_title)
|
||||
.Add(Byte_ascii.Ltr_R , Xop_vnt_flag_.Flag_raw)
|
||||
.Add(Byte_ascii.Ltr_D , Xop_vnt_flag_.Flag_descrip)
|
||||
.Add(Byte_ascii.Dash , Xop_vnt_flag_.Flag_del)
|
||||
.Add(Byte_ascii.Ltr_H , Xop_vnt_flag_.Flag_macro)
|
||||
.Add(Byte_ascii.Ltr_N , Xop_vnt_flag_.Flag_name)
|
||||
;
|
||||
public static Xop_vnt_flag new_langs_(byte[][] langs) {return new Xop_vnt_flag(Tid_lang, langs);}
|
||||
}
|
||||
class Xop_vnt_flag_ary_bldr {
|
||||
private Xop_vnt_flag[] ary = new Xop_vnt_flag[Xop_vnt_flag_.Tid__max];
|
||||
private int add_count = 0;
|
||||
public void Clear() {
|
||||
for (int i = 0; i < Xop_vnt_flag_.Tid__max; i++)
|
||||
ary[i] = null;
|
||||
add_count = 0;
|
||||
}
|
||||
public void Add(Xop_vnt_flag flag) {
|
||||
int idx = flag.Tid();
|
||||
if (ary[idx] == null) {
|
||||
ary[idx] = flag;
|
||||
++add_count;
|
||||
}
|
||||
}
|
||||
public Xop_vnt_flag[] Bld() {
|
||||
Xop_vnt_flag[] rv = new Xop_vnt_flag[add_count];
|
||||
int rv_idx = 0;
|
||||
for (int i = 0; i < Xop_vnt_flag_.Tid__max; i++) {
|
||||
Xop_vnt_flag itm = ary[i];
|
||||
if (itm != null)
|
||||
rv[rv_idx++] = itm;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
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.core.btries.*;
|
||||
class Xop_vnt_flag_lang_bldr {
|
||||
private Xop_vnt_flag_lang_itm[] ary; private int ary_len;
|
||||
private int ary_count;
|
||||
public Xop_vnt_flag_lang_bldr(Xol_vnt_mgr vnt_mgr) {
|
||||
Xol_vnt_converter[] converter_ary = vnt_mgr.Converter_ary();
|
||||
int len = converter_ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
byte[] lang = converter_ary[i].Owner().Key();
|
||||
Xop_vnt_flag_lang_itm itm = new Xop_vnt_flag_lang_itm(i, lang);
|
||||
trie.Add_obj(lang, itm);
|
||||
}
|
||||
ary = new Xop_vnt_flag_lang_itm[len];
|
||||
ary_len = len;
|
||||
}
|
||||
public Btrie_slim_mgr Trie() {return trie;} private Btrie_slim_mgr trie = Btrie_slim_mgr.ci_ascii_(); // NOTE:ci.ascii:MW_const.en; lang variant name; EX:zh-hans
|
||||
public void Add(Xop_vnt_flag_lang_itm itm) {
|
||||
int idx = itm.Idx();
|
||||
if (ary[idx] == null) {
|
||||
ary[idx] = itm;
|
||||
++ary_count;
|
||||
}
|
||||
}
|
||||
public void Clear() {
|
||||
for (int i = 0; i < ary_len; i++)
|
||||
ary[i] = null;
|
||||
ary_count = 0;
|
||||
}
|
||||
public Xop_vnt_flag Bld() {
|
||||
if (ary_count == 0) return Xop_vnt_flag_.Flag_unknown;
|
||||
byte[][] langs = new byte[ary_count][];
|
||||
int ary_idx = 0;
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
Xop_vnt_flag_lang_itm itm = ary[i];
|
||||
if (itm != null)
|
||||
langs[ary_idx++] = itm.Key();
|
||||
}
|
||||
return Xop_vnt_flag_.new_langs_(langs);
|
||||
}
|
||||
}
|
||||
class Xop_vnt_flag_lang_itm {
|
||||
public Xop_vnt_flag_lang_itm(int idx, byte[] key) {this.idx = idx; this.key = key; this.key_len = key.length;}
|
||||
public int Idx() {return idx;} private int idx;
|
||||
public byte[] Key() {return key;} private byte[] key;
|
||||
public int Key_len() {return key_len;} private int key_len;
|
||||
}
|
||||
111
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_flag_parser.java
Normal file
111
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_flag_parser.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
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.core.btries.*;
|
||||
class Xop_vnt_flag_parser {
|
||||
private Xop_vnt_flag_lang_bldr flag_lang_bldr;
|
||||
public Xop_vnt_flag_parser(Xol_vnt_mgr vnt_mgr) {flag_lang_bldr = new Xop_vnt_flag_lang_bldr(vnt_mgr);}
|
||||
private void Clear() {
|
||||
flag_lang_bldr.Clear();
|
||||
}
|
||||
public int Rslt_tkn_pos() {return rslt_tkn_pos;} private int rslt_tkn_pos;
|
||||
public int Rslt_pipe_last() {return rslt_pipe_last;} private int rslt_pipe_last;
|
||||
public Xop_vnt_flag[] Rslt_flags() {return rslt_flags;} private Xop_vnt_flag[] rslt_flags;
|
||||
public void Parse(Xowe_wiki wiki, Xop_vnt_tkn vnt_tkn, int pipe_tkn_count, byte[] src) {
|
||||
this.Clear();
|
||||
rslt_flags = new Xop_vnt_flag[pipe_tkn_count];
|
||||
int rv_idx = 0;
|
||||
int subs_len = vnt_tkn.Subs_len();
|
||||
Bry_bfr flag_bfr = wiki.Utl__bfr_mkr().Get_b128();
|
||||
rslt_tkn_pos = 0;
|
||||
boolean loop = true;
|
||||
while (true) {
|
||||
Xop_tkn_itm sub = vnt_tkn.Subs_get(rslt_tkn_pos);
|
||||
switch (sub.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_txt:
|
||||
flag_bfr.Add_mid(src, sub.Src_bgn(), sub.Src_end());
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_pipe:
|
||||
rslt_flags[rv_idx++] = Parse_flag_bry(flag_bfr.Xto_bry_and_clear());
|
||||
if (rv_idx == pipe_tkn_count) {
|
||||
loop = false;
|
||||
rslt_pipe_last = sub.Src_end();
|
||||
}
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_space:
|
||||
case Xop_tkn_itm_.Tid_tab:
|
||||
case Xop_tkn_itm_.Tid_newLine: // skip ws
|
||||
break;
|
||||
default:
|
||||
wiki.Appe().Usr_dlg().Log_many("", "", "unknown tkn in vnt flag; tid=~{0} txt=~{1}", sub.Tkn_tid(), String_.new_u8(src, sub.Src_bgn(), sub.Src_end()));
|
||||
flag_bfr.Add_mid(src, sub.Src_bgn(), sub.Src_end());
|
||||
break;
|
||||
}
|
||||
++rslt_tkn_pos;
|
||||
if (rslt_tkn_pos == subs_len) break;
|
||||
if (!loop) break;
|
||||
}
|
||||
flag_bfr.Mkr_rls();
|
||||
}
|
||||
private Xop_vnt_flag Parse_flag_bry(byte[] bry) {
|
||||
int bry_len = bry.length;
|
||||
if (bry_len == 0) return Xop_vnt_flag_.Flag_unknown; // EX: exit early if 0 len, else trie will fail; EX: "-{|}-"
|
||||
Object flag_obj = flag_trie.Match_exact(bry, 0, bry_len);
|
||||
return flag_obj == null
|
||||
? Parse_flag_vnts(bry, bry_len) // unknown tid sequence; either (a) "lang" cmd ("-{zh-hans;zh-hant|a}-") or (b) invalid cmd ("-{X|a}-")
|
||||
: (Xop_vnt_flag)flag_obj; // known flag; check that next non_ws is |
|
||||
}
|
||||
private Xop_vnt_flag Parse_flag_vnts(byte[] bry, int bry_len) {
|
||||
boolean loop = true;
|
||||
int vnt_pos = 0;
|
||||
Btrie_slim_mgr trie = flag_lang_bldr.Trie();
|
||||
while (loop) {
|
||||
boolean last = false;
|
||||
boolean valid = true;
|
||||
Object vnt_obj = trie.Match_bgn(bry, vnt_pos, bry_len);
|
||||
if (vnt_obj == null) break; // no more vnts found; stop
|
||||
vnt_pos = trie.Match_pos(); // update pos to end of vnt
|
||||
int semic_pos = Bry_finder.Find_fwd_while_not_ws(bry, vnt_pos, bry_len);
|
||||
if (semic_pos == bry_len) // note that Find_fwd_non_ws will return bry_len if no non-ws found;
|
||||
last = true;
|
||||
else { // char found; make sure it is semic
|
||||
if (bry[semic_pos] != Byte_ascii.Semic) { // invalid vnt; ignore; EX: -{zh-hansx|}-
|
||||
valid = false;
|
||||
}
|
||||
vnt_pos = semic_pos + 1; // update pos to after semic
|
||||
if (vnt_pos == bry_len) last = true; // EX: "a;"
|
||||
}
|
||||
if (valid)
|
||||
flag_lang_bldr.Add((Xop_vnt_flag_lang_itm)vnt_obj);
|
||||
else // invalid entry clears list; EX: -{zh-hans;zh-bad}-
|
||||
flag_lang_bldr.Clear();
|
||||
if (last) break;
|
||||
}
|
||||
return flag_lang_bldr.Bld();
|
||||
}
|
||||
private static Btrie_fast_mgr flag_trie = Xop_vnt_flag_.Trie;
|
||||
// private static final byte Dlm_tid_bgn = 0, Dlm_tid_end = 1, Dlm_tid_pipe = 2, Dlm_tid_colon = 3, Dlm_tid_semic = 4, Dlm_tid_kv = 5;
|
||||
// private static Btrie_fast_mgr dlm_trie = Btrie_fast_mgr.cs_()
|
||||
// .Add_bry_bval(Xop_vnt_lxr_.Hook_bgn , Dlm_tid_bgn)
|
||||
// .Add_bry_bval(Xop_vnt_lxr_.Hook_end , Dlm_tid_end)
|
||||
// .Add_bry_bval(Byte_ascii.Pipe , Dlm_tid_pipe)
|
||||
// .Add_bry_bval(Byte_ascii.Colon , Dlm_tid_colon)
|
||||
// .Add_bry_bval(Byte_ascii.Semic , Dlm_tid_semic)
|
||||
// .Add_bry_bval(Bry_.new_a7("=>") , Dlm_tid_kv)
|
||||
// ;
|
||||
}
|
||||
82
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_html_wtr.java
Normal file
82
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_html_wtr.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
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.html.*;
|
||||
public class Xop_vnt_html_wtr {
|
||||
public static void Write(Bry_bfr bfr, Xoh_html_wtr html_wtr, Xop_ctx ctx, Xoh_wtr_ctx hctx, Xoae_page page, byte[] src, Xop_vnt_tkn vnt) {
|
||||
byte[] cur_lang_vnt = ctx.Wiki().Lang().Vnt_mgr().Cur_vnt();
|
||||
Xop_vnt_rule[] rules = vnt.Vnt_rules(); if (rules == null) return; // shouldn't happen, but guard anyway
|
||||
int rules_len = rules.length;
|
||||
switch (vnt.Vnt_cmd()) {
|
||||
case Xop_vnt_html_wtr.Cmd_empty: break; // nothing: ""
|
||||
case Xop_vnt_html_wtr.Cmd_error: // original token; "-{A}-"
|
||||
bfr.Add_mid(src, vnt.Src_bgn(), vnt.Src_end());
|
||||
break;
|
||||
case Xop_vnt_html_wtr.Cmd_literal: { // val only; "A"
|
||||
Xop_vnt_rule rule_0 = rules[0]; // Cmd_calc guarantees there will always be 1 item
|
||||
html_wtr.Write_tkn_ary(bfr, ctx, hctx, src, rule_0.Rule_subs());
|
||||
break;
|
||||
}
|
||||
case Xop_vnt_html_wtr.Cmd_bidi: { // matching rule: "A" if zh-hans; -{zh-hans:A}-
|
||||
Xop_vnt_rule rule = Get_rule_by_key(rules, rules_len, cur_lang_vnt);
|
||||
if (rule != null) html_wtr.Write_tkn_ary(bfr, ctx, hctx, src, rule.Rule_subs());
|
||||
break;
|
||||
}
|
||||
case Xop_vnt_html_wtr.Cmd_lang: { // matching lang: "A" if zh-hans; -{zh-hans|A}-
|
||||
Xop_vnt_rule rule_0 = rules[0]; // Cmd_calc guarantees there will always be 1 rule
|
||||
Xop_vnt_flag flag_0 = vnt.Vnt_flags()[0]; // parse guarantees there will always be 1 flag
|
||||
byte[][] langs = flag_0.Langs();
|
||||
int flags_len = langs.length;
|
||||
for (int i = 0; i < flags_len; i++) {
|
||||
byte[] lang = langs[i];
|
||||
if (Bry_.Eq(lang, cur_lang_vnt)) {
|
||||
html_wtr.Write_tkn_ary(bfr, ctx, hctx, src, rule_0.Rule_subs());
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Xop_vnt_html_wtr.Cmd_raw: { // raw; everything between last flag and }-: "-{R|zh-hans:A;zh-hant:B}- -> "zh-hans:A;zh-hant:B"
|
||||
bfr.Add_mid(src, vnt.Vnt_pipe_idx_last(), vnt.Src_end() - 2);
|
||||
break;
|
||||
}
|
||||
case Xop_vnt_html_wtr.Cmd_descrip: { // descrip; similar to raw, but use localized lang
|
||||
// bfr.Add_mid(src, vnt.Vnt_pipe_idx_last(), vnt.Src_end() - 2);
|
||||
break;
|
||||
}
|
||||
case Xop_vnt_html_wtr.Cmd_title: break; // title: ignore; already handled during parse; DATE:2014-08-29
|
||||
}
|
||||
}
|
||||
public static Xop_vnt_rule Get_rule_by_key(Xop_vnt_rule[] rules, int rules_len, byte[] cur_lang_vnt) {
|
||||
for (int i = 0; i < rules_len; i++) {
|
||||
Xop_vnt_rule rule = rules[i];
|
||||
if (Bry_.Eq(rule.Rule_lang(), cur_lang_vnt)) return rule;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static final byte
|
||||
Cmd_error = 0 // eror -> output literal; EX: "-{some_unknown_error}-" -> "-{some_unknown_error}-"
|
||||
, Cmd_empty = 1 // empty -> output nothing; EX: "-{}-" -> ""
|
||||
, Cmd_literal = 2 // literal EX: "-{A}-" -> "A"
|
||||
, Cmd_bidi = 3 // bidi EX: "-{zh-hans:A;zh-hant:B}-" -> "A" if zh-hans; "B" if zh-hant
|
||||
, Cmd_lang = 4 // lang EX: "-{zh-hans|A}-" -> "A" if zh-hans; "" if zh-hant
|
||||
, Cmd_raw = 5 // raw; text in -{}- EX: "-{R|zh-hans:A;zh-hant:B}- -> "zh-hans:A;zh-hant:B"
|
||||
, Cmd_descrip = 6 // describe; output rules EX: "-{D|zh-hans:A;zh-hant:B}- -> "简体:A;繁體:B;"
|
||||
, Cmd_title = 7 // title; change title EX: "-{T|zh-hans:A;zh-hant:B}- -> "A" as display title
|
||||
;
|
||||
}
|
||||
95
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_.java
Normal file
95
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
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.core.btries.*;
|
||||
public class Xop_vnt_lxr_ {
|
||||
public static void set_(Xowe_wiki wiki) {
|
||||
Btrie_fast_mgr wiki_trie = wiki.Parser().Wtxt_trie();
|
||||
Object exists = wiki_trie.Match_bgn(Xop_vnt_lxr_.Hook_bgn, 0, Xop_vnt_lxr_.Hook_bgn.length);
|
||||
if (exists == null) {
|
||||
Xop_vnt_lxr_eqgt._.Init_by_wiki(wiki, wiki_trie);
|
||||
Xop_vnt_lxr_bgn._.Init_by_wiki(wiki, wiki_trie);
|
||||
new Xop_vnt_lxr_end().Init_by_wiki(wiki, wiki_trie);
|
||||
// Btrie_fast_mgr tmpl_trie = wiki.Parser().Tmpl_trie(); // do not add to tmpl trie
|
||||
// Xop_vnt_lxr_bgn._.Init_by_wiki(wiki, tmpl_trie);
|
||||
}
|
||||
}
|
||||
public static final byte[] Hook_bgn = new byte[] {Byte_ascii.Dash, Byte_ascii.Curly_bgn}, Hook_end = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Dash};
|
||||
}
|
||||
class Xop_vnt_lxr_eqgt implements Xop_lxr {
|
||||
public byte Lxr_tid() {return Xop_lxr_.Tid_vnt_eqgt;}
|
||||
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Hook, this);}
|
||||
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
|
||||
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
|
||||
ctx.Subs_add_and_stack(root, tkn_mkr.Vnt_eqgt(bgn_pos, cur_pos));
|
||||
return cur_pos;
|
||||
}
|
||||
public static final byte[] Hook = new byte[] {Byte_ascii.Eq, Byte_ascii.Gt};
|
||||
public static final Xop_vnt_lxr_eqgt _ = new Xop_vnt_lxr_eqgt(); Xop_vnt_lxr_eqgt() {}
|
||||
}
|
||||
class Xop_vnt_lxr_bgn implements Xop_lxr {
|
||||
public byte Lxr_tid() {return Xop_lxr_.Tid_vnt_bgn;}
|
||||
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_vnt_lxr_.Hook_bgn, this);}
|
||||
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
|
||||
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
|
||||
ctx.Subs_add_and_stack(root, tkn_mkr.Vnt(bgn_pos, cur_pos));
|
||||
return cur_pos;
|
||||
}
|
||||
public static final Xop_vnt_lxr_bgn _ = new Xop_vnt_lxr_bgn(); Xop_vnt_lxr_bgn() {}
|
||||
}
|
||||
class Xop_vnt_lxr_end implements Xop_lxr {
|
||||
private Xop_vnt_flag_parser flag_parser;
|
||||
private Xop_vnt_rules_parser rule_parser;
|
||||
public byte Lxr_tid() {return Xop_lxr_.Tid_vnt_end;}
|
||||
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {
|
||||
core_trie.Add(Xop_vnt_lxr_.Hook_end, this);
|
||||
Xol_vnt_mgr vnt_mgr = wiki.Lang().Vnt_mgr();
|
||||
flag_parser = new Xop_vnt_flag_parser(vnt_mgr);
|
||||
rule_parser = new Xop_vnt_rules_parser(vnt_mgr);
|
||||
}
|
||||
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
|
||||
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
|
||||
int stack_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_vnt);
|
||||
if (stack_pos == Xop_ctx.Stack_not_found) return ctx.Lxr_make_txt_(cur_pos); // "}-" found but no "-{" in stack;
|
||||
Xop_vnt_tkn vnt_tkn = (Xop_vnt_tkn)ctx.Stack_pop_til(root, src, stack_pos, false, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_vnt);
|
||||
Xowe_wiki wiki = ctx.Wiki();
|
||||
try {
|
||||
vnt_tkn.Src_end_(cur_pos);
|
||||
vnt_tkn.Subs_move(root);
|
||||
Xop_vnt_flag[] vnt_flag_ary = Xop_vnt_flag_.Ary_empty;
|
||||
int rule_subs_bgn = 0;
|
||||
int pipe_tkn_count = vnt_tkn.Vnt_pipe_tkn_count();
|
||||
if (pipe_tkn_count > 0) {
|
||||
flag_parser.Parse(wiki, vnt_tkn, pipe_tkn_count, src);
|
||||
vnt_flag_ary = flag_parser.Rslt_flags();
|
||||
rule_subs_bgn = flag_parser.Rslt_tkn_pos();
|
||||
vnt_tkn.Vnt_pipe_idx_last_(flag_parser.Rslt_pipe_last());
|
||||
}
|
||||
vnt_tkn.Vnt_flags_(vnt_flag_ary);
|
||||
Xop_vnt_rule[] rules = rule_parser.Parse(ctx, vnt_tkn, src, rule_subs_bgn);
|
||||
vnt_tkn.Vnt_rules_(rules);
|
||||
vnt_tkn.Vnt_cmd_calc(wiki, ctx.Cur_page(), ctx, src);
|
||||
}
|
||||
catch (Exception e) {
|
||||
ctx.App().Usr_dlg().Warn_many("", "", "vnt.parse failed: page=~{0} src=~{1} err=~{2}", String_.new_u8(ctx.Cur_page().Ttl().Raw()), String_.new_u8(src, bgn_pos, cur_pos), Err_.Message_gplx_brief(e));
|
||||
if (vnt_tkn != null)
|
||||
root.Subs_add(tkn_mkr.Bry_mid(src, vnt_tkn.Src_bgn(), cur_pos));
|
||||
}
|
||||
return cur_pos;
|
||||
}
|
||||
}
|
||||
163
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_tst.java
Normal file
163
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_lxr_tst.java
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
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 org.junit.*;
|
||||
public class Xop_vnt_lxr_tst {
|
||||
private Xop_vnt_lxr_fxt fxt = new Xop_vnt_lxr_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Flag_unknown() {fxt.Test_parse("-{X|b}-" , fxt.vnt_().Flags_unknown_().Rule_("b"));}
|
||||
@Test public void Flag_raw_basic() {fxt.Test_parse("-{A|b}-" , fxt.vnt_().Flags_codes_("A").Rule_("b"));}
|
||||
@Test public void Flag_add_ws() {fxt.Test_parse("-{ A |b}-" , fxt.vnt_().Flags_codes_("A").Rule_("b"));}
|
||||
@Test public void Flag_add_unknown() {fxt.Test_parse("-{ A x |b}-" , fxt.vnt_().Flags_unknown_().Rule_("b"));}
|
||||
@Test public void Flag_langs_basic() {fxt.Test_parse("-{zh-hans;zh-hant|b}-" , fxt.vnt_().Flags_langs_("zh-hans", "zh-hant").Rule_("b"));}
|
||||
@Test public void Flag_langs_semic() {fxt.Test_parse("-{zh-hans;zh-hant;|b}-" , fxt.vnt_().Flags_langs_("zh-hans", "zh-hant").Rule_("b"));}
|
||||
@Test public void Flag_langs_ws() {fxt.Test_parse("-{ zh-hans ; zh-hant ; |b}-" , fxt.vnt_().Flags_langs_("zh-hans", "zh-hant").Rule_("b"));}
|
||||
@Test public void Flag_unknown_1st() {fxt.Test_parse("-{ zh-hans x ; zh-hant ; |b}-" , fxt.vnt_().Flags_unknown_().Rule_("b"));}
|
||||
@Test public void Flag_unknown_nth() {fxt.Test_parse("-{ zh-hans ; zh-hant x; |b}-" , fxt.vnt_().Flags_unknown_().Rule_("b"));}
|
||||
@Test public void Flag_unknown_all() {fxt.Test_parse("-{ zh-hans x ; zh-hant x;|b}-" , fxt.vnt_().Flags_unknown_().Rule_("b"));}
|
||||
@Test public void Flag_multiple() {fxt.Test_parse("-{A|D|E|b}-" , fxt.vnt_().Flags_codes_("A", "D", "E").Rule_("b"));}
|
||||
@Test public void Rule_add_one() {fxt.Test_parse("-{A|zh-hans:bcd}-" , fxt.vnt_().Flags_codes_("A").Rule_("zh-hans", "bcd"));}
|
||||
@Test public void Rule_add_one_semic() {fxt.Test_parse("-{A|zh-hans:bcd;}-" , fxt.vnt_().Flags_codes_("A").Rule_("zh-hans", "bcd"));}
|
||||
@Test public void Rule_add_one_semic_empty() {fxt.Test_parse("-{A|zh-hans:bcd;;}-" , fxt.vnt_().Flags_codes_("A").Rule_("zh-hans", "bcd"));}
|
||||
@Test public void Rule_add_one_ws() {fxt.Test_parse("-{A|zh-hans : b c ;}-" , fxt.vnt_().Flags_codes_("A").Rule_("zh-hans", "b c"));}
|
||||
@Test public void Rule_add_many() {fxt.Test_parse("-{A|zh-hans:b;zh-hant:c}-" , fxt.vnt_().Flags_codes_("A").Rule_("zh-hans", "b").Rule_("zh-hant", "c"));}
|
||||
@Test public void Macro_one() {fxt.Test_parse("-{H|A1=>zh-hans:b;zh-hant:c}-" , fxt.vnt_().Flags_codes_("H").Rule_("A1", "zh-hans", "b").Rule_("A1", "zh-hant", "c"));}
|
||||
@Test public void Bidi() {fxt.Test_parse("-{zh-hans:b;zh-hant:c}-" , fxt.vnt_().Flags_none_().Rule_("zh-hans", "b").Rule_("zh-hant", "c"));}
|
||||
@Test public void None() {fxt.Test_parse("-{a}-" , fxt.vnt_().Flags_none_().Rule_("a"));}
|
||||
@Test public void Macro_mult() {
|
||||
fxt.Test_parse("-{H|A1=>zh-hans:b;zh-hant:c;A2=>zh-hans:d;zh-hant:e}-"
|
||||
, fxt.vnt_().Flags_codes_("H")
|
||||
.Rule_("A1", "zh-hans", "b").Rule_("A1", "zh-hant", "c")
|
||||
.Rule_("A2", "zh-hans", "d").Rule_("A2", "zh-hant", "e")
|
||||
);
|
||||
}
|
||||
|
||||
// @Test public void Disabled() {
|
||||
// Xop_fxt fxt = new Xop_fxt();
|
||||
// fxt.Wiki().Vnt_mgr().Set(null, null);
|
||||
// fxt.Test_parse_page_all_str("a-{b}-c", "a-{b}-c");
|
||||
// }
|
||||
// @Test public void Enabled() {
|
||||
// Xoae_app app = Xoa_app_fxt.app_();
|
||||
// Xol_lang lang = new Xol_lang(app, Bry_.new_a7("zh"));
|
||||
// Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "zh.wikipedia.org", lang);
|
||||
// Xop_fxt fxt = new Xop_fxt(app, wiki);
|
||||
// fxt.Test_parse_page_all_str("a-{b}-c", "ac");
|
||||
// fxt.Wiki().Vnt_mgr().Set(null, null); // set it back to null for other tests
|
||||
// }
|
||||
}
|
||||
class Xop_vnt_tkn_mok {
|
||||
private List_adp rules_list = List_adp_.new_();
|
||||
private List_adp flags_list = List_adp_.new_();
|
||||
public Xop_vnt_flag[] Flags() {
|
||||
if (flags == null) flags = (Xop_vnt_flag[])flags_list.To_ary(Xop_vnt_flag.class);
|
||||
return flags;
|
||||
} private Xop_vnt_flag[] flags;
|
||||
public Xop_vnt_tkn_mok Flags_none_() {flags_list.Clear(); return this;}
|
||||
public Xop_vnt_tkn_mok Flags_unknown_(String... v) {flags_list.Add(Xop_vnt_flag_.Flag_unknown); return this;}
|
||||
public Xop_vnt_tkn_mok Flags_langs_(String... v) {flags_list.Add(Xop_vnt_flag_.new_langs_(Bry_.Ary(v))); return this;}
|
||||
public Xop_vnt_tkn_mok Flags_codes_(String... ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
byte[] bry = Bry_.new_a7(ary[i]);
|
||||
Xop_vnt_flag flag = (Xop_vnt_flag)Xop_vnt_flag_.Trie.Match_bgn(bry, 0, bry.length);
|
||||
flags_list.Add(flag);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Xop_vnt_rule[] Rules() {
|
||||
if (rules == null) rules = (Xop_vnt_rule[])rules_list.To_ary(Xop_vnt_rule.class);
|
||||
return rules;
|
||||
} private Xop_vnt_rule[] rules;
|
||||
public Xop_vnt_tkn_mok Rule_(String rule) {return Rule_(Xop_vnt_rule.Null_lang, rule);}
|
||||
public Xop_vnt_tkn_mok Rule_(byte[] lang, String rule) {return Rule_(Xop_vnt_rule.Null_macro, lang, new Xop_bry_tkn(-1, -1, Bry_.new_u8(rule)));}
|
||||
public Xop_vnt_tkn_mok Rule_(String lang, String rule) {return Rule_(Xop_vnt_rule.Null_macro, Bry_.new_a7(lang), new Xop_bry_tkn(-1, -1, Bry_.new_u8(rule)));}
|
||||
public Xop_vnt_tkn_mok Rule_(String macro, String lang, String rule) {return Rule_(Bry_.new_a7(macro), Bry_.new_a7(lang), new Xop_bry_tkn(-1, -1, Bry_.new_u8(rule)));}
|
||||
public Xop_vnt_tkn_mok Rule_(byte[] macro, byte[] lang, Xop_tkn_itm... tkns) {rules_list.Add(new Xop_vnt_rule(macro, lang, tkns)); return this;}
|
||||
}
|
||||
class Xop_vnt_lxr_fxt {
|
||||
private Xop_fxt fxt;
|
||||
private Bry_bfr tmp_bfr = Bry_bfr.new_();
|
||||
public Xop_vnt_lxr_fxt Clear() {
|
||||
Xoae_app app = Xoa_app_fxt.app_();
|
||||
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "zh.wikipedia.org");
|
||||
fxt = new Xop_fxt(app, wiki);
|
||||
Xop_vnt_lxr_fxt.Init_vnt_mgr(wiki.Lang().Vnt_mgr(), "zh-hans", "zh-hant");
|
||||
Xop_vnt_lxr_.set_(wiki);
|
||||
return this;
|
||||
}
|
||||
public Xop_vnt_tkn_mok vnt_() {return new Xop_vnt_tkn_mok();}
|
||||
public static void Init_vnt_mgr(Xol_vnt_mgr vnt_mgr, String... vnts_str) {
|
||||
byte[][] vnts_bry = Bry_.Ary(vnts_str);
|
||||
int vnts_bry_len = vnts_bry.length;
|
||||
for (int i = 0; i < vnts_bry_len; i++)
|
||||
vnt_mgr.Get_or_new(vnts_bry[i]);
|
||||
vnt_mgr.Convert_ttl_init();
|
||||
}
|
||||
public Xop_vnt_lxr_fxt Test_parse(String raw, Xop_vnt_tkn_mok expd) {
|
||||
byte[] raw_bry = Bry_.new_u8(raw);
|
||||
Xop_root_tkn root = fxt.Exec_parse_page_all_as_root(raw_bry);
|
||||
Xop_vnt_tkn actl = (Xop_vnt_tkn)root.Subs_get(0);
|
||||
Test_vnt_tkn(raw_bry, expd, actl);
|
||||
return this;
|
||||
}
|
||||
private void Test_vnt_tkn(byte[] raw_bry, Xop_vnt_tkn_mok expd, Xop_vnt_tkn actl) {
|
||||
Tfds.Eq(Vnt_flag_ary_to_str(tmp_bfr, expd.Flags()), Vnt_flag_ary_to_str(tmp_bfr, actl.Vnt_flags()), "flags");
|
||||
Tfds.Eq(Vnt_rule_ary_to_str(tmp_bfr, raw_bry, expd.Rules()), Vnt_rule_ary_to_str(tmp_bfr, raw_bry, actl.Vnt_rules()), "rules");
|
||||
}
|
||||
private String Vnt_flag_ary_to_str(Bry_bfr bfr, Xop_vnt_flag[] ary) {
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xop_vnt_flag itm = ary[i];
|
||||
byte itm_tid = itm.Tid();
|
||||
if (itm_tid == Xop_vnt_flag_.Tid_lang)
|
||||
Vnt_flag_lang_to_bfr(bfr, itm);
|
||||
else
|
||||
bfr.Add_str(Xop_vnt_flag_.Xto_name(itm_tid)).Add_byte(Byte_ascii.Semic);
|
||||
}
|
||||
return bfr.Xto_str_and_clear();
|
||||
}
|
||||
private void Vnt_flag_lang_to_bfr(Bry_bfr bfr, Xop_vnt_flag itm) {
|
||||
byte[][] ary = itm.Langs();
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
bfr.Add(ary[i]).Add_byte(Byte_ascii.Semic);
|
||||
}
|
||||
private String Vnt_rule_ary_to_str(Bry_bfr bfr, byte[] src, Xop_vnt_rule[] ary) {
|
||||
if (ary == null) return "";
|
||||
int len = ary.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xop_vnt_rule itm = ary[i];
|
||||
if (itm.Rule_macro() != Xop_vnt_rule.Null_macro) // macro exists
|
||||
bfr.Add(itm.Rule_macro()).Add_str("=>");
|
||||
if (itm.Rule_lang() != Xop_vnt_rule.Null_lang) // lang exists
|
||||
bfr.Add(itm.Rule_lang()).Add_byte(Byte_ascii.Colon);
|
||||
Xop_tkn_itm[] subs = itm.Rule_subs();
|
||||
int subs_len = subs.length;
|
||||
for (int j = 0; j < subs_len; j++) {
|
||||
Xop_tkn_itm sub = subs[j];
|
||||
if (sub.Tkn_tid() == Xop_tkn_itm_.Tid_bry) // tests uses Xop_tkn_bry
|
||||
bfr.Add(((Xop_bry_tkn)sub).Val());
|
||||
else
|
||||
bfr.Add_mid(src, sub.Src_bgn(), sub.Src_end());
|
||||
}
|
||||
bfr.Add_byte(Byte_ascii.Semic);
|
||||
}
|
||||
return bfr.Xto_str_and_clear();
|
||||
}
|
||||
}
|
||||
88
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_parser_tst.java
Normal file
88
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_parser_tst.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
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 org.junit.*;
|
||||
public class Xop_vnt_parser_tst { // uses zh-hant as cur_vnt
|
||||
private Xop_vnt_parser_fxt fxt = new Xop_vnt_parser_fxt();
|
||||
@Before public void init() {fxt.Clear();}
|
||||
@Test public void Literal() {fxt.Test_parse("-{A}-", "A");}
|
||||
@Test public void Bidi() {fxt.Test_parse("-{zh-hans:A;zh-hant:B}-", "B");}
|
||||
@Test public void Empty() {fxt.Test_parse("a-{}-b", "ab");}
|
||||
@Test public void Unknown_empty() {fxt.Test_parse("a-{|}-c", "ac");}
|
||||
@Test public void Unknown_text() {fxt.Test_parse("a-{|b}-c", "abc");}
|
||||
@Test public void Unknown_flag() {fxt.Test_parse("a-{x|b}-c", "abc");}
|
||||
@Test public void Lang_y() {fxt.Test_parse("-{zh-hant|A}-", "A");}
|
||||
@Test public void Lang_n() {fxt.Test_parse("-{zh-hans|A}-", "");}
|
||||
@Test public void Raw() {fxt.Test_parse("-{R|zh-hans:A;}-", "zh-hans:A;");}
|
||||
// @Test public void Descrip() {fxt.Test_parse("-{D|zh-hans:A;}-", "zh-hans:A");}
|
||||
@Test public void Tmpl() {
|
||||
fxt.Parser_fxt().Init_page_create("Template:A", "B");
|
||||
fxt.Test_parse("-{{{A}}}-", "B");
|
||||
}
|
||||
@Test public void Tmpl_arg_4() { // PURPOSE: handle "-{" + "{{{"
|
||||
fxt.Parser_fxt().Init_page_create("Template:A", "-{{{{1}}}}-");
|
||||
fxt.Test_parse("{{A|B}}", "B"); // -{ {{{1}}} }- -> -{B}- -> B
|
||||
}
|
||||
@Test public void Tmpl_arg_3() { // PURPOSE: handle "-" + "{{{"; PAGE:sr.w:ДНК; EX:<span id="interwiki-{{{1}}}-fa"></span> DATE:2014-07-03
|
||||
fxt.Parser_fxt().Init_page_create("Template:A", "-{{{1}}}-");
|
||||
fxt.Test_parse("{{A|B}}", "-B-");
|
||||
}
|
||||
@Test public void Parser_function() {
|
||||
fxt.Test_parse("-{{{#expr:1}}}-", "1");
|
||||
}
|
||||
@Test public void Ignore() {
|
||||
fxt.Test_parse("-{{#expr:1}}-", "-1-");
|
||||
}
|
||||
@Test public void Expr() {
|
||||
fxt.Parser_fxt().Init_page_create("Template:A", "{{#expr: 0-{{{1|2}}}}}");
|
||||
fxt.Test_parse("{{A}}", "-2");
|
||||
}
|
||||
@Test public void Invalid() { // PURPOSE: invalid flags should cause vnt to render text only; DATE:2014-04-10
|
||||
fxt.Test_parse("-{:a|b}-", "b");
|
||||
}
|
||||
@Test public void Macro_ignore() { // PURPOSE: ignore macro (implement later); EX:zh.v:西安; Template:pagebanner; DATE:2014-05-03
|
||||
fxt.Test_parse("-{H|zh-cn:亚琛; zh-tw:阿亨;}-", "");
|
||||
}
|
||||
@Test public void Title() { // PURPOSE: implement title; PAGE:zh.w:Help:進階字詞轉換處理 DATE:2014-08-29
|
||||
fxt.Test_parse("-{T|zh-hant:A;zh-hans:B}-", "");
|
||||
Tfds.Eq("A", String_.new_u8(fxt.Parser_fxt().Page().Html_data().Display_ttl_vnt()));
|
||||
}
|
||||
}
|
||||
class Xop_vnt_parser_fxt {
|
||||
public Xop_fxt Parser_fxt() {return fxt;} private Xop_fxt fxt;
|
||||
public Xop_vnt_parser_fxt Clear() {
|
||||
Xoae_app app = Xoa_app_fxt.app_();
|
||||
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "zh.wikipedia.org");
|
||||
fxt = new Xop_fxt(app, wiki);
|
||||
Init_vnt_mgr(wiki.Lang().Vnt_mgr(), "zh-hans", "zh-hant");
|
||||
Xop_vnt_lxr_.set_(wiki);
|
||||
wiki.Lang().Vnt_mgr().Cur_vnt_(Bry_.new_a7("zh-hant"));
|
||||
return this;
|
||||
}
|
||||
private static void Init_vnt_mgr(Xol_vnt_mgr vnt_mgr, String... vnts_str) {
|
||||
byte[][] vnts_bry = Bry_.Ary(vnts_str);
|
||||
int vnts_bry_len = vnts_bry.length;
|
||||
for (int i = 0; i < vnts_bry_len; i++)
|
||||
vnt_mgr.Get_or_new(vnts_bry[i]);
|
||||
vnt_mgr.Convert_ttl_init();
|
||||
}
|
||||
public Xop_vnt_parser_fxt Test_parse(String raw, String expd) {
|
||||
fxt.Test_parse_page_all_str(raw, expd);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
26
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rule.java
Normal file
26
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rule.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
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 Xop_vnt_rule extends Xop_tkn_itm_base {
|
||||
public Xop_vnt_rule(byte[] rule_macro, byte[] rule_lang, Xop_tkn_itm[] rule_subs) {this.rule_macro = rule_macro; this.rule_lang = rule_lang; this.rule_subs = rule_subs;}
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_vnt_rule;}
|
||||
public byte[] Rule_macro() {return rule_macro;} private byte[] rule_macro;
|
||||
public byte[] Rule_lang() {return rule_lang;} private byte[] rule_lang;
|
||||
public Xop_tkn_itm[] Rule_subs() {return rule_subs;} private Xop_tkn_itm[] rule_subs;
|
||||
public static final byte[] Null_lang = null, Null_macro = null;
|
||||
}
|
||||
229
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rules_parser.java
Normal file
229
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_rules_parser.java
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
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.core.btries.*;
|
||||
class Xop_vnt_rules_parser {
|
||||
private byte mode;
|
||||
private Xop_vnt_tkn vnt_tkn;
|
||||
private boolean loop_vnt_subs; private int vnt_subs_cur, vnt_subs_bgn, vnt_subs_len;
|
||||
private int rule_texts_bgn;
|
||||
private Btrie_slim_mgr trie;
|
||||
private List_adp rules_list = List_adp_.new_();
|
||||
private List_adp text_tkns_list = List_adp_.new_();
|
||||
private int text_tkns_ws_end_idx;
|
||||
private byte[] src;
|
||||
private Xop_tkn_mkr tkn_mkr;
|
||||
// private int cur_macro_bgn = -1;
|
||||
private int cur_key_bgn = -1;
|
||||
private byte[] cur_macro_bry = null;
|
||||
private byte[] cur_lang_bry = null;
|
||||
public Xop_vnt_rules_parser(Xol_vnt_mgr vnt_mgr) {
|
||||
trie = Btrie_slim_mgr.ci_ascii_(); // NOTE:ci.ascii:MW_const.en; lang variant name; EX:zh-hans
|
||||
Xol_vnt_converter[] ary = vnt_mgr.Converter_ary();
|
||||
int ary_len = ary.length;
|
||||
for (int i = 0; i < ary_len; i++) {
|
||||
Xol_vnt_converter itm = ary[i];
|
||||
byte[] itm_lang = itm.Owner_key();
|
||||
trie.Add_obj(itm_lang, Xop_vnt_rule_trie_itm.lang_(itm_lang));
|
||||
}
|
||||
trie.Add_obj(";", Xop_vnt_rule_trie_itm.Dlm_semic);
|
||||
// trie.Add("=>", Xop_vnt_rule_trie_itm.Dlm_eqgt);
|
||||
}
|
||||
public void Clear_all() {
|
||||
rules_list.Clear();
|
||||
text_tkns_list.Clear();
|
||||
cur_macro_bry = cur_lang_bry = null;
|
||||
cur_key_bgn = -1;
|
||||
text_tkns_ws_bgn = false;
|
||||
text_tkns_ws_end_idx = 0;
|
||||
}
|
||||
public Xop_vnt_rule[] Parse(Xop_ctx ctx, Xop_vnt_tkn vnt_tkn, byte[] src, int vnt_subs_bgn) {
|
||||
this.Clear_all();
|
||||
this.tkn_mkr = ctx.Tkn_mkr(); this.src = src;
|
||||
this.vnt_tkn = vnt_tkn;
|
||||
this.vnt_subs_len = vnt_tkn.Subs_len();
|
||||
this.vnt_subs_bgn = this.vnt_subs_cur = vnt_subs_bgn;
|
||||
mode = Mode_key;
|
||||
loop_vnt_subs = true;
|
||||
while (loop_vnt_subs) {
|
||||
if (vnt_subs_cur == vnt_subs_len) break;
|
||||
Parse_sub();
|
||||
++vnt_subs_cur;
|
||||
}
|
||||
Make_rule(); // make rules for any pending items; EX: "-{A|text}-"; "text" is unclosed by semic and would need to be processed
|
||||
if (mode == Mode_key && rules_list.Count() == 0)
|
||||
Make_rule_literal();
|
||||
return (Xop_vnt_rule[])rules_list.To_ary_and_clear(Xop_vnt_rule.class);
|
||||
}
|
||||
private boolean text_tkns_ws_bgn = false;
|
||||
private void Parse_sub() {
|
||||
Xop_tkn_itm sub = vnt_tkn.Subs_get(vnt_subs_cur);
|
||||
if (cur_key_bgn == -1) cur_key_bgn = sub.Src_bgn();
|
||||
boolean text_tkns_list_add = true;
|
||||
boolean sub_is_ws = false;
|
||||
switch (sub.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_txt:
|
||||
Parse_key(sub, src, sub.Src_bgn(), sub.Src_end());
|
||||
if (mode == Mode_key)
|
||||
text_tkns_list_add = false;
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_bry:
|
||||
Xop_bry_tkn bry_tkn = (Xop_bry_tkn)sub;
|
||||
byte[] bry = bry_tkn.Val();
|
||||
Parse_key(sub, bry, 0, bry.length);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_colon:
|
||||
if ( mode == Mode_lang // colon should only follow lang; EX: zh-hant:text
|
||||
&& cur_lang_bry == null) { // if pending lang, ignore; assume part of text
|
||||
cur_lang_bry = Bry_.Trim(Bry_.Mid(src, cur_key_bgn, sub.Src_bgn()));
|
||||
mode = Mode_text;
|
||||
rule_texts_bgn = vnt_subs_cur + 1;
|
||||
text_tkns_list_add = false;
|
||||
text_tkns_ws_bgn = true;
|
||||
}
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_space:
|
||||
case Xop_tkn_itm_.Tid_tab:
|
||||
case Xop_tkn_itm_.Tid_newLine: // skip ws
|
||||
if (text_tkns_ws_bgn) text_tkns_list_add = false;
|
||||
else sub_is_ws = true;
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_vnt_eqgt:
|
||||
if (mode == Mode_key) {
|
||||
cur_macro_bry = Bry_.Trim(Bry_.Mid(src, cur_key_bgn, sub.Src_bgn()));
|
||||
text_tkns_list_add = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (sub_is_ws)
|
||||
text_tkns_ws_end_idx = text_tkns_list.Count(); // update last_ws_idx
|
||||
else
|
||||
text_tkns_ws_end_idx = -1; // set last_ws_idx to nil
|
||||
if (mode == Mode_text && text_tkns_list_add) { // mode is text && not a "key" tkn
|
||||
text_tkns_list.Add(sub);
|
||||
text_tkns_ws_bgn = false; // mark ws_bgn as false (handles trimming at start)
|
||||
}
|
||||
}
|
||||
private void Parse_key(Xop_tkn_itm sub, byte[] src, int src_bgn, int src_end) {
|
||||
int pos = src_bgn;
|
||||
boolean loop_key_bry = true;
|
||||
// boolean rv_add_as_text_tkn = true;
|
||||
while (loop_key_bry) {
|
||||
if (pos == src_end) break;
|
||||
if (cur_key_bgn == -1) cur_key_bgn = pos;
|
||||
byte b = src[pos];
|
||||
Object itm_obj = trie.Match_bgn_w_byte(b, src, pos, src_end);
|
||||
if (itm_obj == null) { // not a lang, semic, or eqgt; treat rest of vnt as one rule tkn
|
||||
// if (mode == Mode_key)
|
||||
// loop_key_bry = Make_rule_literal();
|
||||
// else
|
||||
++pos;
|
||||
}
|
||||
else {
|
||||
Xop_vnt_rule_trie_itm itm = (Xop_vnt_rule_trie_itm)itm_obj;
|
||||
int new_pos = trie.Match_pos();
|
||||
switch (itm.Tid()) {
|
||||
case Xop_vnt_rule_trie_itm.Tid_lang:
|
||||
if (mode == Mode_key) {
|
||||
int next_char_pos = Bry_finder.Find_fwd_while_space_or_tab(src, new_pos, src_end);
|
||||
if (next_char_pos == src_end) { // eos; EX: "zh-hant :a"
|
||||
cur_key_bgn = pos;
|
||||
mode = Mode_lang;
|
||||
}
|
||||
else
|
||||
loop_key_bry = Make_rule_literal();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case Xop_vnt_rule_trie_itm.Tid_semic:
|
||||
switch (mode) {
|
||||
case Mode_text:
|
||||
text_tkns_list.Add(tkn_mkr.Bry_raw(src_bgn, pos, Bry_.Trim(Bry_.Mid(src, src_bgn, pos))));
|
||||
Make_rule();
|
||||
cur_lang_bry = null;
|
||||
mode = Mode_key;
|
||||
cur_key_bgn = -1;
|
||||
break;
|
||||
case Mode_key: // ignore; empty semic's; EX: "zh-hant:a;;"
|
||||
break;
|
||||
}
|
||||
// rv_add_as_text_tkn = false;
|
||||
break;
|
||||
// case Xop_vnt_rule_trie_itm.Tid_eqgt:
|
||||
// if ( mode == Mode_key) { // if pending lang, ignore; assume part of text
|
||||
// cur_macro_bry = Bry_.Mid(src, cur_key_bgn, sub.Src_bgn());
|
||||
// cur_key_bgn = new_pos + 1;
|
||||
// }
|
||||
// break;
|
||||
}
|
||||
pos = new_pos;
|
||||
}
|
||||
}
|
||||
// if (rv_add_as_text_tkn)
|
||||
// mode = Mode_text;
|
||||
// return rv_add_as_text_tkn;
|
||||
}
|
||||
private boolean Make_rule_literal() { // return false for loop_key_bry
|
||||
this.Clear_all();
|
||||
Xop_tkn_itm[] rule_subs = Make_subs(vnt_subs_bgn, vnt_subs_len);
|
||||
rules_list.Add(new Xop_vnt_rule(Xop_vnt_rule.Null_macro, Xop_vnt_rule.Null_lang, rule_subs));
|
||||
loop_vnt_subs = false;
|
||||
return false;
|
||||
}
|
||||
private Xop_tkn_itm[] Make_subs(int bgn, int end) {
|
||||
int len = end - bgn;
|
||||
Xop_tkn_itm[] rv = new Xop_tkn_itm[len];
|
||||
for (int i = bgn; i < end; i++)
|
||||
rv[i - bgn] = vnt_tkn.Subs_get(i);
|
||||
return rv;
|
||||
}
|
||||
private void Make_rule() {
|
||||
if ( mode == Mode_text
|
||||
&& rule_texts_bgn < vnt_subs_len) {
|
||||
if (text_tkns_ws_end_idx != -1) { // trailing ws
|
||||
text_tkns_list.Del_range(text_tkns_ws_end_idx, text_tkns_list.Count() - 1);
|
||||
}
|
||||
Xop_tkn_itm[] rule_subs = (Xop_tkn_itm[])text_tkns_list.To_ary_and_clear(Xop_tkn_itm.class);
|
||||
Xop_vnt_rule rule = new Xop_vnt_rule(cur_macro_bry, cur_lang_bry, rule_subs);
|
||||
rules_list.Add(rule);
|
||||
}
|
||||
}
|
||||
private static final byte Mode_key = 1, Mode_lang = 2, Mode_text = 3;//, Mode_macro = 4;
|
||||
}
|
||||
class Xop_vnt_rule_trie_itm {
|
||||
public Xop_vnt_rule_trie_itm(byte tid, byte[] lang) {this.tid = tid; this.lang = lang;}
|
||||
public byte Tid() {return tid;} private byte tid;
|
||||
public byte[] Lang() {return lang;} private byte[] lang;
|
||||
public static final byte Tid_semic = 1, Tid_lang = 2;
|
||||
public static Xop_vnt_rule_trie_itm lang_(byte[] lang) {return new Xop_vnt_rule_trie_itm(Tid_lang, lang);}
|
||||
public static final Xop_vnt_rule_trie_itm
|
||||
Dlm_semic = new Xop_vnt_rule_trie_itm(Tid_semic, null)
|
||||
;
|
||||
}
|
||||
/*
|
||||
-{flags|lang:rule}- EX: -{A|zh-hant:a}-
|
||||
-{lang:rule;lang:rule} EX: -{zh-hans:a;zh-hant:b}-
|
||||
-{lang;lang|rule}- EX: -{zh-hans;zh-hant|XXXX}-
|
||||
-{rule}- EX: -{a}-
|
||||
-{flags|from=>variant:to;}- EX: -{H|HUGEBLOCK=>zh-cn:macro;}-
|
||||
-{lang:data_0;data_1;}- EX: -{zh-hans:<span style='border:solid;color:blue;'>;zh-hant:b}-
|
||||
. where data_0 and data_1 is actually one itm since ; is not delimiter b/c data_1 must be variant_code
|
||||
-{zh-hans:a-{zh-hans:b}-c}-
|
||||
*/
|
||||
70
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_tkn.java
Normal file
70
400_xowa/src/gplx/xowa/langs/vnts/Xop_vnt_tkn.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
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.html.*;
|
||||
public class Xop_vnt_tkn extends Xop_tkn_itm_base {
|
||||
public Xop_vnt_tkn(int bgn, int end) {
|
||||
this.Tkn_ini_pos(false, bgn, end);
|
||||
vnt_pipe_idx_last = bgn + Xop_vnt_lxr_.Hook_bgn.length; // default last pipe to pos after -{
|
||||
}
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_vnt;}
|
||||
public int Vnt_pipe_tkn_count() {return vnt_pipe_tkn_count;}
|
||||
public Xop_vnt_tkn Vnt_pipe_tkn_count_add_() {++vnt_pipe_tkn_count; return this;} private int vnt_pipe_tkn_count;
|
||||
public int Vnt_pipe_idx_last() {return vnt_pipe_idx_last;} public Xop_vnt_tkn Vnt_pipe_idx_last_(int v) {vnt_pipe_idx_last = v; return this;} private int vnt_pipe_idx_last = -1;
|
||||
public Xop_vnt_flag[] Vnt_flags() {return vnt_flags;} public Xop_vnt_tkn Vnt_flags_(Xop_vnt_flag[] v) {vnt_flags = v; return this;} private Xop_vnt_flag[] vnt_flags;
|
||||
public Xop_vnt_rule[] Vnt_rules() {return vnt_rules;} public Xop_vnt_tkn Vnt_rules_(Xop_vnt_rule[] v) {vnt_rules = v; return this;} private Xop_vnt_rule[] vnt_rules;
|
||||
public byte Vnt_cmd() {return vnt_cmd;} private byte vnt_cmd;
|
||||
public void Vnt_cmd_calc(Xowe_wiki wiki, Xoae_page page, Xop_ctx ctx, byte[] src) {
|
||||
int flags_len = vnt_flags.length;
|
||||
int rules_len = vnt_rules.length;
|
||||
if (flags_len == 0) { // no flags; either literal ("-{A}-") or bidi ("-{zh-hans:A;zh-hant:B}-");
|
||||
if (rules_len == 0) vnt_cmd = Xop_vnt_html_wtr.Cmd_empty;
|
||||
else {
|
||||
Xop_vnt_rule rule_0 = vnt_rules[0];
|
||||
if ( rules_len == 1 // only one rule
|
||||
&& rule_0.Rule_lang() == Xop_vnt_rule.Null_lang // no lang; EX: -{A}-
|
||||
)
|
||||
vnt_cmd = Xop_vnt_html_wtr.Cmd_literal;
|
||||
else // bidi: either one rule which has lang ("-{zh-hans:A}-") or more than one rule (which can't be literal)
|
||||
vnt_cmd = Xop_vnt_html_wtr.Cmd_bidi;
|
||||
}
|
||||
}
|
||||
else if (flags_len == 1){ // 1 flag; common case
|
||||
Xop_vnt_flag flag_0 = vnt_flags[0];
|
||||
switch (flag_0.Tid()) {
|
||||
case Xop_vnt_flag_.Tid_lang : vnt_cmd = Xop_vnt_html_wtr.Cmd_lang; break;
|
||||
case Xop_vnt_flag_.Tid_raw : vnt_cmd = Xop_vnt_html_wtr.Cmd_raw; break;
|
||||
case Xop_vnt_flag_.Tid_descrip : vnt_cmd = Xop_vnt_html_wtr.Cmd_descrip; break;
|
||||
case Xop_vnt_flag_.Tid_unknown : vnt_cmd = Xop_vnt_html_wtr.Cmd_literal; break; // flag is unknown; output text as literal; EX: "-{|a}-"; "-{X|a}-"
|
||||
case Xop_vnt_flag_.Tid_macro : vnt_cmd = Xop_vnt_html_wtr.Cmd_empty; break; // TODO: implement macro; ignore for now; DATE:2014-05-03
|
||||
case Xop_vnt_flag_.Tid_title: { // title; same as {{DISPLAYTITLE}} but variant aware; PAGE:zh.w:Help:進階字詞轉換處理 DATE:2014-08-29
|
||||
vnt_cmd = Xop_vnt_html_wtr.Cmd_title;
|
||||
byte[] cur_lang_vnt = wiki.Lang().Vnt_mgr().Cur_vnt();
|
||||
Xop_vnt_rule rule = Xop_vnt_html_wtr.Get_rule_by_key(vnt_rules, vnt_rules.length, cur_lang_vnt);
|
||||
if (rule != null) {
|
||||
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512();
|
||||
wiki.Html_mgr().Html_wtr().Write_tkn_ary(tmp_bfr, ctx, Xoh_wtr_ctx.Alt, src, rule.Rule_subs());
|
||||
byte[] display_ttl = tmp_bfr.To_bry_and_rls();
|
||||
page.Html_data().Display_ttl_vnt_(display_ttl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user