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

View File

@@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Pfunc_titleparts_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tmpl_func_titleparts");
public static final Gfo_msg_itm
Len_is_invalid = Gfo_msg_itm_.new_warn_(owner, "Len_is_invalid")
, Bgn_is_invalid = Gfo_msg_itm_.new_warn_(owner, "Bgn_is_invalid")
;
}

View File

@@ -0,0 +1,233 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*; import gplx.core.strings.*;
interface TstRuleMgr {
boolean SkipChkVal(String expdTypeKey, TstAtr expd);
boolean SkipChkObj(String expdTypeKey, String atrKey, TstObj expd);
}
class Xop_rule_mgr implements TstRuleMgr {
public boolean SkipChkVal(String expdTypeKey, TstAtr expd) {
String key = expdTypeKey + "." + expd.Key();
Xop_rule_dat ruleDat = (Xop_rule_dat)hash.Get_by(key); if (ruleDat == null) return false;
if (expd.ValType().Eq(expd.Val(), ruleDat.SkipVal())) return true;
return false;
}
public boolean SkipChkObj(String expdTypeKey, String atrKey, TstObj expd) {
String key = expdTypeKey + "." + atrKey;
Xop_rule_dat ruleDat = (Xop_rule_dat)hash.Get_by(key); if (ruleDat == null) return false;
TstAtr expdAtr = (TstAtr)expd.Atrs().Get_by(ruleDat.SubKey());
if (expdAtr == null) return false;
if (expdAtr.ValType().Eq(expdAtr.Val(), ruleDat.SkipVal())) return true;
return false;
}
public Xop_rule_mgr TypeKey_(String v) {typeKey = v; return this;} private String typeKey;
public Xop_rule_mgr SkipIf_double(String atrKey, double v) {return SkipIfObj(atrKey, null, v);}
public Xop_rule_mgr SkipIf(String atrKey, String v) {return SkipIfObj(atrKey, null, v);}
public Xop_rule_mgr SkipIf(String atrKey, byte v) {return SkipIfObj(atrKey, null, v);}
public Xop_rule_mgr SkipIf(String atrKey, int v) {return SkipIfObj(atrKey, null, v);}
public Xop_rule_mgr SkipIf(String atrKey, boolean v) {return SkipIfObj(atrKey, null, v);}
public Xop_rule_mgr SkipIf(String atrKey, String subKey, Object o) {return SkipIfObj(atrKey, subKey, o);}
public Xop_rule_mgr SkipIfObj_many(String[] atrKeys, String subKey, Object o) {for (String atrKey : atrKeys) SkipIfObj(atrKey, subKey, o); return this;}
Xop_rule_mgr SkipIfObj(String atrKey, String subKey, Object skipVal) {
String key = typeKey + "." + atrKey;
Xop_rule_dat ruleDat = new Xop_rule_dat(key, subKey, skipVal);
hash.Add(key, ruleDat);
return this;
}
public String Reg() {return typeKey;}
Ordered_hash hash = Ordered_hash_.new_();
public static final Xop_rule_mgr _ = new Xop_rule_mgr();
}
class Xop_rule_dat {
public String AtrKey() {return atrKey;} private String atrKey;
public String SubKey() {return subKey;} private String subKey;
public Object SkipVal() {return skipVal;} Object skipVal;
public Xop_rule_dat(String atrKey, String subKey, Object skipVal) {this.atrKey = atrKey; this.subKey = subKey; this.skipVal = skipVal;}
}
public class TstObj_tst {
@Test public void Basic() {
tst_(mock_().Val1_(1).Val2_("a"), mock_().Val1_(1).Val2_("a"));
// tst_(mock_().Val1_(3).Val2_("a"), mock_().Val1_(1).Val2_("b"));
}
MockObj mock_() {return new MockObj();}
private void tst_(MockObj expd, MockObj actl) {
TstObj expdChk = TstObj.new_(), actlChk = TstObj.new_();
expd.SrlObj_Srl(expdChk);
actl.SrlObj_Srl(actlChk);
Eval("", expdChk, actlChk, new Xop_rule_mgr());
}
private static void Max(int[] ary, int idx, String val) {
int len = String_.Len(val);
if (len > ary[idx]) ary[idx] = len;
}
private static int Add(int[] ary) {int rv = 0; for (int i = 0; i < ary.length; i++) rv += ary[i]; return rv;}
@gplx.Internal protected static void Eval(String raw, TstObj expdChk, TstObj actlChk, TstRuleMgr ruleMgr) {
List_adp rslts = List_adp_.new_();
Eval(rslts, ruleMgr, Ordered_hash_.new_(), "", expdChk, actlChk);
String_bldr sb = String_bldr_.new_();
sb.Add(raw).Add(Op_sys.Lnx.Nl_str());
boolean pass = true;
int[] cols = new int[3];
for (int i = 0; i < rslts.Count(); i++) {
TstRslt rslt = (TstRslt)rslts.Get_at(i);
Max(cols, 0, rslt.EvalStr());
Max(cols, 1, rslt.Id());
Max(cols, 2, rslt.Key());
}
String hdr = String_.Repeat(" ", Add(cols) + 3);
for (int i = 0; i < rslts.Count(); i++) {
TstRslt rslt = (TstRslt)rslts.Get_at(i);
// if (rslt.EvalPass()) continue;
sb .Add(String_.PadEnd(rslt.EvalStr(), cols[0] + 1, " "))
.Add(String_.PadEnd(rslt.Id(), cols[1] + 1, " "))
.Add(String_.PadEnd(rslt.Key(), cols[2] + 1, " "))
.Add(rslt.ExpdStr()).Add(Op_sys.Lnx.Nl_str());
if (!rslt.EvalPass()) {
sb.Add(hdr).Add(rslt.ActlStr()).Add(Op_sys.Lnx.Nl_str());
pass = false;
}
}
if (pass) return;
throw Exc_.new_(Op_sys.Lnx.Nl_str() + sb.XtoStr());
}
private static void Eval(List_adp rslts, TstRuleMgr ruleMgr, Ordered_hash props, String idx, TstObj expd, TstObj actl) {
int expdLen = expd.Atrs().Count();
props.Clear();
for (int i = 0; i < expdLen; i++) {
TstAtr expdAtr = (TstAtr)expd.Atrs().Get_at(i);
String key = expdAtr.Key();
TstAtr actlAtr = (TstAtr)actl.Atrs().Get_by(key);
if (expdAtr.ValType() == ObjectClassXtn._) {
SrlObj expdSrl = (SrlObj)expdAtr.Val();
TstObj expdTst = TstObj.new_();
expdSrl.SrlObj_Srl(expdTst);
TstObj actlTst = TstObj.new_();
if (actlAtr != null) ((SrlObj)actlAtr.Val()).SrlObj_Srl(actlTst);
if (ruleMgr.SkipChkObj(expdAtr.TypeKey(), key, expdTst)) continue;
Eval(rslts, ruleMgr, Ordered_hash_.new_(), idx + "." + key, expdTst, actlTst);
}
else {
if (actlAtr == null) actlAtr = new TstAtr();
if (ruleMgr.SkipChkVal(expdAtr.TypeKey(), expdAtr)) continue;
Eval(rslts, idx, key, expdAtr, actlAtr, true);
}
props.Add(key, key);
}
int expdSubsLen = expd.Subs().Count(), actlSubsLen = actl.Subs().Count();
int maxLen = expdSubsLen > actlSubsLen ? expdSubsLen : actlSubsLen;
for (int i = 0; i < maxLen; i++) {
TstObj expdSub = i < expdSubsLen ? (TstObj)expd.Subs().Get_at(i) : TstObj.Null;
TstObj actlSub = i < actlSubsLen ? (TstObj)actl.Subs().Get_at(i) : TstObj.Null;
// if (ruleMgr != null) ruleMgr.Eval(expd.TypeKey(), expdSub.PropName(), expdAtr, actlAtr, skip);
String iAsStr = Int_.Xto_str(i);
String subId = String_.Eq(idx, "") ? iAsStr : idx + "." + iAsStr;
if (expdSub == TstObj.Null && actlSub != TstObj.Null) {
TstAtr mis = new TstAtr().Key_("idx").Val_(i).ValType_(IntClassXtn._);
rslts.Add(new TstRslt().Expd_(mis).Actl_(mis).EvalPass_(false).EvalStr_("!=")
.Id_(subId).Key_("sub_ref")
.ExpdStr_("null").ActlStr_("not null"));
continue;
}
Eval(rslts, ruleMgr, props, subId, expdSub, actlSub);
}
}
private static void Eval(List_adp rslts, String id, String key, TstAtr expd, TstAtr actl, boolean srcIsExpd) {
int evalType = 0;
boolean evalPass = false; String evalStr = "";
switch (evalType) {
case 0:
if (expd.ValType().Eq(expd.Val(), actl.Val())) {
evalPass = true;
evalStr = "==";
}
else {
evalPass = false;
evalStr = "!=";
}
break;
}
TstRslt rslt = new TstRslt().Expd_(expd).Actl_(actl)
.Id_(id).Key_(key)
.EvalType_(evalType).EvalPass_(evalPass).EvalStr_(evalStr)
.ExpdStr_(Object_.Xto_str_strict_or_null_mark(expd.Val())).ActlStr_(Object_.Xto_str_strict_or_null_mark(actl.Val()))
;
rslts.Add(rslt);
}
}
class MockObj {
public int Val1() {return val1;} public MockObj Val1_(int v) {val1 = v; return this;} private int val1;
public String Val2() {return val2;} public MockObj Val2_(String v) {val2 = v; return this;} private String val2;
public void SrlObj_Srl(SrlMgr mgr) {
mgr.TypeKey_("MockObj");
val1 = mgr.SrlIntOr("val1", val1);
val2 = mgr.SrlStrOr("val2", val2);
}
}
class TstObj implements SrlMgr {
public boolean Type_rdr() {return false;}
public Ordered_hash Atrs() {return atrs;} private Ordered_hash atrs = Ordered_hash_.new_();
public Object StoreRoot(SrlObj root, String key) {return null;}
public boolean SrlBoolOr(String key, boolean v) {Atrs_add(key, v, BoolClassXtn._); return v;}
public byte SrlByteOr(String key, byte v) {Atrs_add(key, v, ByteClassXtn._); return v;}
public int SrlIntOr(String key, int v) {Atrs_add(key, v, IntClassXtn._); return v;}
public long SrlLongOr(String key, long v) {Atrs_add(key, v, LongClassXtn._); return v;}
public String SrlStrOr(String key, String v) {Atrs_add(key, v, StringClassXtn._); return v;}
public DecimalAdp SrlDecimalOr(String key, DecimalAdp v) {Atrs_add(key, v, DecimalAdpClassXtn._); return v;}
public DateAdp SrlDateOr(String key, DateAdp v) {Atrs_add(key, v, DateAdpClassXtn._); return v;}
public double SrlDoubleOr(String key, double v) {Atrs_add(key, v, DoubleClassXtn._); return v;}
public Object SrlObjOr(String key, Object v) {
Atrs_add(key, v, ObjectClassXtn._);
return v;
}
public void SrlList(String key, List_adp list, SrlObj proto, String itmKey) {}
public String TypeKey() {return typeKey;} public void TypeKey_(String v) {typeKey = v;} private String typeKey;
private void Atrs_add(String key, Object val, ClassXtn valType) {
atrs.Add(key, new TstAtr().TypeKey_(typeKey).Key_(key).Val_(val).ValType_(valType));
}
public List_adp Subs() {return subs;} List_adp subs = List_adp_.Noop;
public SrlMgr SrlMgr_new(Object o) {return Subs_new();}
public TstObj Subs_new() {
if (subs == List_adp_.Noop) subs = List_adp_.new_();
TstObj rv = TstObj.new_();
subs.Add(rv);
return rv;
}
public static TstObj new_() {return new TstObj();} TstObj() {}
public static final TstObj Null = new TstObj();
}
class TstAtr {
public String TypeKey() {return typeKey;} public TstAtr TypeKey_(String v) {typeKey = v; return this;} private String typeKey;
public String Key() {return key;} public TstAtr Key_(String v) {key = v; return this;} private String key;
public Object Val() {return val;} public TstAtr Val_(Object v) {val = v; return this;} Object val;
public ClassXtn ValType() {return valType;} public TstAtr ValType_(ClassXtn v) {valType = v; return this;} ClassXtn valType;
}
class TstRslt {
public TstAtr Expd() {return expd;} public TstRslt Expd_(TstAtr v) {expd = v; return this;} TstAtr expd;
public TstAtr Actl() {return actl;} public TstRslt Actl_(TstAtr v) {actl = v; return this;} TstAtr actl;
public boolean Ignore() {return ignore;} public TstRslt Ignore_y_(boolean v) {ignore = v; return this;} private boolean ignore;
public int EvalType() {return evalType;} public TstRslt EvalType_(int v) {evalType = v; return this;} private int evalType;
public boolean EvalPass() {return evalPass;} public TstRslt EvalPass_(boolean v) {evalPass = v; return this;} private boolean evalPass;
public String EvalStr() {return evalStr;} public TstRslt EvalStr_(String v) {evalStr = v; return this;} private String evalStr;
public String Id() {return id;} public TstRslt Id_(String v) {id = v; return this;} private String id;
public String Key() {return key;} public TstRslt Key_(String v) {key = v; return this;} private String key;
public String ActlStr() {return actlStr;} public TstRslt ActlStr_(String v) {actlStr = v; return this;} private String actlStr;
public String ExpdStr() {return expdStr;} public TstRslt ExpdStr_(String v) {expdStr = v; return this;} private String expdStr;
public static final Object Ignore_null = new Object();
}

View File

