Xomw.Preprocessor: Start integrating Preprocessor_Hash [#508]

pull/620/head
gnosygnu 5 years ago
parent b65fda764f
commit 7f76d8128d

@ -154,7 +154,7 @@ public class Bry_ {
public static byte[] Resize(byte[] src, int src_bgn, int trg_len) {
byte[] trg = new byte[trg_len];
int src_len = src.length; if (src_len > trg_len) src_len = trg_len; // trg_len can be less than src_len
Copy_by_len(src, src_bgn, src_len, trg, 0);
Copy_to(src, src_bgn, src_len, trg, 0);
return trg;
}
public static byte[] Repeat_space(int len) {return Repeat(Byte_ascii.Space, len);}
@ -178,14 +178,14 @@ public class Bry_ {
public static byte[] Add(byte[] src, byte b) {
int src_len = src.length;
byte[] rv = new byte[src_len + 1];
Copy_by_pos(src, 0, src_len, rv, 0);
Copy_to(src, 0, src_len, rv, 0);
rv[src_len] = b;
return rv;
}
public static byte[] Add(byte b, byte[] src) {
int src_len = src.length;
byte[] rv = new byte[src_len + 1];
Copy_by_pos(src, 0, src_len, rv, 1);
Copy_to(src, 0, src_len, rv, 1);
rv[0] = b;
return rv;
}
@ -297,29 +297,30 @@ public class Bry_ {
for (int i = 0; i < repl_len; i++)
src[i + bgn] = repl[i];
}
public static void Copy_by_pos(byte[] src, int src_bgn, int src_end, byte[] trg, int trg_bgn) {
public static void Copy_to(byte[] src, int src_bgn, int src_end, byte[] trg, int trg_bgn) {
int trg_adj = trg_bgn - src_bgn;
for (int i = src_bgn; i < src_end; i++)
trg[i + trg_adj] = src[i];
}
public static void Copy_by_pos_reversed(byte[] src, int src_bgn, int src_end, byte[] trg, int trg_bgn) {
public static void Copy_to_reversed(byte[] src, int src_bgn, int src_end, byte[] trg, int trg_bgn) {
// copies src to trg, but in reverse order; EX: trg="1" src="432." -> "1.234"
int len = src_end - src_bgn;
for (int i = 0; i < len; i++)
trg[trg_bgn + i] = src[src_end - i - 1];
}
private static void Copy_by_len(byte[] src, int src_bgn, int src_len, byte[] trg, int trg_bgn) {
for (int i = 0; i < src_len; i++)
trg[i + trg_bgn] = src[i + src_bgn];
}
public static byte[] Replace_one(byte[] src, byte[] find, byte[] repl) {
int src_len = src.length;
int findPos = Bry_find_.Find(src, find, 0, src_len, true); if (findPos == Bry_find_.Not_found) return src;
int findLen = find.length, replLen = repl.length;
int rvLen = src_len + replLen - findLen;
byte[] rv = new byte[rvLen];
Copy_by_len(src , 0 , findPos , rv, 0 );
Copy_by_len(repl, 0 , replLen , rv, findPos );
Copy_by_len(src , findPos + findLen , src_len - findPos - findLen , rv, findPos + replLen);
public static byte[] Replace_one(byte[] orig, byte[] find, byte[] repl) {
// find val
int orig_len = orig.length;
int find_pos = Bry_find_.Find(orig, find, 0, orig_len, true);
if (find_pos == Bry_find_.Not_found) return orig; // nothing found; exit
// do copy
int find_len = find.length, repl_len = repl.length;
int rv_len = orig_len + repl_len - find_len;
byte[] rv = new byte[rv_len];
Copy_to(orig, 0 , find_pos, rv, 0 ); // copy orig before repl
Copy_to(repl, 0 , repl_len, rv, find_pos ); // copy repl
Copy_to(orig, find_pos + find_len, orig_len, rv, find_pos + repl_len); // copy orig after repl
return rv;
}
public static void Replace_all_direct(byte[] src, byte find, byte repl) {Replace_all_direct(src, find, repl, 0, src.length);}

@ -79,7 +79,7 @@ public class Bry_bfr {
public Bry_bfr Add(byte[] val) {
int val_len = val.length;
if (bfr_len + val_len > bfr_max) Resize((bfr_max + val_len) * 2);
Bry_.Copy_by_pos(val, 0, val_len, bfr, bfr_len);
Bry_.Copy_to(val, 0, val_len, bfr, bfr_len);
// Array_.Copy_to(val, 0, bfr, bfr_len, val_len);
bfr_len += val_len;
return this;
@ -88,7 +88,7 @@ public class Bry_bfr {
int len = end - bgn;
if (len < 0) throw Err_.new_wo_type("negative len", "bgn", bgn, "end", end, "excerpt", String_.new_u8__by_len(val, bgn, bgn + 16)); // NOTE: check for invalid end < bgn, else difficult to debug errors later; DATE:2014-05-11
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
Bry_.Copy_by_pos(val, bgn, end, bfr, bfr_len);
Bry_.Copy_to(val, bgn, end, bfr, bfr_len);
// Array_.Copy_to(val, bgn, bfr, bfr_len, len);
bfr_len += len;
return this;
@ -97,7 +97,7 @@ public class Bry_bfr {
int len = end - bgn;
if (len < 0) throw Err_.new_wo_type("negative len", "bgn", bgn, "end", end, "excerpt", String_.new_u8__by_len(val, bgn, bgn + 16)); // NOTE: check for invalid end < bgn, else difficult to debug errors later; DATE:2014-05-11
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
Bry_.Copy_by_pos_reversed(val, bgn, end, bfr, bfr_len);
Bry_.Copy_to_reversed(val, bgn, end, bfr, bfr_len);
// Array_.Copy_to(val, bgn, bfr, bfr_len, len);
bfr_len += len;
return this;
@ -118,7 +118,7 @@ public class Bry_bfr {
public Bry_bfr Add_bfr_and_preserve(Bry_bfr src) {
int len = src.bfr_len;
if (bfr_len + len > bfr_max) Resize((bfr_max + len) * 2);
Bry_.Copy_by_pos(src.bfr, 0, len, bfr, bfr_len);
Bry_.Copy_to(src.bfr, 0, len, bfr, bfr_len);
// Array_.Copy_to(src.bfr, 0, bfr, bfr_len, len);
bfr_len += len;
return this;
@ -163,7 +163,7 @@ public class Bry_bfr {
if (all_ws) return this;
}
src_len = src_end - src_bgn;
Bry_.Copy_by_pos(src.bfr, src_bgn, src_end, bfr, bfr_len);
Bry_.Copy_to(src.bfr, src_bgn, src_end, bfr, bfr_len);
// Array_.Copy_to(src.bfr, src_bgn, bfr, bfr_len, src_len);
bfr_len += src_len;
src.Clear();
@ -304,10 +304,10 @@ public class Bry_bfr {
Add_mid(val, bgn, end);
return this;
}
public Bry_bfr Add_bry_many(byte[]... ary) {
int len = ary.length;
public Bry_bfr Add_bry_many(byte[]... val) {
int len = val.length;
for (int i = 0; i < len; i++) {
byte[] bry = ary[i];
byte[] bry = val[i];
if (bry != null && bry.length > 0)
this.Add(bry);
}
@ -338,10 +338,10 @@ public class Bry_bfr {
}
catch (Exception e) {throw Err_.new_exc(e, "core", "invalid UTF-8 sequence", "s", str);}
}
public Bry_bfr Add_str_u8_many(String... ary) {
int len = ary.length;
public Bry_bfr Add_str_u8_many(String... val) {
int len = val.length;
for (int i = 0; i < len; ++i)
Add_str_u8(ary[i]);
Add_str_u8(val[i]);
return this;
}
public Bry_bfr Add_str_u8_fmt(String fmt, Object... args) {
@ -364,6 +364,10 @@ public class Bry_bfr {
}
catch (Exception e) {throw Err_.new_exc(e, "core", "invalid UTF-8 sequence", "s", str);}
}
public Bry_bfr Add_str_mid(String src, int bgn, int end) {
this.Add_str_u8(String_.Mid(src, bgn, end));
return this;
}
public Bry_bfr Add_kv_dlm(boolean line, String key, Object val) {
this.Add_str_a7(key).Add_byte_colon().Add_byte_space();
this.Add(Bry_.new_u8(Object_.Xto_str_strict_or_null_mark(val)));
@ -495,16 +499,16 @@ public class Bry_bfr {
}
public boolean Match_end_byt(byte b) {return bfr_len == 0 ? false : bfr[bfr_len - 1] == b;}
public boolean Match_end_byt_nl_or_bos() {return bfr_len == 0 ? true : bfr[bfr_len - 1] == Byte_ascii.Nl;}
public boolean Match_end_ary(byte[] ary) {return Bry_.Match(bfr, bfr_len - ary.length, bfr_len, ary);}
public boolean Match_end_ary(byte[] val) {return Bry_.Match(bfr, bfr_len - val.length, bfr_len, val);}
public Bry_bfr Insert_at(int add_pos, byte[] add_bry) {return Insert_at(add_pos, add_bry, 0, add_bry.length);}
public Bry_bfr Insert_at(int add_pos, byte[] add_bry, int add_bgn, int add_end) {
int add_len = add_end - add_bgn;
int new_max = bfr_max + add_len;
byte[] new_bfr = new byte[new_max];
if (add_pos > 0)
Bry_.Copy_by_pos (bfr , 0, add_pos, new_bfr, 0);
Bry_.Copy_by_pos (add_bry, add_bgn, add_end, new_bfr, add_pos);
Bry_.Copy_by_pos (bfr , add_pos, bfr_len, new_bfr, add_pos + add_len);
Bry_.Copy_to (bfr , 0, add_pos, new_bfr, 0);
Bry_.Copy_to (add_bry, add_bgn, add_end, new_bfr, add_pos);
Bry_.Copy_to (bfr , add_pos, bfr_len, new_bfr, add_pos + add_len);
bfr = new_bfr;
bfr_len += add_len;
bfr_max = new_max;
@ -514,7 +518,7 @@ public class Bry_bfr {
public Bry_bfr Delete_rng_to_end(int pos) {return Delete_rng(pos, bfr_len);}
public Bry_bfr Delete_rng(int rng_bgn, int rng_end) {
int rng_len = rng_end - rng_bgn;
Bry_.Copy_by_pos(bfr, rng_end, bfr_len, bfr, rng_bgn);
Bry_.Copy_to(bfr, rng_end, bfr_len, bfr, rng_bgn);
bfr_len -= rng_len;
return this;
}
@ -564,10 +568,10 @@ public class Bry_bfr {
rv[11] = true;
return rv;
}
public Bry_bfr Concat_skip_empty(byte[] dlm, byte[]... ary) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
byte[] itm = ary[i];
public Bry_bfr Concat_skip_empty(byte[] dlm, byte[]... val) {
int val_len = val.length;
for (int i = 0; i < val_len; i++) {
byte[] itm = val[i];
boolean itm_has_bytes = Bry_.Len_gt_0(itm);
if ( i != 0
&& itm_has_bytes

@ -21,7 +21,7 @@ class Io_sort_filCmd_reg implements Io_sort_filCmd { // 123|bgn|end|1
public void Bfr_add(Io_line_rdr stream) {
++itm_count;
int key_bgn = stream.Key_pos_bgn(), key_end = stream.Key_pos_end();
Bry_.Copy_by_pos(stream.Bfr(), key_bgn, key_end, prv_key, 0); prv_key_len = key_end - key_bgn;
Bry_.Copy_to(stream.Bfr(), key_bgn, key_end, prv_key, 0); prv_key_len = key_end - key_bgn;
} byte[] prv_key = new byte[1024]; int prv_key_len = 0;
public void Fil_bgn(Io_line_rdr stream) {
bfr.Add_int_variable(fil_idx++).Add_byte(Byte_ascii.Pipe);

@ -44,7 +44,7 @@ public class Xof_file_wkr_ {
if (b == Byte_ascii.Space) {
if (!dirty) {
dirty = true;
rv = new byte[len]; Bry_.Copy_by_pos(src, 0, i, rv, 0);
rv = new byte[len]; Bry_.Copy_to(src, 0, i, rv, 0);
}
rv[i] = Byte_ascii.Underline;
}

@ -0,0 +1,77 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
public class Char_bfr {
private char[] ary;
private int ary_len;
private int ary_max, ary_max_reset;
public Char_bfr(int ary_max) {
this.ary_max = ary_max;
ary = new char[ary_max];
ary_max_reset = ary_max;
}
public Char_bfr Add_char(char val) {
int new_len = ary_len + 1;
if (new_len > ary_len) Resize(ary_len * 2);
ary[ary_len] = val;
ary_len = new_len;
return this;
}
public Char_bfr Add_chry(char[] val) {
int val_len = val.length;
if (ary_len + val_len > ary_max) Resize((ary_max + val_len) * 2);
Copy_to(val, 0, val_len, ary, ary_len);
ary_len += val_len;
return this;
}
public Char_bfr Add_bry(byte[] val) {return Add_str(String_.new_u8(val));}
public Char_bfr Add_str(String val) {
int val_len = String_.Len(val);
if (ary_len + val_len > ary_max) Resize((ary_max + val_len) * 2);
Copy_to(val, 0, val_len, ary, ary_len);
ary_len += val_len;
return this;
}
private void Resize(int new_max) {
ary_max = new_max;
ary = Resize(ary, 0, new_max);
}
public String To_str_and_clear() {
String rv = String_.new_charAry_(ary, 0, ary_len);
ary_len = 0;
ary_max = ary_max_reset;
return rv;
}
public byte[] To_bry_and_clear() {
return Bry_.new_u8(To_str_and_clear());
}
private static char[] Resize(char[] src, int src_bgn, int trg_len) {
char[] trg = new char[trg_len];
int src_len = src.length; if (src_len > trg_len) src_len = trg_len; // trg_len can be less than src_len
Copy_to(src, src_bgn, src_len, trg, 0);
return trg;
}
private static void Copy_to(char[] src, int src_bgn, int src_end, char[] trg, int trg_bgn) {
int trg_adj = trg_bgn - src_bgn;
for (int i = src_bgn; i < src_end; i++)
trg[i + trg_adj] = src[i];
}
private static void Copy_to(String src, int src_bgn, int src_end, char[] trg, int trg_bgn) {
int trg_adj = trg_bgn - src_bgn;
for (int i = src_bgn; i < src_end; i++)
trg[i + trg_adj] = String_.CharAt(src, i);
}
}

@ -14,11 +14,123 @@ GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
public class XophpArray {
public static boolean in_array(String needle, String[] haystack) {
for (String hay : haystack)
if (String_.Eq(hay, needle))
return true;
return false;
import gplx.core.brys.*;
public class XophpArray implements Bry_bfr_able {
private final Ordered_hash hash = Ordered_hash_.New();
private int nxt_idx;
public int Len() {return hash.Len();}
public void Clear() {
hash.Clear();
nxt_idx = 0;
}
public XophpArray Add(Object val) {
int key = nxt_idx++;
XophpArrayItm itm = XophpArrayItm.New_int(key, val);
Set_or_add(key, itm);
return this;
}
public XophpArray Add(int key, Object val) {
nxt_idx = key + 1;
XophpArrayItm itm = XophpArrayItm.New_int(key, val);
Set_or_add(key, itm);
return this;
}
public XophpArray Add(double key, Object val) {
int key_as_int = (int)key;
nxt_idx = key_as_int + 1;
XophpArrayItm itm = XophpArrayItm.New_int(key_as_int, val);
Set_or_add(key_as_int, itm);
return this;
}
public XophpArray Add(boolean key, Object val) {
int key_as_int = key ? 1 : 0;
nxt_idx = key_as_int + 1;
XophpArrayItm itm = XophpArrayItm.New_int(key_as_int, val);
Set_or_add(key_as_int, itm);
return this;
}
public XophpArray Add(String key, Object val) {
XophpArrayItm itm = null;
int key_as_int = Int_.Parse_or(key, Int_.Min_value);
if (key_as_int == Int_.Min_value) {
itm = XophpArrayItm.New_str(key, val);
Set_or_add(key, itm);
}
else {
itm = XophpArrayItm.New_int(key_as_int, val);
Set_or_add(key_as_int, itm);
nxt_idx = key_as_int + 1;
}
return this;
}
public XophpArrayItm Get_at(int i) {
return (XophpArrayItm)hash.Get_at(i);
}
public void Del_at(int i) {
XophpArrayItm itm = (XophpArrayItm)hash.Get_at(i);
if (itm != null) {
if (itm.Key_as_str() == null)
hash.Del(itm.Key_as_int());
else
hash.Del(itm.Key_as_str());
}
}
private void Set_or_add(Object key, XophpArrayItm val) {
XophpArrayItm itm = (XophpArrayItm)hash.Get_by(key);
if (itm == null) {
hash.Add(key, val);
}
else {
itm.Val_(val.Val());
}
}
public XophpArray Add_many(Object... val) {
for (Object itm : val) {
Add(itm);
}
return this;
}
public Object Get(Object key) {
XophpArrayItm itm = (XophpArrayItm)hash.Get_by(key);
return itm.Val();
}
public void Set(int key, Object val) {
hash.Del(key);
this.Add(key, val);
}
public void Unset(Object key) {
hash.Del(key);
}
public boolean Has(Object key) {
return hash.Has(key);
}
public XophpArray Values() {
XophpArray rv = new XophpArray();
int len = hash.Len();
for (int i = 0; i < len; i++) {
XophpArrayItm old_itm = (XophpArrayItm)hash.Get_at(i);
rv.Add(i, old_itm.Val());
}
return rv;
}
public XophpArrayItm[] To_ary() {
return (XophpArrayItm[])hash.To_ary(XophpArrayItm.class);
}
public String To_str() {
Bry_bfr bfr = Bry_bfr_.New();
To_bfr(bfr);
return bfr.To_str_and_clear();
}
public void To_bfr(Bry_bfr bfr) {
XophpArrayItm[] itms = To_ary();
for (XophpArrayItm itm : itms) {
itm.To_bfr(bfr);
}
}
public static XophpArray New(Object... vals) {
XophpArray rv = new XophpArray();
for (Object val : vals)
rv.Add(val);
return rv;
}
}

@ -15,29 +15,32 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
import gplx.core.brys.*;
public class Xophp_ary_itm implements Bry_bfr_able {
public Xophp_ary_itm(int key_as_int, String key_as_str, Object val) {
public class XophpArrayItm implements Bry_bfr_able {
public XophpArrayItm(int key_as_int, String key_as_str, Object val) {
this.key_is_int = key_as_str == null;
this.key_as_int = key_as_int;
this.key_as_str = key_as_str;
this.val = val;
}
public boolean Key_is_int() {return key_is_int;} private final boolean key_is_int;
public int Key_as_int() {return key_as_int;} private final int key_as_int;
public String Key_as_str() {return key_as_str;} private final String key_as_str;
public Object Val() {return val;} private final Object val;
public Object Val() {return val;} public void Val_(Object v) {this.val = v;} private Object val;
public void To_bfr(Bry_bfr bfr) {
String key = key_as_str == null ? Int_.To_str(key_as_int) : key_as_str;
bfr.Add_str_u8(key).Add_byte_eq();
if (Type_.Type_by_obj(val) == Xophp_ary.class) {
Xophp_ary sub_ary = (Xophp_ary)val;
if (Type_.Type_by_obj(val) == XophpArray.class) {
XophpArray sub_ary = (XophpArray)val;
bfr.Add_byte_nl();
sub_ary.To_bfr(bfr);
}
else {
bfr.Add_obj(val);
bfr.Add_obj(val).Add_byte_space();
}
}
public static Xophp_ary_itm New(int key, Object val) {return new Xophp_ary_itm(key, null, val);}
public static Xophp_ary_itm New(String key, Object val) {return new Xophp_ary_itm(-1 , key , val);}
public static XophpArrayItm New_int(int key, Object val) {return new XophpArrayItm(key, null, val);}
public static XophpArrayItm New_str(String key, Object val) {return new XophpArrayItm(-1 , key , val);}
}

@ -51,4 +51,83 @@ public class XophpArrayUtl {
rv[i - 1] = ary[i];
return rv;
}
public static boolean in_array(String needle, String[] haystack) {
for (String hay : haystack)
if (String_.Eq(hay, needle))
return true;
return false;
}
public static XophpArray array_merge(XophpArray... vals) {
XophpArray rv = new XophpArray();
for (XophpArray ary : vals) {
XophpArrayItm[] itms = ary.To_ary();
for (XophpArrayItm itm : itms) {
array_add(rv, itm);
}
}
return rv;
}
private static void array_add(XophpArray ary, XophpArrayItm itm) {
if (itm.Key_as_str() == null)
ary.Add(itm.Val());
else
ary.Add(itm.Key_as_str(), itm.Val());
}
public static XophpArray array_splice(XophpArray src, int bgn) {return array_splice(src, bgn, src.Len(), null);}
public static XophpArray array_splice(XophpArray src, int bgn, int len) {return array_splice(src, bgn, len , null);}
public static XophpArray array_splice(XophpArray src, int bgn, int len, XophpArray repl) {
// get itms before clearing it
int src_len = src.Len();
XophpArrayItm[] itms = src.To_ary();
src.Clear();
// calc bgn
if (bgn < 0) { // negative bgn should be adusted from src_len; EX: -1 means start at last item
bgn += src_len;
if (bgn < 0) // large negative bgn should be capped at 0; EX: -99
bgn = 0;
}
else if (bgn > src_len) // large positive bgn should be capped at src_len; EX: 99
bgn = src_len;
// add src from 0 to bgn
for (int i = 0; i < bgn; i++) {
array_add(src, itms[i]);
}
// add repl
if (repl != null) {
XophpArrayItm[] repl_itms = repl.To_ary();
for (XophpArrayItm itm : repl_itms) {
array_add(src, itm);
}
}
// calc end
int end;
if (len < 0) { // negative len should be adjusted from src_len; EX: -1 means stop at last itm
end = src_len + len;
if (end < 0) // large_negative len should be capped at 0; EX: -99
end = 0;
}
else { // positive len should be added to bgn to find end
end = bgn + len;
}
if (end < bgn) // end should never be less than bgn; EX: splice(1, -99)
end = bgn;
else if (end > src_len) // end should not be more then end;
end = src_len;
// add src from end to len
for (int i = end; i < src_len; i++) {
array_add(src, itms[i]);
}
// add del to rv
XophpArray rv = new XophpArray();
for (int i = bgn; i < end; i++) {
array_add(rv, itms[i]);
}
return rv;
}
}

@ -0,0 +1,228 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
import org.junit.*; import gplx.core.tests.*;
public class XophpArrayUtl_tst { // REF:https://www.php.net/manual/en/function.array-merge.php
private final XophpArrayUtl_fxt fxt = new XophpArrayUtl_fxt();
@Test public void array_merge__basic() {
XophpArray ary1 = fxt.Make().Add("key1", "val1").Add("a");
XophpArray ary2 = fxt.Make().Add("key2", "val2").Add("b");
fxt.Test__array_merge
( fxt.Make().Add("key1", "val1").Add("a").Add("key2", "val2").Add("b")
, ary1, ary2);
}
@Test public void array_merge__same_key() {
XophpArray ary1 = fxt.Make().Add("key", "val1");
XophpArray ary2 = fxt.Make().Add("key", "val2");
fxt.Test__array_merge
( fxt.Make().Add("key", "val2")
, ary1, ary2);
}
@Test public void array_merge__same_idx() {
XophpArray ary1 = fxt.Make().Add(0, "a");
XophpArray ary2 = fxt.Make().Add(0, "b");
fxt.Test__array_merge
( fxt.Make().Add(0, "a").Add(1, "b")
, ary1, ary2);
}
@Test public void array_merge__renumber() {
XophpArray ary1 = fxt.Make().Add(3, "a");
XophpArray ary2 = fxt.Make().Add(2, "b");
fxt.Test__array_merge
( fxt.Make().Add(0, "a").Add(1, "b")
, ary1, ary2);
}
@Test public void array_merge__example_1() {
XophpArray ary1 = fxt.Make().Add("color", "red").Add_many(2, 4);
XophpArray ary2 = fxt.Make().Add_many("a", "b").Add("color", "green").Add("shape", "trapezoid").Add(4);
fxt.Test__array_merge
( fxt.Make().Add("color", "green").Add_many(2, 4, "a", "b").Add("shape", "trapezoid").Add(4)
, ary1, ary2);
}
@Test public void array_merge__example_2() {
XophpArray ary1 = fxt.Make();
XophpArray ary2 = fxt.Make().Add(1, "data");
fxt.Test__array_merge
( fxt.Make().Add(0, "data")
, ary1, ary2);
}
@Test public void array_splice__bgn_is_positive() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, 1);
fxt.Test__eq
( fxt.Make().Add_many("a")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("b", "c", "d")
, del
);
}
@Test public void array_splice__bgn_is_positive_large() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, 99);
fxt.Test__eq
( fxt.Make().Add_many("a", "b", "c", "d")
, src
);
fxt.Test__eq
( fxt.Make().Add_many()
, del
);
}
@Test public void array_splice__bgn_is_negative() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, -3);
fxt.Test__eq
( fxt.Make().Add_many("a")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("b", "c", "d")
, del
);
}
@Test public void array_splice__bgn_is_negative_large() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, -99);
fxt.Test__eq
( fxt.Make()
, src
);
fxt.Test__eq
( fxt.Make().Add_many("a", "b", "c", "d")
, del
);
}
@Test public void array_splice__len_is_positive() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, 1, 2);
fxt.Test__eq
( fxt.Make().Add_many("a", "d")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("b", "c")
, del
);
}
@Test public void array_splice__len_is_positive_large() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, 1, 99);
fxt.Test__eq
( fxt.Make().Add_many("a")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("b", "c", "d")
, del
);
}
@Test public void array_splice__len_is_negative() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, 1, -2);
fxt.Test__eq
( fxt.Make().Add_many("a", "c", "d")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("b")
, del
);
}
@Test public void array_splice__len_is_negative_large() {
XophpArray src = fxt.Make().Add_many("a", "b", "c", "d");
XophpArray del = XophpArrayUtl.array_splice(src, 1, -99);
fxt.Test__eq
( fxt.Make().Add_many("a", "b", "c", "d")
, src
);
fxt.Test__eq
( fxt.Make()
, del
);
}
@Test public void array_splice__repl() {
XophpArray src = fxt.Make().Add(0, "a").Add(1, "b").Add(2, "c").Add(3, "d");
XophpArray del = XophpArrayUtl.array_splice(src, 1, 2, fxt.Make().Add(0, "x"));
fxt.Test__eq
( fxt.Make().Add(0, "a").Add(1, "x").Add(2, "d")
, src
);
fxt.Test__eq
( fxt.Make().Add(0, "b").Add(1, "c")
, del
);
}
@Test public void array_splice__example_1a() {
XophpArray src = fxt.Make().Add_many("red", "green", "blue", "yellow");
XophpArray del = XophpArrayUtl.array_splice(src, 2);
fxt.Test__eq
( fxt.Make().Add_many("red", "green")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("blue", "yellow")
, del
);
}
@Test public void array_splice__example_1b() {
XophpArray src = fxt.Make().Add_many("red", "green", "blue", "yellow");
XophpArray del = XophpArrayUtl.array_splice(src, 1, -1);
fxt.Test__eq
( fxt.Make().Add_many("red", "yellow")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("green", "blue")
, del
);
}
@Test public void array_splice__example_1c() {
XophpArray src = fxt.Make().Add_many("red", "green", "blue", "yellow");
XophpArray del = XophpArrayUtl.array_splice(src, 1, 4, XophpArray.New("orange"));
fxt.Test__eq
( fxt.Make().Add_many("red", "orange")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("green", "blue", "yellow")
, del
);
}
@Test public void array_splice__example_1d() {
XophpArray src = fxt.Make().Add_many("red", "green", "blue", "yellow");
XophpArray del = XophpArrayUtl.array_splice(src, -1, 1, XophpArray.New("black", "maroon"));
fxt.Test__eq
( fxt.Make().Add_many("red", "green", "blue", "black", "maroon")
, src
);
fxt.Test__eq
( fxt.Make().Add_many("yellow")
, del
);
}
}
class XophpArrayUtl_fxt {
public XophpArray Make() {return new XophpArray();}
public void Test__array_merge(XophpArray expd, XophpArray... vals) {
XophpArray actl = XophpArrayUtl.array_merge(vals);
Gftest.Eq__str(expd.To_str(), actl.To_str());
}
public void Test__eq(XophpArray expd, XophpArray actl) {
Gftest.Eq__str(expd.To_str(), actl.To_str());
}
}

@ -15,68 +15,68 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
import org.junit.*; import gplx.core.tests.*;
public class Xophp_ary_tst { // REF: http://php.net/manual/en/language.types.array.php
public class XophpArray_tst { // REF: http://php.net/manual/en/language.types.array.php
private final XophpArray_fxt fxt = new XophpArray_fxt();
@Test public void array__kvs() {
// $array = array("foo" => "bar", "bar" => "foo",);
fxt.Test__array
( Xophp_ary.New()
( XophpArray.New()
. Add("foo", "bar")
. Add("bar", "foo")
, Xophp_ary_itm.New("foo", "bar")
, Xophp_ary_itm.New("bar", "foo")
, XophpArrayItm.New_str("foo", "bar")
, XophpArrayItm.New_str("bar", "foo")
);
}
@Test public void array__casting() {
// $array = array(1 => "a", "1" => "b", 1.5 => "c", true => "d",);
fxt.Test__array
( Xophp_ary.New()
( XophpArray.New()
. Add(1 , "a")
. Add("1" , "b")
. Add(1.5 , "c")
. Add(true, "d")
, Xophp_ary_itm.New(1, "d"));
, XophpArrayItm.New_int(1, "d"));
}
@Test public void array__mixed() {
// $array = array("foo" => "bar", "bar" => "foo", 100 => -100, -100 => 100);
fxt.Test__array
( Xophp_ary.New()
( XophpArray.New()
. Add("foo", "bar")
. Add("bar", "foo")
. Add(100, -100)
. Add(-100, 100)
, Xophp_ary_itm.New("foo", "bar")
, Xophp_ary_itm.New("bar", "foo")
, Xophp_ary_itm.New(100, -100)
, Xophp_ary_itm.New(-100, 100)
, XophpArrayItm.New_str("foo", "bar")
, XophpArrayItm.New_str("bar", "foo")
, XophpArrayItm.New_int(100, -100)
, XophpArrayItm.New_int(-100, 100)
);
}
@Test public void array__objs() {
// $array = array("foo", "bar", "hello", "world");
fxt.Test__array
( Xophp_ary.New()
( XophpArray.New()
. Add("foo")
. Add("bar")
. Add("hello")
. Add("world")
, Xophp_ary_itm.New(0, "foo")
, Xophp_ary_itm.New(1, "bar")
, Xophp_ary_itm.New(2, "hello")
, Xophp_ary_itm.New(3, "world")
, XophpArrayItm.New_int(0, "foo")
, XophpArrayItm.New_int(1, "bar")
, XophpArrayItm.New_int(2, "hello")
, XophpArrayItm.New_int(3, "world")
);
}
@Test public void array__unkeyed() {
// $array = array("a", "b", 6 => "c", "d");
fxt.Test__array
( Xophp_ary.New()
( XophpArray.New()
. Add("a")
. Add("b")
. Add(6, "c")
. Add("d")
, Xophp_ary_itm.New(0, "a")
, Xophp_ary_itm.New(1, "b")
, Xophp_ary_itm.New(6, "c")
, Xophp_ary_itm.New(7, "d")
, XophpArrayItm.New_int(0, "a")
, XophpArrayItm.New_int(1, "b")
, XophpArrayItm.New_int(6, "c")
, XophpArrayItm.New_int(7, "d")
);
}
@Test public void array__multidimensional() {
@ -92,23 +92,23 @@ public class Xophp_ary_tst { // REF: http://php.net/manual/en/language.types.arr
);
*/
fxt.Test__array
( Xophp_ary.New()
( XophpArray.New()
. Add("foo" , "bar")
. Add(42 , 24)
. Add("multi" , Xophp_ary.New()
. Add("dimensional", Xophp_ary.New()
. Add("multi" , XophpArray.New()
. Add("dimensional", XophpArray.New()
. Add("array", "foo")
))
, Xophp_ary_itm.New("foo", "bar")
, Xophp_ary_itm.New(42, "24")
, Xophp_ary_itm.New("multi", Xophp_ary.New()
. Add("dimensional", Xophp_ary.New()
, XophpArrayItm.New_str("foo", "bar")
, XophpArrayItm.New_int(42, "24")
, XophpArrayItm.New_str("multi", XophpArray.New()
. Add("dimensional", XophpArray.New()
. Add("array", "foo")
))
);
}
@Test public void array__unset() {
Xophp_ary ary = Xophp_ary.New();
XophpArray ary = XophpArray.New();
ary.Add(0, "a").Add(1, "b");
// delete all
@ -118,20 +118,20 @@ public class Xophp_ary_tst { // REF: http://php.net/manual/en/language.types.arr
// add new and assert idx is 2
ary.Add("c");
fxt.Test__array(ary, Xophp_ary_itm.New(2, "c"));
fxt.Test__array(ary, XophpArrayItm.New_int(2, "c"));
ary = ary.Values();
ary.Add("d");
fxt.Test__array(ary, Xophp_ary_itm.New(0, "c"), Xophp_ary_itm.New(1, "d"));
fxt.Test__array(ary, XophpArrayItm.New_int(0, "c"), XophpArrayItm.New_int(1, "d"));
}
}
class XophpArray_fxt {
public void Test__array(Xophp_ary ary, Xophp_ary_itm... expd) {
Xophp_ary_itm[] actl = ary.To_ary();
public void Test__array(XophpArray ary, XophpArrayItm... expd) {
XophpArrayItm[] actl = ary.To_ary();
Gftest.Eq__ary(expd, actl);
}
public void Test__unset(Xophp_ary ary, int idx, Xophp_ary_itm... expd) {
Xophp_ary_itm[] actl = ary.To_ary();
public void Test__unset(XophpArray ary, int idx, XophpArrayItm... expd) {
XophpArrayItm[] actl = ary.To_ary();
Gftest.Eq__ary(expd, actl);
}
}

@ -1,90 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
import gplx.core.brys.*;
public class Xophp_ary implements Bry_bfr_able {
private final Ordered_hash hash = Ordered_hash_.New();
private int nxt_idx;
public Xophp_ary Add(Object val) {
int key = nxt_idx++;
Xophp_ary_itm itm = Xophp_ary_itm.New(key, val);
hash.Add_if_dupe_use_nth(key, itm);
return this;
}
public Xophp_ary Add(int key, Object val) {
nxt_idx = key + 1;
Xophp_ary_itm itm = Xophp_ary_itm.New(key, val);
hash.Add_if_dupe_use_nth(key, itm);
return this;
}
public Xophp_ary Add(double key, Object val) {
int key_as_int = (int)key;
nxt_idx = key_as_int + 1;
Xophp_ary_itm itm = Xophp_ary_itm.New(key_as_int, val);
hash.Add_if_dupe_use_nth(key_as_int, itm);
return this;
}
public Xophp_ary Add(boolean key, Object val) {
int key_as_int = key ? 1 : 0;
nxt_idx = key_as_int + 1;
Xophp_ary_itm itm = Xophp_ary_itm.New(key_as_int, val);
hash.Add_if_dupe_use_nth(key_as_int, itm);
return this;
}
public Xophp_ary Add(String key, Object val) {
Xophp_ary_itm itm = null;
int key_as_int = Int_.Parse_or(key, Int_.Min_value);
if (key_as_int != Int_.Min_value) {
itm = Xophp_ary_itm.New(key_as_int, val);
nxt_idx = key_as_int + 1;
hash.Add_if_dupe_use_nth(key_as_int, itm);
}
else {
itm = Xophp_ary_itm.New(key, val);
hash.Add_if_dupe_use_nth(key, itm);
}
return this;
}
public Object Get(Object key) {
Xophp_ary_itm itm = (Xophp_ary_itm)hash.Get_by(key);
return itm.Val();
}
public void Unset(Object key) {
hash.Del(key);
}
public boolean Has(Object key) {
return hash.Has(key);
}
public Xophp_ary Values() {
Xophp_ary rv = new Xophp_ary();
int len = hash.Len();
for (int i = 0; i < len; i++) {
Xophp_ary_itm old_itm = (Xophp_ary_itm)hash.Get_at(i);
rv.Add(i, old_itm.Val());
}
return rv;
}
public Xophp_ary_itm[] To_ary() {
return (Xophp_ary_itm[])hash.To_ary(Xophp_ary_itm.class);
}
public void To_bfr(Bry_bfr bfr) {
Xophp_ary_itm[] itms = To_ary();
for (Xophp_ary_itm itm : itms) {
itm.To_bfr(bfr);
}
}
public static Xophp_ary New() {return new Xophp_ary();}
}

@ -43,7 +43,7 @@ public class JCSingleton {
private final Ordered_hash mapCacheLru = Ordered_hash_.New();
public Xomw_page_fetcher Store() {return store;} public void Store_(Xomw_page_fetcher v) {this.store = v;} private Xomw_page_fetcher store;
public Xophp_ary ConfigModels() {return configModels;} private final Xophp_ary configModels = new Xophp_ary();
public XophpArray ConfigModels() {return configModels;} private final XophpArray configModels = new XophpArray();
// /**
// * @var TitleParser cached invariant title parser
// */
@ -423,8 +423,8 @@ public class JCSingleton {
String clz = null;
if (configModels.Has(modelId)) {
Object val = configModels.Get(modelId);
if (Type_.Type_by_obj(val) == Xophp_ary.class) {
Xophp_ary val_as_ary = (Xophp_ary)val;
if (Type_.Type_by_obj(val) == XophpArray.class) {
XophpArray val_as_ary = (XophpArray)val;
if (val_as_ary.Has("class")) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "JsonConfig: Invalid +$wgJsonConfigModels['modelId'] array " + "value, 'cl"+ "ass' not found");
} else {

@ -20,7 +20,7 @@ public class JCValue {
private Ordered_hash value = Ordered_hash_.New();
private int statusVal;
private XophpStdClass value_as_obj;
private Xophp_ary value_as_ary;
private XophpArray value_as_ary;
private Object value_as_prim;
private int value_tid;
private boolean sameAsDefaultVal = false;
@ -45,7 +45,7 @@ public class JCValue {
/** @param int status
* @param mixed value
*/
public JCValue(int status, XophpStdClass value_as_obj, Xophp_ary value_as_ary, Object value_as_prim) {
public JCValue(int status, XophpStdClass value_as_obj, XophpArray value_as_ary, Object value_as_prim) {
this.statusVal = status;
this.value_as_obj = value_as_obj;
this.value_as_ary = value_as_ary;

@ -2178,12 +2178,12 @@ public class XomwDefaultSettings {
// * Allow schema updates
// */
// $wgAllowSchemaUpdates = true;
//
// /**
// * Maximum article size in kilobytes
// */
// $wgMaxArticleSize = 2048;
//
/**
* Maximum article size in kilobytes
*/
public static int wgMaxArticleSize = 2048;
// /**
// * The minimum amount of memory that MediaWiki "needs"; MediaWiki will try to
// * raise PHP's memory limit if it's below this amount.

@ -532,7 +532,7 @@ public abstract class ContentHandler {
return true; // this means "use the default"
}
return XophpArray.in_array(format, this.mSupportedFormats);
return XophpArrayUtl.in_array(format, this.mSupportedFormats);
}
/**

@ -27,6 +27,7 @@ import gplx.xowa.mediawiki.includes.parsers.quotes.*;
import gplx.xowa.mediawiki.includes.parsers.lnkes.*;
import gplx.xowa.mediawiki.includes.parsers.magiclinks.*;
import gplx.xowa.mediawiki.includes.parsers.nbsps.*;
import gplx.xowa.mediawiki.includes.parsers.preprocessors.*;
/**
* PHP Parser - Processes wiki markup (which uses a more user-friendly
* syntax, such as "[[link]]" for making links), and provides a one-way
@ -163,11 +164,13 @@ public class XomwParser implements XomwParserIface {
// public $mSubstWords;
// # Initialised in constructor
// public $mConf, $mExtLinkBracketedRegex, $mUrlProtocols;
//
// # Initialized in getPreprocessor()
// /** @var Preprocessor */
// public $mPreprocessor;
//
// Initialized in getPreprocessor()
/** @var Preprocessor */
public XomwPreprocessor mPreprocessor;
private XomwPreprocessor mPreprocessorClass;
// # Cleared with clearState():
// /**
// * @var ParserOutput
@ -282,31 +285,33 @@ public class XomwParser implements XomwParserIface {
public XomwSanitizer Sanitizer() {return sanitizer;}
public XomwStripState Strip_state() {return mStripState;}
// /**
// * @param array $conf
// */
// public function __construct($conf = []) {
/**
* @param array $conf
*/
public void __construct() { // $conf = []
// this.mConf = $conf;
// this.mUrlProtocols = wfUrlProtocols();
// this.mExtLinkBracketedRegex = '/\[(((?i)' . this.mUrlProtocols . ')' .
// self::EXT_LINK_ADDR .
// self::EXT_LINK_URL_CLASS . '*)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/Su';
// if (isset($conf['preprocessorClass'])) {
// this.mPreprocessorClass = $conf['preprocessorClass'];
// } elseif (defined('HPHP_VERSION')) {
// # Preprocessor_Hash is much faster than Preprocessor_DOM under HipHop
// this.mPreprocessorClass = 'Preprocessor_Hash';
// } elseif (extension_loaded('domxml')) {
// # PECL extension that conflicts with the core DOM extension (T15770)
// wfDebug("Warning: you have the obsolete domxml extension for PHP. Please remove it!\n");
// this.mPreprocessorClass = 'Preprocessor_Hash';
// } elseif (extension_loaded('dom')) {
// this.mPreprocessorClass = 'Preprocessor_DOM';
// } else {
// this.mPreprocessorClass = 'Preprocessor_Hash';
// }
// wfDebug(__CLASS__ . ": using preprocessor: {this.mPreprocessorClass}\n");
// }
this.mPreprocessorClass = XomwPreprocessor_DOM.Instance;
// if (isset($conf['preprocessorClass'])) {
// this.mPreprocessorClass = $conf['preprocessorClass'];
// } elseif (defined('HPHP_VERSION')) {
// # Preprocessor_Hash is much faster than Preprocessor_DOM under HipHop
// this.mPreprocessorClass = 'Preprocessor_Hash';
// } elseif (extension_loaded('domxml')) {
// # PECL extension that conflicts with the core DOM extension (T15770)
// wfDebug("Warning: you have the obsolete domxml extension for PHP. Please remove it!\n");
// this.mPreprocessorClass = 'Preprocessor_Hash';
// } elseif (extension_loaded('dom')) {
// this.mPreprocessorClass = 'Preprocessor_DOM';
// } else {
// this.mPreprocessorClass = 'Preprocessor_Hash';
// }
// wfDebug(__CLASS__ . ": using preprocessor: {this.mPreprocessorClass}\n");
}
private final Btrie_slim_mgr protocols_trie;
public XomwEnv Env() {return env;}
public Xomw_lnki_wkr Lnki_wkr() {return lnkiWkr;}
@ -314,6 +319,7 @@ public class XomwParser implements XomwParserIface {
public byte[] Get_external_link_rel;
private static byte[] Atr__rel;
public XomwParser(XomwEnv env) {
this.__construct();
if (regex_space == null) {
synchronized (Type_.Type_by_obj(this)) {
regex_space = new Xomw_regex_space();
@ -972,19 +978,19 @@ public class XomwParser implements XomwParserIface {
// }
// return this.mOptions->getUser();
// }
//
// /**
// * Get a preprocessor Object
// *
// * @return Preprocessor
// */
// public function getPreprocessor() {
// if (!isset(this.mPreprocessor)) {
// $class = this.mPreprocessorClass;
// this.mPreprocessor = new $class($this);
// }
// return this.mPreprocessor;
// }
/**
* Get a preprocessor Object
*
* @return Preprocessor
*/
public XomwPreprocessor getPreprocessor() {
if (this.mPreprocessor == null) {
XomwPreprocessor factory = this.mPreprocessorClass;
this.mPreprocessor = factory.Make_new(this);
}
return this.mPreprocessor;
}
/**
* Get a LinkRenderer instance to make links with
@ -2124,34 +2130,34 @@ public class XomwParser implements XomwParserIface {
// this.mVariables = new MagicWordArray($variableIDs);
// this.mSubstWords = new MagicWordArray($substIDs);
// }
//
// /**
// * Preprocess some wikitext and return the document tree.
// * This is the ghost of replace_variables().
// *
// * @param String $text The text to parse
// * @param int $flags Bitwise combination of:
// * - self::PTD_FOR_INCLUSION: Handle "<noinclude>" and "<includeonly>" as if the text is being
// * included. Default is to assume a direct page view.
// *
// * The generated DOM tree must depend only on the input text and the flags.
// * The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of T6899.
// *
// * Any flag added to the $flags parameter here, or any other parameter liable to cause a
// * change in the DOM tree for a given text, must be passed through the section identifier
// * in the section edit link and thus back to extractSections().
// *
// * The output of this function is currently only cached in process memory, but a persistent
// * cache may be implemented at a later date which takes further advantage of these strict
// * dependency requirements.
// *
// * @return PPNode
// */
// public function preprocessToDom($text, $flags = 0) {
// $dom = this.getPreprocessor()->preprocessToObj($text, $flags);
// return $dom;
// }
//
/**
* Preprocess some wikitext and return the document tree.
* This is the ghost of replace_variables().
*
* @param String $text The text to parse
* @param int $flags Bitwise combination of:
* - self::PTD_FOR_INCLUSION: Handle "<noinclude>" and "<includeonly>" as if the text is being
* included. Default is to assume a direct page view.
*
* The generated DOM tree must depend only on the input text and the flags.
* The DOM tree must be the same in OT_HTML and OT_WIKI mode, to avoid a regression of T6899.
*
* Any flag added to the $flags parameter here, or any other parameter liable to cause a
* change in the DOM tree for a given text, must be passed through the section identifier
* in the section edit link and thus back to extractSections().
*
* The output of this function is currently only cached in process memory, but a persistent
* cache may be implemented at a later date which takes further advantage of these strict
* dependency requirements.
*
* @return PPNode
*/
public XomwPPNode preprocessToDom(String text, int flags) {
XomwPPNode dom = this.getPreprocessor().preprocessToObj(text, flags);
return dom;
}
// /**
// * Return a three-element array: leading whitespace, String contents, trailing whitespace
// *
@ -2171,49 +2177,48 @@ public class XomwParser implements XomwParserIface {
// }
// return [ $w1, $trimmed, $w2 ];
// }
//
// /**
// * Replace magic variables, templates, and template arguments
// * with the appropriate text. Templates are substituted recursively,
// * taking care to avoid infinite loops.
// *
// * Note that the substitution depends on value of $mOutputType:
// * self::OT_WIKI: only {{subst:}} templates
// * self::OT_PREPROCESS: templates but not extension tags
// * self::OT_HTML: all templates and extension tags
// *
// * @param String $text The text to transform
// * @param boolean|PPFrame $frame Object describing the arguments passed to the
// * template. Arguments may also be provided as an associative array, as
// * was the usual case before MW1.12. Providing arguments this way may be
// * useful for extensions wishing to perform variable replacement
// * explicitly.
// * @param boolean $argsOnly Only do argument (triple-brace) expansion, not
// * double-brace expansion.
// * @return String
// */
// public function replaceVariables($text, $frame = false, $argsOnly = false) {
// # Is there any text? Also, Prevent too big inclusions!
// $textSize = strlen($text);
// if ($textSize < 1 || $textSize > this.mOptions->getMaxIncludeSize()) {
// return $text;
// }
//
// if ($frame === false) {
// $frame = this.getPreprocessor()->newFrame();
// } elseif (!($frame instanceof PPFrame)) {
// wfDebug(__METHOD__ . " called using plain parameters instead of "
// . "a PPFrame instance. Creating custom frame.\n");
// $frame = this.getPreprocessor()->newCustomFrame($frame);
// }
//
// $dom = this.preprocessToDom($text);
// $flags = $argsOnly ? PPFrame::NO_TEMPLATES : 0;
// $text = $frame->expand($dom, $flags);
//
// return $text;
// }
//
/**
* Replace magic variables, templates, and template arguments
* with the appropriate text. Templates are substituted recursively,
* taking care to avoid infinite loops.
*
* Note that the substitution depends on value of $mOutputType:
* self::OT_WIKI: only {{subst:}} templates
* self::OT_PREPROCESS: templates but not extension tags
* self::OT_HTML: all templates and extension tags
*
* @param String $text The text to transform
* @param boolean|PPFrame $frame Object describing the arguments passed to the
* template. Arguments may also be provided as an associative array, as
* was the usual case before MW1.12. Providing arguments this way may be
* useful for extensions wishing to perform variable replacement
* explicitly.
* @param boolean $argsOnly Only do argument (triple-brace) expansion, not
* double-brace expansion.
* @return String
*/
public String replaceVariables(String text, XomwParserCtx pctx, XomwPPFrame frame, boolean argsOnly) {
// Is there any text? Also, Prevent too big inclusions!
int textSize = String_.Len(text);
if (textSize < 1 || textSize > this.mOptions.getMaxIncludeSize()) {
return text;
}
if (frame == null) {
frame = this.getPreprocessor().newFrame();
} else if (!(Type_.Is_assignable_from_by_obj(frame, XomwPPFrame.class))) {
// wfDebug(__METHOD__ . " called using plain parameters instead of "
// . "a PPFrame instance. Creating custom frame.\n");
frame = this.getPreprocessor().newCustomFrame(frame);
}
XomwPPNode dom = this.preprocessToDom(text, 0);
int flags = argsOnly ? XomwPPFrame.NO_TEMPLATES : 0;
text = frame.expand(dom, flags);
return text;
}
// /**
// * Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.
// *

@ -17,6 +17,7 @@ package gplx.xowa.mediawiki.includes.parsers; import gplx.*; import gplx.xowa.*;
public class XomwParserOptions {
public XomwParserOptions() {
this.mThumbSize = 220;
initialiseFromUser();
}
// /**
// * Interlanguage links are removed and returned in an array
@ -68,11 +69,11 @@ public class XomwParserOptions {
// */
// private $mTargetLanguage = null;
//
// /**
// * Maximum size of template expansions, in bytes
// */
// private $mMaxIncludeSize;
//
/**
* Maximum size of template expansions, in bytes
*/
private int mMaxIncludeSize;
// /**
// * Maximum number of nodes touched by PPFrame::expand()
// */
@ -271,10 +272,10 @@ public class XomwParserOptions {
// return this.mTargetLanguage;
// }
//
// public function getMaxIncludeSize() {
// return this.mMaxIncludeSize;
// }
//
public int getMaxIncludeSize() {
return this.mMaxIncludeSize;
}
// public function getMaxPPNodeCount() {
// return this.mMaxPPNodeCount;
// }
@ -679,28 +680,29 @@ public class XomwParserOptions {
// public static function newFromContext( IContextSource $context ) {
// return new ParserOptions( $context->getUser(), $context->getLanguage() );
// }
//
// /**
// * Get user options
// *
// * @param User $user
// * @param Language $lang
// */
// private function initialiseFromUser( $user, $lang ) {
/**
* Get user options
*
* @param User $user
* @param Language $lang
*/
// private function initialiseFromUser( $user, $lang ) {
private void initialiseFromUser() {
// global $wgInterwikiMagic, $wgAllowExternalImages,
// $wgAllowExternalImagesFrom, $wgEnableImageWhitelist, $wgAllowSpecialInclusion,
// $wgMaxArticleSize, $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth,
// $wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit,
// $wgMaxGeneratedPPNodeCount, $wgDisableLangConversion, $wgDisableTitleConversion,
// $wgEnableMagicLinks;
//
// // *UPDATE* ParserOptions::matches() if any of this changes as needed
// *UPDATE* ParserOptions::matches() if any of this changes as needed
// this.mInterwikiMagic = $wgInterwikiMagic;
// this.mAllowExternalImages = $wgAllowExternalImages;
// this.mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
// this.mEnableImageWhitelist = $wgEnableImageWhitelist;
// this.mAllowSpecialInclusion = $wgAllowSpecialInclusion;
// this.mMaxIncludeSize = $wgMaxArticleSize * 1024;
this.mMaxIncludeSize = XomwDefaultSettings.wgMaxArticleSize * 1024;
// this.mMaxPPNodeCount = $wgMaxPPNodeCount;
// this.mMaxGeneratedPPNodeCount = $wgMaxGeneratedPPNodeCount;
// this.mMaxPPExpandDepth = $wgMaxPPExpandDepth;
@ -719,7 +721,7 @@ public class XomwParserOptions {
// this.mThumbSize = $user->getOption( 'thumbsize' );
// this.mStubThreshold = $user->getStubThreshold();
// this.mUserLang = $lang;
// }
}
//
// /**
// * Check if these options match that of another options set

@ -13,18 +13,155 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
import gplx.core.btries.*;
public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
import gplx.xowa.mediawiki.includes.parsers.preprocessors.*;
/**
* @ingroup Parser
*/
public abstract class XomwPreprocessor {
// private static final int CACHE_VERSION = 1;
// /**
// * @var array Brace matching rules.
// */
// protected $rules = [
// '{' => [
// 'end' => '}',
// 'names' => [
// 2 => 'template',
// 3 => 'tplarg',
// ],
// 'min' => 2,
// 'max' => 3,
// ],
// '[' => [
// 'end' => ']',
// 'names' => [ 2 => null ],
// 'min' => 2,
// 'max' => 2,
// ],
// '-{' => [
// 'end' => '}-',
// 'names' => [ 1 => null ],
// 'min' => 1,
// 'max' => 1,
// ],
// ];
//
// /**
// * Store a document tree in the cache.
// *
// * @param String $text
// * @param int $flags
// */
// protected function cacheSetTree($text, $flags, $tree) {
// $config = RequestContext::getMain()->getConfig();
//
// $length = strlen($text);
// $threshold = $config->get('PreprocessorCacheThreshold');
// if ($threshold === false || $length < $threshold || $length > 1e6) {
// return false;
// }
//
// $key = wfMemcKey(
// defined('static::CACHE_PREFIX') ? static::CACHE_PREFIX : static::class,
// md5($text), $flags);
// $value = sprintf("%08d", static::CACHE_VERSION) . $tree;
//
// $cache = ObjectCache::getInstance($config->get('MainCacheType'));
// $cache->set($key, $value, 86400);
//
// LoggerFactory::getInstance('Preprocessor')
// ->info("Cached preprocessor output (key: $key)");
// }
//
// /**
// * Attempt to load a precomputed document tree for some given wikitext
// * from the cache.
// *
// * @param String $text
// * @param int $flags
// * @return PPNode_Hash_Tree|boolean
// */
// protected function cacheGetTree($text, $flags) {
// $config = RequestContext::getMain()->getConfig();
//
// $length = strlen($text);
// $threshold = $config->get('PreprocessorCacheThreshold');
// if ($threshold === false || $length < $threshold || $length > 1e6) {
// return false;
// }
//
// $cache = ObjectCache::getInstance($config->get('MainCacheType'));
//
// $key = wfMemcKey(
// defined('static::CACHE_PREFIX') ? static::CACHE_PREFIX : static::class,
// md5($text), $flags);
//
// $value = $cache->get($key);
// if (!$value) {
// return false;
// }
//
// $version = intval(substr($value, 0, 8));
// if ($version !== static::CACHE_VERSION) {
// return false;
// }
//
// LoggerFactory::getInstance('Preprocessor')
// ->info("Loaded preprocessor output from cache (key: $key)");
//
// return substr($value, 8);
// }
/**
* Create a new top-level frame for expansion of a page
*
* @return PPFrame
*/
public abstract XomwPPFrame newFrame();
/**
* Create a new custom frame for programmatic use of parameter replacement
* as used in some extensions.
*
* @param array $args
*
* @return PPFrame
*/
public abstract XomwPPFrame newCustomFrame(XomwPPFrame args);
// /**
// * Create a new custom node for programmatic use of parameter replacement
// * as used in some extensions.
// *
// * @param array $values
// */
// abstract public function newPartNodeArray($values);
/**
* Preprocess text to a PPNode
*
* @param String $text
* @param int $flags
*
* @return PPNode
*/
public abstract XomwPPNode preprocessToObj(String text, int flags);
private final List_adp comments_list = List_adp_.New();
private final Btrie_slim_mgr elements_trie__y = Btrie_slim_mgr.ci_a7(), elements_trie__n = Btrie_slim_mgr.ci_a7();
private final Hash_adp_bry xmlish_allow_missing_end_tag = Hash_adp_bry.cs().Add_many_str("includeonly", "noinclude", "onlyinclude");
private final Hash_adp_bry no_more_closing_tag = Hash_adp_bry.cs();
private final Xomw_prepro_stack stack = new Xomw_prepro_stack();
private final XomwPPDStack stack;
private final Btrie_rv trv = new Btrie_rv();
private Bry_bfr accum = Bry_bfr_.New();
private Xomw_prepro_accum accum = null;
public XomwPreprocessor() {
this.stack = new XomwPPDStack(this.Factory__accum());
}
public void Init_by_wiki(String... xmlish_elems_ary) {
Elements_trie__init_by_wiki(elements_trie__y, ignored_tags_y, xmlish_elems_ary, "noinclude");
Elements_trie__init_by_wiki(elements_trie__n, ignored_tags_n, xmlish_elems_ary, "includeonly");
@ -50,7 +187,13 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
private static void Elements_trie__add(Btrie_slim_mgr trie, boolean type_is_comment, String hook, String name) {
trie.Add_obj(hook, new Xomw_prepro_elem(type_is_comment ? Xomw_prepro_elem.Type__comment : Xomw_prepro_elem.Type__other, Bry_.new_a7(name)));
}
public byte[] Preprocess_to_xml(byte[] src, boolean for_inclusion) {
/**
* @param String $text
* @param int $flags
* @return String
*/
public byte[] preprocessToXml(byte[] src, boolean for_inclusion) {
// RELIC.PROC_VAR: forInclusion = $flags & Parser::PTD_FOR_INCLUSION;
// RELIC.INIT_BY_WIKI: $xmlishElements = parser->getStripList();
// RELIC.CLASS_VAR: $xmlishAllowMissingEndTag = [ 'includeonly', 'noinclude', 'onlyinclude' ];
@ -97,18 +240,18 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
int i = 0;
// Current accumulator
accum = stack.Get_accum();
accum.Add_str_a7("<root>");
accum = this.Accum__set(stack.Get_accum());
this.preprocessToObj_root();
// True to find equals signs in arguments
boolean find_equals = false;
boolean findEquals = false;
// True to take notice of pipe characters
boolean find_pipe = false;
boolean findPipe = false;
int heading_index = 1;
// True if $i is inside a possible heading
boolean in_heading = false;
boolean inHeading = false;
// True if there are no more greater-than (>) signs right of $i
boolean no_more_gt = false;
@ -136,11 +279,11 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
int start_pos = Bry_find_.Find_fwd(src, Bry__only_include_bgn, i, src_len);
if (start_pos == Bry_find_.Not_found) {
// Ignored section runs to the end
accum.Add_str_a7("<ignore>").Add_bry_escape_html(src, i, src_len).Add_str_a7("</ignore>");
this.preprocessToObj_ignore(src, i, src_len);
break;
}
int tag_end_pos = start_pos + Bry__only_include_bgn.length; // past-the-end
accum.Add_str_a7("<ignore>").Add_bry_escape_html(src, i, tag_end_pos).Add_str_a7("</ignore>");
this.preprocessToObj_ignore(src, i, tag_end_pos);
i = tag_end_pos;
find_only_include = false;
}
@ -159,10 +302,10 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
cur_closing = stack.top.close;
// RELIC.REGEX: $search .= $currentClosing;
}
if (find_pipe) {
if (findPipe) {
// RELIC.REGEX: $search .= '|';
}
if (find_equals) {
if (findEquals) {
// First equals will be for the template
// RELIC.REGEX: $search .= '=';
}
@ -181,11 +324,11 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
case Byte_ascii.Nl:
loop_stop = true;
break;
case Byte_ascii.Pipe: // handle "find_pipe"
if (find_pipe) loop_stop = true;
case Byte_ascii.Pipe: // handle "findPipe"
if (findPipe) loop_stop = true;
break;
case Byte_ascii.Eq: // handle "find_equals"
if (find_equals) loop_stop = true;
case Byte_ascii.Eq: // handle "findEquals"
if (findEquals) loop_stop = true;
break;
default: // handle "cur_closing"; specified by piece.close and rule.close, so "\n", "}", "]" and "}-"
if (cur_closing != Bry_.Empty) {
@ -209,7 +352,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
literal_len++;
}
if (literal_len > 0) {
accum.Add_bry_escape_html(src, i, i + literal_len);
this.preprocessToObj_literal(src, i, i + literal_len);
i += literal_len;
}
if (i >= src_len) {
@ -232,7 +375,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
case Byte_ascii.Pipe: found = Found__pipe; break;
case Byte_ascii.Eq: found = Found__equals; break;
case Byte_ascii.Angle_bgn: found = Found__angle; break;
case Byte_ascii.Nl: found = in_heading ? Found__line_end : Found__line_bgn; break;
case Byte_ascii.Nl: found = inHeading ? Found__line_end : Found__line_bgn; break;
// PORTED: "elseif ( $curChar == $currentClosing )"
case Byte_ascii.Curly_end: found = Found__close; break;
@ -265,7 +408,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
Xomw_prepro_elem element = (Xomw_prepro_elem)elements_trie.Match_at(trv, src, i + 1, src_len);
if (element == null) {
// Element name missing or not listed
accum.Add(Bry__escaped_lt);
this.preprocessToObj_literal(Byte_ascii.Lt_bry);
i++;
continue;
}
@ -281,7 +424,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
int end_pos = Bry_find_.Find_fwd(src, Bry__comment_end, i + 4, src_len);
if (end_pos == Bry_find_.Not_found) {
// Unclosed comment in input, runs to end
accum.Add_str_a7("<comment>").Add_bry_escape_html(src, i, src_len).Add_str_a7("</comment>");
this.preprocessToObj_comment(src, i, src_len);
i = src_len;
}
else {
@ -318,11 +461,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
// Remove leading whitespace from the end of the accumulator
// Sanity check first though
int ws_len = i - ws_bgn;
int accum_len = accum.Len();
if ( ws_len > 0
&& XophpString.strspn_fwd__space_or_tab(accum.Bfr(), accum_len - ws_len, -1, accum_len) == ws_len) {
accum.Del_by(ws_len);
}
this.preprocessToObj_removeLeadingWhitespaceFromEnd(ws_len);
// Dump all but the last comment to the accumulator
int comments_list_len = comments_list.Len();
@ -334,7 +473,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
break;
}
inner = Bry_.Mid(src, bgn_pos, end_pos);
accum.Add_str_a7("<comment>").Add_bry_escape_html(inner).Add_str_a7("</comment>");
this.preprocessToObj_comment(inner);
}
// Do a line-start run next time to look for headings after the comment
@ -347,16 +486,16 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
}
if (stack.top != null) {
Xomw_prepro_part part = stack.top.Get_current_part();
if (!(part.comment_end != -1 && part.comment_end == ws_bgn - 1)) {
part.visual_end = ws_bgn;
XomwPPDPart part = stack.top.Get_current_part();
if (!(part.commentEnd != -1 && part.commentEnd == ws_bgn - 1)) {
part.visualEnd = ws_bgn;
}
// Else comments abutting, no change in visual end
part.comment_end = end_pos;
part.commentEnd = end_pos;
}
i = end_pos + 1;
inner = Bry_.Mid(src, bgn_pos, end_pos + 1);
accum.Add_str_a7("<comment>").Add_bry_escape_html(inner).Add_str_a7("</comment>");
this.preprocessToObj_comment(inner);
}
continue;
}
@ -371,26 +510,26 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
// Infinite backtrack
// Disable tag search to prevent worst-case O(N^2) performance
no_more_gt = true;
accum.Add(Bry__escaped_lt);
this.preprocessToObj_literal(Byte_ascii.Lt_bry);
i++;
continue;
}
// Handle ignored tags
if (ignored_tags.Has(name)) {
accum.Add_str_a7("<ignore>").Add_bry_escape_html(src, i, tag_end_pos + 1).Add_str_a7("</ignore>");
this.preprocessToObj_ignore(src, i, tag_end_pos + 1);
i = tag_end_pos + 1;
continue;
}
int tag_bgn_pos = i;
int atr_end = -1;
byte[] close = null;
byte[] close = this.preprocessToObj_close_init();
if (src[tag_end_pos - 1] == Byte_ascii.Slash) {
atr_end = tag_end_pos - 1;
inner = null;
i = tag_end_pos + 1;
close = Bry_.Empty;
close = this.preprocessToObj_close_init();
}
else {
atr_end = tag_end_pos;
@ -429,8 +568,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
&& elem_end_found) {
inner = Bry_.Mid(src, tag_end_pos + 1, elem_end_lhs);
i = elem_end_rhs;
tmp_bfr.Add_str_a7("<close>").Add_bry_escape_html(src, elem_end_lhs, elem_end_rhs).Add_str_a7("</close>");
close = tmp_bfr.To_bry_and_clear();
close = this.preprocessToObj_close_make(src, elem_end_lhs, elem_end_rhs);
}
else {
// No end tag
@ -443,7 +581,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
else {
// Don't match the tag, treat opening tag as literal and resume parsing.
i = tag_end_pos + 1;
accum.Add_bry_escape_html(src, tag_bgn_pos, tag_end_pos + 1);
this.preprocessToObj_literal(src, tag_bgn_pos, tag_end_pos + 1);
// Cache results, otherwise we have O(N^2) performance for input like <foo><foo><foo>...
no_more_closing_tag.Add_if_dupe_use_nth(name, name);
continue;
@ -453,28 +591,11 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
// <includeonly> and <noinclude> just become <ignore> tags
if (ignored_elements.Has(name)) {
accum.Add_str_a7("<ignore>").Add_bry_escape_html(src, tag_bgn_pos, i).Add_str_a7("</ignore>");
this.preprocessToObj_ignore(src, tag_bgn_pos, i);
continue;
}
accum.Add_str_a7("<ext>");
// PORTED:
// if ( $attrEnd <= $attrStart ) {
// $attr = '';
// } else {
// $attr = substr( $text, $attrStart, $attrEnd - $attrStart );
// }
accum.Add_str_a7("<name>").Add(name).Add_str_a7("</name>");
// Note that the attr element contains the whitespace between name and attribute,
// this is necessary for precise reconstruction during pre-save transform.
accum.Add_str_a7("<attr>");
if (atr_end > atr_bgn)
accum.Add_bry_escape_html(src, atr_bgn, atr_end);
accum.Add_str_a7("</attr>");
if (inner != null) {
accum.Add_str_a7("<inner>").Add_bry_escape_html(inner).Add_str_a7("</inner>");
}
accum.Add(close).Add_str_a7("</ext>");
this.preprocessToObj_ext(src, name, atr_bgn, atr_end, inner, close);
}
else if (found == Found__line_bgn) {
// Is this the start of a heading?
@ -482,12 +603,12 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
if (fake_line_start) {
fake_line_start = false;
} else {
accum.Add(cur_char);
this.preprocessToObj_literal(cur_char);
i++;
}
int count = XophpString.strspn_fwd__byte(src, Byte_ascii.Eq, i, 6, src_len);
if (count == 1 && find_equals) { // EX: "{{a|\n=b=\n"
if (count == 1 && findEquals) { // EX: "{{a|\n=b=\n"
// DWIM: This looks kind of like a name/value separator.
// Let's let the equals handler have it and break the
// potential heading. This is heuristic, but AFAICT the
@ -495,14 +616,14 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
// complex.
}
else if (count > 0) {
Xomw_prepro_piece piece = new Xomw_prepro_piece(Byte_ascii.Nl_bry, Byte_ascii.Nl_bry, count, i, false);
Xomw_prepro_piece piece = new Xomw_prepro_piece(Factory__part(), Byte_ascii.Nl_bry, Byte_ascii.Nl_bry, count, i, false);
piece.Add_part(Bry_.Repeat(Byte_ascii.Eq, count));
stack.Push(piece);
accum = stack.Get_accum();
accum = this.Accum__set(stack.Get_accum());
Xomw_prepro_flags flags = stack.Get_flags();
find_pipe = flags.Find_pipe;
find_equals = flags.Find_eq;
in_heading = flags.In_heading;
findPipe = flags.findPipe;
findEquals = flags.findEquals;
inHeading = flags.inHeading;
i += count;
}
}
@ -510,7 +631,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
Xomw_prepro_piece piece = stack.top;
// A heading must be open, otherwise \n wouldn't have been in the search list
if (!Bry_.Eq(piece.open, Byte_ascii.Nl_bry)) throw Err_.new_wo_type("assertion:piece must start with \\n");
Xomw_prepro_part part = piece.Get_current_part();
XomwPPDPart part = piece.Get_current_part();
// Search back through the input to see if it has a proper close.
// Do this using the reversed String since the other solutions
@ -518,17 +639,17 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
int ws_len = XophpString.strspn_bwd__space_or_tab(src, src_len - i, -1);
int search_bgn = i - ws_len;
if (part.comment_end != -1 && search_bgn -1 == part.comment_end) {
if (part.commentEnd != -1 && search_bgn -1 == part.commentEnd) {
// Comment found at line end
// Search for equals signs before the comment
search_bgn = part.visual_end;
search_bgn = part.visualEnd;
search_bgn = Bry_find_.Find_bwd__while_space_or_tab(src, search_bgn, 0);
search_bgn -= XophpString.strspn_bwd__space_or_tab(src, search_bgn, -1);
}
int count = piece.count;
int eq_len = XophpString.strspn_bwd__byte(src, Byte_ascii.Eq, search_bgn, -1);
byte[] element = Bry_.Empty;
Xomw_prepro_accum element = null;
if (eq_len > 0) {
if (search_bgn - eq_len == piece.start_pos) {
// This is just a single String of equals signs on its own line
@ -548,29 +669,29 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
}
if (count > 0) {
// Normal match, output <h>
element = tmp_bfr.Add_str_a7("<h level=\"").Add_int_variable(count).Add_str_a7("\" i=\"").Add_int_variable(heading_index).Add_str_a7("\">").Add_bfr_and_preserve(accum).Add_str_a7("</h>").To_bry_and_clear();
element = this.preprocessToObj_heading_init(count, heading_index);
heading_index++;
} else {
// Single equals sign on its own line, count=0
element = accum.To_bry();
element = accum;
}
}
else {
// No match, no <h>, just pass down the inner src
element = accum.To_bry();
element = accum;
}
// Unwind the stack
stack.Pop();
accum = stack.Get_accum();
this.accum = this.Accum__set(stack.Get_accum());
Xomw_prepro_flags flags = stack.Get_flags();
find_pipe = flags.Find_pipe;
find_equals = flags.Find_eq;
in_heading = flags.In_heading;
findPipe = flags.findPipe;
findEquals = flags.findEquals;
inHeading = flags.inHeading;
// Append the result to the enclosing accumulator
accum.Add(element);
this.preprocessToObj_heading_end(element);
// Note that we do NOT increment the input pointer.
// This is because the closing linebreak could be the opening linebreak of
// another heading. Infinite loops are avoided because the next iteration MUST
@ -584,19 +705,19 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
// we need to add to stack only if opening brace count is enough for one of the rules
if (count >= rule.min) {
// Add it to the stack
Xomw_prepro_piece piece = new Xomw_prepro_piece(cur_char, rule.end, count, -1, i > 0 && src[i - 1] == Byte_ascii.Nl);
Xomw_prepro_piece piece = new Xomw_prepro_piece(Factory__part(), cur_char, rule.end, count, -1, i > 0 && src[i - 1] == Byte_ascii.Nl);
stack.Push(piece);
accum = stack.Get_accum();
this.accum = this.Accum__set(stack.Get_accum());
Xomw_prepro_flags flags = stack.Get_flags();
find_pipe = flags.Find_pipe;
find_equals = flags.Find_eq;
in_heading = flags.In_heading;
findPipe = flags.findPipe;
findEquals = flags.findEquals;
inHeading = flags.inHeading;
}
else {
// Add literal brace(s)
for (int j = 0; j < count; j++)
accum.Add_bry_escape_html(cur_char);
this.preprocessToObj_literal(cur_char);
}
i += count;
}
@ -628,55 +749,20 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
// No matching element found in callback array
// Output a literal closing brace and continue
for (int j = 0; j < count; j++)
accum.Add_bry_escape_html(cur_char);
this.preprocessToObj_literal(cur_char);
i += count;
continue;
}
int name_type = rule.names[matching_count];
byte[] element = null;
Xomw_prepro_accum element = null;
if (name_type == Xomw_prepro_rule.Name__null) {
// No element, just literal text
tmp_bfr.Add(piece.Break_syntax(tmp_bfr, matching_count));
element = tmp_bfr.Add(Bry_.Repeat_bry(rule.end, matching_count)).To_bry_and_clear();
element = this.preprocessToObj_text(element, piece, rule.end, matching_count);
}
else {
// Create XML element
// Note: $parts is already XML, does not need to be encoded further
List_adp parts = piece.parts;
byte[] title = ((Xomw_prepro_part)parts.Get_at(0)).bfr.To_bry_and_clear();
parts.Del_at(0);
// The invocation is at the start of the line if lineStart is set in
// the stack, and all opening brackets are used up.
byte[] attr = null;
if (max_count == matching_count && piece.line_start) { // RELIC:!empty( $piece->lineStart )
attr = Bry_.new_a7(" lineStart=\"1\"");
}
else {
attr = Bry_.Empty;
}
byte[] name_bry = Xomw_prepro_rule.Name(name_type);
tmp_bfr.Add_str_a7("<").Add(name_bry).Add(attr).Add_str_a7(">");
tmp_bfr.Add_str_a7("<title>").Add(title).Add_str_a7("</title>");
int arg_idx = 1;
int parts_len = parts.Len();
for (int j = 0; j < parts_len; j++) {
Xomw_prepro_part part = (Xomw_prepro_part)parts.Get_at(j);
if (part.Eqpos != -1) {
Bry_bfr part_bfr = part.bfr;
byte[] part_bfr_bry = part_bfr.Bfr();
tmp_bfr.Add_str_a7("<part><name>").Add_mid(part_bfr_bry, 0, part.Eqpos);
tmp_bfr.Add_str_a7("</name>=<value>").Add_mid(part_bfr_bry, part.Eqpos + 1, part_bfr.Len());
tmp_bfr.Add_str_a7("</value></part>");
}
else {
tmp_bfr.Add_str_a7("<part><name index=\"").Add_int_variable(arg_idx).Add_str_a7("\" /><value>").Add(part.bfr.To_bry()).Add_str_a7("</value></part>");
arg_idx++;
}
}
element = tmp_bfr.Add_str_a7("</").Add(name_bry).Add_str_a7(">").To_bry_and_clear();
element = this.preprocessToObj_xml(piece, Xomw_prepro_rule.Name(name_type), max_count, matching_count);
}
// Advance input pointer
@ -684,7 +770,7 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
// Unwind the stack
stack.Pop();
accum = stack.Get_accum();
this.accum = this.Accum__set(stack.Get_accum());
// Re-add the old stack element if it still has unmatched opening characters remaining
if (matching_count < piece.count) {
@ -695,45 +781,38 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
int min = Get_rule(piece.open).min;
if (piece.count >= min) {
stack.Push(piece);
accum = stack.Get_accum();
this.accum = this.Accum__set(stack.Get_accum());
}
else {
accum.Add(Bry_.Repeat_bry(piece.open, piece.count));
this.preprocessToObj_literal(Bry_.Repeat_bry(piece.open, piece.count));
}
}
Xomw_prepro_flags flags = stack.Get_flags();
find_pipe = flags.Find_pipe;
find_equals = flags.Find_eq;
in_heading = flags.In_heading;
findPipe = flags.findPipe;
findEquals = flags.findEquals;
inHeading = flags.inHeading;
// Add XML element to the enclosing accumulator
accum.Add(element);
this.preprocessToObj_add_element(element);
}
else if (found == Found__pipe) {
find_equals = true; // shortcut for getFlags()
findEquals = true; // shortcut for getFlags()
stack.Add_part(Bry_.Empty);
accum = stack.Get_accum();
this.accum = this.Accum__set(stack.Get_accum());
i++;
}
else if (found == Found__equals) {
find_equals = false; // shortcut for getFlags()
stack.Get_current_part().Eqpos = accum.Len();
accum.Add_byte(Byte_ascii.Eq);
findEquals = false; // shortcut for getFlags()
this.preprocessToObj_equals(stack);
i++;
}
}
// Output any remaining unclosed brackets
Bry_bfr root_accum = stack.Get_root_accum();
int stack_len = stack.stack.Len();
for (int j = 0; j < stack_len; j++) {
Xomw_prepro_piece piece = (Xomw_prepro_piece)stack.stack.Get_at(j);
root_accum.Add(piece.Break_syntax(tmp_bfr, -1));
}
root_accum.Add_str_a7("</root>");
return root_accum.To_bry_and_clear();
return (byte[])this.preprocessToObj_term(stack);
}
private Xomw_prepro_rule Get_rule(byte[] bry) {
if (Bry_.Eq(bry, rule_curly.bgn)) return rule_curly;
else if (Bry_.Eq(bry, rule_brack.bgn)) return rule_brack;
@ -759,7 +838,6 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
, Bry__only_include_end = Bry_.new_a7("</onlyinclude>")
, Bry__comment_bgn = Bry_.new_a7("<!--")
, Bry__comment_end = Bry_.new_a7("-->")
, Bry__escaped_lt = Bry_.new_a7("&lt;")
, Bry__end_lhs = Bry_.new_a7("</")
;
private static final int Len__only_include_end = Bry__only_include_end.length;
@ -783,4 +861,28 @@ public class Xomw_prepro_wkr { // THREAD.UNSAFE: caching for repeated calls
rv.Add_obj(langv_end, new Xomw_prepro_curchar_itm(langv_end, Byte_ascii.At));
return rv;
}
protected abstract Xomw_prepro_accum Factory__accum();
protected abstract XomwPPDPart Factory__part();
protected abstract Xomw_prepro_accum Accum__set(Xomw_prepro_accum accum);
protected abstract void preprocessToObj_root();
protected abstract void preprocessToObj_ignore(byte[] src, int bgn, int end);
protected abstract void preprocessToObj_literal(byte[] src, int bgn, int end);
protected void preprocessToObj_literal(byte[] src) {this.preprocessToObj_literal(src, 0, src.length);}
protected abstract void preprocessToObj_comment(byte[] src, int bgn, int end);
protected void preprocessToObj_comment(byte[] src) {this.preprocessToObj_comment(src, 0, src.length);}
protected abstract byte[] preprocessToObj_close_init();
protected abstract byte[] preprocessToObj_close_make(byte[] src, int bgn, int end);
protected abstract void preprocessToObj_ext(byte[] src, byte[] name, int atr_bgn, int atr_end, byte[] inner, byte[] close);
protected abstract Xomw_prepro_accum preprocessToObj_heading_init(int count, int heading_index);
protected abstract void preprocessToObj_heading_end(Xomw_prepro_accum element);
protected abstract void preprocessToObj_removeLeadingWhitespaceFromEnd(int ws_len);
protected abstract Xomw_prepro_accum preprocessToObj_text(Xomw_prepro_accum element, Xomw_prepro_piece piece, byte[] rule_end, int matching_count);
protected abstract Xomw_prepro_accum preprocessToObj_xml(Xomw_prepro_piece piece, byte[] name_bry, int max_count, int matching_count);
protected abstract void preprocessToObj_add_element(Xomw_prepro_accum element);
protected abstract void preprocessToObj_equals(XomwPPDStack stack);
protected abstract Object preprocessToObj_term(XomwPPDStack stack);
public abstract XomwPreprocessor Make_new(XomwParser parser);
}

@ -0,0 +1,157 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
import gplx.core.btries.*;
import gplx.xowa.mediawiki.includes.parsers.preprocessors.*;
// THREAD.UNSAFE: caching for repeated calls
class XomwPreprocessor_DOM extends XomwPreprocessor { private final Bry_bfr tmp_bfr = Bry_bfr_.New();
private Xomw_prepro_accum__dom accum_dom = new Xomw_prepro_accum__dom("");
@Override protected Xomw_prepro_accum Factory__accum() {return Xomw_prepro_accum__dom.Instance;}
@Override protected XomwPPDPart Factory__part() {return new XomwPPDPart_DOM("");}
@Override public XomwPPNode preprocessToObj(String text, int flags) {
return null;
}
@Override public XomwPPFrame newFrame() {
return null;
}
@Override public XomwPPFrame newCustomFrame(XomwPPFrame args) {
return null;
}
@Override protected Xomw_prepro_accum Accum__set(Xomw_prepro_accum accum) {
this.accum_dom = (Xomw_prepro_accum__dom)accum;
return accum;
}
@Override protected void preprocessToObj_root() {
accum_dom.Clear();
accum_dom.Add_str_literal("<root>");
}
@Override protected void preprocessToObj_ignore(byte[] src, int bgn, int end) {
accum_dom.Add_str_literal("<ignore>").Add_str_escaped(src, bgn, end).Add_str_literal("</ignore>");
}
@Override protected void preprocessToObj_comment(byte[] src, int bgn, int end) {
accum_dom.Add_str_literal("<comment>").Add_str_escaped(src, bgn, end).Add_str_literal("</comment>");
}
@Override protected void preprocessToObj_literal(byte[] src, int bgn, int end) {
accum_dom.Add_str_escaped(src, bgn, end);
}
@Override protected void preprocessToObj_removeLeadingWhitespaceFromEnd(int ws_len) {
int accum_dom_len = accum_dom.Len();
if ( ws_len > 0
&& XophpString.strspn_fwd__space_or_tab(accum_dom.Bfr_bry(), accum_dom_len - ws_len, -1, accum_dom_len) == ws_len) {
accum_dom.Del_at_end(ws_len);
}
}
@Override protected byte[] preprocessToObj_close_init() {return Bry_.Empty;}
@Override protected byte[] preprocessToObj_close_make(byte[] src, int bgn, int end) {
return tmp_bfr.Add_str_a7("<close>").Add_bry_escape_html(src, bgn, end).Add_str_a7("</close>").To_bry_and_clear();
}
@Override protected void preprocessToObj_ext(byte[] src, byte[] name, int atr_bgn, int atr_end, byte[] inner, byte[] close) {
accum_dom.Add_str_literal("<ext>");
// PORTED:
// if ( $attrEnd <= $attrStart ) {
// $attr = '';
// } else {
// $attr = substr( $text, $attrStart, $attrEnd - $attrStart );
// }
accum_dom.Add_str_literal("<name>").Add_bry(name).Add_str_literal("</name>");
// Note that the attr element contains the whitespace between name and attribute,
// this is necessary for precise reconstruction during pre-save transform.
accum_dom.Add_str_literal("<attr>");
if (atr_end > atr_bgn)
accum_dom.Add_str_escaped(src, atr_bgn, atr_end);
accum_dom.Add_str_literal("</attr>");
if (inner != null) {
accum_dom.Add_str_literal("<inner>").Add_str_escaped(inner, 0, inner.length).Add_str_literal("</inner>");
}
accum_dom.Add_bry(close).Add_str_literal("</ext>");
}
@Override protected Xomw_prepro_accum preprocessToObj_heading_init(int count, int heading_index) {
byte[] rv = tmp_bfr.Add_str_a7("<h level=\"").Add_int_variable(count).Add_str_a7("\" i=\"").Add_int_variable(heading_index).Add_str_a7("\">").Add_str_u8(accum_dom.To_str()).Add_str_a7("</h>").To_bry_and_clear();
return new Xomw_prepro_accum__dom(String_.new_u8(rv));
}
@Override protected void preprocessToObj_heading_end(Xomw_prepro_accum element) {
accum_dom.Add_bry(((Xomw_prepro_accum__dom)element).To_bry());
}
@Override protected Xomw_prepro_accum preprocessToObj_text(Xomw_prepro_accum element_obj, Xomw_prepro_piece piece, byte[] rule_end, int matching_count) {
Xomw_prepro_accum__dom element = (Xomw_prepro_accum__dom)element_obj;
tmp_bfr.Add(piece.Break_syntax(tmp_bfr, matching_count));
if (element != null)
tmp_bfr.Add(element.To_bry());
tmp_bfr.Add(Bry_.Repeat_bry(rule_end, matching_count));
byte[] rv = tmp_bfr.To_bry_and_clear();
return new Xomw_prepro_accum__dom(String_.new_u8(rv));
}
@Override protected Xomw_prepro_accum preprocessToObj_xml(Xomw_prepro_piece piece, byte[] name_bry, int max_count, int matching_count) {
// Note: $parts is already XML, does not need to be encoded further
List_adp parts = piece.parts;
byte[] title = ((XomwPPDPart_DOM)parts.Get_at(0)).To_bry();
parts.Del_at(0);
// The invocation is at the start of the line if lineStart is set in
// the stack, and all opening brackets are used up.
byte[] attr = null;
if (max_count == matching_count && piece.line_start) { // RELIC:!empty( $piece->lineStart )
attr = Bry_.new_a7(" lineStart=\"1\"");
}
else {
attr = Bry_.Empty;
}
tmp_bfr.Add_str_a7("<").Add(name_bry).Add(attr).Add_str_a7(">");
tmp_bfr.Add_str_a7("<title>").Add(title).Add_str_a7("</title>");
int arg_idx = 1;
int parts_len = parts.Len();
for (int j = 0; j < parts_len; j++) {
XomwPPDPart_DOM part = (XomwPPDPart_DOM)parts.Get_at(j);
if (part.eqpos != -1) {
byte[] part_bfr_bry = part.To_bry();
tmp_bfr.Add_str_a7("<part><name>").Add_mid(part_bfr_bry, 0, part.eqpos);
tmp_bfr.Add_str_a7("</name>=<value>").Add_mid(part_bfr_bry, part.eqpos + 1, part.Len());
tmp_bfr.Add_str_a7("</value></part>");
}
else {
tmp_bfr.Add_str_a7("<part><name index=\"").Add_int_variable(arg_idx).Add_str_a7("\" /><value>").Add(part.To_bry()).Add_str_a7("</value></part>");
arg_idx++;
}
}
byte[] element = tmp_bfr.Add_str_a7("</").Add(name_bry).Add_str_a7(">").To_bry_and_clear();
return new Xomw_prepro_accum__dom(String_.new_u8(element));
}
@Override protected void preprocessToObj_add_element(Xomw_prepro_accum element) {
accum_dom.Add_bry(((Xomw_prepro_accum__dom)element).To_bry());
}
@Override protected void preprocessToObj_equals(XomwPPDStack stack) {
stack.Get_current_part().eqpos = accum_dom.Len();
accum_dom.Add_bry(Byte_ascii.Eq_bry);
}
@Override protected Object preprocessToObj_term(XomwPPDStack stack) {
Bry_bfr root_accum = Bry_bfr_.New().Add_str_u8(((Xomw_prepro_accum__dom)stack.Get_root_accum()).To_str());
int stack_len = stack.stack.Len();
for (int j = 0; j < stack_len; j++) {
Xomw_prepro_piece piece = (Xomw_prepro_piece)stack.stack.Get_at(j);
root_accum.Add(piece.Break_syntax(tmp_bfr, -1));
}
root_accum.Add_str_a7("</root>");
return root_accum.To_bry_and_clear();
}
@Override public XomwPreprocessor Make_new(XomwParser parser) {return new XomwPreprocessor_DOM();}
public static final XomwPreprocessor Instance = new XomwPreprocessor_DOM();
}

@ -13,10 +13,10 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
import org.junit.*;
public class Xomw_prepro_wkr__tst {
private final Xomw_prepro_wkr__fxt fxt = new Xomw_prepro_wkr__fxt();
public class XomwPreprocessor_DOM__tst {
private final XomwPreprocessor_DOM__fxt fxt = new XomwPreprocessor_DOM__fxt();
@Test public void Text() {
fxt.Test__parse("abc", "<root>abc</root>");
}
@ -218,16 +218,16 @@ public class Xomw_prepro_wkr__tst {
fxt.Test__parse("a<noinclude>b</noinclude>c", "<root>a<ignore>&lt;noinclude&gt;</ignore>b<ignore>&lt;/noinclude&gt;</ignore>c</root>");
}
}
class Xomw_prepro_wkr__fxt {
private final Xomw_prepro_wkr wkr = new Xomw_prepro_wkr();
class XomwPreprocessor_DOM__fxt {
private final XomwPreprocessor_DOM wkr = new XomwPreprocessor_DOM();
private boolean for_inclusion = false;
public Xomw_prepro_wkr__fxt() {
public XomwPreprocessor_DOM__fxt() {
wkr.Init_by_wiki("pre");
}
public void Init__for_inclusion_(boolean v) {for_inclusion = v;}
public void Test__parse(String src_str, String expd) {
byte[] src_bry = Bry_.new_u8(src_str);
byte[] actl = wkr.Preprocess_to_xml(src_bry, for_inclusion);
byte[] actl = wkr.preprocessToXml(src_bry, for_inclusion);
Tfds.Eq_str_lines(expd, String_.new_u8(actl), src_str);
}
}

@ -0,0 +1,187 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
import gplx.xowa.mediawiki.includes.parsers.preprocessors.*;
class XomwPreprocessor_Hash extends XomwPreprocessor { private XophpArray accum = new XophpArray();
@Override public XomwPPNode preprocessToObj(String text, int flags) {
return null;
}
@Override public XomwPPFrame newFrame() {
return null;
}
@Override public XomwPPFrame newCustomFrame(XomwPPFrame args) {
return null;
}
@Override protected Xomw_prepro_accum Factory__accum() {return Xomw_prepro_accum__hash.Instance;}
@Override protected XomwPPDPart Factory__part() {return new XomwPPDPart_Hash("");}
@Override protected Xomw_prepro_accum Accum__set(Xomw_prepro_accum accum) {return accum;}
@Override protected void preprocessToObj_root() {} // NOTE: deliberately empty;
@Override protected void preprocessToObj_ignore(byte[] src, int bgn, int end) {
accum.Add(XophpArray.New("ignore", XophpString.substr(src, bgn, end)));
}
@Override protected void preprocessToObj_literal(byte[] src, int bgn, int end) {
addLiteral(accum, XophpString.substr(src, bgn, end));
}
@Override protected void preprocessToObj_comment(byte[] src, int bgn, int end) {
accum.Add(XophpArray.New("comment", XophpString.substr(src, bgn, end)));
}
@Override protected void preprocessToObj_removeLeadingWhitespaceFromEnd(int ws_len) {
int endIndex = accum.Len() - 1;
if ( ws_len > 0
&& endIndex >= 0) {
Object itm_obj = accum.Get(endIndex);
if (Type_.Eq_by_obj(itm_obj, Bry_.Cls_ref_type)) {
byte[] itm = (byte[])itm_obj;
if (XophpString.strspn_fwd__space_or_tab(itm, 0, itm.length, itm.length) == ws_len) {
accum.Set(endIndex, XophpString.substr(itm, 0, -ws_len));
}
}
}
}
@Override protected byte[] preprocessToObj_close_init() {return null;}
@Override protected byte[] preprocessToObj_close_make(byte[] src, int bgn, int end) {
return Bry_.Mid(src, bgn, end);
}
@Override protected void preprocessToObj_ext(byte[] src, byte[] name, int atr_bgn, int atr_end, byte[] inner, byte[] close) {
XophpArray children = XophpArray.New();
children.Add(XophpArray.New("name", name));
children.Add(XophpArray.New("attr", Bry_.Mid(src, atr_bgn, atr_end)));
if (inner != null)
children.Add(XophpArray.New("inner", inner));
if (close != null)
children.Add(XophpArray.New("close", close));
accum.Add(XophpArray.New("ext", children));
}
@Override protected Xomw_prepro_accum preprocessToObj_heading_init(int count, int heading_index) {
Xomw_prepro_accum__hash rv = new Xomw_prepro_accum__hash();
rv.Ary().Add
( XophpArray.New
( "possible-h",
XophpArrayUtl.array_merge
( XophpArray.New
( XophpArray.New("@level", XophpArray.New(count))
, XophpArray.New("@i" , XophpArray.New(heading_index))
)
, accum
)
)
);
return rv;
}
@Override protected void preprocessToObj_heading_end(Xomw_prepro_accum element) {
XophpArrayUtl.array_splice(accum, accum.Len(), 0, ((Xomw_prepro_accum__hash)element).Ary());
}
@Override protected Xomw_prepro_accum preprocessToObj_text(Xomw_prepro_accum element_obj, Xomw_prepro_piece piece, byte[] rule_end, int matching_count) {
Xomw_prepro_accum__hash element = (Xomw_prepro_accum__hash)element_obj;
// element = piece.breakSyntax(matchingCount);
addLiteral(element.Ary(), String_.new_u8(Bry_.Repeat_bry(rule_end, matching_count)));
return element;
}
@Override protected Xomw_prepro_accum preprocessToObj_xml(Xomw_prepro_piece piece, byte[] name_bry, int max_count, int matching_count) {
List_adp parts = piece.parts;
byte[] title = ((XomwPPDPart_DOM)parts.Get_at(0)).To_bry();
parts.Del_at(0);
XophpArray children = XophpArray.New();
// The invocation is at the start of the line if lineStart is set in
// the stack, and all opening brackets are used up.
if (max_count == matching_count && piece.line_start) { // RELIC:!empty( $piece->lineStart )
children.Add(XophpArray.New("@lineStart", XophpArray.New(1)));
}
XophpArray titleNode = XophpArray.New("title", title);
children.Add(titleNode);
// int argIndex = 1;
int parts_len = parts.Len();
for (int j = 0; j < parts_len; j++) {
XomwPPDPart part = (XomwPPDPart)parts.Get_at(j);
if (part.eqpos != -1) {
/*
Object equalsNode = part.Out()[part.eqpos];
XophpArray nameNode = XophpArray.New("name" , XophpArrayUtl.array_splice(part.Out(), 0, part.eqpos));
XophpArray valueNode = XophpArray.New("value", XophpArrayUtl.array_splice(part.Out(), part.eqpos + 1));
XophpArray partNode = XophpArray.New("part", XophpArray.New(nameNode, equalsNode, valueNode));
children.Add(partNode);
*/
}
else {
/*
XophpArray nameNode = XophpArray.New("name" , XophpArray.New(XophpArray.New("@index", XophpArray.New(argIndex++))));
XophpArray valueNode = XophpArray.New("value", part.Out());
XophpArray partNode = XophpArray.New("part", XophpArray.New(nameNode, valueNode));
children.Add(partNode);
*/
}
}
// XophpArray element = XophpArray.New(XophpArray.New(name, children));
// return new Xomw_prepro_piece__hash(element);
return null;
}
@Override protected void preprocessToObj_add_element(Xomw_prepro_accum element) {
XophpArrayUtl.array_splice(accum, accum.Len(), 0, ((Xomw_prepro_accum__hash)element).Ary());
}
@Override protected void preprocessToObj_equals(XomwPPDStack stack) {
accum.Add(XophpArray.New("equals", XophpArray.New("=")));
stack.Get_current_part().eqpos = accum.Len() - 1;
}
@Override protected Object preprocessToObj_term(XomwPPDStack stack) {
// for ( $stack->stack as $piece ) {
// array_splice( $stack->rootAccum, count( $stack->rootAccum ), 0, $piece->breakSyntax() );
// }
//
// # Enable top-level headings
// for ( $stack->rootAccum as &$node ) {
// if ( is_array( $node ) && $node[PPNode_Hash_Tree::NAME] === 'possible-h' ) {
// $node[PPNode_Hash_Tree::NAME] = 'h';
// }
// }
//
// $rootStore = [ [ 'root', $stack->rootAccum ] ];
// $rootNode = new PPNode_Hash_Tree( $rootStore, 0 );
//
// // Cache
// $tree = json_encode( $rootStore, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
// if ( $tree !== false ) {
// $this->cacheSetTree( $text, $flags, $tree );
// }
//
// return $rootNode;
return null;
}
private static void addLiteral(XophpArray accum, byte[] text) {addLiteral(accum, String_.new_u8(text));}
private static void addLiteral(XophpArray accum, String text) {
int n = accum.Len();
if (n > 0) {
Object itm = accum.Get(n - 1);
if (itm != null) {
accum.Set(n - 1, ((String)itm) + text);
return;
}
}
accum.Add(text);
}
@Override public XomwPreprocessor Make_new(XomwParser parser) {return new XomwPreprocessor_Hash();}
public static final XomwPreprocessor Instance = new XomwPreprocessor_Hash();
}

@ -0,0 +1,48 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
// MW.FILE:Preprocessor_DOM
/**
* @ingroup Parser
*/
public abstract class XomwPPDPart {
/**
* @var String Output accumulator String
*/
// private final byte[] output;
// Optional member variables:
// eqpos Position of equals sign in output accumulator
// commentEnd Past-the-end input pointer for the last comment encountered
// visualEnd Past-the-end input pointer for the end of the accumulator minus comments
public int eqpos = -1;
public int commentEnd = -1;
public int visualEnd = -1;
public XomwPPDPart(String output) {
// accum.Add_bry(Bry_.new_u8(output));
// bfr = ((Xomw_prepro_accum__dom)accum).Bfr();
}
// private final Xomw_prepro_accum__dom accum = new Xomw_prepro_accum__dom("");
// private final Bry_bfr bfr;
public abstract Xomw_prepro_accum Accum();
//
// public Bry_bfr Bfr() {return bfr;}
// public int Len() {return bfr.Len();}
// public byte[] To_bry() {return bfr.To_bry();}
public abstract XomwPPDPart Make_new(String val);
}

@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
// MW.FILE:NONE
public class XomwPPDPart_DOM extends XomwPPDPart { // @codingStandardsIgnoreEnd
private final Bry_bfr bfr;
private final Xomw_prepro_accum__dom accum = new Xomw_prepro_accum__dom("");
public XomwPPDPart_DOM(String output) {super(output);
bfr = accum.Bfr();
if (output != String_.Empty) {
bfr.Add_str_u8(output);
}
}
@Override public Xomw_prepro_accum Accum() {return accum;}
public Bry_bfr Bfr() {return bfr;}
public int Len() {return bfr.Len();}
public byte[] To_bry() {return bfr.To_bry();}
@Override public XomwPPDPart Make_new(String val) {
return new XomwPPDPart_DOM(val);
}
}

@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
// MW.FILE:Preprocessor_Hash
/**
* @ingroup Parser
*/
// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
public class XomwPPDPart_Hash extends XomwPPDPart { // @codingStandardsIgnoreEnd
private final Xomw_prepro_accum__hash accum = new Xomw_prepro_accum__hash();
public XomwPPDPart_Hash(String output) {super(output);
if (output != String_.Empty) {
accum.Ary().Add(output);
}
}
@Override public Xomw_prepro_accum Accum() {return accum;}
@Override public XomwPPDPart Make_new(String val) {
return new XomwPPDPart_Hash(val);
}
}

@ -0,0 +1,94 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
// MW.FILE:Preprocessor_DOM
/**
* Stack class to help Preprocessor::preprocessToObj()
* @ingroup Parser
*/
public class XomwPPDStack {
public final List_adp stack = List_adp_.New();
public Xomw_prepro_piece top;
private final Xomw_prepro_flags flags = new Xomw_prepro_flags();
private Xomw_prepro_accum root_accum, accum;
public XomwPPDStack(Xomw_prepro_accum prototype) {
root_accum = prototype.Make_new();
accum = root_accum;
}
public void Clear() {
stack.Clear();
accum.Clear();
top = null;
}
public int Count() {return stack.Len();}
public Xomw_prepro_accum Get_accum() {return accum;}
public Xomw_prepro_accum Get_root_accum() {return root_accum;}
public XomwPPDPart Get_current_part() {
if (top == null) {
return null;
}
else {
return top.Get_current_part();
}
}
public void Push(Xomw_prepro_piece item) {
stack.Add(item);
this.top = (Xomw_prepro_piece)stack.Get_at(stack.Len() - 1);
accum = top.Get_accum();
}
public Xomw_prepro_piece Pop() {
int len = stack.Count();
if (len == 0) {
throw Err_.new_wo_type("XomwPPDStack: no elements remaining");
}
Xomw_prepro_piece rv = (Xomw_prepro_piece)stack.Get_at(len - 1);
stack.Del_at(len - 1);
len--;
if (len > 0) {
this.top = (Xomw_prepro_piece)stack.Get_at(stack.Len() - 1);
this.accum = top.Get_accum();
} else {
this.top = null;
this.accum = root_accum;
}
return rv;
}
public void Add_part(byte[] bry) {
top.Add_part(bry);
accum = top.Get_accum();
}
public Xomw_prepro_flags Get_flags() {
if (stack.Count() == 0) {
flags.findEquals = false;
flags.findPipe = false;
flags.inHeading = false;
return flags;
}
else {
top.Set_flags(flags);
return flags;
}
}
}

@ -0,0 +1,199 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
// MW.FILE:Preprocessor
/**
* @ingroup Parser
*/
public abstract class XomwPPFrame {
public static final int NO_ARGS = 1;
public static final int NO_TEMPLATES = 2;
public static final int STRIP_COMMENTS = 4;
public static final int NO_IGNORE = 8;
public static final int RECOVER_COMMENTS = 16;
public static final int NO_TAGS = 32;
public static final int RECOVER_ORIG = 59; // = 1|2|8|16|32 no constant expression support in PHP yet
/** This constant exists when $indexOffset is supported in newChild() */
public static final int SUPPORTS_INDEX_OFFSET = 1;
/**
* Create a child frame
*
* @param array|boolean $args
* @param boolean|Title $title
* @param int $indexOffset A number subtracted from the index attributes of the arguments
*
* @return PPFrame
*/
public abstract XomwPPFrame newChild(Object args, XomwTitle title, int indexOffset);
/**
* Expand a document tree node, caching the result on its parent with the given key
* @param String|int $key
* @param String|PPNode $root
* @param int $flags
* @return String
*/
public abstract String cachedExpand(String key, XomwPPNode root, int flags);
/**
* Expand a document tree node
* @param String|PPNode $root
* @param int $flags
* @return String
*/
public abstract String expand(XomwPPNode root, int flags);
/**
* Implode with flags for expand()
* @param String $sep
* @param int $flags
* @param String|PPNode $args,...
* @return String
*/
public abstract String implodeWithFlags(String sep, int flags, Object... args);
/**
* Implode with no flags specified
* @param String $sep
* @param String|PPNode $args,...
* @return String
*/
public abstract String implode(String sep, Object... args);
/**
* Makes an Object that, when expand()ed, will be the same as one obtained
* with implode()
* @param String $sep
* @param String|PPNode $args,...
* @return PPNode
*/
public abstract XomwPPNode virtualImplode(String sep, Object... args);
/**
* Virtual implode with brackets
* @param String $start
* @param String $sep
* @param String $end
* @param String|PPNode $args,...
* @return PPNode
*/
public abstract XomwPPNode virtualBracketedImplode(String start, String sep, String end, Object... args);
/**
* Returns true if there are no arguments in this frame
*
* @return boolean
*/
public abstract boolean isEmpty();
/**
* Returns all arguments of this frame
* @return array
*/
public abstract Object[] getArguments();
/**
* Returns all numbered arguments of this frame
* @return array
*/
public abstract Object[] getNumberedArguments();
/**
* Returns all named arguments of this frame
* @return array
*/
public abstract Object[] getNamedArguments();
/**
* Get an argument to this frame by name
* @param int|String $name
* @return String|boolean
*/
public abstract String getArgument(String name);
/**
* Returns true if the infinite loop check is OK, false if a loop is detected
*
* @param Title $title
* @return boolean
*/
public abstract boolean loopCheck(XomwTitle title);
/**
* Return true if the frame is a template frame
* @return boolean
*/
public abstract boolean isTemplate();
/**
* Set the "volatile" flag.
*
* Note that this is somewhat of a "hack" in order to make extensions
* with side effects (such as Cite) work with the PHP parser. New
* extensions should be written in a way that they do not need this
* function, because other parsers (such as Parsoid) are not guaranteed
* to respect it, and it may be removed in the future.
*
* @param boolean $flag
*/
public abstract void setVolatile(boolean flag);
/**
* Get the "volatile" flag.
*
* Callers should avoid caching the result of an expansion if it has the
* volatile flag set.
*
* @see self::setVolatile()
* @return boolean
*/
public abstract boolean isVolatile();
/**
* Get the TTL of the frame's output.
*
* This is the maximum amount of time, in seconds, that this frame's
* output should be cached for. A value of null indicates that no
* maximum has been specified.
*
* Note that this TTL only applies to caching frames as parts of pages.
* It is not relevant to caching the entire rendered output of a page.
*
* @return int|null
*/
public abstract int getTTL();
/**
* Set the TTL of the output of this frame and all of its ancestors.
* Has no effect if the new TTL is greater than the one already set.
* Note that it is the caller's responsibility to change the cache
* expiry of the page as a whole, if such behavior is desired.
*
* @see self::getTTL()
* @param int $ttl
*/
public abstract void setTTL(int ttl);
/**
* Get a title of frame
*
* @return Title
*/
public abstract XomwTitle getTitle();
}

@ -0,0 +1,108 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
// MW.FILE:Preprocessor
/**
* There are three types of nodes:
* * Tree nodes, which have a name and contain other nodes as children
* * Array nodes, which also contain other nodes but aren't considered part of a tree
* * Leaf nodes, which contain the actual data
*
* This interface provides access to the tree structure and to the contents of array nodes,
* but it does not provide access to the @gplx.Internal protected structure of leaf nodes. Access to leaf
* data is provided via two means:
* * PPFrame::expand(), which provides expanded text
* * The PPNode::split*() functions, which provide metadata about certain types of tree node
* @ingroup Parser
*/
public abstract class XomwPPNode {
/**
* Get an array-type node containing the children of this node.
* Returns false if this is not a tree node.
* @return PPNode
*/
public abstract XomwPPNode[] getChildren();
/**
* Get the first child of a tree node. False if there isn't one.
*
* @return PPNode
*/
public abstract XomwPPNode getFirstChild();
/**
* Get the next sibling of any node. False if there isn't one
* @return PPNode
*/
public abstract XomwPPNode getNextSibling();
/**
* Get all children of this tree node which have a given name.
* Returns an array-type node, or false if this is not a tree node.
* @param String $type
* @return boolean|PPNode
*/
public abstract XomwPPNode getChildrenOfType(String type);
/**
* Returns the length of the array, or false if this is not an array-type node
*/
public abstract int getLength();
/**
* Returns an item of an array-type node
* @param int $i
* @return boolean|PPNode
*/
public abstract XomwPPNode item(int i);
/**
* Get the name of this node. The following names are defined here:
*
* h A heading node.
* template A double-brace node.
* tplarg A triple-brace node.
* title The first argument to a template or tplarg node.
* part Subsequent arguments to a template or tplarg node.
* #nodelist An array-type node
*
* The subclass may define various other names for tree and leaf nodes.
* @return String
*/
public abstract String getName();
/**
* Split a "<part>" node into an associative array containing:
* name PPNode name
* index String index
* value PPNode value
* @return array
*/
public abstract Hash_adp splitArg();
/**
* Split an "<ext>" node into an associative array containing name, attr, inner and close
* All values in the resulting array are PPNodes. Inner and close are optional.
* @return array
*/
public abstract Hash_adp splitExt();
/**
* Split an "<h>" node
* @return array
*/
public abstract Hash_adp splitHeading();
}

@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_frame_itm {
public byte[] Expand(byte[] ttl) {
return null;

@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
// public class Xomw_frame_wkr { // THREAD.UNSAFE: caching for repeated calls
// private final Xomw_parser parser;
// public Xomw_frame_wkr(Xomw_parser parser) {

@ -0,0 +1,20 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public interface Xomw_prepro_accum {
void Clear();
Xomw_prepro_accum Make_new();
}

@ -0,0 +1,54 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_accum__dom implements Xomw_prepro_accum {
private final Bry_bfr bfr = Bry_bfr_.New();
public Xomw_prepro_accum__dom(String val) {
this.Add_str_literal(val);
}
public Xomw_prepro_accum__dom Add_str_literal(String val) {
bfr.Add_str_u8(val);
return this;
}
public Bry_bfr Bfr() {return bfr;}
public byte[] Bfr_bry() {return bfr.Bfr();}
public int Len() {return bfr.Len();}
public void Clear() {bfr.Clear();}
public Xomw_prepro_accum__dom Add_str_escaped(byte[] src, int bgn, int end) {
bfr.Add_bry_escape_html(src, bgn, end);
return this;
}
public Xomw_prepro_accum__dom Add_bry(byte[] val) {
bfr.Add(val);
return this;
}
public Xomw_prepro_accum__dom Add_bry(byte[] val, int bgn, int end) {
bfr.Add_mid(val, bgn, end);
return this;
}
public void Del_at_end(int count) {
bfr.Del_by(count);
}
public String To_str() {
return bfr.To_str();
}
public byte[] To_bry() {
return bfr.To_bry();
}
public static final Xomw_prepro_accum__dom Instance = new Xomw_prepro_accum__dom("");
public Xomw_prepro_accum Make_new() {return new Xomw_prepro_accum__dom("");}
}

@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_accum__hash implements Xomw_prepro_accum {
public Xomw_prepro_accum__hash() {
}
public XophpArray Ary() {return ary;} private final XophpArray ary = new XophpArray();
public void Clear() {ary.Clear();}
public static final Xomw_prepro_accum__hash Instance = new Xomw_prepro_accum__hash();
public Xomw_prepro_accum Make_new() {return new Xomw_prepro_accum__hash();}
}

@ -0,0 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_curchar_itm {
public Xomw_prepro_curchar_itm(byte[] bry, byte type) {
this.bry = bry;
this.type = type;
}
public byte[] bry;
public byte type;
}

@ -0,0 +1,28 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_elem {
private static final byte[] Bry__tag_end = Bry_.new_a7("</");
public Xomw_prepro_elem(int type, byte[] name) {
this.type = type;
this.name = name;
this.tag_end_lhs = Bry_.Add(Bry__tag_end, name);
}
public final int type;
public final byte[] name;
public final byte[] tag_end_lhs;
public static final int Type__comment = 0, Type__other = 1;
}

@ -0,0 +1,21 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_flags {
public boolean findPipe;
public boolean findEquals;
public boolean inHeading;
}

@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public interface Xomw_prepro_node {
int Subs__len();
Xomw_prepro_node Subs__get_at(int i);

@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public abstract class Xomw_prepro_node__base implements Xomw_prepro_node {
private List_adp subs;
public int Subs__len() {return subs == null ? 0 : subs.Len();}

@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_node__part extends Xomw_prepro_node__base {
public Xomw_prepro_node__part(int idx, byte[] key, byte[] val) {
this.idx = idx;

@ -13,7 +13,7 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_node__template extends Xomw_prepro_node__base {
public Xomw_prepro_node__template(byte[] title, Xomw_prepro_node__part[] parts, int line_start) {
this.title = title; this.parts = parts; this.line_start = line_start;

@ -0,0 +1,85 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_piece {
public final byte[] open; // Opening character (\n for heading)
public final byte[] close; // Matching closing char;
public int count; // Number of opening characters found (number of "=" for heading)
public final boolean line_start; // True if the open char appeared at the start of the input line; Not set for headings.
public final int start_pos;
public List_adp parts = List_adp_.New();
private final XomwPPDPart part_factory;
public Xomw_prepro_piece(XomwPPDPart part_factory, byte[] open, byte[] close, int count, int start_pos, boolean line_start) {
this.part_factory = part_factory;
this.open = open;
this.close = close;
this.count = count;
this.start_pos = start_pos;
this.line_start = line_start;
parts.Add(part_factory.Make_new(""));
}
public void Parts__renew() {
parts.Clear();
this.Add_part(Bry_.Empty);
}
public XomwPPDPart Get_current_part() {
return (XomwPPDPart)parts.Get_at(parts.Len() - 1);
}
public Xomw_prepro_accum Get_accum() {
return Get_current_part().Accum();
}
public void Add_part(byte[] bry) {
parts.Add(part_factory.Make_new(String_.new_u8(bry)));
}
public static final byte[] Brack_bgn_bry = Bry_.new_a7("[");
public void Set_flags(Xomw_prepro_flags flags) {
int parts_len = parts.Len();
boolean open_is_nl = Bry_.Eq(open, Byte_ascii.Nl_bry);
boolean findPipe = !open_is_nl && !Bry_.Eq(open, Brack_bgn_bry);
flags.findPipe = findPipe;
flags.findEquals = findPipe && parts_len > 1 && ((XomwPPDPart)parts.Get_at(parts_len - 1)).eqpos != -1;
flags.inHeading = open_is_nl;
}
// Get the output String that would result if the close is not found.
public byte[] Break_syntax(Bry_bfr tmp_bfr, int opening_count) {
byte[] rv = Bry_.Empty;
if (Bry_.Eq(open, Byte_ascii.Nl_bry)) {
rv = ((XomwPPDPart_DOM)parts.Get_at(0)).To_bry();
}
else {
if (opening_count == -1) {
opening_count = count;
}
tmp_bfr.Add(Bry_.Repeat_bry(open, opening_count));
// concat parts with "|"
boolean first = true;
int len = parts.Len();
for (int i = 0; i < len; i++) {
XomwPPDPart part = (XomwPPDPart)parts.Get_at(i);
if (first) {
first = false;
}
else {
tmp_bfr.Add_byte_pipe();
}
tmp_bfr.Add(((XomwPPDPart_DOM)part).To_bry());
}
rv = tmp_bfr.To_bry_and_clear();
}
return rv;
}
}

@ -13,8 +13,8 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
class Xomw_prepro_rule {
package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
public class Xomw_prepro_rule {
public Xomw_prepro_rule(byte[] bgn, byte[] end, int min, int max, int[] names) {
this.bgn = bgn;
this.end = end;
@ -42,23 +42,3 @@ class Xomw_prepro_rule {
}
}
}
class Xomw_prepro_elem {
private static final byte[] Bry__tag_end = Bry_.new_a7("</");
public Xomw_prepro_elem(int type, byte[] name) {
this.type = type;
this.name = name;
this.tag_end_lhs = Bry_.Add(Bry__tag_end, name);
}
public final int type;
public final byte[] name;
public final byte[] tag_end_lhs;
public static final int Type__comment = 0, Type__other = 1;
}
class Xomw_prepro_curchar_itm {
public Xomw_prepro_curchar_itm(byte[] bry, byte type) {
this.bry = bry;
this.type = type;
}
public byte[] bry;
public byte type;
}

@ -1,168 +0,0 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.mediawiki.includes.parsers.prepros; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*; import gplx.xowa.mediawiki.includes.parsers.*;
class Xomw_prepro_stack {
public List_adp stack = List_adp_.New();
public Xomw_prepro_piece top;
private Bry_bfr root_accum = Bry_bfr_.New(), accum;
private final Xomw_prepro_flags flags = new Xomw_prepro_flags();
public Xomw_prepro_stack() {
accum = root_accum;
}
public void Clear() {
stack.Clear();
accum.Clear();
top = null;
}
public int Count() {return stack.Len();}
public Bry_bfr Get_accum() {return accum;}
public Bry_bfr Get_root_accum() {return root_accum;}
public Xomw_prepro_part Get_current_part() {
if (top == null) {
return null;
}
else {
return top.Get_current_part();
}
}
public void Push(Xomw_prepro_piece item) {
stack.Add(item);
this.top = (Xomw_prepro_piece)stack.Get_at(stack.Len() - 1);
accum = top.Get_accum();
}
public Xomw_prepro_piece Pop() {
int len = stack.Count();
if (len == 0) {
throw Err_.new_wo_type("Xomw_prepro_stack: no elements remaining");
}
Xomw_prepro_piece rv = (Xomw_prepro_piece)stack.Get_at(len - 1);
stack.Del_at(len - 1);
len--;
if (len > 0) {
this.top = (Xomw_prepro_piece)stack.Get_at(stack.Len() - 1);
accum = top.Get_accum();
} else {
this.top = null;
this.accum = root_accum;
}
return rv;
}
public void Add_part(byte[] bry) {
top.Add_part(bry);
accum = top.Get_accum();
}
public Xomw_prepro_flags Get_flags() {
if (stack.Count() == 0) {
flags.Find_eq = false;
flags.Find_pipe = false;
flags.In_heading = false;
return flags;
}
else {
top.Set_flags(flags);
return flags;
}
}
}
class Xomw_prepro_flags {
public boolean Find_pipe;
public boolean Find_eq;
public boolean In_heading;
}
class Xomw_prepro_piece {
public final byte[] open; // Opening character (\n for heading)
public final byte[] close; // Matching closing char;
public int count; // Number of opening characters found (number of "=" for heading)
public final boolean line_start; // True if the open char appeared at the start of the input line; Not set for headings.
public final int start_pos;
public List_adp parts = List_adp_.New();
public Xomw_prepro_piece(byte[] open, byte[] close, int count, int start_pos, boolean line_start) {
this.open = open;
this.close = close;
this.count = count;
this.start_pos = start_pos;
this.line_start = line_start;
parts.Add(new Xomw_prepro_part(Bry_.Empty));
}
public void Parts__renew() {
parts.Clear();
this.Add_part(Bry_.Empty);
}
public Xomw_prepro_part Get_current_part() {
return (Xomw_prepro_part)parts.Get_at(parts.Len() - 1);
}
public Bry_bfr Get_accum() {
return Get_current_part().bfr;
}
public void Add_part(byte[] bry) {
parts.Add(new Xomw_prepro_part(bry));
}
public static final byte[] Brack_bgn_bry = Bry_.new_a7("[");
public void Set_flags(Xomw_prepro_flags flags) {
int parts_len = parts.Len();
boolean open_is_nl = Bry_.Eq(open, Byte_ascii.Nl_bry);
boolean find_pipe = !open_is_nl && !Bry_.Eq(open, Brack_bgn_bry);
flags.Find_pipe = find_pipe;
flags.Find_eq = find_pipe && parts_len > 1 && ((Xomw_prepro_part)parts.Get_at(parts_len - 1)).Eqpos != -1;
flags.In_heading = open_is_nl;
}
// Get the output String that would result if the close is not found.
public byte[] Break_syntax(Bry_bfr tmp_bfr, int opening_count) {
byte[] rv = Bry_.Empty;
if (Bry_.Eq(open, Byte_ascii.Nl_bry)) {
rv = ((Xomw_prepro_part)parts.Get_at(0)).bfr.To_bry();
}
else {
if (opening_count == -1) {
opening_count = count;
}
tmp_bfr.Add(Bry_.Repeat_bry(open, opening_count));
// concat parts with "|"
boolean first = true;
int len = parts.Len();
for (int i = 0; i < len; i++) {
Xomw_prepro_part part = (Xomw_prepro_part)parts.Get_at(i);
if (first) {
first = false;
}
else {
tmp_bfr.Add_byte_pipe();
}
tmp_bfr.Add(part.bfr.To_bry());
}
rv = tmp_bfr.To_bry_and_clear();
}
return rv;
}
}
class Xomw_prepro_part {
public Xomw_prepro_part(byte[] bry) {
bfr.Add(bry);
}
public final Bry_bfr bfr = Bry_bfr_.New();
public int Eqpos = -1;
public int comment_end = -1;
public int visual_end = -1;
}
Loading…
Cancel
Save