1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

'v3.8.5.1'

This commit is contained in:
gnosygnu
2016-08-29 23:31:58 -04:00
parent e4a2af026b
commit 232838c732
292 changed files with 4502 additions and 1838 deletions

View File

@@ -63,7 +63,6 @@ public class Xop_ctx {
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_.Max_value;
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.Instance;
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;
@@ -87,7 +86,6 @@ public class Xop_ctx {
stack_len = stack_max = 0;
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;
}
@@ -335,8 +333,8 @@ public class Xop_ctx {
}
private static void Share_ctx_vars(Xop_ctx src, Xop_ctx trg) {
trg.Page().Db().Page().Id_(src.Page().Db().Page().Id());
trg.Lnki().File_logger_(src.Lnki().File_logger()); // always share lnki_logger between sub contexts
trg.tmpl_output = src.tmpl_output; // share bfr for optimization purposes
trg.ref_ignore = src.ref_ignore; // copy ref_ignore; needed for refs inside poem else duplicate refs; it.s:La_Secchia_rapita/Canto_primo; DATE:2015-12-03
trg.references_group = src.references_group;
trg.cur_page.Ref_mgr_(src.cur_page.Ref_mgr());

View File

@@ -18,14 +18,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
import gplx.core.primitives.*; import gplx.core.btries.*;
import gplx.xowa.files.*;
import gplx.xowa.xtns.pfuncs.exprs.*; import gplx.xowa.xtns.math.*;
import gplx.xowa.xtns.pfuncs.exprs.*; import gplx.xowa.xtns.math.*; import gplx.xowa.xtns.pfuncs.ttls.*;
public class Xop_tmp_mgr {
public Xof_math_itm Math_itm() {return math_itm;} private final Xof_math_itm math_itm = new Xof_math_itm();
public Xof_xfer_itm Xfer_itm() {return xfer_itm;} private final Xof_xfer_itm xfer_itm = new Xof_xfer_itm();
public Gfo_number_parser Pfunc_num_parser_0() {return num_parser_0;} private final Gfo_number_parser num_parser_0 = new Gfo_number_parser().Hex_enabled_(true);
public Gfo_number_parser Pfunc_num_parser_1() {return num_parser_1;} private final Gfo_number_parser num_parser_1 = new Gfo_number_parser().Hex_enabled_(true);
public Pfunc_expr_shunter Expr_shunter() {return expr_shunter;} private final Pfunc_expr_shunter expr_shunter = new Pfunc_expr_shunter();
public Btrie_slim_mgr Xnde__xtn_end() {return xnde__xtn_end;} private final Btrie_slim_mgr xnde__xtn_end = Btrie_slim_mgr.ci_a7(); // NOTE:ci.ascii:MW_const.en; listed XML node names are en
public Btrie_rv Xnde__trv() {return xnde__trv;} private final Btrie_rv xnde__trv = new Btrie_rv();
public Int_obj_ref Pfunc_rel2abs() {return pfunc_rel2abs;} private final Int_obj_ref pfunc_rel2abs = Int_obj_ref.New_zero();
public Xof_math_itm Math_itm() {return math_itm;} private final Xof_math_itm math_itm = new Xof_math_itm();
public Xof_xfer_itm Xfer_itm() {return xfer_itm;} private final Xof_xfer_itm xfer_itm = new Xof_xfer_itm();
public Gfo_number_parser Pfunc_num_parser_0() {return num_parser_0;} private final Gfo_number_parser num_parser_0 = new Gfo_number_parser().Hex_enabled_(true);
public Gfo_number_parser Pfunc_num_parser_1() {return num_parser_1;} private final Gfo_number_parser num_parser_1 = new Gfo_number_parser().Hex_enabled_(true);
public Pfunc_expr_shunter Expr_shunter() {return expr_shunter;} private final Pfunc_expr_shunter expr_shunter = new Pfunc_expr_shunter();
public Btrie_slim_mgr Xnde__xtn_end() {return xnde__xtn_end;} private final Btrie_slim_mgr xnde__xtn_end = Btrie_slim_mgr.ci_a7(); // NOTE:ci.ascii:MW_const.en; listed XML node names are en
public Btrie_rv Xnde__trv() {return xnde__trv;} private final Btrie_rv xnde__trv = new Btrie_rv();
public Int_obj_ref Pfunc_rel2abs() {return pfunc_rel2abs;} private final Int_obj_ref pfunc_rel2abs = Int_obj_ref.New_zero();
public Pfunc_anchorencode_mgr Pfunc_anchor_encoder() {
// if (pf
return null;
} //private pfunc_anchor_encoder
}

View File

@@ -19,10 +19,9 @@ package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
import gplx.core.primitives.*; import gplx.core.brys.fmtrs.*;
import gplx.xowa.wikis.*; import gplx.core.envs.*;
import gplx.xowa.files.*;
import gplx.xowa.xtns.pfuncs.ifs.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.pfuncs.times.*; import gplx.xowa.xtns.wbases.hwtrs.*;
import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.wbases.hwtrs.*; import gplx.xowa.xtns.pfuncs.ifs.*; import gplx.xowa.xtns.pfuncs.times.*; import gplx.xowa.xtns.pfuncs.ttls.*;
public class Xow_parser_mgr {
private final Xowe_wiki wiki; private final Xop_tkn_mkr tkn_mkr;
private Xop_parser anchor_encode_parser;
public Xow_parser_mgr(Xowe_wiki wiki) {
this.wiki = wiki; this.tkn_mkr = wiki.Appe().Parser_mgr().Tkn_mkr();
this.ctx = Xop_ctx.New__top(wiki);
@@ -31,11 +30,14 @@ public class Xow_parser_mgr {
public Xop_ctx Ctx() {return ctx;} private final Xop_ctx ctx;
public Xop_parser Main() {return parser;} private final Xop_parser parser;
public Scrib_core_mgr Scrib() {return scrib;} private final Scrib_core_mgr scrib = new Scrib_core_mgr();
public Xof_img_size Img_size() {return img_size;} private final Xof_img_size img_size = new Xof_img_size();
public Pfunc_ifexist_mgr Ifexist_mgr() {return ifexist_mgr;} private final Pfunc_ifexist_mgr ifexist_mgr = new Pfunc_ifexist_mgr();
public Xof_url_bldr Url_bldr() {return url_bldr;} private final Xof_url_bldr url_bldr = Xof_url_bldr.new_v2();
public List_adp Time_parser_itms() {return time_parser_itms;} private final List_adp time_parser_itms = List_adp_.New();
public Pft_func_formatdate_bldr Date_fmt_bldr() {return date_fmt_bldr;} private final Pft_func_formatdate_bldr date_fmt_bldr = new Pft_func_formatdate_bldr();
public Gfo_number_parser Pp_num_parser() {return pp_num_parser;} private final Gfo_number_parser pp_num_parser = new Gfo_number_parser().Ignore_space_at_end_y_();
public int[] Rel2abs_ary() {return rel2abs_ary;} private final int[] rel2abs_ary = new int[Pfunc_rel2abs.Ttl_max];
public boolean Lst__recursing() {return lst_recursing;} private boolean lst_recursing; public void Lst__recursing_(boolean v) {lst_recursing = v;}
public Bry_bfr Wbase__time__bfr() {return wbase__time__bfr;} private final Bry_bfr wbase__time__bfr = Bry_bfr_.New();
public Bry_fmtr Wbase__time__fmtr() {return wbase__time__fmtr;} private final Bry_fmtr wbase__time__fmtr = Bry_fmtr.new_();
public Wdata_hwtr_msgs Wbase__time__msgs() {
@@ -43,16 +45,38 @@ public class Xow_parser_mgr {
wbase__time__msgs = Wdata_hwtr_msgs.new_(wiki.Msg_mgr());
return wbase__time__msgs;
} private Wdata_hwtr_msgs wbase__time__msgs;
public Xop_parser Anchor_encoder() {
if (anchor_encode_parser == null) {
anchor_encode_parser = Xop_parser.new_(wiki, wiki.Parser_mgr().Main().Tmpl_lxr_mgr(), Xop_lxr_mgr.new_anchor_encoder());
anchor_encode_parser.Init_by_wiki(wiki);
anchor_encode_parser.Init_by_lang(wiki.Lang());
public int Tag__next_idx() {return ++tag_idx;} private int tag_idx; // NOTE:must be wiki-level variable, not page-level, b/c pre-compiled templates can reserve tag #s; PAGE:de.s:Seite:NewtonPrincipien.djvu/465 DATE:2015-02-03
public void Tmpl_stack_del() {--tmpl_stack_ary_len;}
public boolean Tmpl_stack_add(byte[] key) {
for (int i = 0; i < tmpl_stack_ary_len; i++) {
if (Bry_.Match(key, tmpl_stack_ary[i])) return false;
}
return anchor_encode_parser;
}
public void Parse(Xoae_page page, boolean clear) { // main parse method
int new_len = tmpl_stack_ary_len + 1;
if (new_len > tmpl_stack_ary_max) {
tmpl_stack_ary_max = new_len * 2;
tmpl_stack_ary = (byte[][])Array_.Resize(tmpl_stack_ary, tmpl_stack_ary_max);
}
tmpl_stack_ary[tmpl_stack_ary_len] = key;
tmpl_stack_ary_len = new_len;
return true;
} private byte[][] tmpl_stack_ary = Bry_.Ary_empty; private int tmpl_stack_ary_len = 0, tmpl_stack_ary_max = 0;
public Pfunc_anchorencode_mgr Anchor_encoder_mgr__dflt_or_new(Xop_ctx calling_ctx) {
// lazy-instantiate anchor_encoder_mgr
if (anchor_encoder_mgr == null) anchor_encoder_mgr = new Pfunc_anchorencode_mgr(wiki);
// default to member instance
Pfunc_anchorencode_mgr rv = anchor_encoder_mgr;
// if used, create a new one; only occurs if {{anchorencode}} is nested
if (rv.Used()) rv = new Pfunc_anchorencode_mgr(wiki);
rv.Used_(Bool_.Y);
return rv;
} private Pfunc_anchorencode_mgr anchor_encoder_mgr;
public void Parse(Xoae_page page, boolean clear) { // main parse method; should never be called nested
if (!Env_.Mode_testing()) wiki.Init_assert();
tmpl_stack_ary = Bry_.Ary_empty;
tmpl_stack_ary_len = tmpl_stack_ary_max = 0;
scrib.When_page_changed(page); // notify scribunto about page changed
ctx.Page_(page);
Xop_root_tkn root = ctx.Tkn_mkr().Root(page.Db().Text().Text_bry());

View File

@@ -76,19 +76,32 @@ public class Xop_link_parser {
return raw;
}
private static boolean Parse__ttl(Bry_bfr tmp_bfr, Xowe_wiki wiki, byte[] wiki_bry, byte[] page_bry) {
// handle colon-only aliases; EX:"link:" PAGE:en.w:Wikipedia:Main_Page_alternative_(CSS_Update) DATE:2016-08-18
Xoa_ttl page_ttl = wiki.Ttl_parse(page_bry);
Xow_xwiki_itm xwiki_itm = page_ttl == null ? null : page_ttl.Wik_itm();
if ( xwiki_itm != null // ttl is xwiki; EX:[[File:A.png|link=wikt:A]]
&& page_ttl.Page_db().length == 0) { // ttl is empty; EX:[[File:A.png|link=wikt:]]
Xow_wiki xwiki_wiki = wiki.App().Wiki_mgri().Get_by_or_make_init_n(page_ttl.Wik_itm().Domain_bry());
page_bry = Bry_.Add(page_bry, xwiki_wiki.Props().Main_page()); // append Main_Page to ttl; EX:"wikt:" + "Wikipedia:Main_Page" -> "wikt:Wikipedia:Main_Page"
page_ttl = wiki.Ttl_parse(page_bry);
xwiki_itm = page_ttl.Wik_itm(); // should still be the same, but re-set it for good form
}
// identify wiki / page
boolean page_ttl_is_valid = page_ttl != null;
if (page_ttl_is_valid) {
Xow_xwiki_itm xwiki_itm = page_ttl.Wik_itm();
if (page_ttl_is_valid) { // xwiki; need to define wiki / page
if (xwiki_itm != null) { // is alias; set wiki, page
wiki_bry = xwiki_itm.Domain_bry();
page_bry = Bry_.Mid(page_bry, xwiki_itm.Key_bry().length + 1, page_bry.length); // +1 for ":"
page_bry = Bry_.Mid(page_bry, xwiki_itm.Key_bry().length + 1, page_bry.length); // +1 to skip ":"
}
else // is regular page; use ttl.Full_db() to normalize; EX: &nbsp; -> _
else // basic; just define page; use ttl.Full_db() to normalize; EX: &nbsp; -> _
page_bry = page_ttl.Full_db_w_anch(); // add anch; PAGE:en.w:History_of_Nauru; DATE:2015-12-27
}
// build either "/wiki/Page" or "/site/domain/wiki/Page"
if (Bry_.Eq(wiki_bry, wiki.Domain_bry())) { // NOTE: check against wiki.Key_bry() again; EX: in en_wiki, and http://commons.wikimedia.org/wiki/w:A
if (page_ttl_is_valid) { // same wiki; parse in same ns to title-case; EX:link=w:Help:a -> Help:A; NOTE: must check for page_ttl_is_valid; DATE:2016-01-11
// title-case by ns; needed to handle "link=w:Help:a" which needs to generate "w:Help:A"
if (page_ttl_is_valid) { // valid_ttl; parse in same ns to title-case; EX:link=w:Help:a -> Help:A; DATE:2016-01-11
page_ttl = wiki.Ttl_parse(page_ttl.Full_db_wo_xwiki());
page_bry = page_ttl.Full_db_w_anch();
}

View File

@@ -19,7 +19,7 @@ package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.
import gplx.core.bits.*;
public class Xop_lnki_type {
public static final byte Id_null = 0, Id_none = 1, Id_frameless = 2, Id_frame = 4, Id_thumb = 8;
public static final byte Tid_null = 0, Tid_none = 1, Tid_frameless = 2, Tid_frame = 3, Tid_thumb = 4; // SERIALIZED
public static final byte Tid_null = 0, Tid_none = 1, Tid_frameless = 2, Tid_frame = 3, Tid_thumb = 4, Tid_orig_known = 64; // SERIALIZED
public static byte To_tid(byte flag) {
switch (flag) {
case Xop_lnki_type.Id_null: return Xop_lnki_type.Tid_null;
@@ -62,6 +62,7 @@ public class Xop_lnki_type {
if ( Bitmask_.Has_int(id, Id_thumb) // [[File:A.png|600px|thumb]] -> 400,200
|| Bitmask_.Has_int(id, Id_frameless) // [[File:A.png|600px|frameless]] -> 400,200
|| Bitmask_.Has_int(id, Id_frame) // [[File:A.png|600px|frame]] -> 400,200 (frame is always default size)
|| id == Tid_orig_known // for hdump
)
return true;
else if ( id == Id_null // [[File:A.png|600px]] -> 600,400; uses orig file of 400,200, but <img> tag src_width / src_height set to 600,400

View File

@@ -44,17 +44,17 @@ public class Xop_lnki_wkr_ {
ttl_bry = gplx.langs.htmls.encoders.Gfo_url_encoder_.Http_url_ttl.Decode(ttl_bry);
int ttl_bry_len = ttl_bry.length;
Xoa_ttl page_ttl = ctx.Page().Ttl();
Xowe_wiki wiki = ctx.Wiki();
if (page_ttl.Ns().Subpages_enabled()
&& Pfunc_rel2abs.Rel2abs_ttl(ttl_bry, 0, ttl_bry_len)) { // Linker.php|normalizeSubpageLink
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
Int_obj_ref rel2abs_tid = ctx.Tmp_mgr().Pfunc_rel2abs().Val_zero_();
byte[] new_bry = Pfunc_rel2abs.Rel2abs(tmp_bfr, ttl_bry, page_ttl.Raw(), rel2abs_tid);
byte[] new_bry = Pfunc_rel2abs.Rel2abs(tmp_bfr, wiki.Parser_mgr().Rel2abs_ary(), ttl_bry, page_ttl.Raw(), rel2abs_tid);
lnki.Subpage_tid_(rel2abs_tid.Val());
lnki.Subpage_slash_at_end_(Bry_.Get_at_end(ttl_bry) == Byte_ascii.Slash);
ttl_bry = new_bry;
tmp_bfr.Mkr_rls();
}
Xowe_wiki wiki = ctx.Wiki();
Xoa_ttl ttl = Xoa_ttl.Parse(wiki, ttl_bry);
if (ttl == null) return false;
if ( wiki.Cfg_parser_lnki_xwiki_repos_enabled() // wiki has lnki.xwiki_repos

View File

@@ -0,0 +1,83 @@
/*
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.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*;
public class Xop_lnki_wkr__link__basic__tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private final Xop_fxt fxt = new Xop_fxt();
@Test public void Link() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_blank() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=|c]]", String_.Concat_lines_nl_skip_last
( "<img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" />"
));
}
@Test public void Link_external() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://www.b.org|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"http://www.b.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_file_system() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=file:///C/B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"file:///C/B.png\" class=\"image\" xowa_title=\"B.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_file_ns() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_relative() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"https://fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_absolute() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"http://fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_double_http() {// PURPOSE.fix: link=http://a.org?b=http://c.org breaks lnki; DATE:2013-02-03
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//a.org?b=http://c.org]]", String_.Concat_lines_nl_skip_last
( "<a href=\"https://a.org?b=http://c.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Encode() {// PURPOSE: encode invalid characters in link; PAGE:en.w:List_of_cultural_heritage_sites_in_Punjab,_Pakistan DATE:2014-07-16
fxt.Test_parse_page_wiki_str
( "[[File:A.png|link=//b?c\">|d]]"
, "<a href=\"https://b?c%22%3E\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"d\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
}
@Test public void Anchor() {// PURPOSE: handle anchors; PAGE:en.w: en.w:History_of_Nauru; DATE:2015-12-27
fxt.Test_parse_page_wiki_str
( "[[File:A.png|link=#b]]"
, "<a href=\"/wiki/Test_page#b\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
}
}

View File

@@ -0,0 +1,104 @@
/*
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.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*;
public class Xop_lnki_wkr__link__xwiki__tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private final Xop_fxt fxt = new Xop_fxt();
@Test public void Relative() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Relative_domain_only() { // lnki_wtr fails if link is only domain; EX: wikimediafoundation.org; [[Image:Wikispecies-logo.png|35px|link=//species.wikimedia.org]]; // NOTE: changed href to return "/wiki/" instead of ""; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Absolute() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Absolute_upload() { // PURPOSE: link to upload.wikimedia.org omits /wiki/; EX: wikimediafoundation.org: [[File:Page1-250px-WMF_AR11_SHIP_spreads_15dec11_72dpi.png|right|125px|border|20102011 Annual Report|link=https://upload.wikimedia.org/wikipedia/commons/4/48/WMF_AR11_SHIP_spreads_15dec11_72dpi.pdf]]
fxt.Init_xwiki_add_user_("commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://upload.wikimedia.org/wikipedia/commons/7/70/A.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/File:A.png\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Relative_deep() {
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/A/b|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/A/b\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Url_w_alias() { // [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Init_xwiki_add_wiki_and_user_("en.wikipedia.org", "en.wikipedia.org"); // DATE:2015-07-22
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/B\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Url_w_alias_and_sub_page() { // same as above, but for sub-page; [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Init_xwiki_add_wiki_and_user_("en.wikipedia.org", "en.wikipedia.org"); // DATE:2015-07-22
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Alias__basic() { // alias: basic; [[File:Commons-logo.svg|25x25px|link=commons:Special:Search/Earth]]; fictitious example; DATE:2013-02-18
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Alias__prepended_colon() { // alias prepended with ":"; [[File:Wikipedia-logo.svg|40px|link=:w:|Wikipedia]]; DATE:2013-05-06
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=:commons:A/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/A/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Alias__colon_only() {// alias: w/ only colon; EX: [[File:Commons-logo.svg|25x25px|link=commons:]]; PAGE:en.w:Wikipedia:Main_Page_alternative_(CSS_Update) DATE:2016-08-18
// make commons wiki
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
Xowe_wiki commons_wiki = (Xowe_wiki)fxt.App().Wiki_mgr().Get_by_or_make_init_n(gplx.xowa.wikis.domains.Xow_domain_itm_.Bry__commons);
commons_wiki.Props().Main_page_(Bry_.new_a7("Test:Commons_main_page"));
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=commons:|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/Test:Commons_main_page\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
}

View File

@@ -1,152 +0,0 @@
/*
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.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*;
public class Xop_lnki_wkr__link_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private final Xop_fxt fxt = new Xop_fxt();
@Test public void Link() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_blank() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=|c]]", String_.Concat_lines_nl_skip_last
( "<img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" />"
));
}
@Test public void Link_external() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://www.b.org|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"http://www.b.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_file_system() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=file:///C/B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"file:///C/B.png\" class=\"image\" xowa_title=\"B.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_file_ns() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_relative() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"https://fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_absolute() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"http://fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_double_http() {// PURPOSE.fix: link=http://a.org?b=http://c.org breaks lnki; DATE:2013-02-03
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//a.org?b=http://c.org]]", String_.Concat_lines_nl_skip_last
( "<a href=\"https://a.org?b=http://c.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_relative() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_relative_domain_only() { // lnki_wtr fails if link is only domain; EX: wikimediafoundation.org; [[Image:Wikispecies-logo.png|35px|link=//species.wikimedia.org]]; // NOTE: changed href to return "/wiki/" instead of ""; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_absolute() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_absolute_upload() { // PURPOSE: link to upload.wikimedia.org omits /wiki/; EX: wikimediafoundation.org: [[File:Page1-250px-WMF_AR11_SHIP_spreads_15dec11_72dpi.png|right|125px|border|20102011 Annual Report|link=https://upload.wikimedia.org/wikipedia/commons/4/48/WMF_AR11_SHIP_spreads_15dec11_72dpi.pdf]]
fxt.Init_xwiki_add_user_("commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://upload.wikimedia.org/wikipedia/commons/7/70/A.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/File:A.png\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_relative_deep() {
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/A/b|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/A/b\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_alias() { // [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Init_xwiki_add_wiki_and_user_("en.wikipedia.org", "en.wikipedia.org"); // DATE:2015-07-22
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/B\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Link_xwiki_alias_sub_page() { // same as above, but for sub-page; [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Init_xwiki_add_wiki_and_user_("en.wikipedia.org", "en.wikipedia.org"); // DATE:2015-07-22
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Link_xwiki_alias_only() { // only alias; [[File:Commons-logo.svg|25x25px|link=commons:Special:Search/Earth]]; fictitious example; DATE:2013-02-18
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Link_xwiki_alias_only_colon() { // only alias, but prepended with ":"; [[File:Wikipedia-logo.svg|40px|link=:w:|Wikipedia]]; DATE:2013-05-06
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=:commons:A/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/A/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Encode() {// PURPOSE: encode invalid characters in link; PAGE:en.w:List_of_cultural_heritage_sites_in_Punjab,_Pakistan DATE:2014-07-16
fxt.Test_parse_page_wiki_str
( "[[File:A.png|link=//b?c\">|d]]"
, "<a href=\"https://b?c%22%3E\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"d\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
}
@Test public void Anchor() {// PURPOSE: handle anchors; PAGE:en.w: en.w:History_of_Nauru; DATE:2015-12-27
fxt.Test_parse_page_wiki_str
( "[[File:A.png|link=#b]]"
, "<a href=\"/wiki/Test_page#b\" class=\"image\" xowa_title=\"A.png\"><img id=\"xoimg_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
}
}

View File

@@ -37,7 +37,7 @@ public class Xop_log_basic_wkr implements Gfo_invk {
log_tbl.Insert
( log_tid
, log_msg == Xop_log_basic_wkr.Null_log_msg ? "" : String_.new_u8(log_msg)
, save_log_time ? Env_.TickCount_elapsed_in_frac(log_bgn) : Xop_log_basic_wkr.Null_log_time
, save_log_time ? System_.Ticks__elapsed_in_frac(log_bgn) : Xop_log_basic_wkr.Null_log_time
, page.Db().Page().Id()
, save_page_ttl ? String_.new_u8(page.Ttl().Full_db()) : Xop_log_basic_wkr.Null_page_ttl
, save_args_len ? args_len : Xop_log_basic_wkr.Null_args_len

View File

@@ -37,7 +37,7 @@ public class Xop_log_invoke_wkr implements Gfo_invk {
public boolean Eval_bgn(Xoae_page page, byte[] mod_name, byte[] fnc_name) {return !exclude_mod_names.Has(mod_name);}
public void Eval_end(Xoae_page page, byte[] mod_name, byte[] fnc_name, long invoke_time_bgn) {
if (log_enabled && stmt != null) {
int eval_time = (int)(Env_.TickCount() - invoke_time_bgn);
int eval_time = (int)(System_.Ticks() - invoke_time_bgn);
Xop_log_invoke_tbl.Insert(stmt, page.Ttl().Rest_txt(), mod_name, fnc_name, eval_time);
log_mgr.Commit_chk();
}

View File

@@ -35,7 +35,7 @@ public class Xop_log_property_wkr implements Gfo_invk {
public boolean Eval_bgn(Xoae_page page, byte[] prop) {return include_all || include_props.Has(prop);}
public void Eval_end(Xoae_page page, byte[] prop, long invoke_time_bgn) {
if (log_enabled && stmt != null) {
int eval_time = (int)(Env_.TickCount() - invoke_time_bgn);
int eval_time = (int)(System_.Ticks() - invoke_time_bgn);
Xob_log_property_temp_tbl.Insert(stmt, page.Ttl().Rest_txt(), prop, eval_time);
log_mgr.Commit_chk();
}

View File

@@ -170,8 +170,11 @@ public class Xop_tblw_wkr implements Xop_ctx_wkr {
if (!tbl_is_xml)
ctx.Para().Process_nl(ctx, root, src, bgn_pos, bgn_pos + 1); // simulate "\n"; 2012-12-08
int stack_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr);
if (stack_pos != Xop_ctx.Stack_not_found) // don't pop <tr> if none found; PAGE:en.w:Turks_in_Denmark DATE:2014-03-02
if ( stack_pos != Xop_ctx.Stack_not_found // don't pop <tr> if none found; PAGE:en.w:Turks_in_Denmark DATE:2014-03-02
&& !tbl_is_xml // cur is "|-", not <tr>; PAGE:en.w:Aargau; DATE:2016-08-14
) {
ctx.Stack_pop_til(root, src, stack_pos, true, bgn_pos, bgn_pos, Xop_tkn_itm_.Tid_tblw_td);
}
break;
case Xop_tkn_itm_.Tid_tblw_tr: // fix; <tr><tr> -> <tr>
if (prv_tkn.Tblw_subs_len() == 0) { // NOTE: set prv_row to ignore, but do not pop; see Tr_dupe_xnde and [[Jupiter]]; only invoke if same type; EX: <tr><tr> but not |-<tr>; DATE:2013-12-09

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_tblw_wkr__tblx_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_y_();} private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset(); fxt.Init_para_y_();} private final Xop_fxt fxt = new Xop_fxt();
@After public void term() {fxt.Init_para_n_();}
@Test public void Ignore_td() { // PURPOSE: do not parse pipe as td if in <table>; EX:ru.w:Сочи; DATE:2014-02-22
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
@@ -129,4 +129,26 @@ public class Xop_tblw_wkr__tblx_tst {
)
);
}
@Test public void Ignore_tr_in_lnki() { // PURPOSE: <tr> fragment within lnki should be ignored; PAGE:en.w:Aargau DATE:2016-08-14
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "<table>"
, "<tr>"
, "<td>[[A|B<tr><td>t_1</td></tr>]]"
, "</td>"
, "</tr>"
, "</table>"
) , String_.Concat_lines_nl_skip_last
( "<table>"
, " <tr>"
, " <td><a href=\"/wiki/A\">B"
, " <tr>"
, " <td>t_1"
, " </td>"
, " </tr>"
, "</a>"
, " </td>"
, " </tr>"
, "</table>"
));
}
}

View File

@@ -60,5 +60,5 @@ public class Xop_tblw_ws_itm {
int tag_name_len = tag_name.length;
trie.Add_obj(Bry_.Add(Bry_xnde_bgn, tag_name), new Xop_tblw_ws_itm(Type_xnde, tag_name_len));
trie.Add_obj(Bry_.Add(Bry_xnde_end, tag_name), new Xop_tblw_ws_itm(Type_xnde, tag_name_len + 1));
} static byte[] Bry_xnde_bgn = new byte[] {Byte_ascii.Lt, Byte_ascii.Slash}, Bry_xnde_end = new byte[] {Byte_ascii.Lt};
} private static byte[] Bry_xnde_bgn = new byte[] {Byte_ascii.Lt, Byte_ascii.Slash}, Bry_xnde_end = new byte[] {Byte_ascii.Lt};
}

View File

@@ -64,7 +64,7 @@ public class Xot_defn_tmpl implements Xot_defn {
public boolean Tmpl_evaluate(Xop_ctx ctx, Xot_invk caller, Bry_bfr bfr) {
if (root == null) Parse_tmpl(ctx);
Xoae_page page = ctx.Page();
if (!page.Tmpl_stack_add(full_name)) {
if (!ctx.Wiki().Parser_mgr().Tmpl_stack_add(full_name)) {
bfr.Add_str_a7("<!-- template loop detected:" + gplx.langs.htmls.Gfh_utl.Escape_html_as_str(String_.new_u8(name)) + " -->");
Xoa_app_.Usr_dlg().Log_many("", "", "template loop detected: url=~{0} name=~{1}", ctx.Page().Url().To_str(), name);
return false;
@@ -87,7 +87,7 @@ public class Xot_defn_tmpl implements Xot_defn {
boolean result = root.Subs_get(i).Tmpl_evaluate(ctx, data_raw, caller, bfr);
if (!result) rv = false;
}
page.Tmpl_stack_del();
ctx.Wiki().Parser_mgr().Tmpl_stack_del();
return rv;
}
public Xot_defn Clone(int id, byte[] name) {throw Err_.new_unimplemented();}

View File

@@ -43,7 +43,7 @@ class Xot_fmtr_prm implements Xot_fmtr {
}
else // invk mode
self.Tmpl_evaluate(ctx, src, caller, trg);
} static final byte[] Bry_bgn = new byte[] {Byte_ascii.Curly_bgn, Byte_ascii.Curly_bgn, Byte_ascii.Curly_bgn}, Bry_end = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Curly_end, Byte_ascii.Curly_end};
} private static final byte[] Bry_bgn = new byte[] {Byte_ascii.Curly_bgn, Byte_ascii.Curly_bgn, Byte_ascii.Curly_bgn}, Bry_end = new byte[] {Byte_ascii.Curly_end, Byte_ascii.Curly_end, Byte_ascii.Curly_end};
public void Reg_tmpl(Xop_ctx ctx, byte[] src, Xop_tkn_itm name_tkn, int args_len, Arg_nde_tkn[] args) {
trg.Add(Xop_curly_bgn_lxr.Hook);
++depth;

View File

@@ -17,12 +17,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.envs.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*; import gplx.xowa.langs.vnts.*; import gplx.xowa.langs.vnts.converts.*; import gplx.xowa.langs.funcs.*;
import gplx.xowa.wikis.nss.*;
import gplx.xowa.wikis.caches.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.pfuncs.*; import gplx.xowa.xtns.pfuncs.ttls.*; import gplx.xowa.wikis.pages.*;
import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.parsers.miscs.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*; import gplx.xowa.langs.funcs.*;
import gplx.xowa.xtns.pfuncs.*; import gplx.xowa.xtns.pfuncs.ttls.*;
import gplx.xowa.wikis.pages.*; import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.caches.*; import gplx.xowa.wikis.data.tbls.*;
public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
public Xot_invk_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return typeId;} private byte typeId = Xop_tkn_itm_.Tid_tmpl_invk;
public void Tkn_tid_to_txt() {typeId = Xop_tkn_itm_.Tid_txt;}
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;
@@ -49,23 +50,36 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
}
}
@Override public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) { // this="{{t|{{{0}}}}}" caller="{{t|1}}"
// init common
boolean rv = false;
Xot_defn defn = tmpl_defn; Xowe_wiki wiki = ctx.Wiki(); Xol_lang_itm lang = wiki.Lang();
byte[] name_ary = defn.Name(), argx_ary = Bry_.Empty; Arg_itm_tkn name_key_tkn = name_tkn.Key_tkn();
Xowe_wiki wiki = ctx.Wiki();
Xol_lang_itm lang = wiki.Lang();
// init defn / name
Xot_defn defn = tmpl_defn;
byte[] name_ary = defn.Name();
byte[] name_ary_orig = Bry_.Empty;
int name_bgn = 0, name_ary_len = 0;
Arg_itm_tkn name_key_tkn = name_tkn.Key_tkn();
// init more
byte[] argx_ary = Bry_.Empty;
boolean subst_found = false;
boolean name_had_subst = false;
boolean template_prefix_found = false;
if (defn == Xot_defn_.Null) { // tmpl_name is not exact match; may be dynamic, subst, transclusion, etc..
if (name_key_tkn.Itm_static() == Bool_.N_byte) { // tmpl is dynamic; EX:{{{{{1}}}|a}}
// tmpl_name does not exist in db; may be dynamic, subst, transclusion, etc..
if (defn == Xot_defn_.Null) {
// dynamic tmpl; EX:{{{{{1}}}|a}}
if (name_key_tkn.Itm_static() == Bool_.N_byte) {
Bry_bfr name_tkn_bfr = Bry_bfr_.New_w_size(name_tkn.Src_end() - name_tkn.Src_bgn());
if (defn_tid == Xot_defn_.Tid_subst)
name_tkn_bfr.Add(Get_first_subst_itm(lang.Kwd_mgr()));
name_tkn.Tmpl_evaluate(ctx, src, caller, name_tkn_bfr);
name_ary = name_tkn_bfr.To_bry_and_clear();
}
else // tmpl is static; note that dat_ary is still valid but rest of name may not be; EX: {{subst:name{{{1}}}}}
// tmpl is static; note that dat_ary is still valid but rest of name may not be; EX: {{subst:name{{{1}}}}}
else
name_ary = Bry_.Mid(src, name_key_tkn.Dat_bgn(), name_key_tkn.Dat_end());
name_had_subst = name_key_tkn.Dat_ary_had_subst();
name_ary_orig = name_ary; // cache name_ary_orig
@@ -73,8 +87,9 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
name_bgn = Bry_find_.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; 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
) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "parser.tmpl:dynamic is blank; page~{0}", ctx.Page().Url_bry_safe());
bfr.Add_str_a7("(? [[dynamic is blank]] ?)");
return false;
}
if (name_ary[name_bgn] == Byte_ascii.Colon) { // check 1st letter for transclusion
@@ -200,7 +215,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
else { // some templates produce null ttls; EX: "Citation needed{{subst"
defn = wiki.Cache_mgr().Defn_cache().Get_by_key(ttl.Page_db());
if (defn == null && ctx.Tmpl_load_enabled())
defn = Load_defn(wiki, ctx, this, ttl, name_ary);
defn = Xot_invk_tkn_.Load_defn(wiki, ctx, this, ttl, name_ary);
}
}
}
@@ -219,40 +234,35 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
}
defn = wiki.Cache_mgr().Defn_cache().Get_by_key(name_ary);
if (defn == null && ctx.Tmpl_load_enabled())
defn = Load_defn(wiki, ctx, this, ttl, name_ary);
defn = Xot_invk_tkn_.Load_defn(wiki, ctx, this, ttl, name_ary);
if (defn == null) defn = Xot_defn_.Null;
}
}
Xot_defn_trace trace = ctx.Defn_trace(); int trg_bgn = bfr.Len();
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_a7();
ignore_hash.Add_str_obj("Citation needed{{subst", String_.Empty);
ignore_hash.Add_str_obj("Clarify{{subst", String_.Empty);
}
if (ignore_hash.Get_by_bry(name_ary) == null) {
if (Pfunc_rel2abs.Rel2abs_ttl(name_ary, name_bgn, name_ary_len)) {// rel_path; EX: {{/../Peer page}}; DATE:2013-03-27
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
name_ary = Pfunc_rel2abs.Rel2abs(tmp_bfr, Bry_.Mid(name_ary, name_bgn, name_ary_len), ctx.Page().Ttl().Raw());
name_ary = Pfunc_rel2abs.Rel2abs(tmp_bfr, wiki.Parser_mgr().Rel2abs_ary(), Bry_.Mid(name_ary, name_bgn, name_ary_len), ctx.Page().Ttl().Raw());
tmp_bfr.Mkr_rls();
return SubEval(ctx, wiki, bfr, name_ary, caller, src);
}
if (subst_found)
return Transclude(ctx, wiki, bfr, template_prefix_found, name_ary, caller, src);
Print_not_found__w_template(bfr, wiki.Ns_mgr(), name_ary);
Xot_invk_tkn_.Print_not_found__w_template(bfr, wiki.Ns_mgr(), name_ary);
return false;
}
break;
case Xot_defn_.Tid_func:
try {
Eval_func(ctx, src, caller, this, bfr, defn, argx_ary);
Xot_invk_tkn_.Eval_func(ctx, src, caller, this, bfr, defn, argx_ary);
rv = true;
} catch (Exception e) {
if (Env_.Mode_testing())
throw Err_.new_exc(e, "xo", "failed to evaluate function", "page", ctx.Page().Ttl().Full_txt_w_ttl_case(), "defn", defn.Name(), "src", String_.new_u8(src, this.Src_bgn(), this.Src_end()));
else {
wiki.Appe().Usr_dlg().Warn_many("", "", "failed to evaluate function: page=~{0} defn=~{1} src=~{2} err=~{3}", ctx.Page().Ttl().Full_txt_w_ttl_case(), defn.Name(), String_.new_u8(src, this.Src_bgn(), this.Src_end()), Err_.Message_gplx_log(e));
wiki.Appe().Usr_dlg().Warn_many("", "", "failed to evaluate function: page=~{0} defn=~{1} src=~{2} err=~{3}", ctx.Page().Ttl().Full_txt_w_ttl_case(), defn.Name(), Bry_.Replace_nl_w_tab(src, this.Src_bgn(), this.Src_end()), Err_.Message_gplx_log(e));
rv = false;
}
}
@@ -266,7 +276,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
Bry_bfr rslt_bfr = wiki.Utl__bfr_mkr().Get_k004();
try {
Bld_key(invk_tmpl, name_ary, rslt_bfr);
Xot_invk_tkn_.Bld_key(invk_tmpl, name_ary, rslt_bfr);
byte[] rslt_key = rslt_bfr.To_bry_and_clear();
Object o = wiki.Cache_mgr().Tmpl_result_cache().Get_by(rslt_key);
Xopg_tmpl_prepend_mgr prepend_mgr = ctx.Page().Tmpl_prepend_mgr().Bgn(bfr);
@@ -297,7 +307,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
break;
}
return rv;
} private static final byte[] Ary_unknown_bgn = Bry_.new_a7("(? [["), Ary_unknown_end = Bry_.new_a7("]] ?)"), Ary_dynamic_is_blank = Bry_.new_a7("dynamic is blank");
}
private boolean Popup_skip(Xop_ctx ctx, byte[] ttl, Bry_bfr bfr) {
boolean skip = false;
skip = this.Src_end() - this.Src_bgn() > ctx.Tmpl_tkn_max();
@@ -316,38 +326,6 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
else
return false;
}
public static void Eval_func(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk invk, Bry_bfr bfr, Xot_defn defn, byte[] argx_ary) {
Pf_func_base defn_func = (Pf_func_base)defn;
int defn_func_id = defn_func.Id();
defn_func = (Pf_func_base)defn_func.New(defn_func_id, defn_func.Name()); // NOTE: always make copy b/c argx_ary may be dynamic
if (argx_ary != Bry_.Empty) defn_func.Argx_dat_(argx_ary);
defn_func.Eval_argx(ctx, src, caller, invk);
if (defn_func_id == Xol_kwd_grp_.Id_invoke) // NOTE: if #invoke, set frame_ttl to argx, not name; EX:{{#invoke:A}}
invk.Frame_ttl_(Bry_.Add(Xow_ns_.Bry__module_w_colon, Xoa_ttl.Replace_unders(defn_func.Argx_dat()))); // NOTE: always prepend "Module:" to frame_ttl; DATE:2014-06-13; NOTE: always use spaces; DATE:2014-08-14; always use canonical English "Module"; DATE:2015-11-09
Bry_bfr bfr_func = Bry_bfr_.New();
defn_func.Func_evaluate(bfr_func, ctx, caller, invk, src);
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.Page().Tmpl_prepend_mgr().End(ctx, bfr, bfr_func.Bfr(), bfr_func.Len(), Bool_.N);
bfr.Add_bfr_and_clear(bfr_func);
}
private static Hash_adp_bry ignore_hash;
public static boolean Cache_enabled = false;
private static void Bld_key(Xot_invk invk, byte[] name_ary, Bry_bfr bfr) {
bfr.Clear();
bfr.Add(name_ary);
int args_len = invk.Args_len();
for (int i = 0; i < args_len; i++) {
Arg_nde_tkn nde = invk.Args_get_by_idx(i);
bfr.Add_byte(Byte_ascii.Pipe);
if (nde.KeyTkn_exists()) {
bfr.Add(nde.Key_tkn().Dat_ary());
bfr.Add_byte(Byte_ascii.Eq);
}
bfr.Add(nde.Val_tkn().Dat_ary());
}
}
private boolean Transclude(Xop_ctx ctx, Xowe_wiki wiki, Bry_bfr bfr, boolean template_prefix_found, byte[] name_ary, Xot_invk caller, byte[] src) {
Xoa_ttl page_ttl = Xoa_ttl.Parse(wiki, name_ary); if (page_ttl == null) return false; // ttl not valid; EX: {{:[[abc]]}}
byte[] transclude_src = null;
@@ -369,7 +347,7 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
return Eval_sub(ctx, transclude_tmpl, caller, src, bfr);
}
else {
Print_not_found__by_transclude(bfr, wiki.Ns_mgr(), template_prefix_found, name_ary);
Xot_invk_tkn_.Print_not_found__by_transclude(bfr, wiki.Ns_mgr(), template_prefix_found, name_ary);
return false;
}
}
@@ -383,34 +361,6 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
doc.Add_bfr_and_clear(tmp_bfr);
return rv;
}
public static Xot_defn_tmpl Load_defn(Xowe_wiki wiki, Xop_ctx ctx, Xot_invk_tkn invk_tkn, Xoa_ttl ttl, byte[] name_ary) {
Xow_page_cache_itm tmpl_page_itm = wiki.Cache_mgr().Page_cache().Get_or_load_as_itm(ttl);
byte[] tmpl_page_bry = tmpl_page_itm == null ? null : tmpl_page_itm.Wtxt__direct();
Xot_defn_tmpl rv = null;
if (tmpl_page_bry != null) {
byte old_parse_tid = ctx.Parse_tid(); // NOTE: reusing ctxs is a bad idea; will change Parse_tid and cause strange errors; however, keeping for PERF reasons
Xow_ns ns_tmpl = wiki.Ns_mgr().Ns_template();
rv = wiki.Parser_mgr().Main().Parse_text_to_defn_obj(ctx, ctx.Tkn_mkr(), ns_tmpl, name_ary, tmpl_page_bry);
Xoa_ttl tmpl_page_ttl = tmpl_page_itm.Ttl();
byte[] frame_ttl = Bry_.Add(Xow_ns_canonical_.To_canonical_or_local_as_bry(tmpl_page_ttl.Ns()), Byte_ascii.Colon_bry, tmpl_page_ttl.Page_txt()); // NOTE: (1) must have ns (Full); (2) must be txt (space, not underscore); EX:Template:Location map+; DATE:2014-08-22; (3) must be canonical; DATE:2015-11-09
rv.Frame_ttl_(frame_ttl); // set defn's frame_ttl; needed for redirect_trg; PAGE:en.w:Statutory_city; DATE:2014-08-22
ctx.Parse_tid_(old_parse_tid);
wiki.Cache_mgr().Defn_cache().Add(rv, ns_tmpl.Case_match());
}
return rv;
}
private static void Print_not_found__by_transclude(Bry_bfr bfr, Xow_ns_mgr ns_mgr, boolean name_has_template, byte[] name_ary) {// print missing as [[Missing]]; PAGE:en.d:a DATE:2016-06-24
bfr.Add(Xop_tkn_.Lnki_bgn);
if (name_has_template)
bfr.Add(ns_mgr.Ns_template().Name_db()).Add_byte(Byte_ascii.Colon);
bfr.Add(name_ary);
bfr.Add(Xop_tkn_.Lnki_end);
}
public static void Print_not_found__w_template(Bry_bfr bfr, Xow_ns_mgr ns_mgr, byte[] name_ary) { // print missing as [[:Template:Missing]]; REF:MW: Parser.php|braceSubstitution|$text = "[[:$titleText]]"; EX:en.d:Kazakhstan; DATE:2014-03-25
bfr.Add(Xop_tkn_.Lnki_bgn).Add_byte(Byte_ascii.Colon);
bfr.Add(ns_mgr.Ns_template().Name_db()).Add_byte(Byte_ascii.Colon);
bfr.Add(name_ary).Add(Xop_tkn_.Lnki_end);
}
private boolean SubEval(Xop_ctx ctx, Xowe_wiki wiki, Bry_bfr bfr, byte[] name_ary, Xot_invk caller, byte[] src_for_tkn) {
Xoa_ttl page_ttl = Xoa_ttl.Parse(wiki, name_ary); if (page_ttl == null) return false; // ttl not valid; EX: {{:[[abc]]}}
Xot_defn_tmpl transclude_tmpl = null;
@@ -470,19 +420,18 @@ public class Xot_invk_tkn extends Xop_tkn_itm_base implements Xot_invk {
arg.Tkn_grp_(this, args_len);
args_len = newLen;
} Arg_nde_tkn[] args = Arg_nde_tkn.Ary_empty; int args_max;
Arg_nde_tkn[] Resize(Arg_nde_tkn[] src, int cur_len, int new_len) {
private Arg_nde_tkn[] Resize(Arg_nde_tkn[] src, int cur_len, int new_len) {
Arg_nde_tkn[] rv = new Arg_nde_tkn[new_len];
Array_.Copy_to(src, 0, rv, 0, cur_len);
return rv;
}
public Xot_invk_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return typeId;} private byte typeId = Xop_tkn_itm_.Tid_tmpl_invk;
public void Tkn_tid_to_txt() {typeId = Xop_tkn_itm_.Tid_txt;}
byte[] Get_first_subst_itm(Xol_kwd_mgr kwd_mgr) {
private byte[] Get_first_subst_itm(Xol_kwd_mgr kwd_mgr) {
Xol_kwd_grp grp = kwd_mgr.Get_at(Xol_kwd_grp_.Id_subst); if (grp == null) return Bry_.Empty;
Xol_kwd_itm[] itms = grp.Itms();
return itms.length == 0 ? Bry_.Empty : itms[0].Val();
}
private static final Hash_adp_bry ignore_hash = Hash_adp_bry.ci_a7().Add_str_obj("Citation needed{{subst", "").Add_str_obj("Clarify{{subst", ""); // ignore SafeSubst templates
public static boolean Cache_enabled = false;
}
/*
NOTE_1: if (finder.Colon_pos() != -1) colon_pos = finder.Func().Name().length;

View File

@@ -0,0 +1,81 @@
/*
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.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.langs.kwds.*;
import gplx.xowa.xtns.pfuncs.*;
import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.caches.*;
public class Xot_invk_tkn_ {
public static void Eval_func(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk invk, Bry_bfr bfr, Xot_defn defn, byte[] argx_ary) {
Pf_func_base defn_func = (Pf_func_base)defn;
int defn_func_id = defn_func.Id();
defn_func = (Pf_func_base)defn_func.New(defn_func_id, defn_func.Name()); // NOTE: always make copy b/c argx_ary may be dynamic
if (argx_ary != Bry_.Empty) defn_func.Argx_dat_(argx_ary);
defn_func.Eval_argx(ctx, src, caller, invk);
if (defn_func_id == Xol_kwd_grp_.Id_invoke) // NOTE: if #invoke, set frame_ttl to argx, not name; EX:{{#invoke:A}}
invk.Frame_ttl_(Bry_.Add(Xow_ns_.Bry__module_w_colon, Xoa_ttl.Replace_unders(defn_func.Argx_dat()))); // NOTE: always prepend "Module:" to frame_ttl; DATE:2014-06-13; NOTE: always use spaces; DATE:2014-08-14; always use canonical English "Module"; DATE:2015-11-09
Bry_bfr bfr_func = Bry_bfr_.New();
defn_func.Func_evaluate(bfr_func, ctx, caller, invk, src);
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.Page().Tmpl_prepend_mgr().End(ctx, bfr, bfr_func.Bfr(), bfr_func.Len(), Bool_.N);
bfr.Add_bfr_and_clear(bfr_func);
}
public static void Bld_key(Xot_invk invk, byte[] name_ary, Bry_bfr bfr) {
bfr.Clear();
bfr.Add(name_ary);
int args_len = invk.Args_len();
for (int i = 0; i < args_len; i++) {
Arg_nde_tkn nde = invk.Args_get_by_idx(i);
bfr.Add_byte(Byte_ascii.Pipe);
if (nde.KeyTkn_exists()) {
bfr.Add(nde.Key_tkn().Dat_ary());
bfr.Add_byte(Byte_ascii.Eq);
}
bfr.Add(nde.Val_tkn().Dat_ary());
}
}
public static Xot_defn_tmpl Load_defn(Xowe_wiki wiki, Xop_ctx ctx, Xot_invk_tkn invk_tkn, Xoa_ttl ttl, byte[] name_ary) { // recursive loading of templates
Xow_page_cache_itm tmpl_page_itm = wiki.Cache_mgr().Page_cache().Get_or_load_as_itm(ttl);
byte[] tmpl_page_bry = tmpl_page_itm == null ? null : tmpl_page_itm.Wtxt__direct();
Xot_defn_tmpl rv = null;
if (tmpl_page_bry != null) {
byte old_parse_tid = ctx.Parse_tid(); // NOTE: reusing ctxs is a bad idea; will change Parse_tid and cause strange errors; however, keeping for PERF reasons
Xow_ns ns_tmpl = wiki.Ns_mgr().Ns_template();
rv = wiki.Parser_mgr().Main().Parse_text_to_defn_obj(ctx, ctx.Tkn_mkr(), ns_tmpl, name_ary, tmpl_page_bry);
Xoa_ttl tmpl_page_ttl = tmpl_page_itm.Ttl();
byte[] frame_ttl = Bry_.Add(Xow_ns_canonical_.To_canonical_or_local_as_bry(tmpl_page_ttl.Ns()), Byte_ascii.Colon_bry, tmpl_page_ttl.Page_txt()); // NOTE: (1) must have ns (Full); (2) must be txt (space, not underscore); EX:Template:Location map+; DATE:2014-08-22; (3) must be canonical; DATE:2015-11-09
rv.Frame_ttl_(frame_ttl); // set defn's frame_ttl; needed for redirect_trg; PAGE:en.w:Statutory_city; DATE:2014-08-22
ctx.Parse_tid_(old_parse_tid);
wiki.Cache_mgr().Defn_cache().Add(rv, ns_tmpl.Case_match());
}
return rv;
}
public static void Print_not_found__by_transclude(Bry_bfr bfr, Xow_ns_mgr ns_mgr, boolean name_has_template, byte[] name_ary) {// print missing as [[Missing]]; PAGE:en.d:a DATE:2016-06-24
bfr.Add(Xop_tkn_.Lnki_bgn);
if (name_has_template)
bfr.Add(ns_mgr.Ns_template().Name_db()).Add_byte(Byte_ascii.Colon);
bfr.Add(name_ary);
bfr.Add(Xop_tkn_.Lnki_end);
}
public static void Print_not_found__w_template(Bry_bfr bfr, Xow_ns_mgr ns_mgr, byte[] name_ary) { // print missing as [[:Template:Missing]]; REF:MW: Parser.php|braceSubstitution|$text = "[[:$titleText]]"; EX:en.d:Kazakhstan; DATE:2014-03-25
bfr.Add(Xop_tkn_.Lnki_bgn).Add_byte(Byte_ascii.Colon);
bfr.Add(ns_mgr.Ns_template().Name_db()).Add_byte(Byte_ascii.Colon);
bfr.Add(name_ary).Add(Xop_tkn_.Lnki_end);
}
}

View File

@@ -26,16 +26,19 @@ public class Xot_invk_wkr implements Xop_ctx_wkr, Xop_arg_wkr {
public int Make_tkn(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int lxr_cur_pos, int lxr_end_pos, Xop_curly_bgn_tkn bgn_tkn, int keep_curly_bgn) {
Xot_invk_tkn invk = tkn_mkr.Tmpl_invk(bgn_tkn.Src_bgn(), lxr_end_pos);
int loop_bgn = bgn_tkn.Tkn_sub_idx() + 1, loop_end = root.Subs_len();
if (loop_bgn == loop_end) { // empty template; EX: "{{}}"
root.Subs_del_after(bgn_tkn.Tkn_sub_idx()); // del invk_bgn_tkn
root.Subs_add(tkn_mkr.Txt(bgn_tkn.Src_bgn(), lxr_end_pos));
ctx.Msg_log().Add_itm_none(Xop_tmpl_log.Tmpl_is_empty, src, bgn_tkn.Src_bgn(), lxr_end_pos);
// handle empty template; EX: "{{}}"
if (loop_bgn == loop_end) {
root.Subs_del_after(bgn_tkn.Tkn_sub_idx()); // del invk_bgn_tkn
root.Subs_add(tkn_mkr.Txt(bgn_tkn.Src_bgn(), lxr_end_pos)); // add txt tkn
return lxr_cur_pos;
}
// make arguments
boolean made = arg_bldr.Bld(ctx, tkn_mkr, this, Xop_arg_wkr_.Typ_tmpl, root, invk, lxr_cur_pos, lxr_end_pos, loop_bgn, loop_end, src);
Arg_itm_tkn key_tkn = invk.Name_tkn().Key_tkn();
if (!made
|| (key_tkn.Dat_bgn() == key_tkn.Dat_end() && key_tkn.Dat_bgn() != -1)) { // key_tkn is entirely whitespace; EX: {{\n}}
if ( !made // invalid args;
|| (key_tkn.Dat_bgn() == key_tkn.Dat_end() && key_tkn.Dat_bgn() != -1)) { // key_tkn is entirely whitespace; EX: {{\n}}
invk.Tkn_tid_to_txt();
ctx.Subs_add(root, tkn_mkr.Txt(lxr_cur_pos, lxr_end_pos));
return lxr_cur_pos;
@@ -61,7 +64,6 @@ public class Xot_invk_wkr implements Xop_ctx_wkr, Xop_arg_wkr {
if (key_tkn.Itm_static() != Bool_.Y_byte) return; // dynamic tkn; can't identify func/name
int colon_pos = -1, txt_bgn = key_tkn.Dat_bgn(), txt_end = key_tkn.Dat_end();
Xol_func_itm finder = new Xol_func_itm(); // TS.MEM: DATE:2016-07-12
ctx.Wiki().Lang().Func_regy().Find_defn(finder, src, txt_bgn, txt_end);
Xot_defn finder_func = finder.Func();

View File

@@ -22,10 +22,8 @@ public class Xot_tmpl_wtr {
public byte[] Write_all(Xop_ctx ctx, Xop_root_tkn root, byte[] src) {
// synchronized (this) { // THREAD:added synchronized after "failed to write tkn" DATE:2015-04-29
Bry_bfr rslt_bfr = ctx.Wiki().Utl__bfr_mkr().Get_m001();
ctx.Tmpl_output_(rslt_bfr);
rslt_bfr.Reset_if_gt(Io_mgr.Len_mb);
Write_tkn(ctx, src, src.length, rslt_bfr, root);
ctx.Tmpl_output_(null);
return rslt_bfr.To_bry_and_rls();
// }
}