@@ -0,0 +1,420 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.core.primitives.*; import gplx.core.btries.*; import gplx.xowa.wikis.xwikis.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.langs.cases.*;
public class Xoa_ttl { // PAGE:en.w:http://en.wikipedia.org/wiki/Help:Link; REF.MW: Ttl.php|secureAndSplit;
public Xow_ns Ns() {return ns;} private Xow_ns ns;
public boolean ForceLiteralLink() {return forceLiteralLink;} private boolean forceLiteralLink;
// NOTE: in procs below, all -1 are used to skip previous delimiters; they will only occur for end_pos arguments
public boolean Eq_page_db(Xoa_ttl comp) {if (comp == null) return false; return Bry_.Eq(this.Page_db(), comp.Page_db());} // check page is same; ignores anchor and xwiki
public boolean Eq_full_db(Xoa_ttl comp) {if (comp == null) return false; return Bry_.Eq(this.Full_db(), comp.Full_db());} // check page is same; ignores anchor and xwiki
public byte[] Raw() {return raw;} private byte[] raw = Bry_.Empty;
public byte[] Wik_txt() {return wik_bgn == -1 ? Bry_.Empty : Bry_.Mid(full_txt, wik_bgn, ns_bgn == -1 ? page_bgn - 1 : ns_bgn - 1);}
public Xow_xwiki_itm Wik_itm() {return wik_itm;} private Xow_xwiki_itm wik_itm;
public byte[] Full_txt() {
int bgn = wik_bgn == -1 ? 0 : ns_bgn == -1 ? page_bgn : ns_bgn;
int end = full_txt.length;
if (anch_bgn != -1) end = anch_bgn - 1;
return Bry_.Mid(full_txt, bgn, end);
}
public byte[] Full_txt_raw() {return full_txt;} private byte[] full_txt = Bry_.Empty;
public byte[] Page_txt_w_anchor() {return Bry_.Mid(full_txt, page_bgn, qarg_bgn == -1 ? full_txt.length : qarg_bgn - 1);}
public byte[] Page_txt() {return Bry_.Mid(full_txt, page_bgn, anch_bgn == -1 ? full_txt.length : anch_bgn - 1);}
public byte[] Page_db() {
byte[] rv = this.Page_txt();
Bry_.Replace_reuse(rv, Byte_ascii.Space, Byte_ascii.Underline);
return rv;
}
public String Page_db_as_str() {return String_.new_u8(Page_db());}
public int Leaf_bgn() {return leaf_bgn;}
public byte[] Base_txt() {return leaf_bgn == -1 ? Page_txt() : Bry_.Mid(full_txt, page_bgn, leaf_bgn - 1);}
public byte[] Leaf_txt() {return leaf_bgn == -1 ? Page_txt() : Bry_.Mid(full_txt, leaf_bgn, anch_bgn == -1 ? full_txt.length : anch_bgn - 1);}
public int Wik_bgn() {return wik_bgn;}
public int Anch_bgn() {return anch_bgn;} // NOTE: anch_bgn is not correct when page has trailing ws; EX: [[A #b]] should have anch_bgn of 3 (1st char after #), but instead it is 2
public byte[] Anch_txt() {return anch_bgn == -1 ? Bry_.Empty : Bry_.Mid(full_txt, anch_bgn, full_txt.length);}
public byte[] Talk_txt() {return ns.Id_talk() ? Full_txt() : Bry_.Add(tors_txt, Page_txt());}
public byte[] Subj_txt() {return ns.Id_subj() ? Full_txt() : Bry_.Add(tors_txt, Page_txt());}
public byte[] Full_url() {return Xoa_url_encoder._.Encode(full_txt);}
public String Full_db_as_str() {return String_.new_u8(Full_db());}
public byte[] Full_db() {return ns.Gen_ttl(this.Page_db());}
public byte[] Page_url() {return Xoa_url_encoder._.Encode(this.Page_txt());}
public byte[] Leaf_url() {return Xoa_url_encoder._.Encode(this.Leaf_txt());}
public byte[] Base_url() {return Xoa_url_encoder._.Encode(this.Base_txt());}
public byte[] Root_txt() {return root_bgn == -1 ? Page_txt() : Bry_.Mid(full_txt, page_bgn, root_bgn - 1);}
public byte[] Rest_txt() {return root_bgn == -1 ? Page_txt() : Bry_.Mid(full_txt, root_bgn, anch_bgn == -1 ? full_txt.length : anch_bgn - 1);}
public byte[] Talk_url() {return Xoa_url_encoder._.Encode(this.Talk_txt());}
public byte[] Subj_url() {return Xoa_url_encoder._.Encode(this.Subj_txt());}
public int Qarg_bgn() {return qarg_bgn;} private int qarg_bgn = -1;
public byte[] Qarg_txt() {return this.Qarg_bgn() == -1 ? null : Bry_.Mid(full_txt, this.Qarg_bgn(), full_txt.length);}
public byte[] Base_txt_wo_qarg() {
int bgn = page_bgn;
int end = full_txt.length;
if (leaf_bgn != -1) end = leaf_bgn - 1;
else if (qarg_bgn != -1) end = qarg_bgn - 1;
return Bry_.Mid(full_txt, bgn, end);
}
public byte[] Leaf_txt_wo_qarg() {
int bgn = leaf_bgn == -1 ? 0 : leaf_bgn;
int end = full_txt.length;
if (anch_bgn != -1) end = anch_bgn - 1;
else if (qarg_bgn != -1) end = qarg_bgn - 1;
return Bry_.Mid(full_txt, bgn, end);
}
public byte[] Full_txt_wo_qarg() {
int bgn = wik_bgn == -1 ? 0 : ns_bgn == -1 ? page_bgn : ns_bgn;
int end = full_txt.length;
if (anch_bgn != -1) end = anch_bgn - 1;
else if (qarg_bgn != -1) end = qarg_bgn - 1;
return Bry_.Mid(full_txt, bgn, end);
}
public byte[] Page_txt_wo_qargs() { // assume that no Special page has non-ascii characters
int full_txt_len = full_txt.length;
int ques_pos = Bry_finder.Find_bwd(full_txt, Byte_ascii.Question, full_txt_len, page_bgn);
return Bry_.Mid(full_txt, page_bgn, ques_pos == Bry_.NotFound ? full_txt_len : ques_pos);
}
public static Xoa_ttl parse_(Xowe_wiki wiki, int ns_id, byte[] ttl) {
Xow_ns ns = wiki.Ns_mgr().Ids_get_or_null(ns_id);
byte[] raw = Bry_.Add(ns.Name_db_w_colon(), ttl);
return new_(wiki, wiki.Appe().Msg_log(), raw, 0, raw.length);
}
public static Xoa_ttl parse_(Xowe_wiki wiki, byte[] raw) {return new_(wiki, wiki.Appe().Msg_log(), raw, 0, raw.length);}
private static final Object thread_lock = new Object();
public static Xoa_ttl new_(Xowe_wiki wiki, Gfo_msg_log msg_log, byte[] src, int bgn, int end) {
Xoae_app app = wiki.Appe();
Bry_bfr_mkr bry_mkr = app.Utl__bfr_mkr();
return parse(bry_mkr, app.Parser_amp_mgr(), wiki.Lang().Case_mgr(), wiki.Xwiki_mgr(), wiki.Ns_mgr(), msg_log, src, bgn, end);
} private Xoa_ttl() {}
public static Xoa_ttl parse(Bry_bfr_mkr bry_mkr, Xop_amp_mgr amp_mgr, Xol_case_mgr case_mgr, Xow_xwiki_mgr xwiki_mgr, Xow_ns_mgr ns_mgr, Gfo_msg_log msg_log, byte[] src, int bgn, int end) {
synchronized (thread_lock) {
Xoa_ttl rv = new Xoa_ttl();
Bry_bfr bfr = bry_mkr.Get_b512();
try {
boolean pass = rv.Parse(bfr, bry_mkr, amp_mgr, case_mgr, xwiki_mgr, ns_mgr, msg_log, src, bgn, end);
return pass ? rv : null;
}
finally {bfr.Mkr_rls();}
}
}
private boolean Parse(Bry_bfr bfr, Bry_bfr_mkr bry_mkr, Xop_amp_mgr amp_mgr, Xol_case_mgr case_mgr, Xow_xwiki_mgr xwiki_mgr, Xow_ns_mgr ns_mgr, Gfo_msg_log msg_log, byte[] src, int bgn, int end) {
/* This proc will
- identify all parts: Wiki, Namespace, Base/Leaf, Anchor; it will also identify Subject/Talk ns
- trim whitespace around part delimiters; EX: "Help : Test" --> "Help:Test"; note that it will trim only if the ns part is real; EX: "Helpx : Test" is unchanged
- replace multiple whitespaces with 1; EX: "Many ws" --> "Many ws"
- capitalize the first letter of the page title
note: a byte[] is needed b/c proc does collapsing and casing
FUTURE:
- "/", "a/" (should be page); "#" (not a page)
- Talk:Help:a disallowed; Category talk:Help:a allowed
- forbid extended ws: '/[ _\xA0\x{1680}\x{180E}\x{2000}-\x{200A}\x{2028}\x{2029}\x{202F}\x{205F}\x{3000}]+/u'
- remove invalid characters $rxTc
- forbid ./ /.
- forbid ~~~
- handle ip address urls for User and User talk
*/
Url_encoder anchor_encoder = null;
Bry_bfr anchor_encoder_bfr = null;
bfr.Clear();
if (end - bgn == 0) {msg_log.Add_itm_none(Xop_ttl_log.Len_0, src, bgn, bgn); return false;}
this.raw = src;
ns = ns_mgr.Ns_main();
boolean add_ws = false, ltr_bgn_reset = false;
int ltr_bgn = -1, txt_bb_len = 0, colon_count = 0; bfr.Clear();
Btrie_slim_mgr amp_trie = amp_mgr.Amp_trie();
byte[] b_ary = null;
int cur = bgn;
int match_pos = -1;
while (cur != end) {
byte b = src[cur];
switch (b) {
case Byte_ascii.Colon:
if (cur == bgn) { // initial colon; flag; note that " :" is not handled; note that colon_count is not incremented
forceLiteralLink = true;
++cur;
if (cur < end && src[cur] == Byte_ascii.Colon)
++cur;
continue; // do not add to bfr
}
else {
if (ltr_bgn == -1) {// no ltrs seen; treat as literal; occurs for ::fr:wikt:test and fr::Help:test
++colon_count;
break;
}
boolean part_found = false;
if (colon_count == 0) {// 1st colon;
Object o = ns_mgr.Names_get_or_null(bfr.Bfr(), ltr_bgn, txt_bb_len);
if (o == null) { // not ns; try alias
wik_itm = xwiki_mgr.Get_by_mid(bfr.Bfr(), ltr_bgn, txt_bb_len); // check if wiki; note: wiki is not possible for other colons
if (wik_itm != null) {
wik_bgn = 0; // wik_bgn can only start at 0
part_found = true;
anch_bgn = -1; // NOTE: do not allow anchors to begin before wiki_itm; breaks Full_txt for [[:#batch:Main Page]]; DATE:20130102
}
}
else {
ns = (Xow_ns)o;
byte[] ns_name = ns.Name_txt();
int ns_name_len = ns_name.length;
int tmp_bfr_end = bfr.Len();
if (!Bry_.Eq(ns_name, bfr.Bfr(), ltr_bgn, tmp_bfr_end) && ns_name_len == tmp_bfr_end - ltr_bgn) { // if (a) ns_name != bfr_txt (b) both are same length; note that (b) should not happen, but want to safeguard against mismatched arrays
Bry_.Set(bfr.Bfr(), ltr_bgn, tmp_bfr_end, ns_name);
}
ns_bgn = ltr_bgn;
part_found = true;
}
}
if (part_found) {
page_bgn = txt_bb_len + 1; // anticipate page_bgn;
add_ws = false; // if there was an add_ws, ignore; EX: "Category :" should ignore space
ltr_bgn_reset = true; // ltr_bgn_reset
}
colon_count++; // increment colon count
break;
}
case Byte_ascii.Hash: anch_bgn = (txt_bb_len) + 1; break; // flag last anch_bgn
case Byte_ascii.Slash:
if (root_bgn == -1)
root_bgn = (txt_bb_len) + 1;
if (anch_bgn == -1) { // only set leaf if anchor found; guards against A#B/C and / setting leaf; DATE:2014-01-14
leaf_bgn = (txt_bb_len) + 1;
qarg_bgn = -1; // always reset qarg; handles ttls which have question_mark which are premptively assumed to be qarg; PAGE:en.w:Portal:Organized_Labour/Did_You_Know?/1 DATE:2014-06-08
}
break; // flag last leaf_bgn
case Byte_ascii.Nl: // NOTE: for now, treat nl just like space; not sure if it should accept "a\nb" or "\nab"; need to handle trailing \n for "Argentina\n\n" in {{Infobox settlement|pushpin_map=Argentina|pushpin_label_position=|pushpin_map_alt=|pushpin_map_caption=Location of Salta in Argentina}};
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.Cr: // added \t, \r; DATE:2013-03-27
case Byte_ascii.Underline:if (ltr_bgn != -1) add_ws = true; ++cur;//cur = ttlTrie.Match_pos();
continue; // only mark add_ws if ltr_seen; this ignores ws at bgn; also, note "continue"
case Byte_ascii.Question:
if (txt_bb_len + 1 < end) // guard against trailing ? (which shouldn't happen)
qarg_bgn = txt_bb_len + 1;
break;
case Byte_ascii.Amp:
int cur2 = cur + 1;//cur = ttlTrie.Match_pos();
if (cur2 == end) {} // guards against terminating &; EX: [[Bisc &]]; NOTE: needed b/c Match_bgn does not do bounds checking for cur in src; src[src.length] will be called when & is last character;
else {
Object html_ent_obj = amp_trie.Match_bgn(src, cur2, end);
if (html_ent_obj != null) {
Xop_amp_trie_itm amp_itm = (Xop_amp_trie_itm)html_ent_obj;
match_pos = amp_trie.Match_pos();
if (amp_itm.Tid() == Xop_amp_trie_itm.Tid_name_std) {
switch (amp_itm.Char_int()) {
case 160: // NOTE: &nbsp must convert to space; EX:w:United States [[Image:Dust Bowl&nbsp;- Dallas, South Dakota 1936.jpg|220px|alt=]]
if (ltr_bgn != -1) add_ws = true; // apply same ws rules as Space, NewLine; needed for converting multiple ws into one; EX:" &nbsp; " -> " " x> " "; PAGEen.w:Greek_government-debt_crisis; DATE:2014-09-25
cur = match_pos; // set cur after ";"
continue;
case Byte_ascii.Amp:
b_ary = Byte_ascii.Amp_bry; // NTOE: if &amp; convert to &; PAGE:en.w:Amadou Bagayoko?redirect=n; DATE:2014-09-23
break;
case Byte_ascii.Quote:
case Byte_ascii.Lt:
case Byte_ascii.Gt:
b_ary = amp_itm.Xml_name_bry();
break;
case Xop_amp_trie_itm.Char_int_null: // &#xx;
int end_pos = Bry_finder.Find_fwd(src, Byte_ascii.Semic, match_pos, end);
if (end_pos == Bry_.NotFound) {} // &# but no terminating ";" noop: defaults to current_byte which will be added below;
else {
b_ary = amp_itm.Xml_name_bry();
match_pos = end_pos + 1;
}
break;
default:
b_ary = amp_itm.Utf8_bry();
break;
}
}
else {
boolean pass = amp_mgr.Parse_as_int(amp_itm.Tid() == Xop_amp_trie_itm.Tid_num_hex, src, end, cur2, match_pos);
if (pass) {
b_ary = gplx.intl.Utf16_.Encode_int_to_bry(amp_mgr.Rslt_val());
if (b_ary.length == 1 && b_ary[0] == Byte_ascii.Hash) // NOTE: A&#x23;B should be interpreted as A#b; PAGE:en.s:The_English_Constitution_(1894) DATE:2014-09-07
anch_bgn = (txt_bb_len) + 1;
match_pos = amp_mgr.Rslt_pos();
}
}
}
}
break;
case Byte_ascii.Lt:
if (cur + 3 < end) {
if ( src[cur + 1] == Byte_ascii.Bang
&& src[cur + 2] == Byte_ascii.Dash
&& src[cur + 3] == Byte_ascii.Dash
) {
int cur3 = cur + 3;//cur = ttlTrie.Match_pos();
int find = Bry_finder.Find_fwd(src, Xop_comm_lxr.End_ary, cur3, end);
if (find != -1) {
cur = find + Xop_comm_lxr.End_ary.length;
continue;
}
else {
msg_log.Add_itm_none(Xop_ttl_log.Comment_eos, src, bgn, end);
return false;
}
}
}
if (anch_bgn != -1) {
if (anchor_encoder == null) {
anchor_encoder = Url_encoder.new_html_id_();
anchor_encoder_bfr = Bry_bfr.reset_(32);
}
anchor_encoder.Encode(anchor_encoder_bfr, src, cur, cur + 1);
b_ary = anchor_encoder_bfr.Xto_bry_and_clear();
match_pos = cur + 1;
}
break;
// NOTE: DefaultSettings.php defines wgLegalTitleChars as " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+"; the characters above are okay; those below are not
case Byte_ascii.Gt: case Byte_ascii.Pipe:
case Byte_ascii.Brack_bgn: case Byte_ascii.Brack_end: case Byte_ascii.Curly_bgn: case Byte_ascii.Curly_end:
if (anch_bgn != -1) {
if (anchor_encoder == null) {
anchor_encoder = Url_encoder.new_html_id_();
anchor_encoder_bfr = Bry_bfr.reset_(32);
}
anchor_encoder.Encode(anchor_encoder_bfr, src, cur, cur + 1);
b_ary = anchor_encoder_bfr.Xto_bry_and_clear();
match_pos = cur + 1;
}
else {
msg_log.Add_itm_none(Xop_ttl_log.Invalid_char, src, bgn, end);
return false;
}
break;
case Bidi_0_E2:
if (cur + 2 < end) {
if ( src[cur + 1] == Bidi_1_80) {
switch (src[cur + 2]) {
case Bidi_2_8E: case Bidi_2_8F: case Bidi_2_AA: case Bidi_2_AB: case Bidi_2_AC: case Bidi_2_AD: case Bidi_2_AE:
cur += 3;
continue;
default:
break;
}
}
}
break;
default:
break;
}
++cur;
if (add_ws) { // add ws and toggle flag
bfr.Add_byte(Byte_ascii.Space); ++txt_bb_len;
add_ws = false;
}
if (ltr_bgn == -1) ltr_bgn = txt_bb_len; // if 1st letter not seen, mark 1st letter
if (b_ary == null) {bfr.Add_byte(b); ++txt_bb_len;} // add to bfr
else {bfr.Add(b_ary); txt_bb_len += b_ary.length; b_ary = null; cur = match_pos;} // NOTE: b_ary != null only for amp_trie
if (ltr_bgn_reset) {// colon found; set ws to bgn mode; note that # and / do not reset
ltr_bgn_reset = false;
ltr_bgn = -1;
}
}
if (txt_bb_len == 0) {msg_log.Add_itm_none(Xop_ttl_log.Len_0, src, bgn, end); return false;}
if (wik_bgn == -1 && page_bgn == txt_bb_len) { // if no wiki, but page_bgn is at end, then ttl is ns only; EX: "Help:"; NOTE: "fr:", "fr:Help" is allowed
msg_log.Add_itm_none(Xop_ttl_log.Ttl_is_ns_only, src, bgn, end);
return false;
}
full_txt = bfr.Xto_bry_and_clear();
if ( ns.Case_match() == Xow_ns_case_.Id_1st
&& wik_bgn == -1 ) { // do not check case if xwiki; EX: "fr:" would have a wik_bgn of 0 (and a wik_end of 3); "A" (and any non-xwiki ttl) would have a wik_bgn == -1
byte char_1st = full_txt[page_bgn];
int char_1st_len = gplx.intl.Utf8_.Len_of_char_by_1st_byte(char_1st);
int page_end = page_bgn + char_1st_len;
if ( char_1st_len > 1) { // 1st char is multi-byte char
int full_txt_len = full_txt.length;
if (page_end > full_txt_len) // ttl is too too short for 1st multi-byte char; EX: [[%D0]] is 208 but in utf8, 208 requires at least another char; DATE:2013-11-11
return false; // ttl is invalid
else { // ttl is long enough for 1st mult-byte char; need to use platform uppercasing; Xol_case_mgr_.Utf_8 is not sufficient
Bry_bfr upper_1st = bry_mkr.Get_b512();
byte[] page_txt = case_mgr.Case_build_1st_upper(upper_1st, full_txt, page_bgn, full_txt_len); // always build; never reuse; (multi-byte character will expand array)
if (page_bgn == 0) // page only; EX: A
full_txt = page_txt;
else // ns + page; EX: Help:A
full_txt = Bry_.Add(Bry_.Mid(full_txt, 0, page_bgn), page_txt); // add page_txt to exsiting ns
upper_1st.Mkr_rls();
}
}
else
full_txt = case_mgr.Case_reuse_upper(full_txt, page_bgn, page_end);
}
Xow_ns tors_ns = ns.Id_talk() ? ns_mgr.Ords_get_at(ns.Ord_subj_id()) : ns_mgr.Ords_get_at(ns.Ord_talk_id());
tors_txt = tors_ns.Name_txt_w_colon();
return true;
}
public static byte[] Replace_spaces(byte[] raw) {return Bry_.Replace(raw, Byte_ascii.Space, Byte_ascii.Underline);}
public static byte[] Replace_unders(byte[] raw) {return Bry_.Replace(raw, Byte_ascii.Underline, Byte_ascii.Space);}
private int wik_bgn = -1, ns_bgn = -1, page_bgn = 0, leaf_bgn = -1, anch_bgn = -1, root_bgn = -1;
private byte[] tors_txt;
public static final int Wik_bgn_int = -1;
public static final byte Subpage_spr = Byte_ascii.Slash; // EX: A/B/C
public static final int Anch_bgn_anchor_only = 1; // signifies lnki which is only anchor; EX: [[#anchor]]
private static final byte // NOTE: Bidi characters appear in File titles /\xE2\x80[\x8E\x8F\xAA-\xAE]/S
Bidi_0_E2 = (byte)226
, Bidi_1_80 = (byte)128
, Bidi_2_8E = (byte)142
, Bidi_2_8F = (byte)143
, Bidi_2_AA = (byte)170
, Bidi_2_AB = (byte)171
, Bidi_2_AC = (byte)172
, Bidi_2_AD = (byte)173
, Bidi_2_AE = (byte)174
;
public static final int Max_len = 2048; // ASSUME: max len of 256 * 8 bytes
public static final int Null_wik_bgn = -1;
public static final Xoa_ttl Null = null;
}
class Xoa_url_encoder {
public byte[] Encode(byte[] src) {
int src_len = src.length;
for (int i = 0; i < src_len; i++) {
byte b = src[i];
switch (b) {
case Byte_ascii.Space: bb.Add(Bry_underline); break;
case Byte_ascii.Amp: bb.Add(Bry_amp); break;
case Byte_ascii.Apos: bb.Add(Bry_apos); break;
case Byte_ascii.Eq: bb.Add(Bry_eq); break;
case Byte_ascii.Plus: bb.Add(Bry_plus); break;
default: bb.Add_byte(b); break;
// FUTURE: html_entities, etc:
}
}
return bb.Xto_bry_and_clear();
}
private static final byte[] Bry_amp = Bry_.new_a7("%26"), Bry_eq = Bry_.new_a7("%3D")
, Bry_plus = Bry_.new_a7("%2B"), Bry_apos = Bry_.new_a7("%27")
, Bry_underline = new byte[] {Byte_ascii.Underline}
;
Bry_bfr bb = Bry_bfr.new_();
public static final Xoa_url_encoder _ = new Xoa_url_encoder(); Xoa_url_encoder() {}
}
class Xoa_ttl_trie {
public static Btrie_fast_mgr new_() {
Btrie_fast_mgr rv = Btrie_fast_mgr.cs_();
rv.Add(Byte_ascii.Colon , Byte_obj_val.new_(Id_colon));
rv.Add(Byte_ascii.Hash , Byte_obj_val.new_(Id_hash));
rv.Add(Byte_ascii.Slash , Byte_obj_val.new_(Id_slash));
rv.Add(Byte_ascii.Space , Byte_obj_val.new_(Id_space));
rv.Add(Byte_ascii.Underline , Byte_obj_val.new_(Id_underline));
rv.Add(Byte_ascii.Amp , Byte_obj_val.new_(Id_amp));
rv.Add(Xop_comm_lxr.Bgn_ary , Byte_obj_val.new_(Id_comment_bgn));
rv.Add(Byte_ascii.Nl , Byte_obj_val.new_(Id_newLine));
rv.Add(Byte_ascii.Brack_bgn , Byte_obj_val.new_(Id_invalid));
rv.Add(Byte_ascii.Curly_bgn , Byte_obj_val.new_(Id_invalid));
return rv;
}
public static final byte Id_colon = 0, Id_hash = 1, Id_slash = 2, Id_space = 3, Id_underline = 4, Id_amp = 5, Id_comment_bgn = 6, Id_invalid = 7, Id_newLine = 8;
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xoa_ttl_chkr implements Tst_chkr {
public Class<?> TypeOf() {return Xoa_ttl.class;}
public int Chk(Tst_mgr mgr, String path, Object o) {
Xoa_ttl actl = (Xoa_ttl)o;
int rv = 0;
rv += mgr.Tst_val(expd_str == null, path, "raw", expd_str, String_.new_u8(actl.Raw()));
return rv;
}
public String Expd_str() {return expd_str;} public Xoa_ttl_chkr Expd_str_(String v) {expd_str = v; return this;} private String expd_str;
public static Xoa_ttl_chkr new_(String v) {return new Xoa_ttl_chkr().Expd_str_(v);} private Xoa_ttl_chkr() {}
}

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_arg_itm_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Arg_itm_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_arg_itm;}
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
// Arg_itm_tkn actl = (Arg_itm_tkn)actl_obj;
return err;
}
}

