1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-07-12 21:10:02 -04:00
commit 794b5a232f
3099 changed files with 238212 additions and 0 deletions

View 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;
}
}

View 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;
}
}

View 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;
}

View 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;
}
}

View 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());
}
}

View 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;
}

View 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";
}

View 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";
}

File diff suppressed because it is too large Load Diff

View 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";}}
*/

View 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;
}
}
}

View 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;
}

View 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");}
}

View 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);
}
}

View 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));
}
}

View 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;
}

View 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.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() {}
}

View 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();
}
}
}

View 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;
}
}

View 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);
}

View 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() {}
}

View 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);
}

View 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() {}
}

View 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");
}

View 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.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;
}
}

View 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;}
}

View 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;
}
}

View 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
*/

View 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
*/

View 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);
}

View 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("###,###,###");
}

View 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 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));
}
}

View 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}
;
}

View 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();
}
}
}

View 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.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;}
}

View 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";
}

View 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);
}

View 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() {}
}

View 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() {}
}

View 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);
}
}

View 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
}
}
}

View 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_";
}

View 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_";
}

View 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);}
}

View 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"
);
}

View 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());
}
}

View 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;
}

View 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;}
}

View 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;
}
}

View 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.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;
}

View 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)
// ;
}

View 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
;
}

View 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;
}
}

View 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();
}
}

View 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;
}
}

View 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;
}

View 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}-
*/

View 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;
}
}
}
}
}