mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v1.7.4.1
This commit is contained in:
@@ -65,14 +65,17 @@ class Arg_bldr {
|
||||
else if (wkr_typ == Xop_arg_wkr_.Typ_prm) {} // always ignore for prm
|
||||
else {
|
||||
if ( cur_nde_idx != 0 // if 1st arg, treat equal_tkn as txt_tkn; i.e.: eq should not be used to separate key/val
|
||||
&& cur_nde.Eq_tkn() == Xop_tkn_null.Null_tkn // only mark key if not set; handle multiple-keys; EX: {{name|key1=b=c}}; DATE:2014-02-09
|
||||
&& cur_nde.Eq_tkn() == Xop_tkn_null.Null_tkn // only mark key if key is not set; handle multiple-keys; EX: {{name|key1=b=c}}; DATE:2014-02-09
|
||||
) {
|
||||
Xop_eq_tkn sub_as_eq = (Xop_eq_tkn)sub;
|
||||
if (sub_as_eq.Eq_len() == 1) { // only treat as kv eq if len == 1; MW.REF:Preprocessor_DOM.php|preprocessToXml; "if ( $count == 1 && $findEquals )" PAGE:en.w:Wikipedia:Picture_of_the_day/June_2014; DATE:2014-07-21
|
||||
cur_nde.Eq_tkn_(sub);
|
||||
key_exists = true;
|
||||
Arg_itm_end(ctx, cur_nde, cur_itm, ws_bgn_idx, ws_end_idx, cur_itm_subs_len, sub_pos_bgn, wkr_typ, key_exists, true, itm_is_static, src, cur_nde_idx);
|
||||
cur_nde.Key_tkn_(cur_itm);
|
||||
cur_itm = null;
|
||||
continue; // do not add tkn to cur_itm
|
||||
}
|
||||
}
|
||||
if (ws_bgn_chk) ws_bgn_chk = false; else ws_end_idx = -1; // INLINE: AdjustWsForTxtTkn
|
||||
break;
|
||||
|
||||
@@ -32,12 +32,3 @@ class Xot_defn_null implements Xot_defn {
|
||||
public void Rls() {}
|
||||
public static final Xot_defn_null _ = new Xot_defn_null(); Xot_defn_null() {}
|
||||
}
|
||||
class Xot_defn_subst implements Xot_defn {
|
||||
public Xot_defn_subst(byte tid, byte[] name) {this.tid = tid; this.name = name;}
|
||||
public byte Defn_tid() {return tid;} private byte tid;
|
||||
public byte[] Name() {return name;} private byte[] name;
|
||||
public Xot_defn Clone(int id, byte[] name) {return new Xot_defn_subst(tid, name);}
|
||||
public boolean Defn_require_colon_arg() {return true;}
|
||||
public void Rls() {name = null;}
|
||||
public int Cache_size() {return 1024;} // arbitrary size
|
||||
}
|
||||
|
||||
27
400_xowa/src_500_tmpl/gplx/xowa/Xot_defn_subst.java
Normal file
27
400_xowa/src_500_tmpl/gplx/xowa/Xot_defn_subst.java
Normal 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 Xot_defn_subst implements Xot_defn {
|
||||
public Xot_defn_subst(byte tid, byte[] name) {this.tid = tid; this.name = name;}
|
||||
public byte Defn_tid() {return tid;} private byte tid;
|
||||
public byte[] Name() {return name;} private byte[] name;
|
||||
public Xot_defn Clone(int id, byte[] name) {return new Xot_defn_subst(tid, name);}
|
||||
public boolean Defn_require_colon_arg() {return true;}
|
||||
public void Rls() {name = null;}
|
||||
public int Cache_size() {return 1024;} // arbitrary size
|
||||
}
|
||||
@@ -33,8 +33,10 @@ public class Xot_defn_tmpl_ {
|
||||
if (orig_arg.KeyTkn_exists()) {
|
||||
Arg_itm_tkn key_tkn = orig_arg.Key_tkn();
|
||||
copy_arg.Key_tkn_(Make_itm(false, ctx, tkn_mkr, src, key_tkn, caller, orig_arg));
|
||||
rv.Args_addByKey(copy_arg.Key_tkn().Dat_ary(), copy_arg); // NOTE: was originally Bry_.Mid(caller.Src(), key_tkn.Dat_bgn(), key_tkn.Dat_end()) which was wrong; caused {{{increment}}} instead of "increment"
|
||||
rv.Args_add_by_key(copy_arg.Key_tkn().Dat_ary(), copy_arg); // NOTE: was originally Bry_.Mid(caller.Src(), key_tkn.Dat_bgn(), key_tkn.Dat_end()) which was wrong; caused {{{increment}}} instead of "increment"
|
||||
}
|
||||
else
|
||||
rv.Args_add_by_idx(copy_arg); // NOTE: not a key, so add to idx_hash; DATE:2014-07-23
|
||||
copy_arg.Val_tkn_(Make_itm(true, ctx, tkn_mkr, src, orig_arg.Val_tkn(), caller, orig_arg));
|
||||
rv.Args_add(copy_arg);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ 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.xtns.pfuncs.*;
|
||||
public class Xot_defn_trace_dbg implements Xot_defn_trace {
|
||||
public void Trace_bgn(Xop_ctx ctx, byte[] src, byte[] name, Xot_invk caller, Xot_invk invk, Xot_defn defn) {
|
||||
if (count++ != 0) bfr.Add_byte_nl(); // do not add new line for 1st template
|
||||
|
||||
@@ -18,9 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa; import gplx.*;
|
||||
public interface Xot_invk {
|
||||
byte Defn_tid();
|
||||
boolean Root_frame();
|
||||
int Src_bgn();
|
||||
int Src_end();
|
||||
boolean Frame_is_root();
|
||||
byte Frame_tid(); void Frame_tid_(byte v);
|
||||
byte[] Frame_ttl(); void Frame_ttl_(byte[] v);
|
||||
int Frame_lifetime(); void Frame_lifetime_(int v);
|
||||
boolean Rslt_is_redirect(); void Rslt_is_redirect_(boolean v);
|
||||
@@ -29,5 +30,4 @@ public interface Xot_invk {
|
||||
Arg_nde_tkn Args_get_by_idx(int i);
|
||||
Arg_nde_tkn Args_eval_by_idx(byte[] src, int idx);
|
||||
Arg_nde_tkn Args_get_by_key(byte[] src, byte[] key);
|
||||
byte Scrib_frame_tid(); void Scrib_frame_tid_(byte v);
|
||||
}
|
||||
|
||||
@@ -19,15 +19,15 @@ package gplx.xowa; import gplx.*;
|
||||
import gplx.xowa.xtns.scribunto.*;
|
||||
public class Xot_invk_mock implements Xot_invk {
|
||||
public Xot_invk_mock(byte defn_tid, int idx_adj) {this.defn_tid = defn_tid; this.idx_adj = idx_adj;} private int idx_adj; // SEE NOTE_1:
|
||||
public boolean Root_frame() {return false;}
|
||||
public int Src_bgn() {return -1;}
|
||||
public int Src_end() {return -1;}
|
||||
public byte Defn_tid() {return defn_tid;} private byte defn_tid = Xot_defn_.Tid_null;
|
||||
public Arg_nde_tkn Name_tkn() {return Arg_nde_tkn.Null;}
|
||||
public boolean Frame_is_root() {return false;}
|
||||
public byte Frame_tid() {return scrib_tid;} public void Frame_tid_(byte v) {scrib_tid = v;} private byte scrib_tid;
|
||||
public byte[] Frame_ttl() {return frame_ttl;} public void Frame_ttl_(byte[] v) {frame_ttl = v;} private byte[] frame_ttl;
|
||||
public int Frame_lifetime() {return frame_lifetime;} public void Frame_lifetime_(int v) {frame_lifetime = v;} private int frame_lifetime;
|
||||
public byte Scrib_frame_tid() {return scrib_tid;} public void Scrib_frame_tid_(byte v) {scrib_tid = v;} private byte scrib_tid;
|
||||
public boolean Rslt_is_redirect() {return rslt_is_redirect;} public void Rslt_is_redirect_(boolean v) {rslt_is_redirect = v;} private boolean rslt_is_redirect;
|
||||
public Arg_nde_tkn Name_tkn() {return Arg_nde_tkn.Null;}
|
||||
public int Args_len() {return args.Count() + idx_adj;} private OrderedHash args = OrderedHash_.new_bry_();
|
||||
public Arg_nde_tkn Args_get_by_idx(int i) {return (Arg_nde_tkn)args.FetchAt(i - idx_adj);}
|
||||
public Arg_nde_tkn Args_eval_by_idx(byte[] src, int idx) {// DUPE:MW_ARG_RETRIEVE
|
||||
|
||||
@@ -18,6 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa; import gplx.*;
|
||||
import gplx.xowa.xtns.scribunto.*;
|
||||
public class Xot_invk_temp implements Xot_invk {
|
||||
private ListAdp list = ListAdp_.new_();
|
||||
private Hash_adp_bry arg_key_hash;
|
||||
private HashAdp arg_idx_hash; private Int_obj_ref arg_idx_ref;
|
||||
Xot_invk_temp() {}
|
||||
public Xot_invk_temp(boolean root_frame) {this.root_frame = root_frame;}
|
||||
public Xot_invk_temp(byte defn_tid, byte[] src, Arg_nde_tkn name_tkn, int src_bgn, int src_end) {
|
||||
this.defn_tid = defn_tid; this.src = src;
|
||||
@@ -25,49 +29,41 @@ public class Xot_invk_temp implements Xot_invk {
|
||||
}
|
||||
public byte[] Src() {return src;} private byte[] src; public Xot_invk_temp Src_(byte[] src) {this.src = src; return this;}
|
||||
public byte Defn_tid() {return defn_tid;} private byte defn_tid = Xot_defn_.Tid_null;
|
||||
public boolean Root_frame() {return root_frame;} private boolean root_frame;
|
||||
public Arg_nde_tkn Name_tkn() {return name_tkn;} Arg_nde_tkn name_tkn;
|
||||
public boolean Frame_is_root() {return root_frame;} private boolean root_frame;
|
||||
public byte Frame_tid() {return scrib_tid;} public void Frame_tid_(byte v) {scrib_tid = v;} private byte scrib_tid;
|
||||
public byte[] Frame_ttl() {return frame_ttl;} public void Frame_ttl_(byte[] v) {frame_ttl = v;} private byte[] frame_ttl = Bry_.Empty; // NOTE: set frame_ttl to non-null value; PAGE:en.w:Constantine_the_Great {{Christianity}}; DATE:2014-06-26
|
||||
public int Frame_lifetime() {return frame_lifetime;} public void Frame_lifetime_(int v) {frame_lifetime = v;} private int frame_lifetime;
|
||||
public boolean Rslt_is_redirect() {return rslt_is_redirect;} public void Rslt_is_redirect_(boolean v) {rslt_is_redirect = v;} private boolean rslt_is_redirect;
|
||||
public int Src_bgn() {return src_bgn;} private int src_bgn;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public byte Scrib_frame_tid() {return scrib_tid;} public void Scrib_frame_tid_(byte v) {scrib_tid = v;} private byte scrib_tid;
|
||||
public Arg_nde_tkn Name_tkn() {return name_tkn;} private Arg_nde_tkn name_tkn;
|
||||
public int Args_len() {return list.Count();}
|
||||
public Arg_nde_tkn Args_eval_by_idx(byte[] src, int idx) { // NOTE: idx is base0
|
||||
int cur = 0, list_len = list.Count();
|
||||
for (int i = 0; i < list_len; i++) { // iterate over list to find nth *non-keyd* arg; SEE:NOTE_1
|
||||
Arg_nde_tkn nde = (Arg_nde_tkn)list.FetchAt(i);
|
||||
if (nde.KeyTkn_exists()) {
|
||||
int key_int = Bry_.Xto_int_or(nde.Key_tkn().Dat_ary(), -1);
|
||||
if (key_int == -1)
|
||||
continue;
|
||||
else { // key is numeric
|
||||
if (key_int - 1 == idx) {
|
||||
return nde;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur++ == idx) return nde;
|
||||
}
|
||||
return Args_get_by_key(src, Bry_.XtoStrBytesByInt(idx + 1, 1));
|
||||
public Arg_nde_tkn Args_eval_by_idx(byte[] src, int idx) { // NOTE: idx is base0
|
||||
return arg_idx_hash == null // only true if no args, or all args are keys; EX: {{A|b=1|c=2}}
|
||||
? null
|
||||
: (Arg_nde_tkn)arg_idx_hash.Fetch(arg_idx_ref.Val_(idx)); // lookup int in hash; needed b/c multiple identical keys should retrieve last, not first; EX: {{A|1=a|1=b}}; PAGE:el.d:ἔχω DATE:2014-07-23
|
||||
}
|
||||
public Arg_nde_tkn Args_get_by_idx(int i) {return (Arg_nde_tkn)list.FetchAt(i);}
|
||||
public Arg_nde_tkn Args_get_by_key(byte[] src, byte[] key) {
|
||||
Object o = hash.Fetch(byteAryRef.Val_(key));
|
||||
return o == null ? null : (Arg_nde_tkn)o;
|
||||
} private Bry_obj_ref byteAryRef = Bry_obj_ref.null_();
|
||||
public void Args_add(Arg_nde_tkn arg) {list.Add(arg);} ListAdp list = ListAdp_.new_();
|
||||
public void Args_addByKey(byte[] key, Arg_nde_tkn arg) {
|
||||
Bry_obj_ref key_ref = Bry_obj_ref.new_(key);
|
||||
hash.Del(key_ref);
|
||||
hash.Add(key_ref, arg);
|
||||
} HashAdp hash = HashAdp_.new_();
|
||||
return arg_key_hash == null ? null : (Arg_nde_tkn)arg_key_hash.Get_by_bry(key);
|
||||
}
|
||||
public void Args_add(Arg_nde_tkn arg) {list.Add(arg);}
|
||||
public void Args_add_by_key(byte[] key, Arg_nde_tkn arg) {
|
||||
if (arg_key_hash == null) arg_key_hash = Hash_adp_bry.cs_(); // PERF: lazy
|
||||
arg_key_hash.AddReplace(key, arg);
|
||||
int key_as_int = Bry_.Xto_int_or(key, Int_.MinValue);
|
||||
if (key_as_int != Int_.MinValue) // key is int; add it to arg_idx_hash; EX:{{A|1=a}} vs {{A|a}}; DATE:2014-07-23
|
||||
Arg_idx_hash_add(key_as_int - ListAdp_.Base1, arg);
|
||||
}
|
||||
public void Args_add_by_idx(Arg_nde_tkn arg) {Arg_idx_hash_add(++args_add_by_idx, arg);} private int args_add_by_idx = -1; // NOTE: args_add_by_idx needs to be a separate variable; keeps track of args which don't have a key;
|
||||
private void Arg_idx_hash_add(int int_key, Arg_nde_tkn arg) {
|
||||
if (arg_idx_hash == null) {
|
||||
arg_idx_hash = HashAdp_.new_();
|
||||
arg_idx_ref = Int_obj_ref.neg1_();
|
||||
}
|
||||
arg_idx_hash.AddReplace(Int_obj_ref.new_(int_key), arg); // AddReplace to keep latest version; needed for {{A|1=a|1=b}} DATE:2014-07-23
|
||||
}
|
||||
public static final Xot_invk_temp Page_is_caller = new Xot_invk_temp(true); // SEE NOTE_2
|
||||
Xot_invk_temp() {}
|
||||
}
|
||||
/*
|
||||
NOTE_1:
|
||||
|
||||
@@ -18,18 +18,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa; import gplx.*;
|
||||
import gplx.xowa.langs.*;
|
||||
import gplx.xowa.langs.vnts.*; import gplx.xowa.langs.cnvs.*;
|
||||
import gplx.xowa.wikis.caches.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.pfuncs.ttls.*;
|
||||
import gplx.xowa.wikis.caches.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.pfuncs.*; import gplx.xowa.xtns.pfuncs.ttls.*;
|
||||
public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
|
||||
public boolean Root_frame() {return false;}
|
||||
public Arg_nde_tkn Name_tkn() {return name_tkn;} public Xot_invk_tkn Name_tkn_(Arg_nde_tkn v) {name_tkn = v; return this;} Arg_nde_tkn name_tkn = Arg_nde_tkn.Null;
|
||||
public byte Defn_tid() {return defn_tid;} private byte defn_tid = Xot_defn_.Tid_null;
|
||||
public int Tmpl_subst_bgn() {return tmpl_subst_bgn;} private int tmpl_subst_bgn;
|
||||
public int Tmpl_subst_end() {return tmpl_subst_end;} private int tmpl_subst_end;
|
||||
public Xot_invk_tkn Tmpl_subst_props_(byte tid, int bgn, int end) {defn_tid = tid; tmpl_subst_bgn = bgn; tmpl_subst_end = end; return this;}
|
||||
public Xot_defn Tmpl_defn() {return tmpl_defn;} public Xot_invk_tkn Tmpl_defn_(Xot_defn v) {tmpl_defn = v; return this;} private Xot_defn tmpl_defn = Xot_defn_.Null;
|
||||
public boolean Frame_is_root() {return false;}
|
||||
public byte Frame_tid() {return scrib_tid;} public void Frame_tid_(byte v) {scrib_tid = v;} private byte scrib_tid;
|
||||
public byte[] Frame_ttl() {return frame_ttl;} public void Frame_ttl_(byte[] v) {frame_ttl = v;} private byte[] frame_ttl;
|
||||
public int Frame_lifetime() {return frame_lifetime;} public void Frame_lifetime_(int v) {frame_lifetime = v;} private int frame_lifetime;
|
||||
public byte Scrib_frame_tid() {return scrib_tid;} public void Scrib_frame_tid_(byte v) {scrib_tid = v;} private byte scrib_tid;
|
||||
public boolean Rslt_is_redirect() {return rslt_is_redirect;} public void Rslt_is_redirect_(boolean v) {rslt_is_redirect = v;} private boolean rslt_is_redirect;
|
||||
@Override public void Tmpl_fmt(Xop_ctx ctx, byte[] src, Xot_fmtr fmtr) {fmtr.Reg_tmpl(ctx, src, name_tkn, args_len, args);}
|
||||
@Override public void Tmpl_compile(Xop_ctx ctx, byte[] src, Xot_compile_data prep_data) {
|
||||
|
||||
@@ -46,7 +46,7 @@ public class Xot_invk_wkr implements Xop_ctx_wkr, Xop_arg_wkr {
|
||||
}
|
||||
public boolean Args_add(Xop_ctx ctx, byte[] src, Xop_tkn_itm tkn, Arg_nde_tkn nde, int nde_idx) {
|
||||
Xot_invk_tkn invk = (Xot_invk_tkn)tkn;
|
||||
if (nde_idx == 0)
|
||||
if (nde_idx == 0) // 1st arg; name_tkn
|
||||
AddNameArg(ctx, src, invk, nde);
|
||||
else
|
||||
invk.Args_add(ctx, nde);
|
||||
|
||||
@@ -418,6 +418,13 @@ public class Xot_invk_wkr_basic_tst {
|
||||
fxt.Test_parse_tmpl_str("{{cASE_MATCH}}", "found"); // Xot_invk_tkn will do 2 searches: "tEST" and "TEST"
|
||||
fxt.Init_defn_clear();
|
||||
}
|
||||
@Test public void Kv_same() { // PURPOSE: multiple identical keys should retrieve last, not first; EX: {{A|1=a|1=b}}; PAGE:el.d:ἔχω DATE:2014-07-23
|
||||
fxt.Init_defn_clear();
|
||||
fxt.Init_defn_add("tmpl_1", "{{{1}}}");
|
||||
fxt.Test_parse_tmpl_str_test("{{tmpl_1|1=a|1=b}}" , "{{test}}" , "b"); // duplicate "1"; use last
|
||||
fxt.Test_parse_tmpl_str_test("{{tmpl_1|a|1=b}}" , "{{test}}" , "b"); // "a" has implicit key of "1"; overwritten by "1=b"; verified against MW
|
||||
fxt.Test_parse_tmpl_str_test("{{tmpl_1|1=a|b}}" , "{{test}}" , "b"); // "b" has implicit key of "1"; overwritten by "1=b"; verified against MW
|
||||
}
|
||||
}
|
||||
/*
|
||||
NOTE_1: function should expand "*a" to "\n*a" even if "*a" is bos
|
||||
|
||||
Reference in New Issue
Block a user