View File

@@ -0,0 +1,322 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.core.btries.*; import gplx.xowa.gui.*; import gplx.xowa.xtns.lst.*;
import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.wdatas.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.hdrs.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.paras.*;
import gplx.xowa.parsers.logs.*; import gplx.xowa.html.modules.popups.keeplists.*;
public class Xop_ctx {
private Xop_ctx_wkr[] wkrs = new Xop_ctx_wkr[] {};
Xop_ctx(Xowe_wiki wiki, Xoae_page page) {
this.app = wiki.Appe(); this.msg_log = app.Msg_log();
this.wiki = wiki; this.cur_page = page;
wkrs = new Xop_ctx_wkr[] {para, apos, xnde, list, lnki, hdr, amp, lnke, tblw, invk};
for (Xop_ctx_wkr wkr : wkrs) wkr.Ctor_ctx(this);
}
public Xoae_app App() {return app;} private Xoae_app app;
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
public Xol_lang Lang() {return wiki.Lang();}
public Xop_tkn_mkr Tkn_mkr() {return app.Tkn_mkr();}
public Xoae_page Cur_page() {return cur_page;} public void Cur_page_(Xoae_page v) {cur_page = v;} private Xoae_page cur_page;
public byte Parse_tid() {return parse_tid;} public Xop_ctx Parse_tid_(byte v) {parse_tid = v; xnde_names_tid = v; return this;} private byte parse_tid = Xop_parser_.Parse_tid_null;
public byte Xnde_names_tid() {return xnde_names_tid;} public Xop_ctx Xnde_names_tid_(byte v) {xnde_names_tid = v; return this;} private byte xnde_names_tid = Xop_parser_.Parse_tid_null;
public Xop_amp_wkr Amp() {return amp;} private Xop_amp_wkr amp = new Xop_amp_wkr();
public Xop_apos_wkr Apos() {return apos;} private Xop_apos_wkr apos = new Xop_apos_wkr();
public Xop_lnke_wkr Lnke() {return lnke;} private Xop_lnke_wkr lnke = new Xop_lnke_wkr();
public Xop_lnki_wkr Lnki() {return lnki;} private Xop_lnki_wkr lnki = new Xop_lnki_wkr();
public Xop_hdr_wkr Hdr() {return hdr;} private Xop_hdr_wkr hdr = new Xop_hdr_wkr();
public Xop_para_wkr Para() {return para;} private Xop_para_wkr para = new Xop_para_wkr();
public Xop_list_wkr List() {return list;} private Xop_list_wkr list = new Xop_list_wkr();
public Xop_tblw_wkr Tblw() {return tblw;} private Xop_tblw_wkr tblw = new Xop_tblw_wkr();
public Xop_xnde_wkr Xnde() {return xnde;} private Xop_xnde_wkr xnde = new Xop_xnde_wkr();
public Xot_invk_wkr Invk() {return invk;} private Xot_invk_wkr invk = new Xot_invk_wkr();
public Xop_curly_wkr Curly() {return curly;} private Xop_curly_wkr curly = new Xop_curly_wkr();
public boolean Tmpl_load_enabled() {return tmpl_load_enabled;} public void Tmpl_load_enabled_(boolean v) {tmpl_load_enabled = v;} private boolean tmpl_load_enabled = true;
public int Tmpl_tkn_max() {return tmpl_tkn_max;} public void Tmpl_tkn_max_(int v) {tmpl_tkn_max = v;} private int tmpl_tkn_max = Int_.MaxValue;
public Xop_keeplist_wiki Tmpl_keeplist() {return tmpl_keeplist;} public void Tmpl_keeplist_(Xop_keeplist_wiki v) {this.tmpl_keeplist = v;} private Xop_keeplist_wiki tmpl_keeplist;
public boolean Tmpl_args_parsing() {return tmpl_args_parsing;} public Xop_ctx Tmpl_args_parsing_(boolean v) {tmpl_args_parsing = v; return this;} private boolean tmpl_args_parsing;
public Bry_bfr Tmpl_output() {return tmpl_output;} public Xop_ctx Tmpl_output_(Bry_bfr v) {tmpl_output = v; return this;} private Bry_bfr tmpl_output; // OBSOLETE: after tmpl_prepend_nl rewrite; DATE:2014-08-21
public Xot_defn_trace Defn_trace() {return defn_trace;} public Xop_ctx Defn_trace_(Xot_defn_trace v) {defn_trace = v; return this;} private Xot_defn_trace defn_trace = Xot_defn_trace_null._;
public boolean Only_include_evaluate() {return only_include_evaluate;} public Xop_ctx Only_include_evaluate_(boolean v) {only_include_evaluate = v; return this;} private boolean only_include_evaluate;
public Lst_section_nde_mgr Lst_section_mgr() {if (lst_section_mgr == null) lst_section_mgr = new Lst_section_nde_mgr(); return lst_section_mgr;} private Lst_section_nde_mgr lst_section_mgr;
public Hash_adp_bry Lst_page_regy() {return lst_page_regy;} private Hash_adp_bry lst_page_regy;
public boolean Ref_ignore() {return ref_ignore;} public Xop_ctx Ref_ignore_(boolean v) {ref_ignore = v; return this;} private boolean ref_ignore; // NOTE: only applies to sub_ctx's created by <pages> and {{#lst}}; if true, does not add <ref> to page.Ref_mgr; DATE:2014-04-24
public byte[] References_group() {return references_group;} public Xop_ctx References_group_(byte[] v) {references_group = v; return this;} private byte[] references_group;
public boolean Tid_is_popup() {return tid_is_popup;} public void Tid_is_popup_(boolean v) {tid_is_popup = v;} private boolean tid_is_popup = false;
public boolean Tid_is_image_map() {return tid_is_image_map;} public Xop_ctx Tid_is_image_map_(boolean v) {tid_is_image_map = v; return this;} private boolean tid_is_image_map;
public Xop_log_invoke_wkr Xtn__scribunto__invoke_wkr() {
if (scrib_invoke_wkr == null)
scrib_invoke_wkr = ((Scrib_xtn_mgr)(app.Xtn_mgr().Get_or_fail(Scrib_xtn_mgr.XTN_KEY))).Invoke_wkr();
return scrib_invoke_wkr;
} private Xop_log_invoke_wkr scrib_invoke_wkr;
public Xop_log_property_wkr Xtn__wikidata__property_wkr() {return app.Wiki_mgr().Wdata_mgr().Property_wkr();}
public Gfo_msg_log Msg_log() {return msg_log;} private Gfo_msg_log msg_log;
public Xop_ctx Clear() {
cur_page.Clear();
stack = Xop_tkn_itm_.Ary_empty;
stack_len = stack_max = 0;
app.Wiki_mgr().Wdata_mgr().Clear();
if (lst_section_mgr != null) lst_section_mgr.Clear();
if (lst_page_regy != null) lst_page_regy.Clear();
tmpl_output = null;
tmpl_args_parsing = false;
return this;
}
public String Page_url_str() {
try {return cur_page.Url().Xto_full_str_safe();}
catch (Exception e) {Exc_.Noop(e); return "page_url shouldn't fail";}
}
public void Page_bgn(Xop_root_tkn root, byte[] src) {
this.Msg_log().Clear(); cur_tkn_tid = Xop_tkn_itm_.Tid_null;
empty_ignored = false;
for (Xop_ctx_wkr wkr : wkrs) wkr.Page_bgn(this, root);
}
public void Page_end(Xop_root_tkn root, byte[] src, int src_len) {
Stack_pop_til(root, src, 0, true, src_len, src_len, Xop_tkn_itm_.Tid_txt);
for (Xop_ctx_wkr wkr : wkrs) wkr.Page_end(this, root, src, src_len);
}
public boolean Lxr_make() {return lxr_make;} public Xop_ctx Lxr_make_(boolean v) {lxr_make = v; return this;} private boolean lxr_make = false;
public int Lxr_make_txt_(int pos) {lxr_make = false; return pos;}
public int Lxr_make_log_(Gfo_msg_itm itm, byte[] src, int bgn_pos, int cur_pos) {lxr_make = false; msg_log.Add_itm_none(itm, src, bgn_pos, cur_pos); return cur_pos;}
public boolean Empty_ignored() {return empty_ignored;}
public void Empty_ignored_y_() {empty_ignored = true;} private boolean empty_ignored = false;
public void Empty_ignored_n_() {empty_ignored = false;}
public void Empty_ignore(Xop_root_tkn root, int empty_bgn) {
int empty_end = root.Subs_len();
for (int i = empty_bgn; i < empty_end; i++) {
Xop_tkn_itm sub_tkn = root.Subs_get(i);
sub_tkn.Ignore_y_grp_(this, root, i);
}
empty_ignored = false;
}
public byte Cur_tkn_tid() {return cur_tkn_tid;} private byte cur_tkn_tid = Xop_tkn_itm_.Tid_null;
public void Subs_add_and_stack_tblw(Xop_root_tkn root, Xop_tblw_tkn owner_tkn, Xop_tkn_itm sub) {
if (owner_tkn != null) owner_tkn.Tblw_subs_len_add_(); // owner_tkn can be null;EX: "{|" -> prv_tkn is null
Subs_add_and_stack(root, sub);
}
public void Subs_add_and_stack(Xop_root_tkn root, Xop_tkn_itm sub) {this.Subs_add(root, sub); this.Stack_add(sub);}
public void Subs_add(Xop_root_tkn root, Xop_tkn_itm sub) {
switch (sub.Tkn_tid()) {
case Xop_tkn_itm_.Tid_space: case Xop_tkn_itm_.Tid_tab: case Xop_tkn_itm_.Tid_newLine:
case Xop_tkn_itm_.Tid_para:
break;
default:
empty_ignored = false;
break;
}
root.Subs_add(sub);
}
public void StackTkn_add(Xop_root_tkn root, Xop_tkn_itm sub) {
root.Subs_add(sub);
this.Stack_add(sub);
}
public void Stack_add(Xop_tkn_itm tkn) {
int newLen = stack_len + 1;
if (newLen > stack_max) {
stack_max = newLen * 2;
stack = (Xop_tkn_itm[])Array_.Resize(stack, stack_max);
}
stack[stack_len] = tkn;
cur_tkn_tid = tkn.Tkn_tid();
stack_len = newLen;
} private Xop_tkn_itm[] stack = Xop_tkn_itm_.Ary_empty; int stack_len = 0, stack_max = 0;
public int Stack_len() {return stack_len;}
public Xop_tkn_itm Stack_get_last() {return stack_len == 0 ? null : stack[stack_len - 1];}
public Xop_tkn_itm Stack_get(int i) {return i < 0 || i >= stack_len ? null : stack[i];}
public Xop_tblw_tkn Stack_get_tblw_tb() {// find any {| (exclude <table)
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
if (tkn.Tkn_tid() == Xop_tkn_itm_.Tid_tblw_tb) {
Xop_tblw_tkn tkn_as_tbl = (Xop_tblw_tkn)tkn;
if (!tkn_as_tbl.Tblw_xml()) return tkn_as_tbl;
}
}
return null;
}
public Xop_tblw_tkn Stack_get_tbl_tb() {
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_tblw_tb:
return (Xop_tblw_tkn)tkn;
case Xop_tkn_itm_.Tid_xnde:
Xop_xnde_tkn xnde_tkn = (Xop_xnde_tkn)tkn;
switch (xnde_tkn.Tag().Id()) {
case Xop_xnde_tag_.Tid_table:
return (Xop_tblw_tkn)tkn;
}
break;
}
}
return null;
}
public Xop_tblw_tkn Stack_get_tbl() {
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_tblw_tb:
case Xop_tkn_itm_.Tid_tblw_tr:
case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_th:
case Xop_tkn_itm_.Tid_tblw_tc:
return (Xop_tblw_tkn)tkn;
case Xop_tkn_itm_.Tid_xnde:
Xop_xnde_tkn xnde_tkn = (Xop_xnde_tkn)tkn;
switch (xnde_tkn.Tag().Id()) {
case Xop_xnde_tag_.Tid_table:
case Xop_xnde_tag_.Tid_tr:
case Xop_xnde_tag_.Tid_td:
case Xop_xnde_tag_.Tid_th:
case Xop_xnde_tag_.Tid_caption:
return (Xop_tblw_tkn)tkn;
}
break;
}
}
return null;
}
public static final int Stack_not_found = -1;
public boolean Stack_has(int typeId) {return Stack_idx_typ(typeId) != Stack_not_found;}
public int Stack_idx_typ(int typeId) {
for (int i = stack_len - 1; i > -1; i--)
if (stack[i].Tkn_tid() == typeId)
return i;
return Stack_not_found;
}
public int Stack_idx_find_but_stop_at_tbl(int tid) {
for (int i = stack_len - 1; i > -1 ; i--) {
Xop_tkn_itm tkn_itm = stack[i];
int tkn_itm_tid = tkn_itm.Tkn_tid();
switch (tkn_itm_tid) {
case Xop_tkn_itm_.Tid_tblw_tb: // NOTE: added DATE:2014-06-26
case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_th:
case Xop_tkn_itm_.Tid_tblw_tc:
return -1;
}
if (tkn_itm_tid == tid)
return i;
}
return -1;
}
public Xop_tkn_itm Stack_get_typ(int tid) {
for (int i = stack_len - 1; i > -1 ; i--) {
Xop_tkn_itm tkn = stack[i];
if (tkn.Tkn_tid() == tid) return tkn;
}
return null;
}
public void Stack_del(Xop_tkn_itm del) {
if (stack_len == 0) return;
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
if (tkn == del) {
for (int j = i + 1; j < stack_len; j++) {
stack[j - 1] = stack[j];
}
--stack_len;
break;
}
}
}
public Xop_tkn_itm Stack_pop_til(Xop_root_tkn root, byte[] src, int til_idx, boolean include, int bgn_pos, int cur_pos, int closing_tkn_tid) { // NOTE: closing_tkn_tid is a book-keeping variable to indicate who started auto-close; only used by xnde.AutoClose
if (stack_len == 0) return null; // nothing to pop; return;
int min_idx = include ? til_idx - 1 : til_idx; // if "include", auto-close tkn at til_idx; if not, auto-close to one before
if (min_idx < -1) min_idx = -1; // bounds-check; make sure til_idx was not -1, resulting in -2; NOTE: does not seem to be needed; DATE:2015-03-31
Xop_tkn_itm rv = null;
for (int i = stack_len - 1; i > min_idx; i--) { // pop tkns going backwards
rv = stack[i];
Stack_auto_close(root, src, rv, bgn_pos, cur_pos, closing_tkn_tid);
}
Stack_pop_idx(til_idx);
return include ? rv : stack[stack_len]; // if include, return popped_tkn; if not, return tkn before popped_tkn
}
public Xop_tkn_itm Stack_pop_before(Xop_root_tkn root, byte[] src, int til_idx, boolean include, int bgn_pos, int cur_pos, int closing_tkn_tid) { // used by Xop_tblw_lxr to detect \n| in lnki; seems useful as well
if (stack_len == 0) return null;
int min_idx = include ? til_idx - 1 : til_idx;
if (min_idx < -1) min_idx = -1;
Xop_tkn_itm rv = null;
for (int i = stack_len - 1; i > min_idx; i--) {
rv = stack[i];
Stack_auto_close(root, src, rv, bgn_pos, cur_pos, closing_tkn_tid);
}
return include ? rv : stack[stack_len]; // if include, return poppedTkn; if not, return tkn before poppedTkn
}
public void Stack_auto_close(Xop_root_tkn root, byte[] src, Xop_tkn_itm tkn, int bgn_pos, int cur_pos, int closing_tkn_tid) {
int src_len = src.length;
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_newLine: break; // NOOP: just a marker
case Xop_tkn_itm_.Tid_list: list.AutoClose(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_xnde: xnde.AutoClose(this, root, src, src_len, bgn_pos, cur_pos, tkn, closing_tkn_tid); break;
case Xop_tkn_itm_.Tid_apos: apos.AutoClose(this, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_lnke: lnke.AutoClose(this, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_hdr: hdr.AutoClose(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_tblw_tb:
case Xop_tkn_itm_.Tid_tblw_tr:
case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_th:
case Xop_tkn_itm_.Tid_tblw_tc: tblw.AutoClose(this, root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_lnki: lnki.Auto_close(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_pre: para.AutoClose(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
}
}
public void Stack_pop_idx(int tilIdx) {
stack_len = tilIdx < 0 ? 0 : tilIdx;
cur_tkn_tid = stack_len == 0 ? Xop_tkn_itm_.Tid_null : stack[stack_len - 1].Tkn_tid();
}
public void Stack_pop_last() { // used primarily by lnke to remove lnke from stack
--stack_len;
cur_tkn_tid = stack_len == 0 ? Xop_tkn_itm_.Tid_null : stack[stack_len - 1].Tkn_tid();
}
public void CloseOpenItms(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
int stack_pos = -1, stack_len = ctx.Stack_len(); boolean stop = false;
for (int i = 0; i < stack_len; i++) { // loop over stack
Xop_tkn_itm prv_tkn = ctx.Stack_get(i);
switch (prv_tkn.Tkn_tid()) { // find first list/hdr; close everything until this
case Xop_tkn_itm_.Tid_list:
case Xop_tkn_itm_.Tid_hdr:
stack_pos = i; stop = true; break;
}
if (stop) break;
}
if (stack_pos == -1) return;
ctx.Stack_pop_til(root, src, stack_pos, true, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_txt);
}
public static Xop_ctx new_(Xowe_wiki wiki) {
Xop_ctx rv = new Xop_ctx(wiki, Xoae_page.new_(wiki, Xoa_ttl.parse_(wiki, Xoa_page_.Main_page_bry))); // HACK: use "Main_Page" to put in valid page title
return rv;
}
public static Xop_ctx new_sub_(Xowe_wiki wiki) {return new_sub_(wiki, wiki.Ctx().cur_page);}
public static Xop_ctx new_sub_(Xowe_wiki wiki, Xoae_page page) { // TODO: new_sub_ should reuse ctx's page; callers who want new_page should call new_sub_page_; DATE:2014-04-10
Xop_ctx ctx = wiki.Ctx();
Xop_ctx rv = new Xop_ctx(wiki, page);
new_copy(ctx, rv);
return rv;
}
public static Xop_ctx new_sub_page_(Xowe_wiki wiki, Xop_ctx ctx, Hash_adp_bry lst_page_regy) {
Xop_ctx rv = new Xop_ctx(wiki, ctx.cur_page);
new_copy(ctx, rv);
rv.lst_page_regy = lst_page_regy; // NOTE: must share ref for lst only (do not share for sub_(), else stack overflow)
return rv;
}
private static void new_copy(Xop_ctx src, Xop_ctx trg) {
trg.Lnki().File_wkr_(src.Lnki().File_wkr()); // always share file_wkr between sub contexts
trg.tmpl_output = src.tmpl_output; // share bfr for optimization purposes
}
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_ctx_ {
public static String Page_as_str(Xop_ctx ctx) {return String_.new_u8(ctx.Cur_page().Ttl().Full_db());}
public static String Src_limit_and_escape_nl(byte[] src, int bgn, int limit) {
int end = bgn + limit;
int src_len = src.length;
if (end > src_len) end = src_len;
byte[] rv = Bry_.Mid(src, bgn, end);
rv = Bry_.Replace(rv, Byte_ascii.Nl, Byte_ascii.Tab); // change nl to tab so text editor will show one warning per line
return String_.new_u8(rv);
}
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xop_ctx__tst {
@Before public void init() {fxt.Clear();} private Xop_ctx__fxt fxt = new Xop_ctx__fxt();
@Test public void Src_limit_and_escape_nl() {
fxt.Test_Src_limit_and_escape_nl("abcdefg", 4, 3, "efg"); // PURPOSE: bug fix; outOfBounds thrown; DATE:2014-03-31
}
}
class Xop_ctx__fxt {
public void Clear() {
}
public void Test_Src_limit_and_escape_nl(String src, int bgn, int limit, String expd) {
String actl = Xop_ctx_.Src_limit_and_escape_nl(Bry_.new_u8(src), bgn, limit);
Tfds.Eq(expd, actl);
}
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public interface Xop_ctx_wkr {
void Ctor_ctx(Xop_ctx ctx);
void Page_bgn(Xop_ctx ctx, Xop_root_tkn root);
void Page_end(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int src_len);
}
interface Xop_arg_wkr {
boolean Args_add(Xop_ctx ctx, byte[] src, Xop_tkn_itm tkn, Arg_nde_tkn arg, int arg_idx);
}
class Xop_arg_wkr_ {
public static final int Typ_lnki = 0, Typ_tmpl = 1, Typ_prm = 2;
}

View File

@@ -0,0 +1,416 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.langs.*; import gplx.xowa.html.*; import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.hdrs.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.paras.*;
import gplx.xowa.files.exts.*;
public class Xop_fxt {
public Xop_fxt() {
Xoae_app app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
ctor(app, wiki);
}
public Xop_fxt(Xoae_app app, Xowe_wiki wiki) {
this.ctor(app, wiki);
}
private void ctor(Xoae_app app, Xowe_wiki wiki) {
this.app = app;
this.wiki = wiki;
app.Wiki_mgr().Add(wiki);
app.File_mgr().Repo_mgr().Set("src:wiki", "mem/wiki/repo/src/", wiki.Domain_str()).Ext_rules_(Xof_rule_grp.Grp_app_default).Dir_depth_(2);
app.File_mgr().Repo_mgr().Set("trg:wiki", "mem/wiki/repo/trg/", wiki.Domain_str()).Ext_rules_(Xof_rule_grp.Grp_app_default).Dir_depth_(2).Primary_(true);
wiki.File_mgr().Repo_mgr().Add_repo(Bry_.new_u8("src:wiki"), Bry_.new_u8("trg:wiki"));
ctx = wiki.Ctx();
mock_wkr.Clear_commons(); // assume all files are in repo 0
wiki.File_mgr().Repo_mgr().Page_finder_(mock_wkr);
parser = wiki.Parser();
tkn_mkr = app.Tkn_mkr();
ctx.Para().Enabled_n_();
hdom_wtr = wiki.Html_mgr().Html_wtr();
wiki.Html_mgr().Img_suppress_missing_src_(false);
wiki.Xtn_mgr().Init_by_wiki(wiki);
Page_ttl_(Ttl_str);
Xot_invk_tkn.Cache_enabled = false;// always disable cache for tests; can cause strange behavior when running entire suite and lnki_temp test turns on;
}
private Xofw_wiki_wkr_mock mock_wkr = new Xofw_wiki_wkr_mock();
public Xoae_app App() {return app;} private Xoae_app app;
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
public Xop_ctx Ctx() {return ctx;} private Xop_ctx ctx;
public Xop_parser Parser() {return parser;} private Xop_parser parser;
public Xoae_page Page() {return ctx.Cur_page();}
public void Lang_by_id_(int id) {ctx.Cur_page().Lang_(wiki.Appe().Lang_mgr().Get_by_key_or_new(Xol_lang_itm_.Get_by_id(id).Key()));}
public Xoh_html_wtr_cfg Wtr_cfg() {return hdom_wtr.Cfg();} private Xoh_html_wtr hdom_wtr;
public Xop_fxt Reset() {
ctx.Clear();
ctx.App().Free_mem(false);
ctx.Cur_page().Clear();
wiki.Db_mgr().Load_mgr().Clear();
app.Wiki_mgr().Clear();
Io_mgr.I.InitEngine_mem(); // clear created pages
wiki.Cfg_parser().Display_title_restrict_(false); // default to false, as a small number of tests assume restrict = false;
return this;
}
public Xop_fxt Reset_for_msgs() {
Io_mgr.I.InitEngine_mem();
wiki.Lang().Msg_mgr().Clear(); // need to clear out lang
wiki.Msg_mgr().Clear(); // need to clear out wiki.Msgs
this.Reset();
return this;
}
public Xoa_ttl Page_ttl_(String txt) {
Xoa_ttl rv = Xoa_ttl.parse_(wiki, Bry_.new_u8(txt));
ctx.Cur_page().Ttl_(rv);
return rv;
}
public Xop_tkn_chkr_base tkn_bry_(int bgn, int end) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_bry).Src_rng_(bgn, end);}
public Xop_tkn_chkr_base tkn_txt_() {return tkn_txt_(String_.Pos_neg1, String_.Pos_neg1);}
public Xop_tkn_chkr_base tkn_txt_(int bgn, int end) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_txt).Src_rng_(bgn, end);}
public Xop_tkn_chkr_base tkn_space_() {return tkn_space_(String_.Pos_neg1, String_.Pos_neg1);}
public Xop_tkn_chkr_base tkn_space_(int bgn, int end) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_space).Src_rng_(bgn, end);}
public Xop_tkn_chkr_base tkn_eq_(int bgn) {return tkn_eq_(bgn, bgn + 1);}
public Xop_tkn_chkr_base tkn_eq_(int bgn, int end) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_eq).Src_rng_(bgn, end);}
public Xop_tkn_chkr_base tkn_colon_(int bgn) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_colon).Src_rng_(bgn, bgn + 1);}
public Xop_tkn_chkr_base tkn_pipe_(int bgn) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_pipe).Src_rng_(bgn, bgn + 1);}
public Xop_tkn_chkr_base tkn_tab_(int bgn) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_tab).Src_rng_(bgn, bgn + 1);}
public Xop_apos_tkn_chkr tkn_apos_(int cmd) {return new Xop_apos_tkn_chkr().Apos_cmd_(cmd);}
public Xop_tkn_chkr_base tkn_html_ref_(String v) {return new Xop_html_txt_tkn_chkr().Html_ref_key_(v);}
public Xop_tkn_chkr_base tkn_html_ncr_(int v) {return new Xop_html_num_tkn_chkr().Html_ncr_val_(v);}
@gplx.Internal protected Xop_ignore_tkn_chkr tkn_comment_(int bgn, int end) {return tkn_ignore_(bgn, end, Xop_ignore_tkn.Ignore_tid_comment);}
@gplx.Internal protected Xop_ignore_tkn_chkr tkn_ignore_(int bgn, int end, byte t){return (Xop_ignore_tkn_chkr)new Xop_ignore_tkn_chkr().Ignore_tid_(t).Src_rng_(bgn, end);}
public Xop_tkn_chkr_hr tkn_hr_(int bgn, int end) {return new Xop_tkn_chkr_hr(bgn, end).Hr_len_(Xop_hr_lxr.Hr_len);}
public Xop_tblw_tb_tkn_chkr tkn_tblw_tb_(int bgn, int end) {return (Xop_tblw_tb_tkn_chkr)new Xop_tblw_tb_tkn_chkr().Src_rng_(bgn, end);}
public Xop_tblw_tc_tkn_chkr tkn_tblw_tc_(int bgn, int end) {return (Xop_tblw_tc_tkn_chkr)new Xop_tblw_tc_tkn_chkr().Src_rng_(bgn, end);}
public Xop_tblw_td_tkn_chkr tkn_tblw_td_(int bgn, int end) {return (Xop_tblw_td_tkn_chkr)new Xop_tblw_td_tkn_chkr().Src_rng_(bgn, end);}
public Xop_tblw_th_tkn_chkr tkn_tblw_th_(int bgn, int end) {return (Xop_tblw_th_tkn_chkr)new Xop_tblw_th_tkn_chkr().Src_rng_(bgn, end);}
public Xop_tblw_tr_tkn_chkr tkn_tblw_tr_(int bgn, int end) {return (Xop_tblw_tr_tkn_chkr)new Xop_tblw_tr_tkn_chkr().Src_rng_(bgn, end);}
public Xop_hdr_tkn_chkr tkn_hdr_(int bgn, int end, int hdr_len) {return (Xop_hdr_tkn_chkr)new Xop_hdr_tkn_chkr().Hdr_len_(hdr_len).Src_rng_(bgn, end);}
public Xop_xnde_tkn_chkr tkn_xnde_br_(int pos) {return tkn_xnde_(pos, pos).Xnde_tagId_(Xop_xnde_tag_.Tid_br);}
public Xop_xnde_tkn_chkr tkn_xnde_() {return tkn_xnde_(String_.Pos_neg1, String_.Pos_neg1);}
public Xop_xnde_tkn_chkr tkn_xnde_(int bgn, int end) {return (Xop_xnde_tkn_chkr)new Xop_xnde_tkn_chkr().Src_rng_(bgn, end);}
public Xop_tkn_chkr_base tkn_curly_bgn_(int bgn) {return new Xop_tkn_chkr_base().TypeId_dynamic(Xop_tkn_itm_.Tid_tmpl_curly_bgn).Src_rng_(bgn, bgn + 2);}
public Xop_tkn_chkr_base tkn_para_blank_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_none, Xop_para_tkn.Tid_none);}
public Xop_tkn_chkr_base tkn_para_bgn_pre_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_none, Xop_para_tkn.Tid_pre);}
public Xop_tkn_chkr_base tkn_para_bgn_para_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_none, Xop_para_tkn.Tid_para);}
public Xop_tkn_chkr_base tkn_para_mid_para_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_para, Xop_para_tkn.Tid_para);}
public Xop_tkn_chkr_base tkn_para_end_para_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_para, Xop_para_tkn.Tid_none);}
public Xop_tkn_chkr_base tkn_para_end_pre_bgn_para_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_pre , Xop_para_tkn.Tid_para);}
public Xop_tkn_chkr_base tkn_para_end_para_bgn_pre_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_para, Xop_para_tkn.Tid_pre);}
public Xop_tkn_chkr_base tkn_para_end_pre_(int pos) {return tkn_para_(pos, Xop_para_tkn.Tid_pre , Xop_para_tkn.Tid_none);}
public Xop_tkn_chkr_base tkn_para_(int pos, byte end, byte bgn) {return new Xop_para_tkn_chkr().Para_end_(end).Para_bgn_(bgn).Src_rng_(pos, pos);}
public Xop_tkn_chkr_base tkn_nl_char_(int bgn, int end) {return tkn_nl_(bgn, end, Xop_nl_tkn.Tid_char);}
public Xop_tkn_chkr_base tkn_nl_char_len1_(int bgn) {return tkn_nl_(bgn, bgn + 1, Xop_nl_tkn.Tid_char);}
public Xop_tkn_chkr_base tkn_nl_char_len0_(int pos) {return tkn_nl_(pos, pos, Xop_nl_tkn.Tid_char);}
public Xop_tkn_chkr_base tkn_nl_(int bgn, int end, byte tid) {return new Xop_nl_tkn_chkr().Nl_tid_(tid).Src_rng_(bgn, end);}
public Xop_list_tkn_chkr tkn_list_bgn_(int bgn, int end, byte listType) {return (Xop_list_tkn_chkr)new Xop_list_tkn_chkr().List_itmTyp_(listType).Src_rng_(bgn, end);}
public Xop_list_tkn_chkr tkn_list_end_(int pos) {return (Xop_list_tkn_chkr)new Xop_list_tkn_chkr().Src_rng_(pos, pos);}
public Xop_tkn_chkr_lnke tkn_lnke_(int bgn, int end) {return new Xop_tkn_chkr_lnke(bgn, end);}
public Xop_lnki_tkn_chkr tkn_lnki_() {return tkn_lnki_(-1, -1);}
public Xop_lnki_tkn_chkr tkn_lnki_(int bgn, int end) {return (Xop_lnki_tkn_chkr)new Xop_lnki_tkn_chkr().Src_rng_(bgn, end);}
@gplx.Internal protected Xop_arg_itm_tkn_chkr tkn_arg_itm_(Xop_tkn_chkr_base... subs) {return (Xop_arg_itm_tkn_chkr)new Xop_arg_itm_tkn_chkr().Subs_(subs);}
@gplx.Internal protected Xop_arg_nde_tkn_chkr tkn_arg_nde_() {return tkn_arg_nde_(String_.Pos_neg1, String_.Pos_neg1);}
@gplx.Internal protected Xop_arg_nde_tkn_chkr tkn_arg_nde_(int bgn, int end) {return (Xop_arg_nde_tkn_chkr)new Xop_arg_nde_tkn_chkr().Src_rng_(bgn, end);}
@gplx.Internal protected Xop_arg_nde_tkn_chkr tkn_arg_val_(Xop_tkn_chkr_base... subs) {
Xop_arg_nde_tkn_chkr rv = new Xop_arg_nde_tkn_chkr();
Xop_arg_itm_tkn_chkr val = new Xop_arg_itm_tkn_chkr();
val.Subs_(subs);
rv.Val_tkn_(val);
return rv;
}
@gplx.Internal protected Xop_arg_nde_tkn_chkr tkn_arg_val_txt_(int bgn, int end) {
Xop_arg_nde_tkn_chkr rv = new Xop_arg_nde_tkn_chkr();
Xop_arg_itm_tkn_chkr itm = new Xop_arg_itm_tkn_chkr();
rv.Val_tkn_(itm);
itm.Src_rng_(bgn, end).Subs_(tkn_txt_(bgn, end));
return rv;
}
Xop_arg_nde_tkn_chkr tkn_arg_key_txt_(int bgn, int end) {
Xop_arg_nde_tkn_chkr rv = new Xop_arg_nde_tkn_chkr();
Xop_arg_itm_tkn_chkr itm = new Xop_arg_itm_tkn_chkr();
rv.Key_tkn_(itm);
itm.Src_rng_(bgn, end).Subs_(tkn_txt_(bgn, end));
return rv;
}
@gplx.Internal protected Xot_invk_tkn_chkr tkn_tmpl_invk_(int bgn, int end) {return (Xot_invk_tkn_chkr)new Xot_invk_tkn_chkr().Src_rng_(bgn, end);}
@gplx.Internal protected Xot_invk_tkn_chkr tkn_tmpl_invk_w_name(int bgn, int end, int name_bgn, int name_end) {
Xot_invk_tkn_chkr rv = new Xot_invk_tkn_chkr();
rv.Src_rng_(bgn, end);
rv.Name_tkn_(tkn_arg_key_txt_(name_bgn, name_end));
return rv;
}
public Xot_prm_chkr tkn_tmpl_prm_find_(Xop_tkn_chkr_base find) {
Xot_prm_chkr rv = new Xot_prm_chkr();
rv.Find_tkn_(tkn_arg_itm_(find));
return rv;
}
public Xop_fxt Init_para_y_() {ctx.Para().Enabled_y_(); return this;}
public Xop_fxt Init_para_n_() {ctx.Para().Enabled_n_(); return this;}
public Xop_fxt Init_log_(Gfo_msg_itm... itms) {for (Gfo_msg_itm itm : itms) log_itms.Add(itm); return this;} List_adp log_itms = List_adp_.new_();
public void Init_defn_add(String name, String text) {Init_defn_add(name, text, Xow_ns_case_.Id_all);}
public void Init_defn_add(String name, String text, byte case_match) {
Xot_defn_tmpl itm = run_Parse_tmpl(Bry_.new_a7(name), Bry_.new_u8(text));
wiki.Cache_mgr().Defn_cache().Add(itm, case_match);
}
public void Init_defn_clear() {wiki.Cache_mgr().Defn_cache().Free_mem_all();}
public Xop_fxt Init_id_create(int id, int fil_idx, int row_idx, boolean type_redirect, int itm_len, int ns_id, String ttl) {Xow_hive_mgr_fxt.Create_id(app, wiki.Hive_mgr(), id, fil_idx, row_idx, type_redirect, itm_len, ns_id, ttl); return this;}
public Xop_fxt Init_ctg_create(String ctg, int... pages) {Xow_hive_mgr_fxt.Create_ctg(app, wiki.Hive_mgr(), ctg, pages); return this;}
public Xop_fxt Init_page_create(String ttl) {return Init_page_create(wiki, ttl, "");}
public Xop_fxt Init_page_create(String ttl, String txt) {return Init_page_create(wiki, ttl, txt);}
public Xop_fxt Init_page_create(Xowe_wiki wiki, String ttl, String txt) {Init_page_create_static(wiki, ttl, txt);return this;}
public static void Init_page_create_static(Xowe_wiki wiki, String ttl_str, String text_str) {
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_u8(ttl_str));
byte[] text = Bry_.new_u8(text_str);
wiki.Db_mgr().Save_mgr().Data_create(ttl, text);
}
public static void Init_msg(Xowe_wiki wiki, String key, String val) {
wiki.Lang().Msg_mgr().Itm_by_key_or_new(key, val);
}
public Xop_fxt Init_page_update(String ttl, String txt) {return Init_page_update(wiki, ttl, txt);}
public Xop_fxt Init_page_update(Xowe_wiki wiki, String ttl, String txt) {
Xoa_ttl page_ttl = Xoa_ttl.parse_(wiki, Bry_.new_u8(ttl));
byte[] page_raw = Bry_.new_u8(txt);
Xoae_page page = wiki.Data_mgr().Get_page(page_ttl, false);
wiki.Db_mgr().Save_mgr().Data_update(page, page_raw);
return this;
}
public Xop_fxt Init_xwiki_clear() {
wiki.Xwiki_mgr().Clear();
app.Usere().Wiki().Xwiki_mgr().Clear();
return this;
}
public Xop_fxt Init_xwiki_add_wiki_and_user_(String alias, String domain) {
wiki.Xwiki_mgr().Add_full(alias, domain);
app.Usere().Wiki().Xwiki_mgr().Add_full(domain, domain);
return this;
}
public Xop_fxt Init_xwiki_add_user_(String domain) {
app.Usere().Wiki().Xwiki_mgr().Add_full(domain, domain);
return this;
}
public void Test_parse_template(String tmpl_raw, String expd) {Test_parse_tmpl_str_test(tmpl_raw, "{{test}}", expd);}
public void Test_parse_tmpl_str_test(String tmpl_raw, String page_raw, String expd) {
Init_defn_add("test", tmpl_raw);
Test_parse_tmpl_str(page_raw, expd);
}
public void Test_parse_tmpl_str(String raw, String expd) {
byte[] actl = Test_parse_tmpl_str_rv(raw);
Tfds.Eq_str_lines(expd, String_.new_u8(actl));
tst_Log_check();
}
public byte[] Test_parse_tmpl_str_rv(String raw) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = tkn_mkr.Root(raw_bry);
return parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, raw_bry);
}
public Xot_defn_tmpl run_Parse_tmpl(byte[] name, byte[] raw) {return parser.Parse_text_to_defn_obj(ctx, ctx.Tkn_mkr(), wiki.Ns_mgr().Ns_template(), name, raw);}
public void Test_parse_tmpl(String raw, Tst_chkr... expd) {
byte[] raw_bry = Bry_.new_u8(raw);
Xot_defn_tmpl itm = run_Parse_tmpl(Bry_.Empty, raw_bry);
Parse_chk(raw_bry, itm.Root(), expd);
}
public void Test_parse_page_tmpl_str(String raw, String expd) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = tkn_mkr.Root(raw_bry);
byte[] actl = parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, raw_bry);
Tfds.Eq(expd, String_.new_u8(actl));
tst_Log_check();
}
public Xop_root_tkn Test_parse_page_tmpl_tkn(String raw) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = tkn_mkr.Root(raw_bry);
parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, raw_bry);
return root;
}
public void Test_parse_page_tmpl(String raw, Tst_chkr... expd_ary) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = tkn_mkr.Root(raw_bry);
parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, raw_bry);
Parse_chk(raw_bry, root, expd_ary);
}
public void Test_parse_page_wiki(String raw, Tst_chkr... expd_ary) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = Test_parse_page_wiki_root(raw_bry);
Parse_chk(raw_bry, root, expd_ary);
}
public Xop_root_tkn Test_parse_page_wiki_root(String raw) {return Test_parse_page_wiki_root(Bry_.new_u8(raw));}
Xop_root_tkn Test_parse_page_wiki_root(byte[] raw_bry) {
Xop_root_tkn root = tkn_mkr.Root(raw_bry);
parser.Parse_wtxt_to_wdom(root, ctx, tkn_mkr, raw_bry, Xop_parser_.Doc_bgn_bos);
return root;
}
public void Test_parse_page_all(String raw, Tst_chkr... expd_ary) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = Exec_parse_page_all_as_root(Bry_.new_u8(raw));
Parse_chk(raw_bry, root, expd_ary);
}
public void Data_create(String ttl_str, String text_str) {Init_page_create(wiki, ttl_str, text_str);}
public void Test_parse_page_all_str(String raw, String expd) {
String actl = Exec_parse_page_all_as_str(raw);
Tfds.Eq_ary_str(String_.SplitLines_nl(expd), String_.SplitLines_nl(actl), raw);
}
public void Test_parse_page_all_str_and_chk(String raw, String expd, Gfo_msg_itm... ary) {
this.Init_log_(ary);
Test_parse_page_all_str(raw, expd);
this.tst_Log_check();
}
public Xop_root_tkn Exec_parse_page_all_as_root(byte[] raw_bry) {
Xop_root_tkn root = tkn_mkr.Root(raw_bry);
parser.Parse_page_all_clear(root, ctx, tkn_mkr, raw_bry);
return root;
}
public String Exec_parse_page_all_as_str(String raw) {
Xop_root_tkn root = Exec_parse_page_all_as_root(Bry_.new_u8(raw));
Bry_bfr actl_bfr = Bry_bfr.new_();
hdom_wtr.Write_all(actl_bfr, ctx, root.Root_src(), root);
return actl_bfr.Xto_str_and_clear();
}
public String Exec_parse_page_wiki_as_str(String raw) {
byte[] raw_bry = Bry_.new_u8(raw);
Xop_root_tkn root = tkn_mkr.Root(raw_bry);
parser.Parse_wtxt_to_wdom(root, ctx, tkn_mkr, raw_bry, Xop_parser_.Doc_bgn_bos);
Bry_bfr actl_bfr = Bry_bfr.new_();
hdom_wtr.Write_all(actl_bfr, ctx, raw_bry, root);
return actl_bfr.Xto_str_and_clear();
}
private void Parse_chk(byte[] raw_bry, Xop_root_tkn root, Tst_chkr[] expd_ary) {
int subs_len = root.Subs_len();
Object[] actl_ary = new Object[subs_len];
for (int i = 0; i < subs_len; i++)
actl_ary[i] = root.Subs_get(i);
tst_mgr.Vars().Clear().Add("raw_bry", raw_bry);
tst_mgr.Tst_ary("tkns:", expd_ary, actl_ary);
tst_Log_check();
}
public Xop_fxt Test_parse_page_wiki_str(String raw, String expd) {
Tfds.Eq_str_lines(expd, Exec_parse_page_wiki_as_str(raw), raw);
return this;
}
public void Log_clear() {ctx.App().Msg_log().Clear();}
public String[] Log_xtoAry() {
Gfo_msg_log msg_log = app.Msg_log();
int len = msg_log.Ary_len();
List_adp actl_list = List_adp_.new_();
for (int i = 0; i < len; i++) {
Gfo_msg_data eny = msg_log.Ary_get(i);
if (eny.Item().Cmd() > Gfo_msg_itm_.Cmd_note) {
actl_list.Add(String_.new_u8(eny.Item().Path_bry()));
}
}
String[] actl = actl_list.To_str_ary();
msg_log.Clear();
return actl;
}
public Xop_fxt tst_Log_check() {
int len = log_itms.Count();
String[] expd = new String[len];
for (int i = 0; i < len; i++) {
Gfo_msg_itm itm = (Gfo_msg_itm)log_itms.Get_at(i);
expd[i] = itm.Path_str();
}
log_itms.Clear();
String[] actl = Log_xtoAry();
Tfds.Eq_ary_str(expd, actl);
return this;
}
public void tst_Warn(String... expd) {
Gfo_usr_dlg usr_dlg = app.Usr_dlg();
Gfo_usr_dlg__gui_test ui_wkr = (Gfo_usr_dlg__gui_test)usr_dlg.Gui_wkr();
String[] actl = ui_wkr.Warns().To_str_ary();
Tfds.Eq_ary_str(expd, actl);
}
public void Test_parse_page(String ttl, String expd) {
byte[] actl = Load_page(wiki, ttl);
Tfds.Eq(expd, String_.new_u8(actl));
}
public static byte[] Load_page(Xowe_wiki wiki, String ttl_str) {
byte[] ttl_bry = Bry_.new_u8(ttl_str);
Xoa_url page_url = Xoa_url.new_(wiki.Domain_bry(), ttl_bry);
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry);
return wiki.Load_page_by_ttl(page_url, ttl).Data_raw();
}
public static void Reg_xwiki_alias(Xowe_wiki wiki, String alias, String domain) {
byte[] domain_bry = Bry_.new_a7(domain);
wiki.Xwiki_mgr().Add_full(Bry_.new_a7(alias), domain_bry, Bry_.Add(domain_bry, Bry_.new_a7("/wiki/~{0}")));
wiki.Appe().Usere().Wiki().Xwiki_mgr().Add_full(domain_bry, domain_bry);
}
public static String html_img_none(String trg, String alt, String src, String ttl) {
return String_.Format(String_.Concat_lines_nl_skip_last("<a href=\"/wiki/{0}\" class=\"image\" xowa_title=\"{3}\"><img id=\"xowa_file_img_0\" alt=\"{1}\" src=\"{2}\" width=\"9\" height=\"8\" /></a>"), trg, alt, src, ttl);
}
private String Exec_html_full(String raw) {return this.Exec_parse_page_all_as_str(raw);}
private String Exec_html_wiki(String raw) {return this.Exec_parse_page_wiki_as_str(raw);}
public void Test_html_wiki_str(String raw, String expd) {Test_str_full(raw, expd, Exec_html_wiki(raw));}
public void Test_html_full_str(String raw, String expd) {Test_str_full(raw, expd, Exec_html_full(raw));}
public void Test_html_wiki_frag(String raw, String... expd_frags) {Test_str_part_y(Exec_html_wiki(raw), expd_frags);}
public void Test_html_full_frag(String raw, String... expd_frags) {Test_str_part_y(Exec_html_full(raw), expd_frags);}
public void Test_html_full_frag_n(String raw, String... expd_frags) {Test_str_part_n(Exec_html_full(raw), expd_frags);}
public void Test_str_full(String raw, String expd, String actl) {Tfds.Eq_str_lines(expd, actl, raw);}
private void Test_str_part_y(String actl, String... expd_parts) {
int expd_parts_len = expd_parts.length;
for (int i = 0; i < expd_parts_len; i++) {
String expd_part = expd_parts[i];
boolean pass = String_.Has(actl, expd_part);
if (!pass)
Tfds.Eq_true(false, expd_part + "\n" + actl);
}
}
private void Test_str_part_n(String actl, String... expd_parts) {
int expd_parts_len = expd_parts.length;
for (int i = 0; i < expd_parts_len; i++) {
String expd_part = expd_parts[i];
boolean has = String_.Has(actl, expd_part);
if (has)
Tfds.Eq_true(false, expd_part + "\n" + actl);
}
}
public void Test_html_modules_js(String expd) {
Bry_bfr bfr = app.Utl__bfr_mkr().Get_k004();
this.Page().Html_data().Module_mgr().Init(app, wiki, this.Page());
this.Page().Html_data().Module_mgr().XferAry(bfr, 0);
bfr.Mkr_rls();
Tfds.Eq_str_lines(expd, bfr.Xto_str_and_clear());
}
private Tst_mgr tst_mgr = new Tst_mgr(); private Xop_tkn_mkr tkn_mkr;
public static final String Ttl_str = "Test page";
public Xop_fxt Init_lang_numbers_separators_en() {return Init_lang_numbers_separators(",", ".");}
public Xop_fxt Init_lang_numbers_separators(String grp_spr, String dec_spr) {return Init_lang_numbers_separators(wiki.Lang(), grp_spr, dec_spr);}
public Xop_fxt Init_lang_numbers_separators(Xol_lang lang, String grp_spr, String dec_spr) {
gplx.xowa.langs.numbers.Xol_transform_mgr separator_mgr = lang.Num_mgr().Separators_mgr();
separator_mgr.Clear();
separator_mgr.Set(gplx.xowa.langs.numbers.Xol_num_mgr.Separators_key__grp, Bry_.new_u8(grp_spr));
separator_mgr.Set(gplx.xowa.langs.numbers.Xol_num_mgr.Separators_key__dec, Bry_.new_u8(dec_spr));
return this;
}
public void Init_lang_kwds(int kwd_id, boolean case_match, String... kwds) {Init_lang_kwds(wiki.Lang(), kwd_id, case_match, kwds);}
public void Init_lang_kwds(Xol_lang lang, int kwd_id, boolean case_match, String... kwds) {
Xol_kwd_mgr kwd_mgr = lang.Kwd_mgr();
Xol_kwd_grp kwd_grp = kwd_mgr.Get_or_new(kwd_id);
kwd_grp.Srl_load(case_match, Bry_.Ary(kwds));
}
public void Init_xtn_pages() {
Io_mgr.I.InitEngine_mem();
wiki.Xtn_mgr().Xtn_proofread().Enabled_y_();
wiki.Db_mgr().Load_mgr().Clear(); // must clear; otherwise fails b/c files get deleted, but wiki.data_mgr caches the Xowd_regy_mgr (the .reg file) in memory;
wiki.Ns_mgr().Add_new(Xowc_xtn_pages.Ns_page_id_default, "Page").Add_new(Xowc_xtn_pages.Ns_index_id_default, "Index").Init();
}
public void Clear_ref_mgr() {this.Page().Ref_mgr().Grps_clear();} // clear to reset count
public static Xop_fxt new_nonwmf() {
Xoae_app app = Xoa_app_fxt.app_();
return new Xop_fxt(app, Xoa_app_fxt.wiki_nonwmf(app, "nethackwiki"));
}
}

