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
2014-07-13 23:23:30 -04:00
parent ecbe2918d8
commit bc10cd76b6
316 changed files with 3251 additions and 1652 deletions

View File

@@ -16,18 +16,19 @@ 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_curly_bgn_tkn extends Xop_tkn_itm_base {
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tmpl_curly_bgn;}
public Xop_curly_bgn_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
}
class Xop_curly_bgn_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_curly_bgn;}
public void Init_by_wiki(Xow_wiki wiki, ByteTrieMgr_fast core_trie) {core_trie.Add(Hook, this);} public static final byte[] Hook = new byte[] {Byte_ascii.Curly_bgn, Byte_ascii.Curly_bgn};
public void Init_by_lang(Xol_lang lang, ByteTrieMgr_fast core_trie) {}
public void Init_by_wiki(Xow_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Hook, this);} public static final byte[] Hook = new byte[] {Byte_ascii.Curly_bgn, Byte_ascii.Curly_bgn};
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) {return ctx.Curly().MakeTkn_bgn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);}
public static final Xop_curly_bgn_lxr _ = new Xop_curly_bgn_lxr(); Xop_curly_bgn_lxr() {}
public static ByteTrieMgr_fast tmpl_bgn_trie_() { // hook sequences for adding new_line to tmpl return; "{|" "|-" ":" ";" "#" "*"; EX: "{{a}}" returns "*"; convert to "\n*"
ByteTrieMgr_fast rv = ByteTrieMgr_fast.cs_();
public static Btrie_fast_mgr tmpl_bgn_trie_() { // hook sequences for adding new_line to tmpl return; "{|" "|-" ":" ";" "#" "*"; EX: "{{a}}" returns "*"; convert to "\n*"
Btrie_fast_mgr rv = Btrie_fast_mgr.cs_();
rv.Add(Xop_tblw_lxr_ws.Hook_tb, Bry_.Empty);
rv.Add(Bry_.new_ascii_("|-"), Bry_.Empty);
rv.Add(Byte_ascii.Colon, Bry_.Empty);
@@ -39,15 +40,15 @@ class Xop_curly_bgn_lxr implements Xop_lxr {
}
class Xop_curly_end_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_curly_end;}
public void Init_by_wiki(Xow_wiki wiki, ByteTrieMgr_fast core_trie) {core_trie.Add(Hook, this);} public static final byte[] Hook = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Curly_end};
public void Init_by_lang(Xol_lang lang, ByteTrieMgr_fast core_trie) {}
public void Init_by_wiki(Xow_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Hook, this);} public static final byte[] Hook = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Curly_end};
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) {return ctx.Curly().MakeTkn_end(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);}
public static final Xop_curly_end_lxr _ = new Xop_curly_end_lxr(); Xop_curly_end_lxr() {}
}
class Xop_brack_bgn_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_brack_bgn;}
public void Init_by_wiki(Xow_wiki wiki, ByteTrieMgr_fast core_trie) {core_trie.Add(Xop_tkn_.Lnki_bgn, this);}
public void Init_by_lang(Xol_lang lang, ByteTrieMgr_fast core_trie) {}
public void Init_by_wiki(Xow_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_bgn, 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_tkn_itm tkn = tkn_mkr.Brack_bgn(bgn_pos, cur_pos);
ctx.Subs_add_and_stack(root, tkn);
@@ -57,8 +58,8 @@ class Xop_brack_bgn_lxr implements Xop_lxr {
}
class Xop_brack_end_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_brack_end;}
public void Init_by_wiki(Xow_wiki wiki, ByteTrieMgr_fast core_trie) {core_trie.Add(Xop_tkn_.Lnki_end, this);}
public void Init_by_lang(Xol_lang lang, ByteTrieMgr_fast core_trie) {}
public void Init_by_wiki(Xow_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_end, 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) {
int acs_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_brack_bgn);
if (acs_pos != -1 && ctx.Cur_tkn_tid() != Xop_tkn_itm_.Tid_tmpl_curly_bgn) // NOTE: do not pop tkn if inside tmpl; EX: [[a|{{#switch:{{{1}}}|b=c]]|d=e]]|f]]}}

View File

