mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
Xomw.Preprocessor: Start integrating Preprocessor_Hash [#508]
This commit is contained in:
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;
|
||||
}
|
||||
|
77
400_xowa/src/gplx/xowa/mediawiki/Char_bfr.java
Normal file
77
400_xowa/src/gplx/xowa/mediawiki/Char_bfr.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
228
400_xowa/src/gplx/xowa/mediawiki/XophpArrayUtl_tst.java
Normal file
228
400_xowa/src/gplx/xowa/mediawiki/XophpArrayUtl_tst.java
Normal file
@ -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,15 +285,17 @@ 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';
|
||||
|
||||
this.mPreprocessorClass = XomwPreprocessor_DOM.Instance;
|
||||
// if (isset($conf['preprocessorClass'])) {
|
||||
// this.mPreprocessorClass = $conf['preprocessorClass'];
|
||||
// } elseif (defined('HPHP_VERSION')) {
|
||||
@ -306,7 +311,7 @@ public class XomwParser implements XomwParserIface {
|
||||
// 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)) {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
// }
|
||||
//
|
||||
// $dom = this.preprocessToDom($text);
|
||||
// $flags = $argsOnly ? PPFrame::NO_TEMPLATES : 0;
|
||||
// $text = $frame->expand($dom, $flags);
|
||||
//
|
||||
// return $text;
|
||||
// }
|
||||
//
|
||||
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
|
||||
// */
|
||||
|
||||
/**
|
||||
* 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("<")
|
||||
, 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><noinclude></ignore>b<ignore></noinclude></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…
Reference in New Issue
Block a user