View File

@@ -0,0 +1,59 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.files.*;
public class Xop_lnki_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_lnki_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_lnki;}
public int Ns_id() {return nsId;} public Xop_lnki_tkn_chkr Ns_id_(int v) {nsId = v; return this;} private int nsId = Int_.MinValue;
public byte ImgType() {return imgType;} public Xop_lnki_tkn_chkr ImgType_(byte v) {imgType = v; return this;} private byte imgType = Byte_.Max_value_127;
public int Width() {return width;} public Xop_lnki_tkn_chkr Width_(int v) {width = v; return this;} private int width = Int_.MinValue;
public int Height() {return height;} public Xop_lnki_tkn_chkr Height_(int v) {height = v; return this;} private int height = Int_.MinValue;
public byte HAlign() {return hAlign;} public Xop_lnki_tkn_chkr HAlign_(byte v) {hAlign = v; return this;} private byte hAlign = Byte_.Max_value_127;
public byte VAlign() {return vAlign;} public Xop_lnki_tkn_chkr VAlign_(byte v) {vAlign = v; return this;} private byte vAlign = Byte_.Max_value_127;
public byte Border() {return border;} public Xop_lnki_tkn_chkr Border_(byte v) {border = v; return this;} private byte border = Bool_.__byte;
public double Upright() {return upright;} public Xop_lnki_tkn_chkr Upright_(double v) {upright = v; return this;} double upright = Xop_lnki_tkn.Upright_null;
public int Thumbtime() {return thumbtime;} public Xop_lnki_tkn_chkr Thumbtime_(int v) {thumbtime = v; return this;} int thumbtime = Xof_lnki_time.Null_as_int;
public int Page() {return page;} public Xop_lnki_tkn_chkr Page_(int v) {page = v; return this;} int page = Xof_lnki_page.Null;
public int Tail_bgn() {return tail_bgn;} public Xop_lnki_tkn_chkr Tail_bgn_(int v) {tail_bgn = v; return this;} private int tail_bgn = String_.Pos_neg1;
public int Tail_end() {return tail_end;} public Xop_lnki_tkn_chkr Tail_end_(int v) {tail_end = v; return this;} private int tail_end = String_.Pos_neg1;
public Xop_tkn_chkr_base Trg_tkn() {return trg_tkn;} public Xop_lnki_tkn_chkr Trg_tkn_(Xop_tkn_chkr_base v) {trg_tkn = v; return this;} private Xop_tkn_chkr_base trg_tkn;
public Xop_tkn_chkr_base Caption_tkn() {return caption_tkn;} public Xop_lnki_tkn_chkr Caption_tkn_(Xop_tkn_chkr_base v) {caption_tkn = v; return this;} private Xop_tkn_chkr_base caption_tkn;
public Xop_tkn_chkr_base Alt_tkn() {return alt_tkn;} public Xop_lnki_tkn_chkr Alt_tkn_(Xop_tkn_chkr_base v) {alt_tkn = v; return this;} private Xop_tkn_chkr_base alt_tkn;
public Xop_tkn_chkr_base Link_tkn() {return link_tkn;} public Xop_lnki_tkn_chkr Link_tkn_(Xop_tkn_chkr_base v) {link_tkn = v; return this;} private Xop_tkn_chkr_base link_tkn;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_lnki_tkn actl = (Xop_lnki_tkn)actl_obj;
err += mgr.Tst_val(nsId == Int_.MinValue, path, "nsId", nsId, actl.Ns_id());
err += mgr.Tst_val(imgType == Byte_.Max_value_127, path, "imgType", imgType, actl.Lnki_type());
err += mgr.Tst_val(width == Int_.MinValue, path, "width", width, actl.W());
err += mgr.Tst_val(height == Int_.MinValue, path, "height", height, actl.H());
err += mgr.Tst_val(hAlign == Byte_.Max_value_127, path, "halign", hAlign, actl.Align_h());
err += mgr.Tst_val(vAlign == Byte_.Max_value_127, path, "valign", vAlign, actl.Align_v());
err += mgr.Tst_val(border == Bool_.__byte, path, "border", border, actl.Border());
err += mgr.Tst_val(tail_bgn == String_.Pos_neg1, path, "tail_bgn", tail_bgn, actl.Tail_bgn());
err += mgr.Tst_val(tail_end == String_.Pos_neg1, path, "tail_end", tail_end, actl.Tail_end());
err += mgr.Tst_val(upright == Xop_lnki_tkn.Upright_null, path, "upright", upright, actl.Upright());
err += mgr.Tst_val(thumbtime == Xof_lnki_time.Null, path, "thumbtime", thumbtime, Xof_lnki_time.X_int(actl.Time()));
err += mgr.Tst_val(page == Xof_lnki_page.Null, path, "page", page, actl.Page());
if (trg_tkn != null) err += mgr.Tst_sub_obj(trg_tkn, actl.Trg_tkn(), path + "." + "trg", err);
if (caption_tkn != null) err += mgr.Tst_sub_obj(caption_tkn, actl.Caption_tkn(), path + "." + "caption", err);
if (alt_tkn != null) err += mgr.Tst_sub_obj(alt_tkn, actl.Alt_tkn(), path + "." + "alt", err);
if (link_tkn != null) err += mgr.Tst_sub_obj(link_tkn, actl.Link_tkn(), path + "." + "link", err);
return err;
}
}