@@ -18,7 +18,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa; import gplx.*;
public class Xot_defn_ {
public static final Xot_defn Null = Xot_defn_null._;
public static final byte Tid_null = 0, Tid_func = 1, Tid_tmpl = 2, Tid_subst = Xol_kwd_grp_.Id_subst, Tid_safesubst = Xol_kwd_grp_.Id_safesubst, Tid_raw = Xol_kwd_grp_.Id_raw;
public static final byte
Tid_null = 0
, Tid_func = 1
, Tid_tmpl = 2
, Tid_subst = Xol_kwd_grp_.Id_subst
, Tid_safesubst = Xol_kwd_grp_.Id_safesubst
, Tid_raw = Xol_kwd_grp_.Id_raw
, Tid_msg = Xol_kwd_grp_.Id_msg
, Tid_msgnw = Xol_kwd_grp_.Id_msgnw
;
public static boolean Tid_is_subst(byte v) {
switch (v) {
case Tid_subst: case Tid_safesubst: return true;

View File

@@ -22,6 +22,8 @@ public interface Xot_invk {
int Src_bgn();
int Src_end();
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);
int Args_len();
Arg_nde_tkn Name_tkn();
Arg_nde_tkn Args_get_by_idx(int i);

View File

@@ -25,8 +25,10 @@ public class Xot_invk_mock implements Xot_invk {
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 byte[] Frame_ttl() {return frame_ttl;} public void Frame_ttl_(byte[] v) {frame_ttl = v;} private byte[] frame_ttl;
public int Args_len() {return args.Count() + idx_adj;} private OrderedHash args = OrderedHash_.new_bry_();
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 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
int cur = 0, list_len = args.Count();

View File

@@ -27,6 +27,8 @@ public class Xot_invk_temp implements Xot_invk {
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 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;

View File

@@ -25,10 +25,12 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
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 type, int bgn, int end) {defn_tid = type; tmpl_subst_bgn = bgn; tmpl_subst_end = end; return this;}
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 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) {
name_tkn.Tmpl_compile(ctx, src, prep_data);
@@ -43,7 +45,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
val.Subs_get(j).Tmpl_compile(ctx, src, prep_data);
}
}
@Override public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) { // EX: this="{{t|{{{0}}}}}" caller="{{t|1}}"
@Override public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) { // this="{{t|{{{0}}}}}" caller="{{t|1}}"
boolean rv = false;
Xot_defn defn = tmpl_defn; Xow_wiki wiki = ctx.Wiki(); Xol_lang lang = wiki.Lang();
byte[] name_ary = defn.Name(), argx_ary = Bry_.Empty; Arg_itm_tkn name_key_tkn = name_tkn.Key_tkn();
@@ -64,7 +66,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
name_ary_len = name_ary.length;
name_bgn = Bry_finder.Find_fwd_while_not_ws(name_ary, 0, name_ary_len);
if ( name_ary_len == 0 // name is blank; can occur with failed inner tmpl; EX: {{ {{does not exist}} }}
|| name_bgn == name_ary_len // name is ws; EX: {{test| }} -> {{{{{1}}}}}is whitespace String; EX.WIKT: wear one's heart on one's sleeve; {{t+|fr|avoir le c<>ur sur la main| }}
|| name_bgn == name_ary_len // name is ws; EX: {{test| }} -> {{{{{1}}}}}is whitespace String; PAGE:en.d:wear_one's_heart_on_one's_sleeve; EX:{{t+|fr|avoir le c<>ur sur la main| }}
) {
bfr.Add(Ary_unknown_bgn).Add(Ary_dynamic_is_blank).Add(Ary_unknown_end); // FUTURE: excerpt actual String; WHEN: add raw to defn
return false;
@@ -90,9 +92,9 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
}
Object ns_eval = wiki.Ns_mgr().Names_get_w_colon(name_ary, 0, name_ary_len); // match {{:Portal or {{:Wikipedia
if (ns_eval != null && !template_prefix_found) { // do not transclude ns if Template prefix seen earlier; EX: {{Template:Wikipedia:A}} should not transclude "Wikipedia:A"; DATE:2013-04-03
if (ns_eval != null && !template_prefix_found) // do not transclude ns if Template prefix seen earlier; EX: {{Template:Wikipedia:A}} should not transclude "Wikipedia:A"; DATE:2013-04-03
return SubEval(ctx, wiki, bfr, name_ary, caller, src);
}
Xol_func_name_itm finder = lang.Func_regy().Find_defn(name_ary, name_bgn, name_ary_len);
defn = finder.Func();
int colon_pos = -1;
@@ -137,12 +139,12 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
}
break;
case Xot_defn_.Tid_raw:
case Xot_defn_.Tid_msg:
int raw_colon_pos = Bry_finder.Find_fwd(name_ary, Byte_ascii.Colon);
if (raw_colon_pos == Bry_.NotFound) {} // colon missing; EX: {{raw}}; noop and assume template name; DATE:2014-02-11
else { // colon present;
name_ary = Bry_.Mid(name_ary, finder.Subst_end() + 1, name_ary_len); // chop off "raw"; +1 is for ":"; note that +1 is in bounds b/c raw_colon was found
if (raw_colon_pos == Bry_.NotFound) {} // colon missing; EX: {{raw}}; noop and assume template name; DATE:2014-02-11
else { // colon present;
name_ary = Bry_.Mid(name_ary, finder.Subst_end() + 1, name_ary_len); // chop off "raw"; +1 is for ":"; note that +1 is in bounds b/c raw_colon was found
name_ary_len = name_ary.length;
Object ns_eval2 = wiki.Ns_mgr().Names_get_w_colon(name_ary, 0, name_ary_len); // match {{:Portal or {{:Wikipedia
if (ns_eval2 != null) {
Xow_ns ns_eval_itm = (Xow_ns)ns_eval2;
@@ -151,6 +153,11 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
return SubEval(ctx, wiki, bfr, name_ary, caller, src);
}
}
switch (finder.Tid()) {
case Xot_defn_.Tid_msg:
defn = Xot_defn_.Null; // null out defn to force template load below; DATE:2014-07-10
break;
}
break;
}
if (subst_found) {// subst found; remove Template: if it exists; EX: {{safesubst:Template:A}} -> {{A}} not {{Template:A}}; EX:en.d:Kazakhstan; DATE:2014-03-25
@@ -213,7 +220,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
switch (defn.Defn_tid()) {
case Xot_defn_.Tid_null: // defn is unknown
if (ignore_hash == null) { // ignore SafeSubst templates
ignore_hash = Hash_adp_bry.ci_();
ignore_hash = Hash_adp_bry.ci_ascii_();
ignore_hash.Add_str_obj("Citation needed{{subst", String_.Empty);
ignore_hash.Add_str_obj("Clarify{{subst", String_.Empty);
}
@@ -289,12 +296,11 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
if (tmpl_keeplist != null && tmpl_keeplist.Enabled()) {
byte[] ttl_lower = Xoa_ttl.Replace_spaces(ctx.Wiki().Lang().Case_mgr().Case_build_lower(ttl));
skip = !tmpl_keeplist.Match(ttl_lower);
// if (skip)
// Tfds.Write_bry(ttl_lower);
// if (skip) Tfds.Write_bry(ttl_lower);
}
}
if (skip) {
bfr.Add(gplx.xowa.html.modules.popups.Xow_popup_parser.Comment_tkn); // add comment tkn; need something to separate ''{{lang|la|Ragusa}}'' else will become ''''; PAGE:en.w:Republic_of_Ragusa; DATE:2014-06-28
bfr.Add(gplx.xowa.Xop_comm_lxr.Xowa_skip_comment_bry); // add comment tkn; need something to separate ''{{lang|la|Ragusa}}'' else will become ''''; PAGE:en.w:Republic_of_Ragusa; DATE:2014-06-28
return true;
}
else
@@ -310,7 +316,10 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
invk.Frame_ttl_(ctx.Wiki().Ns_mgr().Ns_module().Gen_ttl(defn_func.Argx_dat())); // NOTE: always prepend "Module:" to frame_ttl; DATE:2014-06-13
Bry_bfr bfr_func = Bry_bfr.new_();
defn_func.Func_evaluate(ctx, src, caller, invk, bfr_func);
ctx.Tmpl_prepend_nl(bfr, bfr_func.Bfr(), bfr_func.Len());
if (caller.Rslt_is_redirect()) // do not prepend if page is redirect; EX:"#REDIRECT" x> "\n#REDIRECT" DATE:2014-07-11
caller.Rslt_is_redirect_(false); // reset flag; needed for TEST; kludgy, but Rslt_is_redirect is intended for single use
else
ctx.Tmpl_prepend_nl(bfr, bfr_func.Bfr(), bfr_func.Len());
bfr.Add_bfr_and_clear(bfr_func);
}
private static Hash_adp_bry ignore_hash;

View File

@@ -292,28 +292,6 @@ public class Xot_invk_wkr_basic_tst {
)
);
}
@Test public void Raw() { // PURPOSE: {{raw:A}} is same as {{A}}; EX.WIKT:android; {{raw:ja/script}}
fxt.Init_defn_clear();
fxt.Init_defn_add("Test 1", "{{#if:|y|{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{raw:Test 1|a}}", "a");
fxt.Init_defn_clear();
}
@Test public void Raw_spanish() { // PURPOSE.fix: {{raw}} should not fail; EX:es.s:Carta_a_Silvia; DATE:2014-02-11
fxt.Test_parse_tmpl_str("{{raw}}", "[[:Template:raw]]"); // used to fail; now tries to get Template:Raw which doesn't exist
}
@Test public void Special() { // PURPOSE: {{Special:Whatlinkshere}} is same as [[:Special:Whatlinkshere]]; EX.WIKT:android; isValidPageName
fxt.Test_parse_page_tmpl_str("{{Special:Whatlinkshere}}", "[[:Special:Whatlinkshere]]");
}
@Test public void Special_arg() { // PURPOSE: make sure Special still works with {{{1}}}
fxt.Init_defn_clear();
fxt.Init_defn_add("Test1", "{{Special:Whatlinkshere/{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{Test1|-1}}", "[[:Special:Whatlinkshere/-1]]");
fxt.Init_defn_clear();
}
@Test public void Raw_special() { // PURPOSE: {{raw:A}} is same as {{A}}; EX.WIKT:android; {{raw:ja/script}}
fxt.Test_parse_tmpl_str("{{raw:Special:Whatlinkshere}}", "[[:Special:Whatlinkshere]]");
fxt.Init_defn_clear();
}
@Test public void Lnki_has_invk_end() {// PURPOSE: [[A|bcd}}]] should not break enclosing templates; EX.CM:Template:Protect
fxt.Test_parse_page_tmpl_str(String_.Concat_lines_nl_skip_last
( "{{#switch:y"

View File

@@ -0,0 +1,49 @@
/*
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 Xot_invk_wkr_raw_msg_tst {
@Before public void init() {fxt.Reset();} private Xop_fxt fxt = new Xop_fxt();
@After public void term() {fxt.Init_defn_clear();}
@Test public void Raw() { // PURPOSE: {{raw:A}} is same as {{A}}; EX.WIKT:android; {{raw:ja/script}}
fxt.Init_defn_clear();
fxt.Init_defn_add("Test 1", "{{#if:|y|{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{raw:Test 1|a}}", "a");
fxt.Init_defn_clear();
}
@Test public void Raw_spanish() { // PURPOSE.fix: {{raw}} should not fail; EX:es.s:Carta_a_Silvia; DATE:2014-02-11
fxt.Test_parse_tmpl_str("{{raw}}", "[[:Template:raw]]"); // used to fail; now tries to get Template:Raw which doesn't exist
}
@Test public void Special() { // PURPOSE: {{Special:Whatlinkshere}} is same as [[:Special:Whatlinkshere]]; EX.WIKT:android; isValidPageName
fxt.Test_parse_page_tmpl_str("{{Special:Whatlinkshere}}", "[[:Special:Whatlinkshere]]");
}
@Test public void Special_arg() { // PURPOSE: make sure Special still works with {{{1}}}
fxt.Init_defn_clear();
fxt.Init_defn_add("Test1", "{{Special:Whatlinkshere/{{{1}}}}}");
fxt.Test_parse_tmpl_str("{{Test1|-1}}", "[[:Special:Whatlinkshere/-1]]");
fxt.Init_defn_clear();
}
@Test public void Raw_special() { // PURPOSE: {{raw:A}} is same as {{A}}; EX.WIKT:android; {{raw:ja/script}}
fxt.Test_parse_tmpl_str("{{raw:Special:Whatlinkshere}}", "[[:Special:Whatlinkshere]]");
fxt.Init_defn_clear();
}
@Test public void Msg() {
fxt.Init_defn_add("CURRENTMONTH", "a");
fxt.Test_parse_tmpl_str("{{msg:CURRENTMONTH}}", "a");
}
}