diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java b/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java
index ce1f880ee..b40d86f69 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/XophpArray.java
@@ -19,6 +19,7 @@ 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 int Count() {return hash.Len();}
public void Clear() {
hash.Clear();
nxt_idx = 0;
diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpArrayUtl.java b/400_xowa/src/gplx/xowa/mediawiki/XophpArrayUtl.java
index 780657d25..1e7213b1a 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/XophpArrayUtl.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/XophpArrayUtl.java
@@ -17,6 +17,13 @@ package gplx.xowa.mediawiki; import gplx.*; import gplx.xowa.*;
public class XophpArrayUtl {
public static boolean popBoolOrN(List_adp list) {return Bool_.Cast(List_adp_.Pop_or(list, false));}
public static byte[] popBryOrNull(List_adp list) {return (byte[])List_adp_.Pop_or(list, null);}
+ public static Object pop_obj(XophpArray array) {
+ int array_count = array.Count();
+ if (array_count == 0) return null;
+ Object rv = array.Get_at(array_count - 1);
+ array.Del_at(array_count - 1);
+ return rv;
+ }
public static boolean isset(XophpArray ary, int idx) {
return ary.Get_at(idx) == null;
}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpString.java b/400_xowa/src/gplx/xowa/mediawiki/XophpString.java
index 2618fb19c..93ff1ae76 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/XophpString.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/XophpString.java
@@ -158,4 +158,14 @@ public class XophpString {
return pos == Bry_find_.Not_found ? null : Bry_.Mid(src, pos, src.length);
}
public static int strlen(byte[] src) {return src.length;}
+ public static String str_repeat(String val, int count) {
+ int val_len = String_.Len(val);
+ char[] chry = new char[val_len];
+ for (int i = 0; i < count; i++) {
+ for (int j = 0; i < val_len; j++) {
+ chry[(i * val_len) + j] = String_.CharAt(val, j);
+ }
+ }
+ return String_.new_charAry_(chry, 0, val_len);
+ }
}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/XophpTypeUtl.java b/400_xowa/src/gplx/xowa/mediawiki/XophpTypeUtl.java
index e713e382f..08c668330 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/XophpTypeUtl.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/XophpTypeUtl.java
@@ -29,4 +29,6 @@ public class XophpTypeUtl {
return false;
}
}
+
+ public static boolean is_string(Object obj) {return Type_.Eq_by_obj(obj, String.class);}
}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/XomwExceptionUtl.java b/400_xowa/src/gplx/xowa/mediawiki/includes/XomwExceptionUtl.java
deleted file mode 100644
index 86326a0a2..000000000
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/XomwExceptionUtl.java
+++ /dev/null
@@ -1,21 +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; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*;
-public class XomwExceptionUtl {
- public static Err New_by_method(Class> type, String method, String msg) {
- return Err_.new_wo_type(Type_.Name(type) + "." + method + ":" + msg);
- }
-}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java b/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java
index e2087963f..194c83cce 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/exception/XomwMWException.java
@@ -17,4 +17,7 @@ package gplx.xowa.mediawiki.includes.exception; import gplx.*; import gplx.xowa.
public class XomwMWException extends Err {
public XomwMWException(String msg) {super(true, "", "", msg);
}
+ public static Err New_by_method(Class> type, String method, String msg) {
+ return Err_.new_wo_type(Type_.Name(type) + "." + method + ":" + msg);
+ }
}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor.java
index 728bcc290..3d95d6781 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor.java
@@ -155,7 +155,7 @@ public abstract class XomwPreprocessor {
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 XomwPPDStack stack;
+ private final XomwPPDStackOld stack;
private final Btrie_rv trv = new Btrie_rv();
private Xomw_prepro_accum accum = null;
@@ -864,7 +864,7 @@ public abstract class XomwPreprocessor {
}
protected abstract XomwPPDPart Factory__part();
- protected abstract XomwPPDStack Factory__stack();
+ protected abstract XomwPPDStackOld Factory__stack();
protected abstract Xomw_prepro_accum Accum__set(Xomw_prepro_accum accum);
@@ -883,7 +883,7 @@ public abstract class XomwPreprocessor {
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);
+ protected abstract void preprocessToObj_equals(XomwPPDStackOld stack);
+ protected abstract Object preprocessToObj_term(XomwPPDStackOld stack);
public abstract XomwPreprocessor Make_new(XomwParser parser);
}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_DOM.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_DOM.java
index 1fe416fa7..6832619b2 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_DOM.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_DOM.java
@@ -20,7 +20,7 @@ import gplx.xowa.mediawiki.includes.parsers.preprocessors.*;
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 XomwPPDStack Factory__stack() {return new XomwPPDStack(Xomw_prepro_accum__dom.Instance);}
+ @Override protected XomwPPDStackOld Factory__stack() {return new XomwPPDStackOld(Xomw_prepro_accum__dom.Instance);}
@Override protected XomwPPDPart Factory__part() {return new XomwPPDPart_DOM("");}
@Override public XomwPPFrame newFrame() {
@@ -138,11 +138,11 @@ class XomwPreprocessor_DOM extends XomwPreprocessor { private final Bry_bfr
@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) {
+ @Override protected void preprocessToObj_equals(XomwPPDStackOld stack) {
stack.Get_current_part().eqpos = accum_dom.Len();
accum_dom.Add_bry(Byte_ascii.Eq_bry);
}
- @Override protected Object preprocessToObj_term(XomwPPDStack stack) {
+ @Override protected Object preprocessToObj_term(XomwPPDStackOld 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++) {
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_Hash.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_Hash.java
index d01d39d97..8d612f479 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_Hash.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor_Hash.java
@@ -25,7 +25,7 @@ class XomwPreprocessor_Hash extends XomwPreprocessor { private XophpArray accum
return null;
}
- @Override protected XomwPPDStack Factory__stack() {return new XomwPPDStack_Hash(Xomw_prepro_accum__hash.Instance);}
+ @Override protected XomwPPDStackOld Factory__stack() {return new XomwPPDStackOld_Hash(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_obj) {
this.accum = ((Xomw_prepro_accum__hash)accum_obj).Ary();
@@ -147,11 +147,11 @@ class XomwPreprocessor_Hash extends XomwPreprocessor { private XophpArray accum
@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) {
+ @Override protected void preprocessToObj_equals(XomwPPDStackOld stack) {
accum.Add(XophpArray.New("equals", XophpArray.New("=")));
stack.Get_current_part().eqpos = accum.Len() - 1;
}
- @Override protected Object preprocessToObj_term(XomwPPDStack stack) {
+ @Override protected Object preprocessToObj_term(XomwPPDStackOld stack) {
Xomw_prepro_accum__hash stack_accum = (Xomw_prepro_accum__hash)stack.Get_accum();
XophpArray stack_ary = stack_accum.Ary();
int len = stack_ary.Len();
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor__tst.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor__tst.java
index e610b3819..dbe55c2cb 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor__tst.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/XomwPreprocessor__tst.java
@@ -19,7 +19,6 @@ public class XomwPreprocessor__tst {
private final XomwPreprocessor__fxt fxt = new XomwPreprocessor__fxt();
@Before public void init() {fxt.Clear();}
@Test public void Text() {
- fxt.Init__hash_y();
fxt.Test__parse("abc", "abc");
}
@Test public void Brack() {
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart.java
index 299867aa8..c36602f49 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart.java
@@ -22,7 +22,7 @@ public abstract class XomwPPDPart {
/**
* @var String Output accumulator String
*/
-// private final byte[] output;
+// public final byte[] output;
// Optional member variables:
// eqpos Position of equals sign in output accumulator
@@ -36,13 +36,22 @@ public abstract class XomwPPDPart {
// 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);
}
+// class XomwPPDPart {
+// /**
+// * @var String Output accumulator String
+// */
+// public String 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 XomwPPDPart(String output) {
+// this.output = output;
+// }
+// }
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart_DOM.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart_DOM.java
index cf7622a49..3e8e9a609 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart_DOM.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDPart_DOM.java
@@ -15,8 +15,7 @@ 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;
+public class XomwPPDPart_DOM extends XomwPPDPart { 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();
@@ -28,6 +27,7 @@ public class XomwPPDPart_DOM extends XomwPPDPart { // @codingStandardsIgnoreEnd
public Bry_bfr Bfr() {return bfr;}
public int Len() {return bfr.Len();}
public byte[] To_bry() {return bfr.To_bry();}
+ public String To_str() {return bfr.To_str();}
@Override public XomwPPDPart Make_new(String val) {
return new XomwPPDPart_DOM(val);
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStack.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStack.java
index 051bc30be..e229f0db8 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStack.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStack.java
@@ -14,82 +14,91 @@ 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
+import gplx.xowa.mediawiki.includes.exception.*;
+// MW.FILE:Preprocessor
/**
-* Stack class to help Preprocessor::preprocessToObj()
+* Stack clazz 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();
- protected Xomw_prepro_accum root_accum;
+ public XophpArray stack;
+ public Xomw_prepro_accum rootAccum;
protected Xomw_prepro_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();}
+ /**
+ * @var PPDStack
+ */
+ public XomwPPDStackElement top;
+// public $out;
+// public $elementClass = 'PPDStackElement';
- public Xomw_prepro_accum Get_accum() {return accum;}
- public Xomw_prepro_accum Get_root_accum() {return root_accum;}
+ public XomwPPDStack (Xomw_prepro_accum prototype) {
+ this.stack = XophpArray.New();
+ this.top = null;
+ this.rootAccum = prototype.Make_new();
+ this.accum = rootAccum;
+ }
- public XomwPPDPart Get_current_part() {
- if (top == null) {
+ /**
+ * @return int
+ */
+ public int count() {
+ return this.stack.Count();
+ }
+
+ public Xomw_prepro_accum getAccum() {
+ return this.accum;
+ }
+
+ public XomwPPDPart getCurrentPart() {
+ if (this.top == null) {
return null;
+ } else {
+ return this.top.getCurrentPart();
+ }
+ }
+
+ public void push(XomwPPDStackElement data) {
+ if (Type_.Eq_by_obj(data, XomwPPDStackElement.class)) {
+ this.stack.Add(data);
}
else {
- return top.Get_current_part();
+// $class = this.elementClass;
+// this.stack[] = new $class($data);
}
+ this.top = (XomwPPDStackElement)this.stack.Get_at(this.stack.Count() - 1);
+ this.accum = this.top.getAccum();
}
- 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");
+ public XomwPPDStackElement pop() {
+ if (this.stack.Count() == 0) {
+ throw XomwMWException.New_by_method(XomwPPDStack.class, "pop", "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();
+ XomwPPDStackElement temp = (XomwPPDStackElement)XophpArrayUtl.pop_obj(this.stack);
+ if (this.stack.Count()> 0) {
+ this.top = (XomwPPDStackElement)this.stack.Get_at(this.stack.Count() - 1);
+ this.accum = this.top.getAccum();
} else {
this.top = null;
- this.accum = root_accum;
+ this.accum = this.rootAccum;
}
- return rv;
+ return temp;
}
- public void Add_part(byte[] bry) {
- top.Add_part(bry);
- accum = top.Get_accum();
+ public void addPart(String s) {
+ this.top.addPart(s);
+ this.accum = this.top.getAccum();
}
- public Xomw_prepro_flags Get_flags() {
- if (stack.Count() == 0) {
- flags.findEquals = false;
- flags.findPipe = false;
- flags.inHeading = false;
- return flags;
+ /**
+ * @return array
+ */
+ public XomwPPDStackElementFlags getFlags() {
+ if (this.stack.Count() == 0) {
+ return XomwPPDStackElementFlags.Empty;
}
else {
- top.Set_flags(flags);
- return flags;
+ return this.top.getFlags();
}
}
}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElement.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElement.java
new file mode 100644
index 000000000..38263b8f0
--- /dev/null
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElement.java
@@ -0,0 +1,2061 @@
+/*
+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 class XomwPPDStackElement {
+ /**
+ * @var String Opening character (\n for heading)
+ */
+ public String open;
+
+ /**
+ * @var String Matching closing character
+ */
+ public String close;
+
+ /**
+ * @var int Number of opening characters found (number of "=" for heading)
+ */
+ public int count;
+
+ /**
+ * @var PPDPart[] Array of PPDPart objects describing pipe-separated parts.
+ */
+ public XophpArray parts;
+
+ /**
+ * @var boolean True if the open char appeared at the start of the input line.
+ * Not set for headings.
+ */
+// public boolean lineStart;
+
+ public String partClass = "PPDPart";
+
+ public XomwPPDStackElement(String open, String close, int count) {
+ this.parts = new XophpArray();
+
+ this.open = open;
+ this.close = close;
+ this.count = count;
+ }
+
+ public Xomw_prepro_accum getAccum() {
+ return (Xomw_prepro_accum)Get_at(this.parts.Count() - 1);
+ }
+
+ public void addPart(String s) {
+ this.parts.Add(Make_part(s));
+ }
+ @gplx.Virtual protected XomwPPDPart Make_part(String s) {
+ return new XomwPPDPart_DOM(s);
+ }
+
+ public XomwPPDPart getCurrentPart() {
+ return (XomwPPDPart)this.parts.Get_at(this.parts.Count() - 1);
+ }
+
+ /**
+ * @return array
+ */
+ public XomwPPDStackElementFlags getFlags() {
+ int partCount = this.parts.Count();
+ boolean findPipe = String_.EqNot(this.open, "\n") && String_.EqNot(this.open, "[");
+ return new XomwPPDStackElementFlags
+ ( findPipe
+ , findPipe && partCount > 1 && !XophpUtility.isset(Get_at(partCount - 1).eqpos)
+ , String_.Eq(this.open, "\n")
+ );
+ }
+
+ /**
+ * Get the output String that would result if the close is not found.
+ *
+ * @param boolean|int $openingCount
+ * @return String
+ */
+ @gplx.Virtual public String breakSyntax(int openingCount) {
+ Char_bfr bfr = new Char_bfr(16);
+ if (String_.Eq(this.open, "\n")) {
+ bfr.Add_bry(Get_at(0).To_bry());
+ }
+ else {
+ if (openingCount == -1) {
+ openingCount = this.count;
+ }
+ bfr.Add_str(XophpString.str_repeat(this.open, openingCount));
+ boolean first = true;
+ int parts_len = parts.Len();
+ for (int i = 0; i < parts_len; i++) {
+ XomwPPDPart_DOM part = Get_at(i);
+ if (first) {
+ first = false;
+ } else {
+ bfr.Add_char('|');
+ }
+ bfr.Add_bry(part.To_bry());
+ }
+ }
+ return bfr.To_str_and_clear();
+ }
+ private XomwPPDPart_DOM Get_at(int i) {
+ return (XomwPPDPart_DOM)this.parts.Get_at(i);
+ }
+}
+// MW.FILE:Preprocessor_Hash
+/**
+* @ingroup Parser
+*/
+class XomwPPDStackElement_Hash extends XomwPPDStackElement { public XomwPPDStackElement_Hash(String open, String close, int count) {super(open, close, count);
+ }
+
+ private XomwPPDPart_Hash Get_at_hash(int i) {
+ return (XomwPPDPart_Hash)this.parts.Get_at(i);
+ }
+ /**
+ * Get the accumulator that would result if the close is not found.
+ *
+ * @param int|boolean $openingCount
+ * @return array
+ */
+ public XophpArray breakSyntax_Hash(int openingCount) {
+ XophpArray accum = null;
+ if (String_.Eq(this.open, "\n")) {
+ accum = (XophpArray)Get_at_hash(0).Accum();
+ }
+ else {
+ if (openingCount == -1) {
+ openingCount = this.count;
+ }
+ accum = XophpArray.New(XophpString.str_repeat(this.open, openingCount));
+ int lastIndex = 0;
+ boolean first = true;
+ int parts_len = parts.Len();
+ for (int i = 0; i < parts_len; i++) {
+ XomwPPDPart_Hash part = Get_at_hash(i);
+ if (first) {
+ first = false;
+ }
+ else if (XophpTypeUtl.is_string(accum.Get_at_str(lastIndex))) {
+ accum.Set(lastIndex, accum.Get_at_str(lastIndex) + "|");
+ } else {
+ accum.Set(++lastIndex, "|");
+ }
+
+ XophpArray part_out = ((Xomw_prepro_accum__hash)part.Accum()).Ary();
+ int part_out_len = part_out.Len();
+ for (int j = 0; j < part_out_len; j++) {
+ Object node = part_out.Get_at(j);
+ if (XophpTypeUtl.is_string(node) && XophpTypeUtl.is_string(accum.Get_at(lastIndex))) {
+ accum.Set(lastIndex, accum.Get_at_str(lastIndex) + (String)node);
+ } else {
+ accum.Set(++lastIndex, node);
+ }
+ }
+ }
+ }
+ return accum;
+ }
+}
+///**
+// * An expansion frame, used as a context to expand the result of preprocessToObj()
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPFrame_DOM implements PPFrame {
+// // @codingStandardsIgnoreEnd
+//
+// /**
+// * @var Preprocessor
+// */
+// public $preprocessor;
+//
+// /**
+// * @var Parser
+// */
+// public $parser;
+//
+// /**
+// * @var Title
+// */
+// public $title;
+// public $titleCache;
+//
+// /**
+// * Hashtable listing templates which are disallowed for expansion in this frame,
+// * having been encountered previously in parent frames.
+// */
+// public $loopCheckHash;
+//
+// /**
+// * Recursion depth of this frame, top = 0
+// * Note that this is NOT the same as expansion depth in expand()
+// */
+// public $depth;
+//
+// private $volatile = false;
+// private $ttl = null;
+//
+// /**
+// * @var array
+// */
+// protected $childExpansionCache;
+//
+// /**
+// * Construct a new preprocessor frame.
+// * @param Preprocessor $preprocessor The parent preprocessor
+// */
+// public function __construct($preprocessor) {
+// this.preprocessor = $preprocessor;
+// this.parser = $preprocessor.parser;
+// this.title = this.parser.mTitle;
+// this.titleCache = [ this.title ? this.title.getPrefixedDBkey() : false ];
+// this.loopCheckHash = [];
+// this.depth = 0;
+// this.childExpansionCache = [];
+// }
+//
+// /**
+// * Create a new child frame
+// * $args is optionally a multi-root PPNode or array containing the template arguments
+// *
+// * @param boolean|array $args
+// * @param Title|boolean $title
+// * @param int $indexOffset
+// * @return PPTemplateFrame_DOM
+// */
+// public function newChild($args = false, $title = false, $indexOffset = 0) {
+// $namedArgs = [];
+// $numberedArgs = [];
+// if ($title === false) {
+// $title = this.title;
+// }
+// if ($args !== false) {
+// $xpath = false;
+// if ($args instanceof PPNode) {
+// $args = $args.node;
+// }
+// for each ($args as $arg) {
+// if ($arg instanceof PPNode) {
+// $arg = $arg.node;
+// }
+// if (!$xpath || $xpath.document !== $arg.ownerDocument) {
+// $xpath = new DOMXPath($arg.ownerDocument);
+// }
+//
+// $nameNodes = $xpath.query('name', $arg);
+// $value = $xpath.query('value', $arg);
+// if ($nameNodes.item(0).hasAttributes()) {
+// // Numbered parameter
+// $index = $nameNodes.item(0).attributes.getNamedItem('index').textContent;
+// $index = $index - $indexOffset;
+// if (isset($namedArgs[$index]) || isset($numberedArgs[$index])) {
+// this.parser.getOutput().addWarning(wfMessage('duplicate-args-warning',
+// wfEscapeWikiText(this.title),
+// wfEscapeWikiText($title),
+// wfEscapeWikiText($index)).text());
+// this.parser.addTrackingCategory('duplicate-args-category');
+// }
+// $numberedArgs[$index] = $value.item(0);
+// unset($namedArgs[$index]);
+// } else {
+// // Named parameter
+// $name = trim(this.expand($nameNodes.item(0), PPFrame::STRIP_COMMENTS));
+// if (isset($namedArgs[$name]) || isset($numberedArgs[$name])) {
+// this.parser.getOutput().addWarning(wfMessage('duplicate-args-warning',
+// wfEscapeWikiText(this.title),
+// wfEscapeWikiText($title),
+// wfEscapeWikiText($name)).text());
+// this.parser.addTrackingCategory('duplicate-args-category');
+// }
+// $namedArgs[$name] = $value.item(0);
+// unset($numberedArgs[$name]);
+// }
+// }
+// }
+// return new PPTemplateFrame_DOM(this.preprocessor, $this, $numberedArgs, $namedArgs, $title);
+// }
+//
+// /**
+// * @throws MWException
+// * @param String|int $key
+// * @param String|PPNode_DOM|DOMDocument $root
+// * @param int $flags
+// * @return String
+// */
+// public function cachedExpand($key, $root, $flags = 0) {
+// // we don't have a parent, so we don't have a cache
+// return this.expand($root, $flags);
+// }
+//
+// /**
+// * @throws MWException
+// * @param String|PPNode_DOM|DOMDocument $root
+// * @param int $flags
+// * @return String
+// */
+// public function expand($root, $flags = 0) {
+// static $expansionDepth = 0;
+// if (is_string($root)) {
+// return $root;
+// }
+//
+// if (++this.parser.mPPNodeCount > this.parser.mOptions.getMaxPPNodeCount()) {
+// this.parser.limitationWarn('node-count-exceeded',
+// this.parser.mPPNodeCount,
+// this.parser.mOptions.getMaxPPNodeCount()
+// );
+// return 'Node-count limit exceeded';
+// }
+//
+// if ($expansionDepth > this.parser.mOptions.getMaxPPExpandDepth()) {
+// this.parser.limitationWarn('expansion-depth-exceeded',
+// $expansionDepth,
+// this.parser.mOptions.getMaxPPExpandDepth()
+// );
+// return 'Expansion depth limit exceeded';
+// }
+// ++$expansionDepth;
+// if ($expansionDepth > this.parser.mHighestExpansionDepth) {
+// this.parser.mHighestExpansionDepth = $expansionDepth;
+// }
+//
+// if ($root instanceof PPNode_DOM) {
+// $root = $root.node;
+// }
+// if ($root instanceof DOMDocument) {
+// $root = $root.documentElement;
+// }
+//
+// $outStack = [ '', '' ];
+// $iteratorStack = [ false, $root ];
+// $indexStack = [ 0, 0 ];
+//
+// while (count($iteratorStack) > 1) {
+// $level = count($outStack) - 1;
+// $iteratorNode =& $iteratorStack[$level];
+// $out =& $outStack[$level];
+// $index =& $indexStack[$level];
+//
+// if ($iteratorNode instanceof PPNode_DOM) {
+// $iteratorNode = $iteratorNode.node;
+// }
+//
+// if (is_array($iteratorNode)) {
+// if ($index >= count($iteratorNode)) {
+// // All done with this iterator
+// $iteratorStack[$level] = false;
+// $contextNode = false;
+// } else {
+// $contextNode = $iteratorNode[$index];
+// $index++;
+// }
+// } elseif ($iteratorNode instanceof DOMNodeList) {
+// if ($index >= $iteratorNode.length) {
+// // All done with this iterator
+// $iteratorStack[$level] = false;
+// $contextNode = false;
+// } else {
+// $contextNode = $iteratorNode.item($index);
+// $index++;
+// }
+// } else {
+// // Copy to $contextNode and then delete from iterator stack,
+// // because this is not an iterator but we do have to execute it once
+// $contextNode = $iteratorStack[$level];
+// $iteratorStack[$level] = false;
+// }
+//
+// if ($contextNode instanceof PPNode_DOM) {
+// $contextNode = $contextNode.node;
+// }
+//
+// $newIterator = false;
+//
+// if ($contextNode === false) {
+// // nothing to do
+// } elseif (is_string($contextNode)) {
+// $out .= $contextNode;
+// } elseif (is_array($contextNode) || $contextNode instanceof DOMNodeList) {
+// $newIterator = $contextNode;
+// } elseif ($contextNode instanceof DOMNode) {
+// if ($contextNode.nodeType == XML_TEXT_NODE) {
+// $out .= $contextNode.nodeValue;
+// } elseif ($contextNode.nodeName == 'template') {
+// # Double-brace expansion
+// $xpath = new DOMXPath($contextNode.ownerDocument);
+// $titles = $xpath.query('title', $contextNode);
+// $title = $titles.item(0);
+// $parts = $xpath.query('part', $contextNode);
+// if ($flags & PPFrame::NO_TEMPLATES) {
+// $newIterator = this.virtualBracketedImplode('{{', '|', '}}', $title, $parts);
+// } else {
+// $lineStart = $contextNode.getAttribute('lineStart');
+// $params = [
+// 'title' => new PPNode_DOM($title),
+// 'parts' => new PPNode_DOM($parts),
+// 'lineStart' => $lineStart ];
+// $ret = this.parser.braceSubstitution($params, $this);
+// if (isset($ret['Object'])) {
+// $newIterator = $ret['Object'];
+// } else {
+// $out .= $ret['text'];
+// }
+// }
+// } elseif ($contextNode.nodeName == 'tplarg') {
+// # Triple-brace expansion
+// $xpath = new DOMXPath($contextNode.ownerDocument);
+// $titles = $xpath.query('title', $contextNode);
+// $title = $titles.item(0);
+// $parts = $xpath.query('part', $contextNode);
+// if ($flags & PPFrame::NO_ARGS) {
+// $newIterator = this.virtualBracketedImplode('{{{', '|', '}}}', $title, $parts);
+// } else {
+// $params = [
+// 'title' => new PPNode_DOM($title),
+// 'parts' => new PPNode_DOM($parts) ];
+// $ret = this.parser.argSubstitution($params, $this);
+// if (isset($ret['Object'])) {
+// $newIterator = $ret['Object'];
+// } else {
+// $out .= $ret['text'];
+// }
+// }
+// } elseif ($contextNode.nodeName == 'comment') {
+// # HTML-style comment
+// # Remove it in HTML, pre+remove and STRIP_COMMENTS modes
+// # Not in RECOVER_COMMENTS mode (msgnw) though.
+// if ((this.parser.ot['html']
+// || (this.parser.ot['pre'] && this.parser.mOptions.getRemoveComments())
+// || ($flags & PPFrame::STRIP_COMMENTS)
+// ) && !($flags & PPFrame::RECOVER_COMMENTS)
+// ) {
+// $out .= '';
+// } elseif (this.parser.ot['wiki'] && !($flags & PPFrame::RECOVER_COMMENTS)) {
+// # Add a strip marker in PST mode so that pstPass2() can
+// # run some old-fashioned regexes on the result.
+// # Not in RECOVER_COMMENTS mode (extractSections) though.
+// $out .= this.parser.insertStripItem($contextNode.textContent);
+// } else {
+// # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
+// $out .= $contextNode.textContent;
+// }
+// } elseif ($contextNode.nodeName == 'ignore') {
+// # Output suppression used by etc.
+// # OT_WIKI will only respect in substed templates.
+// # The other output types respect it unless NO_IGNORE is set.
+// # extractSections() sets NO_IGNORE and so never respects it.
+// if ((!isset(this.parent) && this.parser.ot['wiki'])
+// || ($flags & PPFrame::NO_IGNORE)
+// ) {
+// $out .= $contextNode.textContent;
+// } else {
+// $out .= '';
+// }
+// } elseif ($contextNode.nodeName == 'ext') {
+// # Extension tag
+// $xpath = new DOMXPath($contextNode.ownerDocument);
+// $names = $xpath.query('name', $contextNode);
+// $attrs = $xpath.query('attr', $contextNode);
+// $inners = $xpath.query('inner', $contextNode);
+// $closes = $xpath.query('close', $contextNode);
+// if ($flags & PPFrame::NO_TAGS) {
+// $s = '<' . this.expand($names.item(0), $flags);
+// if ($attrs.length > 0) {
+// $s .= this.expand($attrs.item(0), $flags);
+// }
+// if ($inners.length > 0) {
+// $s .= '>' . this.expand($inners.item(0), $flags);
+// if ($closes.length > 0) {
+// $s .= this.expand($closes.item(0), $flags);
+// }
+// } else {
+// $s .= '/>';
+// }
+// $out .= $s;
+// } else {
+// $params = [
+// 'name' => new PPNode_DOM($names.item(0)),
+// 'attr' => $attrs.length > 0 ? new PPNode_DOM($attrs.item(0)) : null,
+// 'inner' => $inners.length > 0 ? new PPNode_DOM($inners.item(0)) : null,
+// 'close' => $closes.length > 0 ? new PPNode_DOM($closes.item(0)) : null,
+// ];
+// $out .= this.parser.extensionSubstitution($params, $this);
+// }
+// } elseif ($contextNode.nodeName == 'h') {
+// # Heading
+// $s = this.expand($contextNode.childNodes, $flags);
+//
+// # Insert a heading marker only for children of
+// # This is to stop extractSections from going over multiple tree levels
+// if ($contextNode.parentNode.nodeName == 'root' && this.parser.ot['html']) {
+// # Insert heading index marker
+// $headingIndex = $contextNode.getAttribute('i');
+// $titleText = this.title.getPrefixedDBkey();
+// this.parser.mHeadings[] = [ $titleText, $headingIndex ];
+// $serial = count(this.parser.mHeadings) - 1;
+// $marker = Parser::MARKER_PREFIX . "-h-$serial-" . Parser::MARKER_SUFFIX;
+// $count = $contextNode.getAttribute('level');
+// $s = substr($s, 0, $count) . $marker . substr($s, $count);
+// this.parser.mStripState.addGeneral($marker, '');
+// }
+// $out .= $s;
+// } else {
+// # Generic recursive expansion
+// $newIterator = $contextNode.childNodes;
+// }
+// } else {
+// throw new MWException(__METHOD__ . ': Invalid parameter type');
+// }
+//
+// if ($newIterator !== false) {
+// if ($newIterator instanceof PPNode_DOM) {
+// $newIterator = $newIterator.node;
+// }
+// $outStack[] = '';
+// $iteratorStack[] = $newIterator;
+// $indexStack[] = 0;
+// } elseif ($iteratorStack[$level] === false) {
+// // Return accumulated value to parent
+// // With tail recursion
+// while ($iteratorStack[$level] === false && $level > 0) {
+// $outStack[$level - 1] .= $out;
+// array_pop($outStack);
+// array_pop($iteratorStack);
+// array_pop($indexStack);
+// $level--;
+// }
+// }
+// }
+// --$expansionDepth;
+// return $outStack[0];
+// }
+//
+// /**
+// * @param String $sep
+// * @param int $flags
+// * @param String|PPNode_DOM|DOMDocument $args,...
+// * @return String
+// */
+// public function implodeWithFlags($sep, $flags /*, ... */) {
+// $args = array_slice(func_get_args(), 2);
+//
+// $first = true;
+// $s = '';
+// for each ($args as $root) {
+// if ($root instanceof PPNode_DOM) {
+// $root = $root.node;
+// }
+// if (!is_array($root) && !($root instanceof DOMNodeList)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= $sep;
+// }
+// $s .= this.expand($node, $flags);
+// }
+// }
+// return $s;
+// }
+//
+// /**
+// * Implode with no flags specified
+// * This previously called implodeWithFlags but has now been inlined to reduce stack depth
+// *
+// * @param String $sep
+// * @param String|PPNode_DOM|DOMDocument $args,...
+// * @return String
+// */
+// public function implode($sep /*, ... */) {
+// $args = array_slice(func_get_args(), 1);
+//
+// $first = true;
+// $s = '';
+// for each ($args as $root) {
+// if ($root instanceof PPNode_DOM) {
+// $root = $root.node;
+// }
+// if (!is_array($root) && !($root instanceof DOMNodeList)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= $sep;
+// }
+// $s .= this.expand($node);
+// }
+// }
+// return $s;
+// }
+//
+// /**
+// * Makes an Object that, when expand()ed, will be the same as one obtained
+// * with implode()
+// *
+// * @param String $sep
+// * @param String|PPNode_DOM|DOMDocument $args,...
+// * @return array
+// */
+// public function virtualImplode($sep /*, ... */) {
+// $args = array_slice(func_get_args(), 1);
+// $out = [];
+// $first = true;
+//
+// for each ($args as $root) {
+// if ($root instanceof PPNode_DOM) {
+// $root = $root.node;
+// }
+// if (!is_array($root) && !($root instanceof DOMNodeList)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $out[] = $sep;
+// }
+// $out[] = $node;
+// }
+// }
+// return $out;
+// }
+//
+// /**
+// * Virtual implode with brackets
+// * @param String $start
+// * @param String $sep
+// * @param String $end
+// * @param String|PPNode_DOM|DOMDocument $args,...
+// * @return array
+// */
+// public function virtualBracketedImplode($start, $sep, $end /*, ... */) {
+// $args = array_slice(func_get_args(), 3);
+// $out = [ $start ];
+// $first = true;
+//
+// for each ($args as $root) {
+// if ($root instanceof PPNode_DOM) {
+// $root = $root.node;
+// }
+// if (!is_array($root) && !($root instanceof DOMNodeList)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $out[] = $sep;
+// }
+// $out[] = $node;
+// }
+// }
+// $out[] = $end;
+// return $out;
+// }
+//
+// public function __toString() {
+// return 'frame{}';
+// }
+//
+// public function getPDBK($level = false) {
+// if ($level === false) {
+// return this.title.getPrefixedDBkey();
+// } else {
+// return isset(this.titleCache[$level]) ? this.titleCache[$level] : false;
+// }
+// }
+//
+// /**
+// * @return array
+// */
+// public function getArguments() {
+// return [];
+// }
+//
+// /**
+// * @return array
+// */
+// public function getNumberedArguments() {
+// return [];
+// }
+//
+// /**
+// * @return array
+// */
+// public function getNamedArguments() {
+// return [];
+// }
+//
+// /**
+// * Returns true if there are no arguments in this frame
+// *
+// * @return boolean
+// */
+// public function isEmpty() {
+// return true;
+// }
+//
+// /**
+// * @param int|String $name
+// * @return boolean Always false in this implementation.
+// */
+// public function getArgument($name) {
+// return false;
+// }
+//
+// /**
+// * Returns true if the infinite loop check is OK, false if a loop is detected
+// *
+// * @param Title $title
+// * @return boolean
+// */
+// public function loopCheck($title) {
+// return !isset(this.loopCheckHash[$title.getPrefixedDBkey()]);
+// }
+//
+// /**
+// * Return true if the frame is a template frame
+// *
+// * @return boolean
+// */
+// public function isTemplate() {
+// return false;
+// }
+//
+// /**
+// * Get a title of frame
+// *
+// * @return Title
+// */
+// public function getTitle() {
+// return this.title;
+// }
+//
+// /**
+// * Set the volatile flag
+// *
+// * @param boolean $flag
+// */
+// public function setVolatile($flag = true) {
+// this.volatile = $flag;
+// }
+//
+// /**
+// * Get the volatile flag
+// *
+// * @return boolean
+// */
+// public function isVolatile() {
+// return this.volatile;
+// }
+//
+// /**
+// * Set the TTL
+// *
+// * @param int $ttl
+// */
+// public function setTTL($ttl) {
+// if ($ttl !== null && (this.ttl === null || $ttl < this.ttl)) {
+// this.ttl = $ttl;
+// }
+// }
+//
+// /**
+// * Get the TTL
+// *
+// * @return int|null
+// */
+// public function getTTL() {
+// return this.ttl;
+// }
+//}
+//
+///**
+// * Expansion frame with template arguments
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPTemplateFrame_DOM extends PPFrame_DOM {
+// // @codingStandardsIgnoreEnd
+//
+// public $numberedArgs, $namedArgs;
+//
+// /**
+// * @var PPFrame_DOM
+// */
+// public $parent;
+// public $numberedExpansionCache, $namedExpansionCache;
+//
+// /**
+// * @param Preprocessor $preprocessor
+// * @param boolean|PPFrame_DOM $parent
+// * @param array $numberedArgs
+// * @param array $namedArgs
+// * @param boolean|Title $title
+// */
+// public function __construct($preprocessor, $parent = false, $numberedArgs = [],
+// $namedArgs = [], $title = false
+// ) {
+// parent::__construct($preprocessor);
+//
+// this.parent = $parent;
+// this.numberedArgs = $numberedArgs;
+// this.namedArgs = $namedArgs;
+// this.title = $title;
+// $pdbk = $title ? $title.getPrefixedDBkey() : false;
+// this.titleCache = $parent.titleCache;
+// this.titleCache[] = $pdbk;
+// this.loopCheckHash = /*clone*/ $parent.loopCheckHash;
+// if ($pdbk !== false) {
+// this.loopCheckHash[$pdbk] = true;
+// }
+// this.depth = $parent.depth + 1;
+// this.numberedExpansionCache = this.namedExpansionCache = [];
+// }
+//
+// public function __toString() {
+// $s = 'tplframe{';
+// $first = true;
+// $args = this.numberedArgs + this.namedArgs;
+// for each ($args as $name => $value) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= ', ';
+// }
+// $s .= "\"$name\":\"" .
+// str_replace('"', '\\"', $value.ownerDocument.saveXML($value)) . '"';
+// }
+// $s .= '}';
+// return $s;
+// }
+//
+// /**
+// * @throws MWException
+// * @param String|int $key
+// * @param String|PPNode_DOM|DOMDocument $root
+// * @param int $flags
+// * @return String
+// */
+// public function cachedExpand($key, $root, $flags = 0) {
+// if (isset(this.parent.childExpansionCache[$key])) {
+// return this.parent.childExpansionCache[$key];
+// }
+// $retval = this.expand($root, $flags);
+// if (!this.isVolatile()) {
+// this.parent.childExpansionCache[$key] = $retval;
+// }
+// return $retval;
+// }
+//
+// /**
+// * Returns true if there are no arguments in this frame
+// *
+// * @return boolean
+// */
+// public function isEmpty() {
+// return !count(this.numberedArgs) && !count(this.namedArgs);
+// }
+//
+// public function getArguments() {
+// $arguments = [];
+// for each (array_merge(
+// array_keys(this.numberedArgs),
+// array_keys(this.namedArgs)) as $key) {
+// $arguments[$key] = this.getArgument($key);
+// }
+// return $arguments;
+// }
+//
+// public function getNumberedArguments() {
+// $arguments = [];
+// for each (array_keys(this.numberedArgs) as $key) {
+// $arguments[$key] = this.getArgument($key);
+// }
+// return $arguments;
+// }
+//
+// public function getNamedArguments() {
+// $arguments = [];
+// for each (array_keys(this.namedArgs) as $key) {
+// $arguments[$key] = this.getArgument($key);
+// }
+// return $arguments;
+// }
+//
+// /**
+// * @param int $index
+// * @return String|boolean
+// */
+// public function getNumberedArgument($index) {
+// if (!isset(this.numberedArgs[$index])) {
+// return false;
+// }
+// if (!isset(this.numberedExpansionCache[$index])) {
+// # No trimming for unnamed arguments
+// this.numberedExpansionCache[$index] = this.parent.expand(
+// this.numberedArgs[$index],
+// PPFrame::STRIP_COMMENTS
+// );
+// }
+// return this.numberedExpansionCache[$index];
+// }
+//
+// /**
+// * @param String $name
+// * @return String|boolean
+// */
+// public function getNamedArgument($name) {
+// if (!isset(this.namedArgs[$name])) {
+// return false;
+// }
+// if (!isset(this.namedExpansionCache[$name])) {
+// # Trim named arguments post-expand, for backwards compatibility
+// this.namedExpansionCache[$name] = trim(
+// this.parent.expand(this.namedArgs[$name], PPFrame::STRIP_COMMENTS));
+// }
+// return this.namedExpansionCache[$name];
+// }
+//
+// /**
+// * @param int|String $name
+// * @return String|boolean
+// */
+// public function getArgument($name) {
+// $text = this.getNumberedArgument($name);
+// if ($text === false) {
+// $text = this.getNamedArgument($name);
+// }
+// return $text;
+// }
+//
+// /**
+// * Return true if the frame is a template frame
+// *
+// * @return boolean
+// */
+// public function isTemplate() {
+// return true;
+// }
+//
+// public function setVolatile($flag = true) {
+// parent::setVolatile($flag);
+// this.parent.setVolatile($flag);
+// }
+//
+// public function setTTL($ttl) {
+// parent::setTTL($ttl);
+// this.parent.setTTL($ttl);
+// }
+//}
+//
+///**
+// * Expansion frame with custom arguments
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPCustomFrame_DOM extends PPFrame_DOM {
+// // @codingStandardsIgnoreEnd
+//
+// public $args;
+//
+// public function __construct($preprocessor, $args) {
+// parent::__construct($preprocessor);
+// this.args = $args;
+// }
+//
+// public function __toString() {
+// $s = 'cstmframe{';
+// $first = true;
+// for each (this.args as $name => $value) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= ', ';
+// }
+// $s .= "\"$name\":\"" .
+// str_replace('"', '\\"', $value.__toString()) . '"';
+// }
+// $s .= '}';
+// return $s;
+// }
+//
+// /**
+// * @return boolean
+// */
+// public function isEmpty() {
+// return !count(this.args);
+// }
+//
+// /**
+// * @param int|String $index
+// * @return String|boolean
+// */
+// public function getArgument($index) {
+// if (!isset(this.args[$index])) {
+// return false;
+// }
+// return this.args[$index];
+// }
+//
+// public function getArguments() {
+// return this.args;
+// }
+//}
+//
+///**
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPNode_DOM implements PPNode {
+// // @codingStandardsIgnoreEnd
+//
+// /**
+// * @var DOMElement
+// */
+// public $node;
+// public $xpath;
+//
+// public function __construct($node, $xpath = false) {
+// this.node = $node;
+// }
+//
+// /**
+// * @return DOMXPath
+// */
+// public function getXPath() {
+// if (this.xpath === null) {
+// this.xpath = new DOMXPath(this.node.ownerDocument);
+// }
+// return this.xpath;
+// }
+//
+// public function __toString() {
+// if (this.node instanceof DOMNodeList) {
+// $s = '';
+// for each (this.node as $node) {
+// $s .= $node.ownerDocument.saveXML($node);
+// }
+// } else {
+// $s = this.node.ownerDocument.saveXML(this.node);
+// }
+// return $s;
+// }
+//
+// /**
+// * @return boolean|PPNode_DOM
+// */
+// public function getChildren() {
+// return this.node.childNodes ? new self(this.node.childNodes) : false;
+// }
+//
+// /**
+// * @return boolean|PPNode_DOM
+// */
+// public function getFirstChild() {
+// return this.node.firstChild ? new self(this.node.firstChild) : false;
+// }
+//
+// /**
+// * @return boolean|PPNode_DOM
+// */
+// public function getNextSibling() {
+// return this.node.nextSibling ? new self(this.node.nextSibling) : false;
+// }
+//
+// /**
+// * @param String $type
+// *
+// * @return boolean|PPNode_DOM
+// */
+// public function getChildrenOfType($type) {
+// return new self(this.getXPath().query($type, this.node));
+// }
+//
+// /**
+// * @return int
+// */
+// public function getLength() {
+// if (this.node instanceof DOMNodeList) {
+// return this.node.length;
+// } else {
+// return false;
+// }
+// }
+//
+// /**
+// * @param int $i
+// * @return boolean|PPNode_DOM
+// */
+// public function item($i) {
+// $item = this.node.item($i);
+// return $item ? new self($item) : false;
+// }
+//
+// /**
+// * @return String
+// */
+// public function getName() {
+// if (this.node instanceof DOMNodeList) {
+// return '#nodelist';
+// } else {
+// return this.node.nodeName;
+// }
+// }
+//
+// /**
+// * Split a "" node into an associative array containing:
+// * - name PPNode name
+// * - index String index
+// * - value PPNode value
+// *
+// * @throws MWException
+// * @return array
+// */
+// public function splitArg() {
+// $xpath = this.getXPath();
+// $names = $xpath.query('name', this.node);
+// $values = $xpath.query('value', this.node);
+// if (!$names.length || !$values.length) {
+// throw new MWException('Invalid brace node passed to ' . __METHOD__);
+// }
+// $name = $names.item(0);
+// $index = $name.getAttribute('index');
+// return [
+// 'name' => new self($name),
+// 'index' => $index,
+// 'value' => new self($values.item(0)) ];
+// }
+//
+// /**
+// * Split an "" node into an associative array containing name, attr, inner and close
+// * All values in the resulting array are PPNodes. Inner and close are optional.
+// *
+// * @throws MWException
+// * @return array
+// */
+// public function splitExt() {
+// $xpath = this.getXPath();
+// $names = $xpath.query('name', this.node);
+// $attrs = $xpath.query('attr', this.node);
+// $inners = $xpath.query('inner', this.node);
+// $closes = $xpath.query('close', this.node);
+// if (!$names.length || !$attrs.length) {
+// throw new MWException('Invalid ext node passed to ' . __METHOD__);
+// }
+// $parts = [
+// 'name' => new self($names.item(0)),
+// 'attr' => new self($attrs.item(0)) ];
+// if ($inners.length) {
+// $parts['inner'] = new self($inners.item(0));
+// }
+// if ($closes.length) {
+// $parts['close'] = new self($closes.item(0));
+// }
+// return $parts;
+// }
+//
+// /**
+// * Split a "" node
+// * @throws MWException
+// * @return array
+// */
+// public function splitHeading() {
+// if (this.getName() !== 'h') {
+// throw new MWException('Invalid h node passed to ' . __METHOD__);
+// }
+// return [
+// 'i' => this.node.getAttribute('i'),
+// 'level' => this.node.getAttribute('level'),
+// 'contents' => this.getChildren()
+// ];
+// }
+//}
+///**
+// * Stack class to help Preprocessor::preprocessToObj()
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPDStack_Hash extends PPDStack {
+// // @codingStandardsIgnoreEnd
+//
+// public function __construct() {
+// this.elementClass = 'PPDStackElement_Hash';
+// parent::__construct();
+// this.rootAccum = [];
+// }
+//}
+//
+///**
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPDPart_Hash extends PPDPart {
+// // @codingStandardsIgnoreEnd
+//
+// public function __construct($out = '') {
+// if ($out !== '') {
+// $accum = [ $out ];
+// } else {
+// $accum = [];
+// }
+// parent::__construct($accum);
+// }
+//}
+//
+///**
+// * An expansion frame, used as a context to expand the result of preprocessToObj()
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPFrame_Hash implements PPFrame {
+// // @codingStandardsIgnoreEnd
+//
+// /**
+// * @var Parser
+// */
+// public $parser;
+//
+// /**
+// * @var Preprocessor
+// */
+// public $preprocessor;
+//
+// /**
+// * @var Title
+// */
+// public $title;
+// public $titleCache;
+//
+// /**
+// * Hashtable listing templates which are disallowed for expansion in this frame,
+// * having been encountered previously in parent frames.
+// */
+// public $loopCheckHash;
+//
+// /**
+// * Recursion depth of this frame, top = 0
+// * Note that this is NOT the same as expansion depth in expand()
+// */
+// public $depth;
+//
+// private $volatile = false;
+// private $ttl = null;
+//
+// /**
+// * @var array
+// */
+// protected $childExpansionCache;
+//
+// /**
+// * Construct a new preprocessor frame.
+// * @param Preprocessor $preprocessor The parent preprocessor
+// */
+// public function __construct($preprocessor) {
+// this.preprocessor = $preprocessor;
+// this.parser = $preprocessor.parser;
+// this.title = this.parser.mTitle;
+// this.titleCache = [ this.title ? this.title.getPrefixedDBkey() : false ];
+// this.loopCheckHash = [];
+// this.depth = 0;
+// this.childExpansionCache = [];
+// }
+//
+// /**
+// * Create a new child frame
+// * $args is optionally a multi-root PPNode or array containing the template arguments
+// *
+// * @param array|boolean|PPNode_Hash_Array $args
+// * @param Title|boolean $title
+// * @param int $indexOffset
+// * @throws MWException
+// * @return PPTemplateFrame_Hash
+// */
+// public function newChild($args = false, $title = false, $indexOffset = 0) {
+// $namedArgs = [];
+// $numberedArgs = [];
+// if ($title === false) {
+// $title = this.title;
+// }
+// if ($args !== false) {
+// if ($args instanceof PPNode_Hash_Array) {
+// $args = $args.value;
+// } elseif (!is_array($args)) {
+// throw new MWException(__METHOD__ . ': $args must be array or PPNode_Hash_Array');
+// }
+// for each ($args as $arg) {
+// $bits = $arg.splitArg();
+// if ($bits['index'] !== '') {
+// // Numbered parameter
+// $index = $bits['index'] - $indexOffset;
+// if (isset($namedArgs[$index]) || isset($numberedArgs[$index])) {
+// this.parser.getOutput().addWarning(wfMessage('duplicate-args-warning',
+// wfEscapeWikiText(this.title),
+// wfEscapeWikiText($title),
+// wfEscapeWikiText($index)).text());
+// this.parser.addTrackingCategory('duplicate-args-category');
+// }
+// $numberedArgs[$index] = $bits['value'];
+// unset($namedArgs[$index]);
+// } else {
+// // Named parameter
+// $name = trim(this.expand($bits['name'], PPFrame::STRIP_COMMENTS));
+// if (isset($namedArgs[$name]) || isset($numberedArgs[$name])) {
+// this.parser.getOutput().addWarning(wfMessage('duplicate-args-warning',
+// wfEscapeWikiText(this.title),
+// wfEscapeWikiText($title),
+// wfEscapeWikiText($name)).text());
+// this.parser.addTrackingCategory('duplicate-args-category');
+// }
+// $namedArgs[$name] = $bits['value'];
+// unset($numberedArgs[$name]);
+// }
+// }
+// }
+// return new PPTemplateFrame_Hash(this.preprocessor, $this, $numberedArgs, $namedArgs, $title);
+// }
+//
+// /**
+// * @throws MWException
+// * @param String|int $key
+// * @param String|PPNode $root
+// * @param int $flags
+// * @return String
+// */
+// public function cachedExpand($key, $root, $flags = 0) {
+// // we don't have a parent, so we don't have a cache
+// return this.expand($root, $flags);
+// }
+//
+// /**
+// * @throws MWException
+// * @param String|PPNode $root
+// * @param int $flags
+// * @return String
+// */
+// public function expand($root, $flags = 0) {
+// static $expansionDepth = 0;
+// if (is_string($root)) {
+// return $root;
+// }
+//
+// if (++this.parser.mPPNodeCount > this.parser.mOptions.getMaxPPNodeCount()) {
+// this.parser.limitationWarn('node-count-exceeded',
+// this.parser.mPPNodeCount,
+// this.parser.mOptions.getMaxPPNodeCount()
+// );
+// return 'Node-count limit exceeded';
+// }
+// if ($expansionDepth > this.parser.mOptions.getMaxPPExpandDepth()) {
+// this.parser.limitationWarn('expansion-depth-exceeded',
+// $expansionDepth,
+// this.parser.mOptions.getMaxPPExpandDepth()
+// );
+// return 'Expansion depth limit exceeded';
+// }
+// ++$expansionDepth;
+// if ($expansionDepth > this.parser.mHighestExpansionDepth) {
+// this.parser.mHighestExpansionDepth = $expansionDepth;
+// }
+//
+// $outStack = [ '', '' ];
+// $iteratorStack = [ false, $root ];
+// $indexStack = [ 0, 0 ];
+//
+// while (count($iteratorStack) > 1) {
+// $level = count($outStack) - 1;
+// $iteratorNode =& $iteratorStack[$level];
+// $out =& $outStack[$level];
+// $index =& $indexStack[$level];
+//
+// if (is_array($iteratorNode)) {
+// if ($index >= count($iteratorNode)) {
+// // All done with this iterator
+// $iteratorStack[$level] = false;
+// $contextNode = false;
+// } else {
+// $contextNode = $iteratorNode[$index];
+// $index++;
+// }
+// } elseif ($iteratorNode instanceof PPNode_Hash_Array) {
+// if ($index >= $iteratorNode.getLength()) {
+// // All done with this iterator
+// $iteratorStack[$level] = false;
+// $contextNode = false;
+// } else {
+// $contextNode = $iteratorNode.item($index);
+// $index++;
+// }
+// } else {
+// // Copy to $contextNode and then delete from iterator stack,
+// // because this is not an iterator but we do have to execute it once
+// $contextNode = $iteratorStack[$level];
+// $iteratorStack[$level] = false;
+// }
+//
+// $newIterator = false;
+// $contextName = false;
+// $contextChildren = false;
+//
+// if ($contextNode === false) {
+// // nothing to do
+// } elseif (is_string($contextNode)) {
+// $out .= $contextNode;
+// } elseif ($contextNode instanceof PPNode_Hash_Array) {
+// $newIterator = $contextNode;
+// } elseif ($contextNode instanceof PPNode_Hash_Attr) {
+// // No output
+// } elseif ($contextNode instanceof PPNode_Hash_Text) {
+// $out .= $contextNode.value;
+// } elseif ($contextNode instanceof PPNode_Hash_Tree) {
+// $contextName = $contextNode.name;
+// $contextChildren = $contextNode.getRawChildren();
+// } elseif (is_array($contextNode)) {
+// // Node descriptor array
+// if (count($contextNode) !== 2) {
+// throw new MWException(__METHOD__.
+// ': found an array where a node descriptor should be');
+// }
+// list($contextName, $contextChildren) = $contextNode;
+// } else {
+// throw new MWException(__METHOD__ . ': Invalid parameter type');
+// }
+//
+// // Handle node descriptor array or tree Object
+// if ($contextName === false) {
+// // Not a node, already handled above
+// } elseif ($contextName[0] === '@') {
+// // Attribute: no output
+// } elseif ($contextName === 'template') {
+// # Double-brace expansion
+// $bits = PPNode_Hash_Tree::splitRawTemplate($contextChildren);
+// if ($flags & PPFrame::NO_TEMPLATES) {
+// $newIterator = this.virtualBracketedImplode(
+// '{{', '|', '}}',
+// $bits['title'],
+// $bits['parts']
+// );
+// } else {
+// $ret = this.parser.braceSubstitution($bits, $this);
+// if (isset($ret['Object'])) {
+// $newIterator = $ret['Object'];
+// } else {
+// $out .= $ret['text'];
+// }
+// }
+// } elseif ($contextName === 'tplarg') {
+// # Triple-brace expansion
+// $bits = PPNode_Hash_Tree::splitRawTemplate($contextChildren);
+// if ($flags & PPFrame::NO_ARGS) {
+// $newIterator = this.virtualBracketedImplode(
+// '{{{', '|', '}}}',
+// $bits['title'],
+// $bits['parts']
+// );
+// } else {
+// $ret = this.parser.argSubstitution($bits, $this);
+// if (isset($ret['Object'])) {
+// $newIterator = $ret['Object'];
+// } else {
+// $out .= $ret['text'];
+// }
+// }
+// } elseif ($contextName === 'comment') {
+// # HTML-style comment
+// # Remove it in HTML, pre+remove and STRIP_COMMENTS modes
+// # Not in RECOVER_COMMENTS mode (msgnw) though.
+// if ((this.parser.ot['html']
+// || (this.parser.ot['pre'] && this.parser.mOptions.getRemoveComments())
+// || ($flags & PPFrame::STRIP_COMMENTS)
+// ) && !($flags & PPFrame::RECOVER_COMMENTS)
+// ) {
+// $out .= '';
+// } elseif (this.parser.ot['wiki'] && !($flags & PPFrame::RECOVER_COMMENTS)) {
+// # Add a strip marker in PST mode so that pstPass2() can
+// # run some old-fashioned regexes on the result.
+// # Not in RECOVER_COMMENTS mode (extractSections) though.
+// $out .= this.parser.insertStripItem($contextChildren[0]);
+// } else {
+// # Recover the literal comment in RECOVER_COMMENTS and pre+no-remove
+// $out .= $contextChildren[0];
+// }
+// } elseif ($contextName === 'ignore') {
+// # Output suppression used by etc.
+// # OT_WIKI will only respect in substed templates.
+// # The other output types respect it unless NO_IGNORE is set.
+// # extractSections() sets NO_IGNORE and so never respects it.
+// if ((!isset(this.parent) && this.parser.ot['wiki'])
+// || ($flags & PPFrame::NO_IGNORE)
+// ) {
+// $out .= $contextChildren[0];
+// } else {
+// // $out .= '';
+// }
+// } elseif ($contextName === 'ext') {
+// # Extension tag
+// $bits = PPNode_Hash_Tree::splitRawExt($contextChildren) +
+// [ 'attr' => null, 'inner' => null, 'close' => null ];
+// if ($flags & PPFrame::NO_TAGS) {
+// $s = '<' . $bits['name'].getFirstChild().value;
+// if ($bits['attr']) {
+// $s .= $bits['attr'].getFirstChild().value;
+// }
+// if ($bits['inner']) {
+// $s .= '>' . $bits['inner'].getFirstChild().value;
+// if ($bits['close']) {
+// $s .= $bits['close'].getFirstChild().value;
+// }
+// } else {
+// $s .= '/>';
+// }
+// $out .= $s;
+// } else {
+// $out .= this.parser.extensionSubstitution($bits, $this);
+// }
+// } elseif ($contextName === 'h') {
+// # Heading
+// if (this.parser.ot['html']) {
+// # Expand immediately and insert heading index marker
+// $s = this.expand($contextChildren, $flags);
+// $bits = PPNode_Hash_Tree::splitRawHeading($contextChildren);
+// $titleText = this.title.getPrefixedDBkey();
+// this.parser.mHeadings[] = [ $titleText, $bits['i'] ];
+// $serial = count(this.parser.mHeadings) - 1;
+// $marker = Parser::MARKER_PREFIX . "-h-$serial-" . Parser::MARKER_SUFFIX;
+// $s = substr($s, 0, $bits['level']) . $marker . substr($s, $bits['level']);
+// this.parser.mStripState.addGeneral($marker, '');
+// $out .= $s;
+// } else {
+// # Expand in virtual stack
+// $newIterator = $contextChildren;
+// }
+// } else {
+// # Generic recursive expansion
+// $newIterator = $contextChildren;
+// }
+//
+// if ($newIterator !== false) {
+// $outStack[] = '';
+// $iteratorStack[] = $newIterator;
+// $indexStack[] = 0;
+// } elseif ($iteratorStack[$level] === false) {
+// // Return accumulated value to parent
+// // With tail recursion
+// while ($iteratorStack[$level] === false && $level > 0) {
+// $outStack[$level - 1] .= $out;
+// array_pop($outStack);
+// array_pop($iteratorStack);
+// array_pop($indexStack);
+// $level--;
+// }
+// }
+// }
+// --$expansionDepth;
+// return $outStack[0];
+// }
+//
+// /**
+// * @param String $sep
+// * @param int $flags
+// * @param String|PPNode $args,...
+// * @return String
+// */
+// public function implodeWithFlags($sep, $flags /*, ... */) {
+// $args = array_slice(func_get_args(), 2);
+//
+// $first = true;
+// $s = '';
+// for each ($args as $root) {
+// if ($root instanceof PPNode_Hash_Array) {
+// $root = $root.value;
+// }
+// if (!is_array($root)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= $sep;
+// }
+// $s .= this.expand($node, $flags);
+// }
+// }
+// return $s;
+// }
+//
+// /**
+// * Implode with no flags specified
+// * This previously called implodeWithFlags but has now been inlined to reduce stack depth
+// * @param String $sep
+// * @param String|PPNode $args,...
+// * @return String
+// */
+// public function implode($sep /*, ... */) {
+// $args = array_slice(func_get_args(), 1);
+//
+// $first = true;
+// $s = '';
+// for each ($args as $root) {
+// if ($root instanceof PPNode_Hash_Array) {
+// $root = $root.value;
+// }
+// if (!is_array($root)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= $sep;
+// }
+// $s .= this.expand($node);
+// }
+// }
+// return $s;
+// }
+//
+// /**
+// * 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_Hash_Array
+// */
+// public function virtualImplode($sep /*, ... */) {
+// $args = array_slice(func_get_args(), 1);
+// $out = [];
+// $first = true;
+//
+// for each ($args as $root) {
+// if ($root instanceof PPNode_Hash_Array) {
+// $root = $root.value;
+// }
+// if (!is_array($root)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $out[] = $sep;
+// }
+// $out[] = $node;
+// }
+// }
+// return new PPNode_Hash_Array($out);
+// }
+//
+// /**
+// * Virtual implode with brackets
+// *
+// * @param String $start
+// * @param String $sep
+// * @param String $end
+// * @param String|PPNode $args,...
+// * @return PPNode_Hash_Array
+// */
+// public function virtualBracketedImplode($start, $sep, $end /*, ... */) {
+// $args = array_slice(func_get_args(), 3);
+// $out = [ $start ];
+// $first = true;
+//
+// for each ($args as $root) {
+// if ($root instanceof PPNode_Hash_Array) {
+// $root = $root.value;
+// }
+// if (!is_array($root)) {
+// $root = [ $root ];
+// }
+// for each ($root as $node) {
+// if ($first) {
+// $first = false;
+// } else {
+// $out[] = $sep;
+// }
+// $out[] = $node;
+// }
+// }
+// $out[] = $end;
+// return new PPNode_Hash_Array($out);
+// }
+//
+// public function __toString() {
+// return 'frame{}';
+// }
+//
+// /**
+// * @param boolean $level
+// * @return array|boolean|String
+// */
+// public function getPDBK($level = false) {
+// if ($level === false) {
+// return this.title.getPrefixedDBkey();
+// } else {
+// return isset(this.titleCache[$level]) ? this.titleCache[$level] : false;
+// }
+// }
+//
+// /**
+// * @return array
+// */
+// public function getArguments() {
+// return [];
+// }
+//
+// /**
+// * @return array
+// */
+// public function getNumberedArguments() {
+// return [];
+// }
+//
+// /**
+// * @return array
+// */
+// public function getNamedArguments() {
+// return [];
+// }
+//
+// /**
+// * Returns true if there are no arguments in this frame
+// *
+// * @return boolean
+// */
+// public function isEmpty() {
+// return true;
+// }
+//
+// /**
+// * @param int|String $name
+// * @return boolean Always false in this implementation.
+// */
+// public function getArgument($name) {
+// return false;
+// }
+//
+// /**
+// * Returns true if the infinite loop check is OK, false if a loop is detected
+// *
+// * @param Title $title
+// *
+// * @return boolean
+// */
+// public function loopCheck($title) {
+// return !isset(this.loopCheckHash[$title.getPrefixedDBkey()]);
+// }
+//
+// /**
+// * Return true if the frame is a template frame
+// *
+// * @return boolean
+// */
+// public function isTemplate() {
+// return false;
+// }
+//
+// /**
+// * Get a title of frame
+// *
+// * @return Title
+// */
+// public function getTitle() {
+// return this.title;
+// }
+//
+// /**
+// * Set the volatile flag
+// *
+// * @param boolean $flag
+// */
+// public function setVolatile($flag = true) {
+// this.volatile = $flag;
+// }
+//
+// /**
+// * Get the volatile flag
+// *
+// * @return boolean
+// */
+// public function isVolatile() {
+// return this.volatile;
+// }
+//
+// /**
+// * Set the TTL
+// *
+// * @param int $ttl
+// */
+// public function setTTL($ttl) {
+// if ($ttl !== null && (this.ttl === null || $ttl < this.ttl)) {
+// this.ttl = $ttl;
+// }
+// }
+//
+// /**
+// * Get the TTL
+// *
+// * @return int|null
+// */
+// public function getTTL() {
+// return this.ttl;
+// }
+//}
+//
+///**
+// * Expansion frame with template arguments
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPTemplateFrame_Hash extends PPFrame_Hash {
+// // @codingStandardsIgnoreEnd
+//
+// public $numberedArgs, $namedArgs, $parent;
+// public $numberedExpansionCache, $namedExpansionCache;
+//
+// /**
+// * @param Preprocessor $preprocessor
+// * @param boolean|PPFrame $parent
+// * @param array $numberedArgs
+// * @param array $namedArgs
+// * @param boolean|Title $title
+// */
+// public function __construct($preprocessor, $parent = false, $numberedArgs = [],
+// $namedArgs = [], $title = false
+// ) {
+// parent::__construct($preprocessor);
+//
+// this.parent = $parent;
+// this.numberedArgs = $numberedArgs;
+// this.namedArgs = $namedArgs;
+// this.title = $title;
+// $pdbk = $title ? $title.getPrefixedDBkey() : false;
+// this.titleCache = $parent.titleCache;
+// this.titleCache[] = $pdbk;
+// this.loopCheckHash = /*clone*/ $parent.loopCheckHash;
+// if ($pdbk !== false) {
+// this.loopCheckHash[$pdbk] = true;
+// }
+// this.depth = $parent.depth + 1;
+// this.numberedExpansionCache = this.namedExpansionCache = [];
+// }
+//
+// public function __toString() {
+// $s = 'tplframe{';
+// $first = true;
+// $args = this.numberedArgs + this.namedArgs;
+// for each ($args as $name => $value) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= ', ';
+// }
+// $s .= "\"$name\":\"" .
+// str_replace('"', '\\"', $value.__toString()) . '"';
+// }
+// $s .= '}';
+// return $s;
+// }
+//
+// /**
+// * @throws MWException
+// * @param String|int $key
+// * @param String|PPNode $root
+// * @param int $flags
+// * @return String
+// */
+// public function cachedExpand($key, $root, $flags = 0) {
+// if (isset(this.parent.childExpansionCache[$key])) {
+// return this.parent.childExpansionCache[$key];
+// }
+// $retval = this.expand($root, $flags);
+// if (!this.isVolatile()) {
+// this.parent.childExpansionCache[$key] = $retval;
+// }
+// return $retval;
+// }
+//
+// /**
+// * Returns true if there are no arguments in this frame
+// *
+// * @return boolean
+// */
+// public function isEmpty() {
+// return !count(this.numberedArgs) && !count(this.namedArgs);
+// }
+//
+// /**
+// * @return array
+// */
+// public function getArguments() {
+// $arguments = [];
+// for each (array_merge(
+// array_keys(this.numberedArgs),
+// array_keys(this.namedArgs)) as $key) {
+// $arguments[$key] = this.getArgument($key);
+// }
+// return $arguments;
+// }
+//
+// /**
+// * @return array
+// */
+// public function getNumberedArguments() {
+// $arguments = [];
+// for each (array_keys(this.numberedArgs) as $key) {
+// $arguments[$key] = this.getArgument($key);
+// }
+// return $arguments;
+// }
+//
+// /**
+// * @return array
+// */
+// public function getNamedArguments() {
+// $arguments = [];
+// for each (array_keys(this.namedArgs) as $key) {
+// $arguments[$key] = this.getArgument($key);
+// }
+// return $arguments;
+// }
+//
+// /**
+// * @param int $index
+// * @return String|boolean
+// */
+// public function getNumberedArgument($index) {
+// if (!isset(this.numberedArgs[$index])) {
+// return false;
+// }
+// if (!isset(this.numberedExpansionCache[$index])) {
+// # No trimming for unnamed arguments
+// this.numberedExpansionCache[$index] = this.parent.expand(
+// this.numberedArgs[$index],
+// PPFrame::STRIP_COMMENTS
+// );
+// }
+// return this.numberedExpansionCache[$index];
+// }
+//
+// /**
+// * @param String $name
+// * @return String|boolean
+// */
+// public function getNamedArgument($name) {
+// if (!isset(this.namedArgs[$name])) {
+// return false;
+// }
+// if (!isset(this.namedExpansionCache[$name])) {
+// # Trim named arguments post-expand, for backwards compatibility
+// this.namedExpansionCache[$name] = trim(
+// this.parent.expand(this.namedArgs[$name], PPFrame::STRIP_COMMENTS));
+// }
+// return this.namedExpansionCache[$name];
+// }
+//
+// /**
+// * @param int|String $name
+// * @return String|boolean
+// */
+// public function getArgument($name) {
+// $text = this.getNumberedArgument($name);
+// if ($text === false) {
+// $text = this.getNamedArgument($name);
+// }
+// return $text;
+// }
+//
+// /**
+// * Return true if the frame is a template frame
+// *
+// * @return boolean
+// */
+// public function isTemplate() {
+// return true;
+// }
+//
+// public function setVolatile($flag = true) {
+// parent::setVolatile($flag);
+// this.parent.setVolatile($flag);
+// }
+//
+// public function setTTL($ttl) {
+// parent::setTTL($ttl);
+// this.parent.setTTL($ttl);
+// }
+//}
+//
+///**
+// * Expansion frame with custom arguments
+// * @ingroup Parser
+// */
+//// @codingStandardsIgnoreStart Squiz.Classes.ValidClassName.NotCamelCaps
+//class PPCustomFrame_Hash extends PPFrame_Hash {
+// // @codingStandardsIgnoreEnd
+//
+// public $args;
+//
+// public function __construct($preprocessor, $args) {
+// parent::__construct($preprocessor);
+// this.args = $args;
+// }
+//
+// public function __toString() {
+// $s = 'cstmframe{';
+// $first = true;
+// for each (this.args as $name => $value) {
+// if ($first) {
+// $first = false;
+// } else {
+// $s .= ', ';
+// }
+// $s .= "\"$name\":\"" .
+// str_replace('"', '\\"', $value.__toString()) . '"';
+// }
+// $s .= '}';
+// return $s;
+// }
+//
+// /**
+// * @return boolean
+// */
+// public function isEmpty() {
+// return !count(this.args);
+// }
+//
+// /**
+// * @param int|String $index
+// * @return String|boolean
+// */
+// public function getArgument($index) {
+// if (!isset(this.args[$index])) {
+// return false;
+// }
+// return this.args[$index];
+// }
+//
+// public function getArguments() {
+// return this.args;
+// }
+//}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElementFlags.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElementFlags.java
new file mode 100644
index 000000000..268211fcb
--- /dev/null
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackElementFlags.java
@@ -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 XomwPPDStackElementFlags {
+ public XomwPPDStackElementFlags(boolean findPipe, boolean findEquals, boolean inHeading) {
+ this.findPipe = findPipe;
+ this.findEquals = findEquals;
+ this.inHeading = inHeading;
+ }
+ public boolean FindPipe() {return findPipe;} private final boolean findPipe;
+ public boolean FindEquals() {return findEquals;} private final boolean findEquals;
+ public boolean InHeading() {return inHeading;} private final boolean inHeading;
+
+ public static final XomwPPDStackElementFlags Empty = new XomwPPDStackElementFlags(false, false, false);
+}
\ No newline at end of file
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackOld.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackOld.java
new file mode 100644
index 000000000..0b68dd8d2
--- /dev/null
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackOld.java
@@ -0,0 +1,95 @@
+/*
+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 XomwPPDStackOld {
+ public final List_adp stack = List_adp_.New();
+ public Xomw_prepro_piece top;
+ private final Xomw_prepro_flags flags = new Xomw_prepro_flags();
+ protected Xomw_prepro_accum root_accum;
+ protected Xomw_prepro_accum accum;
+
+ public XomwPPDStackOld(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("XomwPPDStackOld: 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;
+ }
+ }
+}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStack_Hash.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackOld_Hash.java
similarity index 85%
rename from 400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStack_Hash.java
rename to 400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackOld_Hash.java
index 1156135de..28138833a 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStack_Hash.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPDStackOld_Hash.java
@@ -14,7 +14,7 @@ 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 XomwPPDStack_Hash extends XomwPPDStack { public XomwPPDStack_Hash(Xomw_prepro_accum prototype) {super(prototype);
+public class XomwPPDStackOld_Hash extends XomwPPDStackOld { public XomwPPDStackOld_Hash(Xomw_prepro_accum prototype) {super(prototype);
this.root_accum = prototype.Make_new();
this.accum = root_accum;
}
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Text.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Text.java
index 0d40f1a0c..166cb7601 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Text.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Text.java
@@ -18,6 +18,7 @@ package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; impor
/**
* @ingroup Parser
*/
+import gplx.xowa.mediawiki.includes.exception.*;
public class XomwPPNode_Hash_Text extends XomwPPNode { public String value;
private final XophpArray store;
private final int index;
@@ -32,7 +33,7 @@ public class XomwPPNode_Hash_Text extends XomwPPNode { public String value;
public XomwPPNode_Hash_Text(XophpArray store, int index) {
Object value_obj = store.Get_at(index);
if (!XophpTypeUtl.is_scalar(value_obj)) {
- throw XomwExceptionUtl.New_by_method(XomwPPNode_Hash_Text.class, "CTOR", "given Object instead of String");
+ throw XomwMWException.New_by_method(XomwPPNode_Hash_Text.class, "CTOR", "given Object instead of String");
}
this.value = Object_.Xto_str_strict_or_null(value_obj);
this.store = store;
diff --git a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java
index e0dcc85d5..b45f33eff 100644
--- a/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java
+++ b/400_xowa/src/gplx/xowa/mediawiki/includes/parsers/preprocessors/XomwPPNode_Hash_Tree.java
@@ -18,6 +18,7 @@ package gplx.xowa.mediawiki.includes.parsers.preprocessors; import gplx.*; impor
/**
* @ingroup Parser
*/
+import gplx.xowa.mediawiki.includes.exception.*;
public class XomwPPNode_Hash_Tree extends XomwPPNode { public final String name;
/**
* The store array for children of this node. It is "raw" in the sense that
@@ -93,7 +94,7 @@ public class XomwPPNode_Hash_Tree extends XomwPPNode { public final String na
}
}
else {
- throw XomwExceptionUtl.New_by_method(XomwPPNode_Hash_Tree.class, "factory", "invalid node descriptor");
+ throw XomwMWException.New_by_method(XomwPPNode_Hash_Tree.class, "factory", "invalid node descriptor");
}
}