View File

@@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.core.btries.*;
public interface Xop_lxr {
byte Lxr_tid();
void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie);
void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie);
int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos);
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_lxr_ {
public static final byte
Tid_pipe = 0, Tid_space = 1, Tid_nbsp = 2, Tid_tab = 3, Tid_nl = 4, Tid_amp = 5, Tid_apos = 6, Tid_colon = 7, Tid_lnki_bgn = 8, Tid_lnki_end = 9
, Tid_list = 10, Tid_hdr = 11, Tid_hr = 12, Tid_xnde = 13, Tid_lnke_bgn = 14, Tid_lnke_end = 15, Tid_tblw = 16, Tid_pre = 17, Tid_under = 18, Tid_comment = 19
, Tid_eq = 20, Tid_curly_bgn = 21, Tid_curly_end = 22, Tid_brack_bgn = 23, Tid_brack_end = 24, Tid_poem = 25
, Tid_tvar = 26, Tid_vnt_bgn = 27, Tid_vnt_end = 28, Tid_vnt_eqgt = 29, Tid_vnt_tmpl_bgn = 30, Tid_word = 31, Tid_nl_poem = 32, Tid_cr = 33
, Tid_brack_end_lnki = 34, Tid_nl_tab = 35
;
}

View File

@@ -0,0 +1,79 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.core.btries.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.hdrs.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.paras.*;
public class Xop_lxr_mgr {
private Xop_lxr[] ary;
public Xop_lxr_mgr(Xop_lxr[] ary) {this.ary = ary;}
public Btrie_fast_mgr Trie() {return trie;} private Btrie_fast_mgr trie = Btrie_fast_mgr.cs_();
public void Init_by_wiki(Xowe_wiki wiki) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
Xop_lxr lxr = ary[i];
lxr.Init_by_wiki(wiki, trie);
}
}
public void Init_by_lang(Xol_lang lang) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
Xop_lxr lxr = ary[i];
lxr.Init_by_lang(lang, trie);
}
}
public static Xop_lxr_mgr new_tmpl_() {
return new Xop_lxr_mgr(new Xop_lxr[]
{ Xop_pipe_lxr._, new Xop_eq_lxr(true), Xop_colon_lxr._, Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._
, Xop_curly_bgn_lxr._, Xop_curly_end_lxr._
, Xop_brack_bgn_lxr._, Xop_brack_end_lxr._
, Xop_comm_lxr._
, Xop_xnde_lxr._ // needed for xtn, noinclude, etc.
, Xop_under_lxr._
, gplx.xowa.xtns.translates.Xop_tvar_lxr._
, Xop_cr_lxr._ // always ignore \r; DATE:2014-03-02
});
}
public static Xop_lxr_mgr new_wiki_() {
return new Xop_lxr_mgr(new Xop_lxr[]
{ Xop_pipe_lxr._, new Xop_eq_lxr(false), Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._
, Xop_amp_lxr._, Xop_apos_lxr._, Xop_colon_lxr._
, Xop_lnki_lxr_bgn._, Xop_lnki_lxr_end._
, Xop_list_lxr._
, Xop_hdr_lxr._
, Xop_hr_lxr._
, Xop_xnde_lxr._
, Xop_lnke_lxr._, Xop_lnke_end_lxr._
, Xop_tblw_lxr._
, Xop_pre_lxr._, Xop_nl_tab_lxr._
, Xop_comm_lxr._
, Xop_under_lxr._
});
}
public static final Xop_lxr_mgr Popup_lxr_mgr // same as orig_page, except apos_lxr added
= new Xop_lxr_mgr(new Xop_lxr[]
{ Xop_pipe_lxr._, new Xop_eq_lxr(true), Xop_colon_lxr._, Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._
, Xop_curly_bgn_lxr._, Xop_curly_end_lxr._
, Xop_brack_bgn_lxr._, Xop_brack_end_lxr._
, Xop_comm_lxr._
, Xop_xnde_lxr._ // needed for xtn, noinclude, etc.
, Xop_under_lxr._
, gplx.xowa.xtns.translates.Xop_tvar_lxr._
, Xop_cr_lxr._ // always ignore \r; DATE:2014-03-02
, gplx.xowa.parsers.apos.Xop_apos_lxr._ // needed else multiple apos may be split across blocks;
});
}

View File

@@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.core.btries.*; import gplx.xowa.parsers.lists.*;
class Xop_colon_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_colon;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Byte_ascii.Colon, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
Xop_list_wkr listCtx = ctx.List();
if (listCtx.Dd_chk()) { // handle ";a:b" construct; REF.MW: Parser.php|doBlockLevels|; title : definition text
int prv_pos = cur_pos -1 ;
if ( ctx.Cur_tkn_tid() != Xop_tkn_itm_.Tid_lnki // ignore if inside link
&& prv_pos > 0
&& src[prv_pos] != Byte_ascii.Nl // only consider ":" which are not preceded by \n; DATE:2014-07-11 TODO: emulate Parser.php|findColonNoLinks which does much more logic to see if ";a:b" construct should apply
) {
listCtx.Dd_chk_(false);
return listCtx.MakeTkn_bgn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);
}
}
ctx.Subs_add(root, tkn_mkr.Colon(bgn_pos, cur_pos));
return cur_pos;
}
public static final Xop_colon_lxr _ = new Xop_colon_lxr();
}

View File

@@ -0,0 +1,214 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.core.btries.*;
public class Xop_parser { // NOTE: parsers are reused; do not keep any read-write state
private Xowe_wiki wiki;
public Xop_parser(Xowe_wiki wiki, Xop_lxr_mgr tmpl_lxr_mgr, Xop_lxr_mgr wtxt_lxr_mgr) {
this.wiki = wiki;
this.tmpl_lxr_mgr = tmpl_lxr_mgr; this.tmpl_trie = tmpl_lxr_mgr.Trie();
this.wtxt_lxr_mgr = wtxt_lxr_mgr; this.wtxt_trie = wtxt_lxr_mgr.Trie();
}
public Xop_lxr_mgr Tmpl_lxr_mgr() {return tmpl_lxr_mgr;} private Xop_lxr_mgr tmpl_lxr_mgr;
public Xop_lxr_mgr Wtxt_lxr_mgr() {return wtxt_lxr_mgr;} private Xop_lxr_mgr wtxt_lxr_mgr;
public Btrie_fast_mgr Tmpl_trie() {return tmpl_trie;} private Btrie_fast_mgr tmpl_trie;
public Btrie_fast_mgr Wtxt_trie() {return wtxt_trie;} private Btrie_fast_mgr wtxt_trie;
public void Init_by_wiki(Xowe_wiki wiki) {
tmpl_lxr_mgr.Init_by_wiki(wiki);
wtxt_lxr_mgr.Init_by_wiki(wiki);
}
public void Init_by_lang(Xol_lang lang) {
tmpl_lxr_mgr.Init_by_lang(lang);
wtxt_lxr_mgr.Init_by_lang(lang);
}
public byte[] Parse_text_to_html(Xop_ctx ctx, byte[] src) {
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512();
Parse_text_to_html(bfr, ctx.Cur_page(), false, src);
return bfr.To_bry_and_rls();
}
public void Parse_text_to_html(Bry_bfr trg, Xoae_page page, boolean para_enabled, byte[] src) {
Xop_ctx ctx = Xop_ctx.new_sub_(wiki, page);
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
Xop_parser parser = wiki.Parser();
byte[] wtxt = parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
root.Reset();
ctx.Para().Enabled_(para_enabled);
parser.Parse_wtxt_to_wdom(root, ctx, ctx.Tkn_mkr(), wtxt, Xop_parser_.Doc_bgn_bos);
wiki.Html_mgr().Html_wtr().Write_all(trg, ctx, wtxt, root);
}
public Xot_defn_tmpl Parse_text_to_defn_obj(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xow_ns ns, byte[] name, byte[] src) {
Xot_defn_tmpl rv = new Xot_defn_tmpl();
Parse_text_to_defn(rv, ctx, tkn_mkr, ns, name, src);
return rv;
}
public void Parse_text_to_defn(Xot_defn_tmpl tmpl, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xow_ns ns, byte[] name, byte[] src) {
Xop_root_tkn root = tkn_mkr.Root(src);
Parse(root, ctx, tkn_mkr, src, Xop_parser_.Parse_tid_tmpl, tmpl_trie, Xop_parser_.Doc_bgn_bos);
tmpl_props.OnlyInclude_exists = false; int subs_len = root.Subs_len();
for (int i = 0; i < subs_len; i++)
root.Subs_get(i).Tmpl_compile(ctx, src, tmpl_props);
boolean only_include_chk = Bry_finder.Find_fwd(src, Xop_xnde_tag_.Name_onlyinclude, 0, src.length) != Bry_.NotFound;
if (only_include_chk) tmpl_props.OnlyInclude_exists = true;
tmpl.Init_by_new(ns, name, src, root, tmpl_props.OnlyInclude_exists);
} private Xot_compile_data tmpl_props = new Xot_compile_data();
public void Parse_page_all_clear(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src) {
ctx.Cur_page().Clear(); ctx.App().Msg_log().Clear();
Parse_text_to_wdom(root, ctx, tkn_mkr, src, Xop_parser_.Doc_bgn_bos);
}
public Xop_root_tkn Parse_text_to_wdom_old_ctx(Xop_ctx old_ctx, byte[] src, boolean doc_bgn_pos) {return Parse_text_to_wdom(Xop_ctx.new_sub_(old_ctx.Wiki()), src, doc_bgn_pos);}
public Xop_root_tkn Parse_text_to_wdom(Xop_ctx new_ctx, byte[] src, boolean doc_bgn_pos) {
new_ctx.Para().Enabled_n_();
Xop_tkn_mkr tkn_mkr = new_ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
Parse_text_to_wdom(root, new_ctx, tkn_mkr, src, doc_bgn_pos ? Xop_parser_.Doc_bgn_bos : Xop_parser_.Doc_bgn_char_0);
return root;
}
public void Parse_text_to_wdom(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, int doc_bgn_pos) {
byte parse_tid_old = ctx.Parse_tid();// NOTE: must store parse_tid b/c ctx can be reused by other classes
ctx.Parse_tid_(Xop_parser_.Parse_tid_page_tmpl);
root.Reset();
byte[] mid_bry = Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
root.Data_mid_(mid_bry);
root.Reset();
Parse_wtxt_to_wdom(root, ctx, tkn_mkr, mid_bry, doc_bgn_pos);
ctx.Parse_tid_(parse_tid_old);
}
public byte[] Parse_text_to_wtxt(byte[] src) {
Xop_ctx ctx = Xop_ctx.new_sub_(wiki);
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
return wiki.Parser().Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
}
public byte[] Parse_text_to_wtxt(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src) {
Parse(root, ctx, tkn_mkr, src, Xop_parser_.Parse_tid_page_tmpl, tmpl_trie, Xop_parser_.Doc_bgn_bos);
int subs_len = root.Subs_len();
for (int i = 0; i < subs_len; i++)
root.Subs_get(i).Tmpl_compile(ctx, src, tmpl_props);
return Xot_tmpl_wtr._.Write_all(ctx, root, src); // NOTE: generate new src since most callers will use it;
}
public void Parse_wtxt_to_wdom(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] wtxt, int doc_bgn_pos) {
root.Root_src_(wtxt); // always set latest src; needed for Parse_all wherein src will first be raw and then parsed tmpl
Parse(root, ctx, tkn_mkr, wtxt, Xop_parser_.Parse_tid_page_wiki, wtxt_trie, doc_bgn_pos);
}
private void Parse(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, byte parse_type, Btrie_fast_mgr trie, int doc_bgn_pos) {
int len = src.length; if (len == 0) return; // nothing to parse;
byte parse_tid_old = ctx.Parse_tid(); // NOTE: must store parse_tid b/c ctx can be reused by other classes
ctx.Parse_tid_(parse_type);
ctx.Page_bgn(root, src);
Parse_to_src_end(root, ctx, tkn_mkr, src, trie, doc_bgn_pos, len);
ctx.Page_end(root, src, len);
ctx.Parse_tid_(parse_tid_old);
}
public int Parse_to_src_end(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, Btrie_fast_mgr trie, int pos, int len) {
byte b = pos == -1 ? Byte_ascii.Nl : src[pos]; // simulate newLine at bgn of src; needed for lxrs which rely on \n (EX: "=a=")
int txt_bgn = pos == -1 ? 0 : pos; Xop_tkn_itm txt_tkn = null;
while (true) {
Object o = trie.Match_bgn_w_byte(b, src, pos, len);
if (o == null) // no lxr found; char is txt; increment pos
pos++;
else { // lxr found
Xop_lxr lxr = (Xop_lxr)o;
if (txt_bgn != pos) // chars exist between pos and txt_bgn; make txt_tkn; see NOTE_1
txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
ctx.Lxr_make_(true);
pos = lxr.Make_tkn(ctx, tkn_mkr, root, src, len, pos, trie.Match_pos());
if (ctx.Lxr_make()) {txt_bgn = pos; txt_tkn = null;} // reset txt_tkn
}
if (pos == len) break;
b = src[pos];
}
if (txt_bgn != pos) txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
return pos;
}
public int Parse_to_stack_end(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, int src_len, Btrie_fast_mgr trie, int pos, int end) {
byte b = pos == -1 ? Byte_ascii.Nl : src[pos]; // simulate newLine at bgn of src; needed for lxrs which rely on \n (EX: "=a=")
int txt_bgn = pos == -1 ? 0 : pos; Xop_tkn_itm txt_tkn = null;
Xop_lxr lxr = null;
while (true) {
lxr = null;
Object o = trie.Match_bgn_w_byte(b, src, pos, src_len);
if (o == null) // no lxr found; char is txt; increment pos
pos++;
else { // lxr found
lxr = (Xop_lxr)o;
if (txt_bgn != pos) // chars exist between pos and txt_bgn; make txt_tkn; see NOTE_1
txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
ctx.Lxr_make_(true);
pos = lxr.Make_tkn(ctx, tkn_mkr, root, src, src_len, pos, trie.Match_pos());
if (ctx.Lxr_make()) {txt_bgn = pos; txt_tkn = null;} // reset txt_tkn
}
if ( pos >= end
&& ctx.Stack_len() == 0 // check stack is 0 to avoid dangling templates
) {
if (o == null) {} // last sequence is not text; avoids splitting words across blocks; EX: 4 block and word of "abcde" will split to "abcd" and "e"
else {
if (lxr != null) {
boolean stop = true;
switch (lxr.Lxr_tid()) {
case Xop_lxr_.Tid_eq:
case Xop_lxr_.Tid_nl:
stop = false;
break;
}
if (stop)
break;
}
else {
break;
}
}
}
if (pos >= src_len) break;
b = src[pos];
}
if (txt_bgn != pos) txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
return pos;
}
private static Xop_tkn_itm Txt_add(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, Xop_tkn_itm tkn, int txt_bgn, int pos) {
if (pos == Xop_parser_.Doc_bgn_bos) return null; // don't make txt_tkn for Bos_pos
if (tkn == null) { // no existing txt_tkn; create new one
tkn = tkn_mkr.Txt(txt_bgn, pos);
ctx.Subs_add(root, tkn);
}
else // existing txt_tkn; happens for false matches; EX: abc[[\nef[[a]]; see NOTE_1
tkn.Src_end_(pos);
return tkn;
}
public static Xop_parser new_wiki_(Xowe_wiki wiki) {
Xop_parser rv = new Xop_parser(wiki, Xop_lxr_mgr.new_tmpl_(), Xop_lxr_mgr.new_wiki_());
rv.Init_by_wiki(wiki);
rv.Init_by_lang(wiki.Lang());
return rv;
}
}
/*
NOTE_1
abc[[\nef[[a]]
<BOS> : txt_bgn = 0; txt_tkn = null;
abc : increment pos
[[\n : lnki lxr
: (1): txt_tkn == null, so create txt_tkn with (0, 3)
: (2): lxr.Make_tkn() entered for lnki; however \n exits lnki
: (3): note that ctx.Lxr_make == false, so txt_bgn/txt_tkn is not reset
ef : still just text; increment pos
[[a]] : lnki entered
: (1): txt_tkn != null; set end to 8
: (2): lxr.Make_tkn() entered and lnki made
: (3): note that ctx.Lxr_make == true, so txt_bgn = 13 and txt_tkn = null
*/

View File

@@ -0,0 +1,36 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.langs.vnts.*;
public class Xop_parser_ {
public static final byte Parse_tid_null = 0, Parse_tid_tmpl = 1, Parse_tid_page_tmpl = 2, Parse_tid_page_wiki = 3;
public static final int Doc_bgn_bos = -1, Doc_bgn_char_0 = 0;
public static byte[] Parse_text_to_html(Xowe_wiki wiki, Xoae_page page, Xoa_ttl ttl, byte[] src, boolean para_enabled) { // NOTE: must pass in same page instance; do not do Xoa_page_.new_(), else img_idx will get reset to 0; DATE:2015-02-08
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512();
Xop_ctx ctx = Xop_ctx.new_sub_(wiki, page);
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
Xop_parser parser = wiki.Parser();
byte[] wtxt = parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
root.Reset();
ctx.Para().Enabled_(para_enabled);
parser.Parse_wtxt_to_wdom(root, ctx, ctx.Tkn_mkr(), wtxt, Xop_parser_.Doc_bgn_bos);
wiki.Html_mgr().Html_wtr().Write_all(bfr, ctx, wtxt, root);
return bfr.To_bry_and_rls();
}
}

View File

@@ -0,0 +1,58 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xop_parser__tst {
@Before public void init() {fxt.Clear();} private Xop_parser__fxt fxt = new Xop_parser__fxt();
@Test public void Para_y() {
fxt.Test_parse_to_html(String_.Concat_lines_nl_skip_last
( "a"
, ""
, "b"
), true, String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, ""
, "<p>b"
, "</p>"
, ""
));
}
@Test public void Para_n() {
fxt.Test_parse_to_html(String_.Concat_lines_nl_skip_last
( "a"
, ""
, "b"
), false, String_.Concat_lines_nl_skip_last
( "a"
, "b"
));
}
}
class Xop_parser__fxt {
private Xop_fxt fxt = new Xop_fxt();
private Bry_bfr bfr = Bry_bfr.reset_(255);
public void Clear() {
fxt.Reset();
}
public void Test_parse_to_html(String raw, boolean para_enabled, String expd) {
byte[] raw_bry = Bry_.new_u8(raw);
fxt.Wiki().Parser().Parse_text_to_html(bfr, fxt.Page(), para_enabled, raw_bry);
Tfds.Eq(expd, bfr.Xto_str_and_clear());
}
}

View File

@@ -0,0 +1,125 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.html.*; import gplx.xowa.html.hrefs.*;
public class Xop_redirect_mgr {
private final Xowe_wiki wiki; private final Url_encoder url_decoder; private Hash_adp_bry redirect_hash;
public Xop_redirect_mgr(Xowe_wiki wiki) {this.wiki = wiki; this.url_decoder = Xoa_app_.Utl__encoder_mgr().Http_url_ttl();} // NOTE: must be Url_ttl, not Url; PAGE:en.w:Template:Positionskarte+ -> Template:Location_map+, not Template:Location_map DATE:2014-08-21
public void Clear() {redirect_hash = null;} // TEST:
public boolean Is_redirect(byte[] text, int text_len) {return this.Extract_redirect(text, text_len) != null;}
public Xoa_ttl Extract_redirect_loop(byte[] src) {
Xoa_ttl rv = null;
for (int i = 0; i < Redirect_max_allowed; i++) {
rv = Extract_redirect(src, src.length);
if (rv != null) return rv;
}
return null;
}
public Xoa_ttl Extract_redirect(byte[] src) {return Extract_redirect(src, src.length);}
public Xoa_ttl Extract_redirect(byte[] src, int src_len) { // NOTE: this proc is called by every page. be careful of changes; DATE:2014-07-05
if (src_len == 0) return Redirect_null_ttl;
int bgn = Bry_finder.Find_fwd_while_not_ws(src, 0, src_len);
if (bgn == src_len) return Redirect_null_ttl; // article is entirely whitespace
int kwd_end = Xop_redirect_mgr_.Get_kwd_end_or_end(src, bgn, src_len);
if (kwd_end == src_len) return Redirect_null_ttl;
if (redirect_hash == null) redirect_hash = Xol_kwd_mgr.hash_(wiki.Lang().Kwd_mgr(), Xol_kwd_grp_.Id_redirect);
Object redirect_itm = redirect_hash.Get_by_mid(src, bgn, kwd_end);
if (redirect_itm == null) return Redirect_null_ttl; // not a redirect kwd
int ttl_bgn = Xop_redirect_mgr_.Get_ttl_bgn_or_neg1(src, kwd_end, src_len);
if (ttl_bgn == Bry_.NotFound) return Redirect_null_ttl;
ttl_bgn += Xop_tkn_.Lnki_bgn.length;
int ttl_end = Bry_finder.Find_fwd(src, Xop_tkn_.Lnki_end, ttl_bgn);
if (ttl_end == Bry_.NotFound) return Redirect_null_ttl;
byte[] redirect_bry = Bry_.Mid(src, ttl_bgn, ttl_end);
redirect_bry = url_decoder.Decode(redirect_bry); // NOTE: url-decode links; PAGE: en.w:Watcher_(Buffy_the_Vampire_Slayer); DATE:2014-08-18
return Xoa_ttl.parse_(wiki, redirect_bry);
}
public static final Xoa_ttl Extract_redirect_is_null = null;
public static final int Redirect_max_allowed = 4;
public static final Xoa_ttl Redirect_null_ttl = null;
public static final byte[] Redirect_null_bry = Bry_.Empty;
private static final byte[] Redirect_bry = Bry_.new_a7("#REDIRECT ");
public static byte[] Make_redirect_text(byte[] redirect_to_ttl) {
return Bry_.Add
( Redirect_bry // "#REDIRECT "
, Xop_tkn_.Lnki_bgn // "[["
, redirect_to_ttl // "Page"
, Xop_tkn_.Lnki_end // "]]"
);
}
public static byte[] Bld_redirect_msg(Xoae_app app, Xowe_wiki wiki, Xoae_page page) {
List_adp list = page.Redirected_ttls();
int list_len = list.Count();
if (list_len == 0) return Bry_.Empty;
Bry_bfr redirect_bfr = app.Utl__bfr_mkr().Get_b512();
for (int i = 0; i < list_len; i++) {
if (i != 0) redirect_bfr.Add(Bry_redirect_dlm);
byte[] redirect_ttl = (byte[])list.Get_at(i);
redirect_bfr.Add(Xoh_consts.A_bgn) // '<a href="'
.Add(Xoh_href_parser.Href_wiki_bry) // '/wiki/'
.Add(redirect_ttl) // 'PageA'
.Add(Bry_redirect_arg) // ?redirect=no
.Add(Xoh_consts.A_bgn_lnki_0) // '" title="'
.Add(redirect_ttl) // 'PageA'
.Add(Xoh_consts.__end_quote) // '">'
.Add(redirect_ttl) // 'PageA'
.Add(Xoh_consts.A_end) // </a>
;
}
Xol_msg_itm msg_itm = wiki.Lang().Msg_mgr().Itm_by_id_or_null(Xol_msg_itm_.Id_redirectedfrom);
Bry_bfr fmt_bfr = app.Utl__bfr_mkr().Get_b512();
app.Tmp_fmtr().Fmt_(msg_itm.Val()).Bld_bfr_one(fmt_bfr, redirect_bfr);
redirect_bfr.Clear().Mkr_rls(); fmt_bfr.Mkr_rls();
return fmt_bfr.Xto_bry_and_clear();
} private static byte[] Bry_redirect_dlm = Bry_.new_a7(" <--- "), Bry_redirect_arg = Bry_.new_a7("?redirect=no");
}
class Xop_redirect_mgr_ {
public static int Get_kwd_end_or_end(byte[] src, int bgn, int end) { // get end of kwd
for (int i = bgn; i < end; ++i) {
switch (src[i]) {
case Byte_ascii.Nl: case Byte_ascii.Space: case Byte_ascii.Tab:
case Byte_ascii.Brack_bgn: case Byte_ascii.Colon:
return i; // ASSUME: kwd does not have these chars
default:
break;
}
}
return end;
}
public static int Get_ttl_bgn_or_neg1(byte[] src, int bgn, int end) { // get bgn of ttl
boolean colon_null = true;
for (int i = bgn; i < end; ++i) {
switch (src[i]) {
case Byte_ascii.Nl: case Byte_ascii.Space: case Byte_ascii.Tab: break; // skip all ws
case Byte_ascii.Colon: // allow 1 colon
if (colon_null)
colon_null = false;
else
return Bry_.NotFound;
break;
default:
break;
case Byte_ascii.Brack_bgn:
int nxt_pos = i + 1;
if (nxt_pos >= end) return Bry_.NotFound; // [ at eos
return src[nxt_pos] == Byte_ascii.Brack_bgn ? i : Bry_.NotFound;
}
}
return Bry_.NotFound;
}
}

View File

@@ -0,0 +1,69 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
public class Xop_redirect_mgr_tst {
@Before public void init() {fxt.Clear();} private Xop_redirect_mgr_fxt fxt = new Xop_redirect_mgr_fxt();
@Test public void Basic() {fxt.Test_redirect("#REDIRECT [[a]]", "A");}
@Test public void Basic_colon() {fxt.Test_redirect("#REDIRECT:[[a]]", "A");}
@Test public void Ns_help() {fxt.Test_redirect("#REDIRECT [[Help:a]]", "Help:A");}
@Test public void First() {fxt.Test_redirect("#REDIRECT [[a]] [[b]]", "A");}
@Test public void Exc_false_match() {fxt.Test_redirect("#REDIRECTA [[a]]", "");}
@Test public void Exc_lnki_not_found() {fxt.Test_redirect("#REDIRECT test", "");}
@Test public void Ws() {fxt.Test_redirect("\n#REDIRECT [[a]]", "A");} // PAGE:en.w:Germany; {{Template group}} -> \n#REDIRECT [[Template:Navboxes]]
@Test public void Utf8() {
fxt.Init_utf8();
fxt.Init_kwds(Bool_.N, "#REDIRECT", "#перенаправление");
fxt.Test_redirect("#REDIRECT [[A]]", "A");
fxt.Test_redirect("#reDirect [[A]]", "A");
fxt.Test_redirect("#перенаправление [[A]]", "A");
fxt.Test_redirect("#ПЕРЕНАПРАВЛЕНИЕ [[A]]", "A");
}
@Test public void Url_decode() {fxt.Test_redirect("#REDIRECT [[A%28B%29]]" , "A(B)");} // PURPOSE: url-decode links; PAGE:en.w:Watcher_(Buffy_the_Vampire_Slayer); DATE:2014-08-18
@Test public void Url_decode_plus() {fxt.Test_redirect("#REDIRECT [[A%28B%29+]]", "A(B)+");} // PURPOSE: do not url-decode +; PAGE:en.w:Template:Positionskarte+; DATE:2014-08-22
@Test public void Amp() {fxt.Test_redirect("#REDIRECT [[A &amp; B]]", "A & B");} // PURPOSE: &amp; -> &; PAGE:en.w:Amadou Bagayoko?redirect=n; DATE:2014-09-23
@Test public void Frame_ttl() { // PURPOSE: redirect should set invk frame title to redirect_trg, not original; PAGE:en.w:Statutory_city DATE:2014-08-22
fxt.Test_frame_ttl("Template:A", "#REDIRECT [[Template:B]]", "Template:B", "Template:B");
}
}
class Xop_redirect_mgr_fxt {
private Xop_fxt fxt = new Xop_fxt();
public void Clear() {
fxt.Reset();
}
public void Init_kwds(boolean case_match, String... kwds) {fxt.Init_lang_kwds(Xol_kwd_grp_.Id_redirect, case_match, kwds);}
public void Init_utf8() {
fxt.Wiki().Lang().Case_mgr_utf8_();
}
public void Test_frame_ttl(String tmpl_ttl_str, String tmpl_wtxt_str, String redirect_ttl, String expd_frame_ttl) {
fxt.Init_page_create(tmpl_ttl_str, tmpl_wtxt_str); // create redirect_src
fxt.Init_page_create(redirect_ttl, "test"); // create redirect_trg
fxt.Test_parse_page_tmpl_tkn("{{" + tmpl_ttl_str + "}}"); // parse {{redirect_src}}
Xoa_ttl tmpl_ttl = Xoa_ttl.parse_(fxt.Wiki(), Bry_.new_u8(tmpl_ttl_str));
Xot_defn_tmpl defn_tmpl = (Xot_defn_tmpl)fxt.Wiki().Cache_mgr().Defn_cache().Get_by_key(tmpl_ttl.Page_db()); // get defn (which parse should have created)
Tfds.Eq(expd_frame_ttl, String_.new_u8(defn_tmpl.Frame_ttl())); // check frame_ttl
}
public void Test_redirect(String raw_str, String expd_str) {
Xop_redirect_mgr redirect_mgr = fxt.Ctx().Wiki().Redirect_mgr();
redirect_mgr.Clear();
byte[] raw_bry = Bry_.new_u8(raw_str);
Xoa_ttl actl_ttl = redirect_mgr.Extract_redirect(raw_bry, raw_bry.length);
byte[] actl_bry = actl_ttl == null ? Bry_.Empty : actl_ttl.Full_txt();
Tfds.Eq(expd_str, String_.new_u8(actl_bry));
}
}

View File

@@ -0,0 +1,110 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.core.btries.*; import gplx.xowa.parsers.amps.*;
public class Xop_sanitizer {
private Btrie_slim_mgr trie = Btrie_slim_mgr.cs_(), amp_trie;
private Xop_amp_mgr amp_mgr;
private Bry_bfr tmp_bfr = Bry_bfr.reset_(255);
public Xop_sanitizer(Xop_amp_mgr amp_mgr, Gfo_msg_log msg_log) {
this.amp_mgr = amp_mgr; this.amp_trie = amp_mgr.Amp_trie();
trie_add("&" , Tid_amp);
trie_add(" " , Tid_space);
trie_add("%3A" , Tid_colon);
trie_add("%3a" , Tid_colon);
trie_add("%" , Tid_percent);
}
private void trie_add(String hook, byte tid) {trie.Add_stub(hook, tid);}
public byte[] Escape_id(byte[] src) {
boolean dirty = Escape_id(src, 0, src.length, tmp_bfr);
return dirty ? tmp_bfr.Xto_bry_and_clear() : src;
}
public boolean Escape_id(byte[] src, int bgn, int end, Bry_bfr bfr) {
boolean dirty = false;
int pos = bgn;
boolean loop = true;
while (loop) {
if (pos == end) break;
byte b = src[pos];
Object o = trie.Match_bgn_w_byte(b, src, pos, end);
if (o == null) {
if (dirty) bfr.Add_byte(b);
++pos;
}
else {
if (!dirty) {
bfr.Add_mid(src, bgn, pos);
dirty = true;
}
Btrie_itm_stub stub = (Btrie_itm_stub)o;
switch (stub.Tid()) {
case Tid_space: bfr.Add_byte(Byte_ascii.Underline) ; ++pos ; break;
case Tid_percent: bfr.Add_byte(Byte_ascii.Percent) ; ++pos ; break;
case Tid_colon: bfr.Add_byte(Byte_ascii.Colon) ; pos += 3 ; break;
case Tid_amp:
++pos;
if (pos == end) {
bfr.Add_byte(Byte_ascii.Amp);
loop = false;
continue;
}
b = src[pos];
Object amp_obj = amp_trie.Match_bgn_w_byte(b, src, pos, end);
if (amp_obj == null) {
bfr.Add_byte(Byte_ascii.Amp);
bfr.Add_byte(b);
++pos;
}
else {
Xop_amp_trie_itm itm = (Xop_amp_trie_itm)amp_obj;
byte itm_tid = itm.Tid();
switch (itm_tid) {
case Xop_amp_trie_itm.Tid_name_std:
case Xop_amp_trie_itm.Tid_name_xowa:
bfr.Add(itm.Utf8_bry());
pos += itm.Key_name_len() + 1; // 1 for trailing ";"; EX: for "&nbsp; ", (a) pos is at "&", (b) "nbsp" is Key_name_len, (c) ";" needs + 1
break;
case Xop_amp_trie_itm.Tid_num_dec:
case Xop_amp_trie_itm.Tid_num_hex:
boolean pass = amp_mgr.Parse_as_int(itm_tid == Xop_amp_trie_itm.Tid_num_hex, src, end, pos - 1, pos + itm.Xml_name_bry().length);
if (pass)
bfr.Add_u8_int(amp_mgr.Rslt_val());
else
bfr.Add_byte(Byte_ascii.Amp);
pos = amp_mgr.Rslt_pos();
break;
}
}
break;
}
}
}
return dirty;
}
static final byte Tid_amp = 1, Tid_space = 2, Tid_colon = 3, Tid_percent = 4;
}
/*
NOTE: original escapeID does following
1: ' ' -> _
2: decode_html_ent();
3: '%3A' -> :
4: % -> .
for performance
. combine 1,2,3,4: this will fail in cases like &#32; which will become " " instead of "_".
. if that happens, go to 2 passes and move 2: to 1 (this should have no side-effect)
*/

View File

@@ -0,0 +1,44 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import org.junit.*;
import gplx.xowa.parsers.amps.*;
public class Xop_sanitizer_tst {
Xop_sanitizer_fxt fxt = new Xop_sanitizer_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Space() {fxt.tst_Escape_id("a b" , "a_b");}
@Test public void Colon() {fxt.tst_Escape_id("a%3Ab" , "a:b");}
@Test public void Percent() {fxt.tst_Escape_id("a%b" , "a%b");}
@Test public void Amp_eos() {fxt.tst_Escape_id("a&" , "a&");}
@Test public void Amp_unrecognized() {fxt.tst_Escape_id("a&bcd" , "a&bcd");}
@Test public void Amp_name() {fxt.tst_Escape_id("a&lt;b" , "a<b");}
@Test public void Amp_ncr_dec_pass() {fxt.tst_Escape_id("a&#33;b" , "a!b");}
@Test public void Amp_ncr_dec_fail() {fxt.tst_Escape_id("a&#33x;b" , "a&#33x;b");}
@Test public void Amp_ncr_hex_pass() {fxt.tst_Escape_id("a&#x21;b" , "a!b");}
}
class Xop_sanitizer_fxt {
public Xop_sanitizer sanitizer;
public void Clear() {
if (sanitizer != null) return;
sanitizer = new Xop_sanitizer(new Xop_amp_mgr(), new Gfo_msg_log(Xoa_app_.Name));
}
public void tst_Escape_id(String raw, String expd) {
byte[] raw_bry = Bry_.new_u8(raw);
Tfds.Eq(expd, String_.new_u8(sanitizer.Escape_id(raw_bry)));
}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_tblw_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tblw");
public static final Gfo_msg_itm
Dangling = Gfo_msg_itm_.new_warn_(owner, "dangling_tblw")
, Elem_without_tbl = Gfo_msg_itm_.new_warn_(owner, "elem_without_tbl")
// , Row_trailing = Gfo_msg_itm_.new_warn_(owner, "Row_trailing")
, Caption_after_tr = Gfo_msg_itm_.new_warn_(owner, "caption_after_tr")
, Caption_after_td = Gfo_msg_itm_.new_warn_(owner, "caption_after_td")
, Caption_after_tc = Gfo_msg_itm_.new_warn_(owner, "caption_after_tc")
, Hdr_after_cell = Gfo_msg_itm_.new_warn_(owner, "hdr_after_cell")
, Tbl_empty = Gfo_msg_itm_.new_warn_(owner, "tbl_empty")
;
}

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.parsers.tblws.*;
public class Xop_tblw_tb_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_tb_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tb;}
public int Caption_count() {return caption_count;} public Xop_tblw_tb_tkn_chkr Caption_count_(int v) {caption_count = v; return this;} private int caption_count = Int_.Neg1_count;
public Xop_tblw_tb_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_tb_tkn actl = (Xop_tblw_tb_tkn)actl_obj;
err += mgr.Tst_val(caption_count == Int_.Neg1_count, path, "caption_count", caption_count, actl.Caption_count());
err += mgr.Tst_val(atrs_bgn == Xop_tblw_wkr.Atrs_null, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == Xop_tblw_wkr.Atrs_null, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

@@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.parsers.tblws.*;
public class Xop_tblw_tc_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_tc_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tc;}
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
// Xop_tblw_tc_tkn actl = (Xop_tblw_tc_tkn)actl_obj;
return err;
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.parsers.tblws.*;
public class Xop_tblw_td_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_td_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_td;}
public Xop_tblw_td_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_td_tkn actl = (Xop_tblw_td_tkn)actl_obj;
err += mgr.Tst_val(atrs_bgn == Xop_tblw_wkr.Atrs_null, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == Xop_tblw_wkr.Atrs_null, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.parsers.tblws.*;
public class Xop_tblw_th_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_th_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_th;}
public Xop_tblw_th_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_th_tkn actl = (Xop_tblw_th_tkn)actl_obj;
err += mgr.Tst_val(atrs_bgn == -1, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == -1, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

@@ -0,0 +1,30 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.parsers.tblws.*;
public class Xop_tblw_tr_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_tr_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tr;}
public Xop_tblw_tr_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_tr_tkn actl = (Xop_tblw_tr_tkn)actl_obj;
err += mgr.Tst_val(atrs_bgn == -1, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == -1, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

@@ -0,0 +1,64 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_tkn_chkr_base implements Tst_chkr {
@gplx.Virtual public Class<?> TypeOf() {return Xop_tkn_itm.class;}
@gplx.Virtual public byte Tkn_tid() {return Byte_.Max_value_127;}
public Xop_tkn_chkr_base TypeId_dynamic(int v) {typeId = Xop_tkn_itm_.Tid__names[v]; return this;} private String typeId = null;
public int Src_bgn() {return src_bgn;} private int src_bgn = -1;
public int Src_end() {return src_end;} private int src_end = -1;
public byte Ignore() {return ignore;} private Xop_tkn_chkr_base Ignore_(byte v) {ignore = v; return this;} private byte ignore = Bool_.__byte;
public Xop_tkn_chkr_base Ignore_y_() {return Ignore_(Bool_.Y_byte);}
public Xop_tkn_chkr_base Src_rng_(int bgn, int end) {src_bgn = bgn; src_end = end; return this;}
public String Raw() {return raw;} public Xop_tkn_chkr_base Raw_(String v) {raw = v; return this;} private String raw;
public String Raw_src() {return raw_src;} public Xop_tkn_chkr_base Raw_src_(String v) {raw_src = v; return this;} private String raw_src;
public Xop_tkn_chkr_base[] Subs() {return subs;} public Xop_tkn_chkr_base Subs_(Xop_tkn_chkr_base... v) {subs = v; return this;} private Xop_tkn_chkr_base[] subs = null;
@gplx.Virtual public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
Xop_tkn_itm actl = (Xop_tkn_itm)actl_obj;
int rv = 0;
rv += Chk_basic(mgr, path, actl, rv);
rv += Chk_hook(mgr, path, actl, rv);
rv += Chk_subs(mgr, path, actl, rv);
return rv;
}
@gplx.Virtual public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {return 0;}
int Chk_basic(Tst_mgr mgr, String path, Xop_tkn_itm actl, int err) {
if (typeId == null) typeId = Xop_tkn_itm_.Tid__names[this.Tkn_tid()];
err += mgr.Tst_val(typeId == null, path, "typeId", typeId, Xop_tkn_itm_.Tid__names[actl.Tkn_tid()]);
if (ignore != Bool_.__byte) err += mgr.Tst_val(ignore == Bool_.__byte, path, "ignore", ignore == Bool_.Y_byte, actl.Ignore()); // "ignore !=" to skip comparison unless explicitly toggled
err += mgr.Tst_val(src_bgn == -1, path, "src_bgn", src_bgn, actl.Src_bgn());
err += mgr.Tst_val(src_end == -1, path, "src_end", src_end, actl.Src_end());
if (raw != null) {
String raw_actl = raw_src == null ? mgr.Vars_get_bry_as_str("raw_bry", actl.Src_bgn(), actl.Src_end()) : String_.Mid(raw_src, actl.Src_bgn(), actl.Src_end());
err += mgr.Tst_val(raw == null, path, "raw", raw, raw_actl);
}
return err;
}
int Chk_subs(Tst_mgr mgr, String path, Xop_tkn_itm actl, int err) {
if (subs != null) {
int actl_subs_len = actl.Subs_len();
Xop_tkn_itm[] actl_subs = new Xop_tkn_itm[actl_subs_len];
for (int i = 0; i < actl_subs_len; i++)
actl_subs[i] = actl.Subs_get(i);
return mgr.Tst_sub_ary(subs, actl_subs, path, err);
}
return err;
}
public static final Tst_chkr Null = Tst_mgr.Null_chkr;
public static final Xop_tkn_chkr_base[] Ary_empty = new Xop_tkn_chkr_base[0];
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_tkn_chkr_hr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_hr_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_hr;}
public Xop_tkn_chkr_hr(int bgn, int end) {super.Src_rng_(bgn, end);}
public int Hr_len() {return hr_len;} public Xop_tkn_chkr_hr Hr_len_(int v) {hr_len = v; return this;} private int hr_len = -1;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_hr_tkn actl = (Xop_hr_tkn)actl_obj;
err += mgr.Tst_val(hr_len == -1, path, "hr_len", hr_len, actl.Hr_len());
return err;
}
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.parsers.lnkes.*;
public class Xop_tkn_chkr_lnke extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_lnke_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_lnke;}
public Xop_tkn_chkr_lnke(int bgn, int end) {super.Src_rng_(bgn, end);}
public byte Lnke_typ() {return lnke_typ;} public Xop_tkn_chkr_lnke Lnke_typ_(byte v) {lnke_typ = v; return this;} private byte lnke_typ = Xop_lnke_tkn.Lnke_typ_null;
public Xop_tkn_chkr_lnke Lnke_rng_(int bgn, int end) {lnke_bgn = bgn; lnke_end = end; return this;} private int lnke_bgn = -1; int lnke_end = -1;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_lnke_tkn actl = (Xop_lnke_tkn)actl_obj;
err += mgr.Tst_val(lnke_typ == Xop_lnke_tkn.Lnke_typ_null, path, "lnke_typ", lnke_typ, actl.Lnke_typ());
err += mgr.Tst_val(lnke_bgn == -1, path, "lnke_bgn", lnke_bgn, actl.Lnke_bgn());
err += mgr.Tst_val(lnke_end == -1, path, "lnke_end", lnke_end, actl.Lnke_end());
return err;
}
}

View File

@@ -0,0 +1,109 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_ttl_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "ttl");
public static final Gfo_msg_itm
Len_0 = Gfo_msg_itm_.new_warn_(owner, "Len_0")
, Len_max = Gfo_msg_itm_.new_warn_(owner, "Len_max")
, Ttl_has_ns_but_no_page = Gfo_msg_itm_.new_warn_(owner, "Ttl_has_ns_but_no_page")
, Ttl_is_ns_only = Gfo_msg_itm_.new_warn_(owner, "Ttl_is_ns_only")
, Amp_unknown = Gfo_msg_itm_.new_warn_(owner, "Amp_unknown")
, Comment_eos = Gfo_msg_itm_.new_warn_(owner, "Comment_eos")
, Invalid_char = Gfo_msg_itm_.new_warn_(owner, "Invalid_char")
;
}
class Xop_comment_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "comment");
public static final Gfo_msg_itm
Eos = Gfo_msg_itm_.new_warn_(owner, "eos")
;
}
class Xop_lnki_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "lnki");
public static final Gfo_msg_itm
Upright_val_is_invalid = Gfo_msg_itm_.new_warn_(owner, "upright_val_is_invalid")
, Escaped_lnki = Gfo_msg_itm_.new_warn_(owner, "escaped_lnki")
, Key_is_empty = Gfo_msg_itm_.new_warn_(owner, "key_is_empty")
, Ext_is_missing = Gfo_msg_itm_.new_warn_(owner, "ext_is_missing")
, Invalid_ttl = Gfo_msg_itm_.new_warn_(owner, "invalid_ttl")
;
}
class Xop_tmpl_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tmpl");
public static final Gfo_msg_itm
Escaped_tmpl = Gfo_msg_itm_.new_warn_(owner, "Escaped_tmpl")
, Escaped_end = Gfo_msg_itm_.new_warn_(owner, "Escaped_end")
, Key_is_empty = Gfo_msg_itm_.new_note_(owner, "Key_is_empty")
, Dangling = Gfo_msg_itm_.new_note_(owner, "Dangling_tmpl")
, Tmpl_end_autoCloses_something = Gfo_msg_itm_.new_note_(owner, "Tmpl_end_autoCloses_something")
, Tmpl_is_empty = Gfo_msg_itm_.new_note_(owner, "Tmpl_is_empty")
;
}
class Xop_misc_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "super");
public static final Gfo_msg_itm
Eos = Gfo_msg_itm_.new_warn_(owner, "End_of_string")
;
}
class Xot_prm_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tmpl_defn_arg");
public static final Gfo_msg_itm
Dangling = Gfo_msg_itm_.new_warn_(owner, "Dangling_tmpl_defn_arg")
, Elem_without_tbl = Gfo_msg_itm_.new_warn_(owner, "Elem_without_tbl")
, Lkp_is_nil = Gfo_msg_itm_.new_note_(owner, "Lkp_is_nil")
, Lkp_and_pipe_are_nil = Gfo_msg_itm_.new_warn_(owner, "Lkp_and_pipe_are_nil")
, Prm_has_2_or_more = Gfo_msg_itm_.new_note_(owner, "Prm_has_2_or_more")
;
}
class Xop_curly_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "curly");
public static final Gfo_msg_itm
Bgn_not_found = Gfo_msg_itm_.new_warn_(owner, "Bgn_not_found")
, End_should_not_autoclose_anything = Gfo_msg_itm_.new_warn_(owner, "End_should_not_autoclose_anything")
, Bgn_len_0 = Gfo_msg_itm_.new_warn_(owner, "Bgn_len_0")
, Bgn_len_1 = Gfo_msg_itm_.new_warn_(owner, "Bgn_len_1")
, Tmpl_is_empty = Gfo_msg_itm_.new_warn_(owner, "Tmpl_is_empty")
;
}
class Xop_redirect_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "redirect");
public static final Gfo_msg_itm
False_match = Gfo_msg_itm_.new_warn_(owner, "False_match")
, Lnki_not_found = Gfo_msg_itm_.new_warn_(owner, "Lnki_not_found")
;
}
class Xop_tag_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tag");
public static final Gfo_msg_itm
Invalid = Gfo_msg_itm_.new_warn_(owner, "Invalid")
;
}
// class Pf_func_lang_log {
// private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tmpl_func_lang");
// public static final Gfo_msg_itm
// Arg_out_of_bounds = Gfo_msg_itm_.new_warn_(owner, "Arg_out_of_bounds")
// ;
// }
// class Mwl_expr_log {
// private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "expr");
// public static final Gfo_msg_itm
// Divide_by_zero = Gfo_msg_itm_.new_warn_(owner, "Divide_by_zero")
// , Expr_len0 = Gfo_msg_itm_.new_warn_(owner, "Expr_len0")
// ;
// }

View File

@@ -0,0 +1,36 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xop_xnde_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "xnde");
public static final Gfo_msg_itm
Dangling_xnde = Gfo_msg_itm_.new_warn_(owner, "dangling_xnde")
, End_tag_not_allowed = Gfo_msg_itm_.new_note_(owner, "end_tag_not_allowed")
, Escaped_xnde = Gfo_msg_itm_.new_warn_(owner, "escaped_xnde")
, Invalid_char = Gfo_msg_itm_.new_warn_(owner, "invalid_char")
, Xtn_end_not_found = Gfo_msg_itm_.new_warn_(owner, "xtn_end_not_found")
, Invalid_tbl_sub = Gfo_msg_itm_.new_warn_(owner, "invalid_tbl_sub")
, Invalid_nest = Gfo_msg_itm_.new_warn_(owner, "invalid_nest")
, No_inline = Gfo_msg_itm_.new_warn_(owner, "no_inline")
, Tbl_sub_already_opened = Gfo_msg_itm_.new_warn_(owner, "tbl_sub_already_opened")
, Auto_closing_section = Gfo_msg_itm_.new_warn_(owner, "auto_closing_section")
, Eos_while_closing_tag = Gfo_msg_itm_.new_warn_(owner, "eos_while_closing_tag")
, Sub_sup_swapped = Gfo_msg_itm_.new_warn_(owner, "sub_sup_swapped")
, Restricted_tag = Gfo_msg_itm_.new_warn_(owner, "restricted_tag")
;
}

View File

@@ -0,0 +1,124 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
import gplx.xowa.files.*; import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.paras.*;
public class Xop_xnde_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_xnde_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_xnde;}
public String Xnde_tagId() {return xnde_tagId;}
public Xop_xnde_tkn_chkr Xnde_tagId_(int v) {xnde_tagId = Xop_xnde_tag_.Ary[v].Name_str(); return this;} private String xnde_tagId = null;
public Tst_chkr Xnde_xtn() {return xnde_data;} public Xop_xnde_tkn_chkr Xnde_xtn_(Tst_chkr v) {xnde_data = v; return this;} Tst_chkr xnde_data = null;
public byte CloseMode() {return closeMode;} public Xop_xnde_tkn_chkr CloseMode_(byte v) {closeMode = v; return this;} private byte closeMode = Xop_xnde_tkn.CloseMode_null;
public Xop_xnde_tkn_chkr Name_rng_(int bgn, int end) {name_bgn = bgn; name_end = end; return this;} private int name_bgn = String_.Pos_neg1; int name_end = String_.Pos_neg1;
public Xop_xnde_tkn_chkr Atrs_rng_(int bgn, int end) {atrs_bgn = bgn; atrs_end = end; return this;} private int atrs_bgn = String_.Pos_neg1; int atrs_end = String_.Pos_neg1;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_xnde_tkn actl = (Xop_xnde_tkn)actl_obj;
err += mgr.Tst_val(xnde_tagId == null, path, "xnde_tagId", xnde_tagId, Xop_xnde_tag_.Ary[actl.Tag().Id()].Name_str());
err += mgr.Tst_val(closeMode == Xop_xnde_tkn.CloseMode_null, path, "close_mode", closeMode, actl.CloseMode());
err += mgr.Tst_val(name_bgn == String_.Pos_neg1, path, "name_bgn", name_bgn, actl.Name_bgn());
err += mgr.Tst_val(name_end == String_.Pos_neg1, path, "name_end", name_end, actl.Name_end());
err += mgr.Tst_val(atrs_bgn == String_.Pos_neg1, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == String_.Pos_neg1, path, "atrs_end", atrs_end, actl.Atrs_end());
if (xnde_data != null)
err += mgr.Tst_sub_obj(xnde_data, actl.Xnde_xtn(), path + "." + "xndeData", err);
return err;
}
}
class Xop_para_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_para_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_para;}
public byte Para_end() {return para_end;} public Xop_para_tkn_chkr Para_end_(byte v) {para_end = v; return this;} private byte para_end = Byte_.Max_value_127;
public byte Para_bgn() {return para_bgn;} public Xop_para_tkn_chkr Para_bgn_(byte v) {para_bgn = v; return this;} private byte para_bgn = Byte_.Max_value_127;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_para_tkn actl = (Xop_para_tkn)actl_obj;
err += mgr.Tst_val(para_end == Byte_.Max_value_127, path, "para_end", para_end, actl.Para_end());
err += mgr.Tst_val(para_bgn == Byte_.Max_value_127, path, "para_bgn", para_bgn, actl.Para_bgn());
return err;
}
}
class Xop_nl_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_nl_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_newLine;}
public byte Nl_tid() {return nl_typeId;} public Xop_nl_tkn_chkr Nl_tid_(byte v) {nl_typeId = v; return this;} private byte nl_typeId = Xop_nl_tkn.Tid_unknown;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_nl_tkn actl = (Xop_nl_tkn)actl_obj;
err += mgr.Tst_val(nl_typeId == Xop_nl_tkn.Tid_unknown, path, "nl_typeId", nl_typeId, actl.Nl_tid());
return err;
}
}
class Xop_html_txt_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_amp_tkn_txt.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_html_ref;}
public String Html_ref_key() {return html_ref_key;} public Xop_html_txt_tkn_chkr Html_ref_key_(String v) {html_ref_key = v; return this;} private String html_ref_key;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_amp_tkn_txt actl = (Xop_amp_tkn_txt)actl_obj;
err += mgr.Tst_val(html_ref_key == null, path, "html_ref_key", html_ref_key, String_.new_u8(actl.Xml_name_bry()));
return err;
}
}
class Xop_html_num_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_amp_tkn_num.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_html_ncr;}
public int Html_ncr_val() {return html_ncr_val;} public Xop_html_num_tkn_chkr Html_ncr_val_(int v) {html_ncr_val = v; return this;} private int html_ncr_val = -1;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_amp_tkn_num actl = (Xop_amp_tkn_num)actl_obj;
err += mgr.Tst_val(html_ncr_val == -1, path, "html_ncr_val", html_ncr_val, actl.Val());
return err;
}
}
class Xop_ignore_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_ignore_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_ignore;}
public byte Ignore_type() {return ignore_type;} public Xop_ignore_tkn_chkr Ignore_tid_(byte v) {ignore_type = v; return this;} private byte ignore_type = Xop_ignore_tkn.Ignore_tid_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_ignore_tkn actl = (Xop_ignore_tkn)actl_obj;
err += mgr.Tst_val(ignore_type == Xop_ignore_tkn.Ignore_tid_null, path, "ignore_type", ignore_type, actl.Ignore_type());
return err;
}
}
class Xop_arg_nde_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Arg_nde_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_arg_nde;}
public Xop_tkn_chkr_base Key_tkn() {return key_tkn;} public Xop_arg_nde_tkn_chkr Key_tkn_(Xop_tkn_chkr_base v) {key_tkn = v; return this;} private Xop_tkn_chkr_base key_tkn;
public Xop_tkn_chkr_base Val_tkn() {return val_tkn;} public Xop_arg_nde_tkn_chkr Val_tkn_(Xop_tkn_chkr_base v) {val_tkn = v; return this;} private Xop_tkn_chkr_base val_tkn;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Arg_nde_tkn actl = (Arg_nde_tkn)actl_obj;
if (key_tkn != null) err += mgr.Tst_sub_obj(key_tkn, actl.Key_tkn(), path + "." + "key", err);
if (val_tkn != null) err += mgr.Tst_sub_obj(val_tkn, actl.Val_tkn(), path + "." + "val", err);
return err;
}
}
class Xot_invk_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xot_invk_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tmpl_invk;}
public Xop_tkn_chkr_base Name_tkn() {return name_tkn;} public Xot_invk_tkn_chkr Name_tkn_(Xop_tkn_chkr_base v) {name_tkn = v; return this;} private Xop_tkn_chkr_base name_tkn;
public Xop_tkn_chkr_base[] Args() {return args;} public Xot_invk_tkn_chkr Args_(Xop_tkn_chkr_base... v) {args = v; return this;} private Xop_tkn_chkr_base[] args = Xop_tkn_chkr_base.Ary_empty;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xot_invk_tkn actl = (Xot_invk_tkn)actl_obj;
if (name_tkn != null) err += mgr.Tst_sub_obj(name_tkn, actl.Name_tkn(), path + "." + "name", err);
err += mgr.Tst_sub_ary(args, Args_xtoAry(actl), path + "." + "args", err);
return err;
}
Arg_nde_tkn[] Args_xtoAry(Xot_invk_tkn tkn) {
int args_len = tkn.Args_len();
Arg_nde_tkn[] rv = new Arg_nde_tkn[args_len];
for (int i = 0; i < args_len; i++)
rv[i] = tkn.Args_get_by_idx(i);
return rv;
}
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa; import gplx.*;
public class Xot_prm_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xot_prm_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tmpl_prm;}
public Xop_tkn_chkr_base Find_tkn() {return find_tkn;} public Xot_prm_chkr Find_tkn_(Xop_arg_itm_tkn_chkr v) {find_tkn = v; return this;} private Xop_arg_itm_tkn_chkr find_tkn;
public Xop_tkn_chkr_base[] Args() {return args;} public Xot_prm_chkr Args_(Xop_tkn_chkr_base... v) {args = v; return this;} private Xop_tkn_chkr_base[] args = Xop_tkn_chkr_base.Ary_empty;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xot_prm_tkn actl = (Xot_prm_tkn)actl_obj;
if (find_tkn != null) err += mgr.Tst_sub_obj(find_tkn, actl.Find_tkn(), path + "." + "find", err);
return err;
}
}