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

@@ -55,7 +55,7 @@ public class Gallery_itm implements Js_img_wkr {
String itm_html = bfr.To_str_and_clear();
js_wkr.Html_elem_replace_html(String_.new_u8(gallery_li_id_bry), itm_html);
if (gallery_itm_idx == xnde.Itms_len() - 1 && Gallery_mgr_base_.Mode_is_packed(xnde.Mode()))
page.Xtn_gallery_packed_exists_y_(); // set flag for packed_gallery; don't fire multiple times; PAGE:en.w:National_Sculpture_Museum_(Valladolid); DATE:2014-07-21
page.Html_data().Xtn_gallery_packed_exists_y_(); // set flag for packed_gallery; don't fire multiple times; PAGE:en.w:National_Sculpture_Museum_(Valladolid); DATE:2014-07-21
}
finally {
bfr.Mkr_rls(); tmp_bfr.Mkr_rls();

View File

@@ -64,6 +64,10 @@ public class Gallery_xnde implements Xox_xnde, Mwh_atr_itm_owner2 {
Gallery_parser parser = xtn_mgr.Parser();
if (parser.Parse_in_progress()) parser = new Gallery_parser().Init_by_wiki(wiki); // handle nested galleries; EX: <gallery><ref><gallery>; PAGE:es.w:Arquitectura_medieval DATE:2015-07-10
parser.Parse_all(itms, gallery_mgr, this, src, xnde.Tag_open_end(), xnde.Tag_close_bgn());
// if packed, enable flag; needed for reload in Xog_async_wkr; PAGE:en.w:Mexico; DATE:2016-08-14
if (Gallery_mgr_base_.Mode_is_packed(this.mode))
ctx.Page().Xtn_gallery_packed_exists_y_();
} catch (Exception exc) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "failed to write gallery; src=~{0} err=~{1}", String_.new_u8(src, xnde.Src_bgn(), xnde.Src_end()), Err_.Message_gplx_full(exc));
}

View File

@@ -43,23 +43,29 @@ public class Imap_map implements Xoh_file_fmtr, Js_img_wkr {
xfer_itm.Html_img_wkr_(this);
xfer_itm.Html_elem_tid_(Xof_html_elem.Tid_imap);
if (hctx.Mode_is_hdump()) {
img_w = xfer_itm.Lnki_w(); // NOTE: hdump must dump lnki_w, not img_w; GUI will either (a) write -1 and update later thru js_wkr; (b) get correct img_w from cache; hdump can do neither (a) nor (b); DATE:2016-06-17
img_h = xfer_itm.Lnki_h();
if (xfer_itm.Orig_exists()) {
img_w = xfer_itm.Html_w();
img_h = xfer_itm.Html_h();
}
else {
img_w = xfer_itm.Lnki_w(); // NOTE: hdump must dump lnki_w, not img_w; GUI will either (a) write -1 and update later thru js_wkr; (b) get correct img_w from cache; hdump can do neither (a) nor (b); DATE:2016-06-17
img_h = xfer_itm.Lnki_h();
}
}
Write_imap_div(tmp_bfr, hctx, uid, img_w, img_h, img_src, xfer_itm.Orig_w(), xfer_itm.Orig_h(), a_xowa_title);
Write_imap_div(tmp_bfr, hctx, uid, img_w, img_h, img_src, xfer_itm.Orig_exists(), xfer_itm.Orig_w(), xfer_itm.Orig_h(), a_xowa_title);
}
public void Js_wkr__update_hdoc(Xoa_page page, Xog_js_wkr js_wkr, int html_uid
, int html_w, int html_h, Io_url html_view_url
, int orig_w, int orig_h, Xof_ext orig_ext, Io_url html_orig_url, byte[] lnki_ttl) {
Bry_bfr tmp_bfr = Bry_bfr_.Get();
try {
Write_imap_div(tmp_bfr, Xoh_wtr_ctx.Basic, html_uid, html_w, html_h, html_view_url.To_http_file_bry(), orig_w, orig_h, lnki_ttl);
Write_imap_div(tmp_bfr, Xoh_wtr_ctx.Basic, html_uid, html_w, html_h, html_view_url.To_http_file_bry(), orig_w > 0, orig_w, orig_h, lnki_ttl);
js_wkr.Html_elem_replace_html("imap_div_" + Int_.To_str(html_uid), tmp_bfr.To_str_and_rls());
} finally {tmp_bfr.Mkr_rls();}
}
private void Write_imap_div(Bry_bfr bfr, Xoh_wtr_ctx hctx, int html_uid, int html_w, int html_h, byte[] img_src, int orig_w, int orig_h, byte[] lnki_ttl) {
private void Write_imap_div(Bry_bfr bfr, Xoh_wtr_ctx hctx, int html_uid, int html_w, int html_h, byte[] img_src, boolean orig_exists, int orig_w, int orig_h, byte[] lnki_ttl) {
Imap_map_arg map_arg = new Imap_map_arg(id, shapes, Calc_scale(orig_w, orig_h, html_w, html_h));
Imap_img_arg img_arg = new Imap_img_arg(hctx, xtn_mgr, this, html_uid, img_alt, img_src, html_w, html_h, Xoh_img_cls_.To_html(img_cls_tid, img_cls_other), a_href, lnki_ttl);
Imap_img_arg img_arg = new Imap_img_arg(hctx, xtn_mgr, this, html_uid, img_alt, img_src, html_w, html_h, Xoh_img_cls_.To_html(img_cls_tid, img_cls_other), a_href, lnki_ttl, orig_exists);
Imap_html_fmtrs.All.Bld_bfr_many(bfr, html_uid, Calc_desc_style(desc, html_w, html_h), map_arg, img_arg);
}
private static byte[] Calc_desc_style(Imap_part_desc desc, int html_w, int html_h) {

View File

@@ -192,7 +192,7 @@ public class Imap_parser {
if ( tkn_itm == null // no lnki or lnke
|| tkn_itm.Tkn_tid() != Xop_tkn_itm_.Tid_lnki // no lnki; occurs with badly constructed maps; PAGE:en.w:Demography_of_the_United_Kingdom DATE:2015-01-22
)
Xoa_app_.Usr_dlg().Warn_many("", "", "image_map failed to find lnki; page=~{0} imageMap=~{1}", page_url.To_str(), imap_img_src);
Xoa_app_.Usr_dlg().Note_many("", "", "image_map failed to find lnki; page=~{0} imageMap=~{1}", page_url.To_str(), imap_img_src);
else {
Xop_lnki_tkn lnki_tkn = (Xop_lnki_tkn)tkn_itm;
imap_img = new Imap_part_img(lnki_tkn);

View File

@@ -31,12 +31,12 @@ public class Imap_html__hdump__tst {
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div class=\"thumbinner\" style=\"width:100px;\">" // NOTE:220px is default w for "non-found" thumb; DATE:2014-09-24
, " <div id='imap_div_0' class=\"noresize\">"
, " <div id=\"imap_div_0\" class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " <area href=\"/wiki/B\" shape=\"circle\" coords=\"0,0,5\" alt=\"b1\" title=\"b1\"/>"
, " <area href=\"/wiki/C\" shape=\"rect\" coords=\"0,0,4,8\" alt=\"c1\" title=\"c1\"/>"
, " </map>"
, " <img data-xowa-title=\"A.png\" data-xoimg=\"1|100|200|-1|-1|-1\" src=\"\" width=\"0\" height=\"0\" class=\"thumbimage\" alt=\"\" usemap=\"#imagemap_1_1\"/>"
, " <img data-xowa-title=\"A.png\" data-xoimg=\"1|100|200|-1|-1|-1\" src=\"\" width=\"0\" height=\"0\" alt=\"\" usemap=\"#imagemap_1_1\"/>"
, " </div>"
, " <div class=\"thumbcaption\">"
, "<div class=\"magnify\"><a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\"></a></div>a1"

View File

@@ -30,7 +30,7 @@ public class Imap_html__hview__tst {
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">" // NOTE:220px is default w for "non-found" thumb; DATE:2014-09-24
, " <div id='imap_div_0' class=\"noresize\">"
, " <div id=\"imap_div_0\" class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " <area href=\"/wiki/B\" shape=\"circle\" coords=\"0,0,5\" alt=\"b1\" title=\"b1\"/>"
, " <area href=\"/wiki/C\" shape=\"rect\" coords=\"0,0,4,8\" alt=\"c1\" title=\"c1\"/>"
@@ -56,7 +56,7 @@ public class Imap_html__hview__tst {
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">" // NOTE:220px is default w for "non-found" thumb; DATE:2014-09-24
, " <div id='imap_div_0' class=\"noresize\">"
, " <div id=\"imap_div_0\" class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <a href=\"/wiki/B\" title=\"b1\">"
@@ -77,7 +77,7 @@ public class Imap_html__hview__tst {
, "desc top-left"
, "</imagemap>"
), String_.Concat_lines_nl_skip_last
( "<div id='imap_div_0' class=\"noresize\" style=\"height:0px; width: 123px;\">"
( "<div id=\"imap_div_0\" class=\"noresize\" style=\"height:0px; width: 123px;\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <img id=\"xoimg_0\" alt=\"a1\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" usemap=\"#imageMap_1_1\"/>"
@@ -99,7 +99,7 @@ public class Imap_html__hview__tst {
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">" // NOTE:220px is default w for "non-found" thumb; DATE:2014-09-24
, " <div id='imap_div_0' class=\"noresize\">"
, " <div id=\"imap_div_0\" class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " <area href=\"http://b.org\" shape=\"circle\" coords=\"0,0,5\" alt=\"b1\" title=\"b1\"/>"
, " </map>"
@@ -138,7 +138,7 @@ public class Imap_html__hview__tst {
( "<table>"
, " <tr>"
, " <td> z"
, "<div id='imap_div_0' class=\"noresize\">"
, "<div id=\"imap_div_0\" class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <img id=\"xoimg_0\" alt=\"b\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" usemap=\"#imageMap_1_1\"/>" // NOTE: width must be 123, not 0
@@ -165,7 +165,7 @@ public class Imap_html__hview__tst {
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">" // NOTE:220px is default w for "non-found" thumb; DATE:2014-09-24
, " <div id='imap_div_0' class=\"noresize\">"
, " <div id=\"imap_div_0\" class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " <area href=\"/wiki/B\" shape=\"circle\" coords=\"0,0,5\" alt=\"b1\" title=\"b1\"/>"
, " </map>"
@@ -198,7 +198,7 @@ class Imap_xnde_html_fxt {
public void Test_html_full_frag(String raw, String expd) {fxt.Test_html_full_frag(raw, expd);}
public String Frag_html_full() {
return String_.Concat_lines_nl_skip_last
( "<div id='imap_div_0' class=\"noresize\">"
( "<div id=\"imap_div_0\" class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <img id=\"xoimg_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" usemap=\"#imageMap_1_1\"/>"

View File

@@ -20,7 +20,7 @@ import gplx.core.brys.fmtrs.*;
public class Imap_html_fmtrs {
public static final Bry_fmtr
All = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<div id='imap_div_~{imap_id}' class=\"noresize\"~{desc_style}>~{map}~{img}"
( "<div id=\"imap_div_~{imap_id}\" class=\"noresize\"~{desc_style}>~{map}~{img}"
, " </div>"
), "imap_id", "desc_style", "map", "img"
)

View File

@@ -26,12 +26,14 @@ public class Imap_img_arg implements gplx.core.brys.Bfr_arg {
private final int img_elem_id, img_w, img_h;
private final byte[] img_alt, img_src, img_cls, img_href, lnki_ttl;
private final Int_2_ref margin_calc = new Int_2_ref();
private final boolean orig_exists;
public Imap_img_arg(Xoh_wtr_ctx hctx, Imap_xtn_mgr xtn_mgr, Imap_map map
, int img_elem_id, byte[] img_alt, byte[] img_src, int img_w, int img_h, byte[] img_cls, byte[] img_href, byte[] lnki_ttl) {
, int img_elem_id, byte[] img_alt, byte[] img_src, int img_w, int img_h, byte[] img_cls, byte[] img_href, byte[] lnki_ttl, boolean orig_exists) {
this.hctx = hctx; this.map = map; this.xtn_mgr = xtn_mgr;
this.img_elem_id = img_elem_id; this.img_w = img_w; this.img_h = img_h;
this.img_alt = img_alt; this.img_src = img_src; this.img_cls = img_cls; this.img_href = img_href;
this.lnki_ttl = lnki_ttl;
this.orig_exists = orig_exists;
}
public void Bfr_arg__add(Bry_bfr bfr) {
Bry_fmtr fmtr = Imap_html_fmtrs.Img_anchor_none;
@@ -43,7 +45,16 @@ public class Imap_img_arg implements gplx.core.brys.Bfr_arg {
byte[] data_xowa_image = Xoh_file_fmtr__hdump.Bld_xowa_image_data(tmp_bfr, Xop_lnki_type.Id_none, img_w, img_h, Xop_lnki_tkn.Upright_null, Xof_lnki_time.Null, Xof_lnki_page.Null);
byte[] data_xowa_title = Gfh_atr_.Make(tmp_bfr, Xoh_img_xoimg_data.Bry__data_xowa_title, lnki_ttl);
byte[] usemap = tmp_bfr.Add(Imap_xtn_mgr.Bry__usemap__html).Add_int_variable(map.Id()).Add_byte_quote().To_bry_and_clear();
Xoh_file_fmtr__hdump.Add_anch_n(tmp_bfr, data_xowa_title, data_xowa_image, Xoh_img_cls_.Tid__thumbimage, Bry_.Empty, Bry_.Empty, usemap);
int img_w_tmp = img_w; int img_h_tmp = img_h;
byte[] img_src_tmp = img_src;
if (orig_exists) {
data_xowa_image = data_xowa_title = Bry_.Empty;
}
else {
img_w_tmp = img_h_tmp = 0;
img_src_tmp = Bry_.Empty;
}
Xoh_file_fmtr__hdump.Add_anch_n(tmp_bfr, data_xowa_title, data_xowa_image, img_src_tmp, img_w_tmp, img_h_tmp, Xoh_img_cls_.Tid__none, Bry_.Empty, Bry_.Empty, usemap);
bfr.Add_byte_nl().Add_byte_repeat(Byte_ascii.Space, 6);
bfr.Add_bfr_and_clear(tmp_bfr);
} finally {tmp_bfr.Mkr_rls();}

View File

@@ -0,0 +1,115 @@
/*
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.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.hdrs.*;
import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.pages.wtxts.*;
public class Lst_pfunc_itm {
public Lst_pfunc_itm(byte[] itm_src, Lst_section_nde_mgr sec_mgr, Xopg_toc_mgr toc_mgr) {
this.itm_src = itm_src; this.sec_mgr = sec_mgr; this.toc_mgr = toc_mgr;
}
public byte[] Itm_src() {return itm_src;} private final byte[] itm_src;
public Lst_section_nde_mgr Sec_mgr() {return sec_mgr;} private final Lst_section_nde_mgr sec_mgr;
public Xopg_toc_mgr Toc_mgr() {return toc_mgr;} private final Xopg_toc_mgr toc_mgr;
public static Lst_pfunc_itm New_sect_or_null(Xop_ctx ctx, byte[] ttl_bry) {
// init wiki, ttl
Xowe_wiki wiki = ctx.Wiki();
Xoa_ttl ttl = wiki.Ttl_parse(ttl_bry); if (ttl == null) return null; // EX:{{#lst:<>}} -> ""
// get from cache
Lst_pfunc_itm rv = (Lst_pfunc_itm)wiki.Cache_mgr().Lst_cache().Get_by_bry(ttl_bry);
if (rv == null) { // cache transclusions to prevent multiple parsings; DATE:2014-02-22
// get sub_src;
Xop_ctx sub_ctx = Xop_ctx.New__top(wiki).Ref_ignore_(true);
sub_ctx.Page().Ttl_(ctx.Page().Ttl()); // NOTE: must set ttl on page, else test fails;
byte[] sub_src = wiki.Cache_mgr().Page_cache().Get_or_load_as_src(ttl); if (sub_src == null) return null; // {{#lst:missing}} -> ""
// parse page; note adding to stack to prevent circular recursions
if (!wiki.Parser_mgr().Tmpl_stack_add(ttl.Full_db())) return null;
Xot_defn_tmpl tmpl = wiki.Parser_mgr().Main().Parse_text_to_defn_obj(sub_ctx, sub_ctx.Tkn_mkr(), ttl.Ns(), ttl_bry, sub_src); // NOTE: parse as tmpl to ignore <noinclude>
wiki.Parser_mgr().Tmpl_stack_del(); // take template off stack; evaluate will never recurse, but will fail if ttl is still on stack; DATE:2014-03-10
// eval tmpl
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001();
tmpl.Tmpl_evaluate(sub_ctx, Xot_invk_temp.Page_is_caller, tmp_bfr);
sub_src = tmp_bfr.To_bry_and_rls();
// parse again
if (!wiki.Parser_mgr().Tmpl_stack_add(ttl.Full_db())) return null; // put template back on stack;
sub_ctx.Page().Wtxt().Toc().Clear(); // HACK: must clear toc hdrs; should probably create a new top sub_ctx; DATE:2016-08-17
Xop_root_tkn root = wiki.Parser_mgr().Main().Parse_text_to_wdom(sub_ctx, sub_src, true); // NOTE: pass sub_ctx as old_ctx b/c entire document will be parsed, and references outside the section should be ignored;
wiki.Parser_mgr().Tmpl_stack_del();
sub_src = root.Data_mid(); // NOTE: must set src to root.Data_mid() which is result of parse; else <nowiki> will break text; DATE:2013-07-11
// add to cache
rv = new Lst_pfunc_itm(sub_src, Clone(sub_ctx.Lst_section_mgr()), Clone(sub_ctx.Page().Wtxt().Toc(), sub_src, ttl_bry));
wiki.Cache_mgr().Lst_cache().Add(ttl_bry, rv);
}
return rv;
}
public static Lst_pfunc_itm New_hdr_or_null(Xop_ctx ctx, byte[] ttl_bry) {
// init wiki, ttl
Xowe_wiki wiki = ctx.Wiki();
Xoa_ttl ttl = wiki.Ttl_parse(ttl_bry); if (ttl == null) return null; // EX:{{#lst:<>}} -> ""
// get from cache
Lst_pfunc_itm rv = (Lst_pfunc_itm)wiki.Cache_mgr().Lst_cache().Get_by_bry(ttl_bry);
if (rv == null) { // cache transclusions to prevent multiple parsings; DATE:2014-02-22
// get sub_ctx: note new ctx is needed b/c sub_page objects must not get added to owner_page; for example, references / hdrs / lnki.files
Xop_ctx sub_ctx = Xop_ctx.New__top(wiki).Ref_ignore_(true);
sub_ctx.Page().Ttl_(ctx.Page().Ttl()); // NOTE: must set ttl on page, else test fails;
byte[] sub_src = wiki.Cache_mgr().Page_cache().Get_or_load_as_src(ttl); if (sub_src == null) return null; // {{#lst:missing}} -> ""
// parse sub_src; note adding to page's stack to prevent circular recursions
if (!wiki.Parser_mgr().Tmpl_stack_add(ttl.Full_db())) return null;
Xop_root_tkn root = wiki.Parser_mgr().Main().Parse_text_to_wdom(sub_ctx, sub_src, true); // NOTE: parse as defn will drop <onlyinclude>; PAGE:en.w:10s_BC; DATE:2016-08-13
wiki.Parser_mgr().Tmpl_stack_del();
// HACK: parse sub_src again b/c transcluded templates will add their hdrs to toc_mgr; PAGE:en.w:Germany_national_football_team DATE:2016-08-13
sub_src = root.Data_mid(); // NOTE: must set src to root.Data_mid() which is result of parse; else <nowiki> will break text; DATE:2013-07-11
sub_ctx.Page().Wtxt().Toc().Clear(); // HACK: must clear toc hdrs; should probably create a new top sub_ctx; DATE:2016-08-17
root = wiki.Parser_mgr().Main().Parse_text_to_wdom(sub_ctx, sub_src, true);
sub_src = root.Data_mid(); // NOTE: must call root.Data_mid() again b/c previous src may have nowiki which will get removed in 2nd pass; see TEST:Tmpl_w_nowiki; DATE:2016-08-13
// add to cache
rv = new Lst_pfunc_itm(sub_src, Clone(sub_ctx.Lst_section_mgr()), Clone(sub_ctx.Page().Wtxt().Toc(), sub_src, ttl_bry));
wiki.Cache_mgr().Lst_cache().Add(ttl_bry, rv);
}
return rv;
}
private static Xopg_toc_mgr Clone(Xopg_toc_mgr prime, byte[] src, byte[] ttl_bry) {
Xopg_toc_mgr rv = new Xopg_toc_mgr();
int len = prime.Len();
int src_len = src.length;
for (int i = 0; i < len; ++i) {
Xop_hdr_tkn hdr = prime.Get_at(i);
if (hdr.Src_bgn() > src_len || hdr.Src_end() > src_len) // DEBUG:handle random cases where hdr is out of bounds of source; PAGE:en.w:Germany_national_football_team DATE:2016-08-13
Gfo_usr_dlg_.Instance.Warn_many("", "", "lst:headers are not in bounds of source; ttl=~{0} src=~{1} hdr_bgn=~{2} hdr_end=~{3}", ttl_bry, src_len, hdr.Src_bgn(), hdr.Src_end());
rv.Add(hdr);
}
return rv;
}
private static Lst_section_nde_mgr Clone(Lst_section_nde_mgr src) {
Lst_section_nde_mgr rv = new Lst_section_nde_mgr();
int len = src.Len();
for (int i = 0; i < len; ++i)
rv.Add(src.Get_at(i));
return rv;
}
public static final byte[] Null_arg = null;
}

View File

@@ -23,11 +23,16 @@ public class Lst_pfunc_lst extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_lst;}
@Override public Pf_func New(int id, byte[] name) {return new Lst_pfunc_lst().Name_(name);}
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
byte[] src_ttl_bry = Eval_argx(ctx, src, caller, self); if (Bry_.Len_eq_0(src_ttl_bry)) return; // {{#lst:}} -> ""
// get args
byte[] page_ttl = Eval_argx(ctx, src, caller, self); if (Bry_.Len_eq_0(page_ttl)) return; // {{#lst:}} -> ""
int args_len = self.Args_len();
byte[] sect_bgn = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 0, Lst_pfunc_wkr.Null_arg);
byte[] sect_end = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 1, Lst_pfunc_wkr.Null_arg);
new Lst_pfunc_wkr().Init_include(src_ttl_bry, sect_bgn, sect_end).Exec(bfr, ctx);
byte[] sect_bgn = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 0, Lst_pfunc_itm.Null_arg);
byte[] sect_end = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 1, Lst_pfunc_itm.Null_arg);
// parse
Lst_pfunc_itm itm = Lst_pfunc_itm.New_sect_or_null(ctx, page_ttl); if (itm == null) return;
Lst_pfunc_lst_.Sect_include(bfr, itm.Sec_mgr(), itm.Itm_src(), sect_bgn, sect_end);
}
public static final Lst_pfunc_lst Instance = new Lst_pfunc_lst(); Lst_pfunc_lst() {}
public static final Lst_pfunc_lst Prime = new Lst_pfunc_lst(); Lst_pfunc_lst() {}
}

View File

@@ -0,0 +1,72 @@
/*
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.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
public class Lst_pfunc_lst_ {
private static final byte Include_between = 0, Include_to_eos = 1, Include_to_bos = 2;
public static void Sect_include(Bry_bfr bfr, Lst_section_nde_mgr sec_mgr, byte[] src, byte[] lst_bgn, byte[] lst_end) {
if (lst_end == Lst_pfunc_itm.Null_arg) { // no end arg; EX: {{#lst:page|bgn}}; NOTE: different than {{#lst:page|bgn|}}
if (lst_bgn == Lst_pfunc_itm.Null_arg) { // no bgn arg; EX: {{#lst:page}}
bfr.Add(src); // write all and exit
return;
}
else // bgn exists; set end to bgn; EX: {{#lst:page|bgn}} is same as {{#lst:page|bgn|bgn}}; NOTE: {{#lst:page|bgn|}} means write from bgn to eos
lst_end = lst_bgn;
}
byte include_mode = Include_between;
if (Bry_.Len_eq_0(lst_end))
include_mode = Include_to_eos;
else if (Bry_.Len_eq_0(lst_bgn))
include_mode = Include_to_bos;
int bgn_pos = 0; boolean bgn_found = false; int src_page_bry_len = src.length;
int sections_len = sec_mgr.Len();
for (int i = 0; i < sections_len; i++) {
Lst_section_nde section = sec_mgr.Get_at(i);
byte section_tid = section.Name_tid();
byte[] section_key = section.Section_name();
if (section_tid == Lst_section_nde.Xatr_bgn && Bry_.Eq(section_key, lst_bgn)) {
int sect_bgn_rhs = section.Xnde().Tag_close_end();
if (include_mode == Include_to_eos) { // write from cur to eos; EX: {{#lst:page|bgn|}}
bfr.Add_mid(src, sect_bgn_rhs, src_page_bry_len);
return;
}
else { // bgn and end
if (!bgn_found) { // NOTE: !bgn_found to prevent "resetting" of dupe; EX: <s begin=key0/>a<s begin=key0/>b; should start from a not b
bgn_pos = sect_bgn_rhs;
bgn_found = true;
}
}
}
else if (section_tid == Lst_section_nde.Xatr_end && Bry_.Eq(section_key, lst_end)) {
int sect_end_lhs = section.Xnde().Tag_open_bgn();
if (include_mode == Include_to_bos) { // write from bos to cur; EX: {{#lst:page||end}}
bfr.Add_mid(src, 0, sect_end_lhs);
return;
}
else {
if (bgn_found) { // NOTE: bgn_found to prevent writing from bos; EX: a<s end=key0/>b should not write anything
bfr.Add_mid(src, bgn_pos, sect_end_lhs);
bgn_found = false;
}
}
}
}
if (bgn_found) // bgn_found, but no end; write to end of page; EX: "a <section begin=key/> b" -> " b"
bfr.Add_mid(src, bgn_pos, src_page_bry_len);
}
}

View File

@@ -0,0 +1,37 @@
/*
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.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
import gplx.xowa.xtns.pfuncs.*;
public class Lst_pfunc_lsth extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_lsth;}
@Override public Pf_func New(int id, byte[] name) {return new Lst_pfunc_lsth().Name_(name);}
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
// get args
byte[] page_ttl = Eval_argx(ctx, src, caller, self); if (Bry_.Len_eq_0(page_ttl)) return; // {{#lsth:}} -> ""
int args_len = self.Args_len();
byte[] hdr_bgn = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 0, Lst_pfunc_itm.Null_arg);
byte[] hdr_end = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 1, Lst_pfunc_itm.Null_arg);
// parse
Lst_pfunc_itm itm = Lst_pfunc_itm.New_hdr_or_null(ctx, page_ttl); if (itm == null) return;
Lst_pfunc_lsth_.Hdr_include(bfr, itm.Itm_src(), itm.Toc_mgr(), hdr_bgn, hdr_end);
}
public static final Lst_pfunc_lsth Prime = new Lst_pfunc_lsth(); Lst_pfunc_lsth() {}
}

View File

@@ -0,0 +1,73 @@
/*
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.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.wikis.pages.wtxts.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.hdrs.*;
class Lst_pfunc_lsth_ {
public static void Hdr_include(Bry_bfr bfr, byte[] src, Xopg_toc_mgr toc_mgr, byte[] lhs_hdr, byte[] rhs_hdr) {// REF.MW:LabeledSectionTransclusion.class.php|pfuncIncludeHeading; MW does regex on text; XO uses section_itms
// get <hdr> idxs
int len = toc_mgr.Len();
int lhs_idx = Match_or_neg1(toc_mgr, len, src, lhs_hdr, 0) ; if (lhs_idx == -1) return;
int rhs_idx = Match_or_neg1(toc_mgr, len, src, rhs_hdr, lhs_idx + 1);
// get snip_bgn
Xop_hdr_tkn lhs_tkn = toc_mgr.Get_at(lhs_idx);
int snip_bgn = lhs_tkn.Src_end();
// get snip_end
int snip_end = -1;
if (rhs_idx == -1) { // rhs_idx missing or not supplied
rhs_idx = lhs_idx + 1;
if (rhs_idx < len) { // next hdr after lhs_hdr exists; try to get next "matching" hdr; EX: h2 should match next h2; PAGE:en.w:10s_BC; DATE:2016-08-13
for (int i = rhs_idx; i < len; ++i) {
Xop_hdr_tkn rhs_tkn = toc_mgr.Get_at(i);
if (rhs_tkn.Num() == lhs_tkn.Num()) {
snip_end = rhs_tkn.Src_bgn();
break;
}
}
}
if (snip_end == -1) // no matching rhs exists, or rhs is last; get till EOS
snip_end = src.length;
}
else {
Xop_hdr_tkn rhs_tkn = toc_mgr.Get_at(rhs_idx);
snip_end = rhs_tkn.Src_bgn();
}
bfr.Add_mid(src, snip_bgn, snip_end);
}
private static int Match_or_neg1(Xopg_toc_mgr toc_mgr, int hdrs_len, byte[] src, byte[] match, int hdrs_bgn) {
for (int i = hdrs_bgn; i < hdrs_len; ++i) {
Xop_hdr_tkn hdr = toc_mgr.Get_at(i);
int txt_bgn = hdr.Src_bgn() + hdr.Num(); // skip "\n=="; 1=leading \n
if (hdr.Src_bgn() != Xop_parser_.Doc_bgn_char_0)
++txt_bgn;
// get txt_end; note that this needs to handle multiple trailing \n which is included in hdr.Src_end()
int txt_end = Bry_find_.Find_fwd(src, Bry__hdr_end, txt_bgn); // find "=\n"
txt_end = Bry_find_.Find_bwd__skip(src, txt_end, txt_bgn, Byte_ascii.Eq); // skip bwd to get to pos before 1st "="; EX: "===\n" -> find "=="
// remove ws
txt_bgn = Bry_find_.Find_fwd_while_ws(src, txt_bgn, txt_end);
txt_end = Bry_find_.Find_bwd__skip_ws(src, txt_end, txt_bgn);
if (Bry_.Eq(src, txt_bgn, txt_end, match)) return i;
}
return -1;
}
private static final byte[] Bry__hdr_end = Bry_.new_a7("=\n");
}

View File

@@ -0,0 +1,132 @@
/*
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.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Lst_pfunc_lsth_tst {
private final Lst_pfunc_lst_fxt fxt = new Lst_pfunc_lst_fxt();
private final String src_str_dflt = String_.Concat_lines_nl_skip_last
( "txt_0"
, "== hdr_1 =="
, "txt_1"
, "== hdr_2 =="
, "txt_2"
, "== hdr_3 =="
, "txt_3"
);
@Before public void init() {fxt.Clear();}
@Test public void Bgn__missing() { // PURPOSE: return ""
fxt.Page_txt_(src_str_dflt).Test_lst("{{#lsth:section_test|hdr_x}}", "");
}
@Test public void End__exists() {
fxt.Page_txt_(src_str_dflt).Test_lst("{{#lsth:section_test|hdr_1|hdr_3}}", String_.Concat_lines_nl_skip_last
( "txt_1"
, ""
, "<h2> hdr_2 </h2>"
, "txt_2"
));
}
@Test public void End__missing() { // PURPOSE: read to end of next section
String expd = String_.Concat_lines_nl_skip_last
( "txt_1"
);
fxt.Clear().Page_txt_(src_str_dflt).Test_lst("{{#lsth:section_test|hdr_1}}" , expd); // argument not given
fxt.Clear().Page_txt_(src_str_dflt).Test_lst("{{#lsth:section_test|hdr_1|hdr_x}}", expd); // argument is wrong
}
@Test public void End__missing_eos() { // PURPOSE: read to EOS if last
String expd = String_.Concat_lines_nl_skip_last
( "txt_3"
);
fxt.Clear().Page_txt_(src_str_dflt).Test_lst("{{#lsth:section_test|hdr_3}}" , expd); // argument not given
fxt.Clear().Page_txt_(src_str_dflt).Test_lst("{{#lsth:section_test|hdr_3|hdr_x}}", expd); // argument is wrong
}
@Test public void End__missing__match__len() { // PURPOSE:match next hdr with same length; PAGE:en.w:10s_BC; DATE:2016-08-13
String src_str = String_.Concat_lines_nl_skip_last
( "txt_0"
, "== hdr_1 =="
, "txt_1"
, "=== hdr_1a ==="
, "txt_1a"
, "== hdr_2 =="
, "txt_2"
);
fxt.Page_txt_(src_str).Test_lst("{{#lsth::section_test|hdr_1}}", String_.Concat_lines_nl_skip_last
( "txt_1"
, ""
, "<h3> hdr_1a </h3>"
, "txt_1a"
));
}
@Test public void Extra_nl() { // PURPOSE: hdr.Src_end() includes trailing nl; PAGE:en.w:10s_BC; DATE:2016-08-13
String src_str = String_.Concat_lines_nl_skip_last
( "txt_0"
, "== hdr_1 =="
, ""
, "txt_1"
, "== hdr_2 =="
, "txt_2"
);
fxt.Clear().Page_txt_(src_str).Test_lst("{{#lsth:section_test|hdr_1}}" , "txt_1");
}
@Test public void Only_include() { // PAGE:en.w:10s_BC; DATE:2016-08-13
String src_str = String_.Concat_lines_nl_skip_last
( "txt_0"
, "== hdr_1 =="
, "<onlyinclude>txt_1</onlyinclude>"
, "== hdr_2 =="
, "txt_2"
, "== hdr_3 =="
, "txt_3"
);
fxt.Page_txt_(src_str).Test_lst("{{#lsth::section_test|hdr_1}}", "txt_1");
}
@Test public void Bos() { // PURPOSE.defensive:handle == at BOS; DATE:2016-08-13
String src_str = String_.Concat_lines_nl_skip_last
( "==hdr_1 =="
, "txt_1"
, "== hdr_2 =="
, "txt_2"
);
fxt.Clear().Page_txt_(src_str).Test_lst("{{#lsth:section_test|hdr_1}}", "txt_1");
}
@Test public void Nested__lst() { // PURPOSE:lst inside lsth will add its toc_mgr to lsth; PAGE:en.w:Germany_national_football_team; DATE:2016-08-13
fxt.Fxt().Init_page_create("Nested_lst", String_.Concat_lines_nl_skip_last
( "test"
, "==hdr_1=="
, "txt_1"
));
String src_str = String_.Concat_lines_nl_skip_last
( "{{#lst:Nested_lst}}"
, "==hdr_2=="
, "txt_2"
, "==hdr_3=="
, "txt_3"
);
fxt.Page_txt_(src_str).Test_lst("{{#lsth::section_test|hdr_1}}", "txt_1"); // will fail with idx_out_of_bounds b/c hdr_1.Src_bgn / hdr_1.Src_end will be for Nested_lst's src
}
@Test public void Tmpl_w_nowiki() { // ISSUE:nowiki inside template can cause wrong offsets; PAGE:en.w:Germany_national_football_team; DATE:2016-08-13
fxt.Fxt().Init_page_create("Template:Nested_nowiki", "<nowiki>test</nowiki>");
String src_str = String_.Concat_lines_nl_skip_last
( "{{Nested_nowiki}}"
, "==hdr_2=="
, "txt_2"
, "==hdr_3=="
, "txt_3"
);
fxt.Page_txt_(src_str).Test_lst("{{#lsth::section_test|hdr_2}}", "txt_2"); // will fail with "" b/c <nowiki> requires a 2nd "sub_src = root.Data_mid()"
}
}

View File

@@ -23,11 +23,14 @@ public class Lst_pfunc_lstx extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_lstx;}
@Override public Pf_func New(int id, byte[] name) {return new Lst_pfunc_lstx().Name_(name);}
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
byte[] src_ttl_bry = Eval_argx(ctx, src, caller, self); if (Bry_.Len_eq_0(src_ttl_bry)) return; // {{#lst:}} -> ""
byte[] page_ttl = Eval_argx(ctx, src, caller, self); if (Bry_.Len_eq_0(page_ttl)) return; // {{#lst:}} -> ""
int args_len = self.Args_len();
byte[] sect_exclude = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 0, Lst_pfunc_wkr.Null_arg);
byte[] sect_replace = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 1, Lst_pfunc_wkr.Null_arg);
new Lst_pfunc_wkr().Init_exclude(src_ttl_bry, sect_exclude, sect_replace).Exec(bfr, ctx);
byte[] sect_exclude = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 0, Lst_pfunc_itm.Null_arg);
byte[] sect_replace = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 1, Lst_pfunc_itm.Null_arg);
// parse
Lst_pfunc_itm itm = Lst_pfunc_itm.New_sect_or_null(ctx, page_ttl); if (itm == null) return;
Lst_pfunc_lstx_.Sect_exclude(bfr, itm.Sec_mgr(), itm.Itm_src(), sect_exclude, sect_replace);
}
public static final Lst_pfunc_lstx Instance = new Lst_pfunc_lstx(); Lst_pfunc_lstx() {}
public static final Lst_pfunc_lstx Prime = new Lst_pfunc_lstx(); Lst_pfunc_lstx() {}
}

View File

@@ -0,0 +1,44 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.parsers.*;
class Lst_pfunc_lstx_ {
public static void Sect_exclude(Bry_bfr bfr, Lst_section_nde_mgr sec_mgr, byte[] src, byte[] sect_exclude, byte[] sect_replace) {
if (Bry_.Len_eq_0(sect_exclude)) { // no exclude arg; EX: {{#lstx:page}} or {{#lstx:page}}
bfr.Add(src); // write all and exit
return;
}
int sections_len = sec_mgr.Len();
int bgn_pos = 0;
for (int i = 0; i < sections_len; i++) {
Lst_section_nde section = sec_mgr.Get_at(i);
byte section_tid = section.Name_tid();
byte[] section_key = section.Section_name();
if (section_tid == Lst_section_nde.Xatr_bgn && Bry_.Eq(section_key, sect_exclude)) { // exclude section found
bfr.Add_mid(src, bgn_pos, section.Xnde().Tag_open_bgn()); // write everything from bgn_pos up to exclude
}
else if (section_tid == Lst_section_nde.Xatr_end && Bry_.Eq(section_key, sect_exclude)) { // exclude end found
if (sect_replace != null)
bfr.Add(sect_replace); // write replacement
bgn_pos = section.Xnde().Tag_close_end(); // reset bgn_pos
}
}
bfr.Add_mid(src, bgn_pos, src.length);
}
public static final byte[] Null_arg = null;
}

View File

@@ -1,141 +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.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.wikis.nss.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
public class Lst_pfunc_wkr {
private boolean mode_include = true;
private byte[] src_ttl_bry;
private byte[] sect_bgn, sect_end;
private byte[] sect_exclude, sect_replace;
public Lst_pfunc_wkr Init_include(byte[] src_ttl_bry, byte[] sect_bgn, byte[] sect_end) {
this.mode_include = Bool_.Y; this.src_ttl_bry = src_ttl_bry; this.sect_bgn = sect_bgn; this.sect_end = sect_end; return this;
}
public Lst_pfunc_wkr Init_exclude(byte[] src_ttl_bry, byte[] sect_exclude, byte[] sect_replace) {
this.mode_include = Bool_.N; this.src_ttl_bry = src_ttl_bry; this.sect_exclude = sect_exclude; this.sect_replace = sect_replace; return this;
}
public void Exec(Bry_bfr bfr, Xop_ctx ctx) {
Xowe_wiki wiki = ctx.Wiki();
Xoa_ttl src_ttl = Xoa_ttl.Parse(wiki, src_ttl_bry); if (src_ttl == null) return; // {{#lst:<>}} -> ""
Xot_defn_tmpl defn_tmpl = (Xot_defn_tmpl)wiki.Cache_mgr().Lst_cache().Get_by_key(src_ttl_bry);
Xop_ctx sub_ctx = null;
byte[] src = null;
if (defn_tmpl == null) { // cache transclusions to prevent multiple parsings; DATE:2014-02-22
sub_ctx = Xop_ctx.New__sub__reuse_page(ctx).Ref_ignore_(true);
byte[] src_page_bry = wiki.Cache_mgr().Page_cache().Get_or_load_as_src(src_ttl);
if (src_page_bry == null) return; // {{#lst:missing}} -> ""
Xoae_page page = ctx.Page();
if (!page.Tmpl_stack_add(src_ttl.Full_db())) return;
defn_tmpl = wiki.Parser_mgr().Main().Parse_text_to_defn_obj(sub_ctx, sub_ctx.Tkn_mkr(), src_ttl.Ns(), src_ttl_bry, src_page_bry); // NOTE: parse as tmpl to ignore <noinclude>
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_m001();
page.Tmpl_stack_del(); // take template off stack; evaluate will never recurse, and will fail if ttl is still on stack; DATE:2014-03-10
defn_tmpl.Tmpl_evaluate(sub_ctx, Xot_invk_temp.Page_is_caller, tmp_bfr);
src = tmp_bfr.To_bry_and_rls();
if (!page.Tmpl_stack_add(src_ttl.Full_db())) return; // put template back on stack;
Xop_root_tkn root = wiki.Parser_mgr().Main().Parse_text_to_wdom(sub_ctx, src, true); // NOTE: pass sub_ctx as old_ctx b/c entire document will be parsed, and references outside the section should be ignored;
src = root.Data_mid(); // NOTE: must set src to root.Data_mid() which is result of parse; else <nowiki> will break text; DATE:2013-07-11
wiki.Cache_mgr().Lst_cache().Add(defn_tmpl, Xow_ns_case_.Tid__all);
page.Tmpl_stack_del();
defn_tmpl.Data_mid_(src);
defn_tmpl.Ctx_(sub_ctx);
}
else {
src = defn_tmpl.Data_mid();
sub_ctx = defn_tmpl.Ctx();
}
if (mode_include) Write_include(bfr, sub_ctx, src, sect_bgn, sect_end);
else Write_exclude(bfr, sub_ctx, src, sect_exclude, sect_replace);
}
private static final byte Include_between = 0, Include_to_eos = 1, Include_to_bos = 2;
private static void Write_include(Bry_bfr bfr, Xop_ctx sub_ctx, byte[] src, byte[] lst_bgn, byte[] lst_end) {
if (lst_end == Null_arg) { // no end arg; EX: {{#lst:page|bgn}}; NOTE: different than {{#lst:page|bgn|}}
if (lst_bgn == Null_arg) { // no bgn arg; EX: {{#lst:page}}
bfr.Add(src); // write all and exit
return;
}
else // bgn exists; set end to bgn; EX: {{#lst:page|bgn}} is same as {{#lst:page|bgn|bgn}}; NOTE: {{#lst:page|bgn|}} means write from bgn to eos
lst_end = lst_bgn;
}
byte include_mode = Include_between;
if (Bry_.Len_eq_0(lst_end))
include_mode = Include_to_eos;
else if (Bry_.Len_eq_0(lst_bgn))
include_mode = Include_to_bos;
int bgn_pos = 0; boolean bgn_found = false; int src_page_bry_len = src.length;
Lst_section_nde_mgr section_mgr = sub_ctx.Lst_section_mgr(); // get section_mgr from Parse
int sections_len = section_mgr.Count();
for (int i = 0; i < sections_len; i++) {
Lst_section_nde section = section_mgr.Get_at(i);
byte section_tid = section.Name_tid();
byte[] section_key = section.Section_name();
if (section_tid == Lst_section_nde.Xatr_bgn && Bry_.Eq(section_key, lst_bgn)) {
int sect_bgn_rhs = section.Xnde().Tag_close_end();
if (include_mode == Include_to_eos) { // write from cur to eos; EX: {{#lst:page|bgn|}}
bfr.Add_mid(src, sect_bgn_rhs, src_page_bry_len);
return;
}
else { // bgn and end
if (!bgn_found) { // NOTE: !bgn_found to prevent "resetting" of dupe; EX: <s begin=key0/>a<s begin=key0/>b; should start from a not b
bgn_pos = sect_bgn_rhs;
bgn_found = true;
}
}
}
else if (section_tid == Lst_section_nde.Xatr_end && Bry_.Eq(section_key, lst_end)) {
int sect_end_lhs = section.Xnde().Tag_open_bgn();
if (include_mode == Include_to_bos) { // write from bos to cur; EX: {{#lst:page||end}}
bfr.Add_mid(src, 0, sect_end_lhs);
return;
}
else {
if (bgn_found) { // NOTE: bgn_found to prevent writing from bos; EX: a<s end=key0/>b should not write anything
bfr.Add_mid(src, bgn_pos, sect_end_lhs);
bgn_found = false;
}
}
}
}
if (bgn_found) // bgn_found, but no end; write to end of page; EX: "a <section begin=key/> b" -> " b"
bfr.Add_mid(src, bgn_pos, src_page_bry_len);
}
private static void Write_exclude(Bry_bfr bfr, Xop_ctx sub_ctx, byte[] src, byte[] sect_exclude, byte[] sect_replace) {
if (Bry_.Len_eq_0(sect_exclude)) { // no exclude arg; EX: {{#lstx:page}} or {{#lstx:page}}
bfr.Add(src); // write all and exit
return;
}
Lst_section_nde_mgr section_mgr = sub_ctx.Lst_section_mgr(); // get section_mgr from Parse
int sections_len = section_mgr.Count();
int bgn_pos = 0;
for (int i = 0; i < sections_len; i++) {
Lst_section_nde section = section_mgr.Get_at(i);
byte section_tid = section.Name_tid();
byte[] section_key = section.Section_name();
if (section_tid == Lst_section_nde.Xatr_bgn && Bry_.Eq(section_key, sect_exclude)) { // exclude section found
bfr.Add_mid(src, bgn_pos, section.Xnde().Tag_open_bgn()); // write everything from bgn_pos up to exclude
}
else if (section_tid == Lst_section_nde.Xatr_end && Bry_.Eq(section_key, sect_exclude)) { // exclude end found
if (sect_replace != null)
bfr.Add(sect_replace); // write replacement
bgn_pos = section.Xnde().Tag_close_end(); // reset bgn_pos
}
}
bfr.Add_mid(src, bgn_pos, src.length);
}
public static final byte[] Null_arg = null;
}

View File

@@ -17,7 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public class Lst_section_nde_mgr {
public int Count() {return list.Count();} private List_adp list = List_adp_.New();
private final List_adp list = List_adp_.New();
public int Len() {return list.Count();}
public Lst_section_nde Get_at(int i) {return (Lst_section_nde)list.Get_at(i);}
public void Add(Lst_section_nde xnde) {list.Add(xnde);}
public void Clear() {list.Clear();}

View File

@@ -221,6 +221,7 @@ public class Pf_func_ {
, Xol_kwd_grp_.Id_url_canonicalurle
, Xol_kwd_grp_.Id_lst
, Xol_kwd_grp_.Id_lstx
, Xol_kwd_grp_.Id_lsth
, Xol_kwd_grp_.Id_invoke
, Xol_kwd_grp_.Id_property
, Xol_kwd_grp_.Id_noexternallanglinks
@@ -390,8 +391,11 @@ public class Pf_func_ {
case Xol_kwd_grp_.Id_xowa_dbg: return new Xop_xowa_dbg();
case Xol_kwd_grp_.Id_xowa: return new gplx.xowa.xtns.xowa_cmds.Xop_xowa_func();
case Xol_kwd_grp_.Id_xtn_geodata_coordinates: return gplx.xowa.xtns.geodata.Geo_coordinates_func.Instance;
case Xol_kwd_grp_.Id_lst: return gplx.xowa.xtns.lst.Lst_pfunc_lst.Instance;
case Xol_kwd_grp_.Id_lstx: return gplx.xowa.xtns.lst.Lst_pfunc_lstx.Instance;
case Xol_kwd_grp_.Id_lst: return gplx.xowa.xtns.lst.Lst_pfunc_lst.Prime;
case Xol_kwd_grp_.Id_lstx: return gplx.xowa.xtns.lst.Lst_pfunc_lstx.Prime;
case Xol_kwd_grp_.Id_lsth: return gplx.xowa.xtns.lst.Lst_pfunc_lsth.Prime;
case Xol_kwd_grp_.Id_invoke: return new gplx.xowa.xtns.scribunto.Scrib_invoke_func();
case Xol_kwd_grp_.Id_pagebanner: return new gplx.xowa.xtns.pagebanners.Pgbnr_func();
case Xol_kwd_grp_.Id_new_window_link: return new gplx.xowa.xtns.new_window_links.New_window_link_func();

View File

@@ -29,6 +29,6 @@ public class Pfunc_grammar extends Pf_func_base {
boolean pass = false;
try {pass = lang.Grammar().Grammar_eval(bfr, lang, word, argx);}
catch (Exception e) {Err_.Noop(e);}
if (!pass) Xot_invk_tkn.Print_not_found__w_template(bfr, ctx.Wiki().Ns_mgr(), this.Name());
if (!pass) Xot_invk_tkn_.Print_not_found__w_template(bfr, ctx.Wiki().Ns_mgr(), this.Name());
}
}

View File

@@ -27,7 +27,7 @@ public class Pfunc_plural extends Pf_func_base {
if (arg_idx == 1 && self_args_len == 1) arg_idx = 0; // number is plural, but plural_arg not present; use singular; see test
byte[] word = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, arg_idx);
bfr.Add(word);
} static final byte[] Ary_Num_1 = new byte[] {Byte_ascii.Num_1};
} private static final byte[] Ary_Num_1 = new byte[] {Byte_ascii.Num_1};
@Override public int Id() {return Xol_kwd_grp_.Id_i18n_plural;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_plural().Name_(name);}
}

View File

@@ -27,8 +27,7 @@ public class Pfunc_tag extends Pf_func_base {
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
try {
// get tag_idx, tag_data, and tag_is_ref
int tag_idx = -1;
synchronized (next_id_lock) {tag_idx = ++next_id_val;}
int tag_idx = ctx.Wiki().Parser_mgr().Tag__next_idx();
byte[] tag_name = Eval_argx(ctx, src, caller, self); if (tag_name.length == 0) return;
Xop_xnde_tag tag = (Xop_xnde_tag)ctx.Xnde_tag_regy().Get_trie(ctx.Xnde_names_tid()).Match_exact(tag_name, 0, tag_name.length);
boolean tag_is_ref = tag != null && tag.Id() == Xop_xnde_tag_.Tid__ref;
@@ -74,6 +73,4 @@ public class Pfunc_tag extends Pf_func_base {
, Xtag_bgn = 14 // <xtag_bgn id='
, Id_len = 10
;
private static final Object next_id_lock = new Object();
private static int next_id_val = 0;// NOTE:must be app-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
}

View File

@@ -39,12 +39,10 @@ class Pft_fmt_itm_hebrew_ {
mar += (int)(year_minus_3761 / 100 ) - (int)(year_minus_3761 / 400) - 24;
return mar;
}
private static final int[] Hebrew_date_rslt = new int[4];
public static int[] Calc_hebrew_date(DateAdp date) {
synchronized (Hebrew_date_rslt) {
Calc_hebrew_date(Hebrew_date_rslt, date.Year(), date.Month(), date.Day());
return Hebrew_date_rslt;
}
int[] rv = new int[4]; // MEM:cache
Calc_hebrew_date(rv, date.Year(), date.Month(), date.Day());
return rv;
}
public static boolean Calc_hebrew_date(int[] rv, int year, int month, int day) { // REF.MW:Language.php|tsToHebrew
// Calculate Hebrew year
@@ -176,27 +174,27 @@ class Pft_fmt_itm_hebrew_ {
byte[] msg_key = name_ary[hebrew_month];
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
}
private static final byte[][] Month_name_full_ary = new byte[][]
private static final byte[][] Month_name_full_ary = new byte[][]
{ Bry_.new_a7("hebrew-calendar-m1"), Bry_.new_a7("hebrew-calendar-m2"), Bry_.new_a7("hebrew-calendar-m3")
, Bry_.new_a7("hebrew-calendar-m4"), Bry_.new_a7("hebrew-calendar-m5"), Bry_.new_a7("hebrew-calendar-m6")
, Bry_.new_a7("hebrew-calendar-m7"), Bry_.new_a7("hebrew-calendar-m8"), Bry_.new_a7("hebrew-calendar-m9")
, Bry_.new_a7("hebrew-calendar-m10"), Bry_.new_a7("hebrew-calendar-m11"), Bry_.new_a7("hebrew-calendar-m12")
, Bry_.new_a7("hebrew-calendar-m6a"), Bry_.new_a7("hebrew-calendar-m6b")
};
private static final byte[][] Month_name_gen_ary = new byte[][]
private static final byte[][] Month_name_gen_ary = new byte[][]
{ Bry_.new_a7("hebrew-calendar-m1-gen"), Bry_.new_a7("hebrew-calendar-m2-gen"), Bry_.new_a7("hebrew-calendar-m3-gen")
, Bry_.new_a7("hebrew-calendar-m4-gen"), Bry_.new_a7("hebrew-calendar-m5-gen"), Bry_.new_a7("hebrew-calendar-m6-gen")
, Bry_.new_a7("hebrew-calendar-m7-gen"), Bry_.new_a7("hebrew-calendar-m8-gen"), Bry_.new_a7("hebrew-calendar-m9-gen")
, Bry_.new_a7("hebrew-calendar-m10-gen"), Bry_.new_a7("hebrew-calendar-m11-gen"), Bry_.new_a7("hebrew-calendar-m12-gen")
, Bry_.new_a7("hebrew-calendar-m6a-gen"), Bry_.new_a7("hebrew-calendar-m6b-gen")
};
public static final int
public static final int
Rslt_year_num = 0
, Rslt_month_num = 1
, Rslt_day_num = 2
, Rslt_month_days_count = 3
;
private static final byte[][][] Numeral_tbls = new byte[][][]
private static final byte[][][] Numeral_tbls = new byte[][][]
{ new byte[][] {Bry_.Empty, Bry_.new_u8("א"), Bry_.new_u8("ב"), Bry_.new_u8("ג"), Bry_.new_u8("ד"), Bry_.new_u8("ה") , Bry_.new_u8("ו") , Bry_.new_u8("ז") , Bry_.new_u8("ח") , Bry_.new_u8("ט") , Bry_.new_u8("י")}
, new byte[][] {Bry_.Empty, Bry_.new_u8("י"), Bry_.new_u8("כ"), Bry_.new_u8("ל"), Bry_.new_u8("מ"), Bry_.new_u8("נ") , Bry_.new_u8("ס") , Bry_.new_u8("ע") , Bry_.new_u8("פ") , Bry_.new_u8("צ") , Bry_.new_u8("ק")}
, new byte[][] {Bry_.Empty, Bry_.new_u8("ק"), Bry_.new_u8("ר"), Bry_.new_u8("ש"), Bry_.new_u8("ת"), Bry_.new_u8("תק") , Bry_.new_u8("תר") , Bry_.new_u8("תש") , Bry_.new_u8("תת") , Bry_.new_u8("תתק"), Bry_.new_u8("תתר")}
@@ -238,7 +236,7 @@ class Pft_fmt_itm_hebrew_ {
}
return rv;
}
private static final gplx.core.btries.Btrie_slim_mgr end_trie = gplx.core.btries.Btrie_slim_mgr.cs()
private static final gplx.core.btries.Btrie_slim_mgr end_trie = gplx.core.btries.Btrie_slim_mgr.cs()
.Add_str_str("כ", "ך")
.Add_str_str("מ", "ם")
.Add_str_str("נ", "ן")

View File

@@ -17,12 +17,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
class Pft_fmt_itm_hijiri {
private static final int[] tmp_rslt = new int[3];
public static int[] Calc_date(DateAdp date) {
synchronized (tmp_rslt) {
Calc_date(tmp_rslt, date.Year(), date.Month(), date.Day());
return tmp_rslt;
}
int[] rv = new int[3]; // MEM:cache
Calc_date(rv, date.Year(), date.Month(), date.Day());
return rv;
}
public static boolean Calc_date(int[] rv, int greg_y, int greg_m, int greg_d) {
int hiji_d = greg_d;
@@ -61,13 +59,13 @@ class Pft_fmt_itm_hijiri {
byte[] msg_key = Month_names[m];
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
}
private static final byte[][] Month_names = new byte[][]
private static final byte[][] Month_names = new byte[][]
{ Bry_.new_a7("hijiri-calendar-m1"), Bry_.new_a7("hijiri-calendar-m2"), Bry_.new_a7("hijiri-calendar-m3")
, Bry_.new_a7("hijiri-calendar-m4"), Bry_.new_a7("hijiri-calendar-m5"), Bry_.new_a7("hijiri-calendar-m6")
, Bry_.new_a7("hijiri-calendar-m7"), Bry_.new_a7("hijiri-calendar-m8"), Bry_.new_a7("hijiri-calendar-m9")
, Bry_.new_a7("hijiri-calendar-m10"), Bry_.new_a7("hijiri-calendar-m11"), Bry_.new_a7("hijiri-calendar-m12")
};
public static final int
public static final int
Rslt__year = 0
, Rslt__month = 1
, Rslt__day = 2

View File

@@ -17,14 +17,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
class Pft_fmt_itm_iranian {
private static final int[] Md__greg = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static final int[] Md__iran = new int[] { 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 };
private static final int[] tmp_rslt = new int[3];
private static final int[] Md__greg = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static final int[] Md__iran = new int[] { 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 };
public static int[] Calc_date(DateAdp date) {
synchronized (Md__iran) {
Calc_date(tmp_rslt, date.Year(), date.Month(), date.Day());
return tmp_rslt;
}
int[] rv = new int[3]; // MEM:cache
Calc_date(rv, date.Year(), date.Month(), date.Day());
return rv;
}
public static boolean Calc_date(int[] rv, int greg_y, int greg_m, int greg_d) { // REF.MW:Language.php|tsToIranian
greg_y -= 1600;
@@ -81,13 +79,13 @@ class Pft_fmt_itm_iranian {
byte[] msg_key = Month_names[m];
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
}
private static final byte[][] Month_names = new byte[][]
private static final byte[][] Month_names = new byte[][]
{ Bry_.new_a7("iranian-calendar-m1"), Bry_.new_a7("iranian-calendar-m2"), Bry_.new_a7("iranian-calendar-m3")
, Bry_.new_a7("iranian-calendar-m4"), Bry_.new_a7("iranian-calendar-m5"), Bry_.new_a7("iranian-calendar-m6")
, Bry_.new_a7("iranian-calendar-m7"), Bry_.new_a7("iranian-calendar-m8"), Bry_.new_a7("iranian-calendar-m9")
, Bry_.new_a7("iranian-calendar-m10"), Bry_.new_a7("iranian-calendar-m11"), Bry_.new_a7("iranian-calendar-m12")
};
public static final int
public static final int
Rslt__year = 0
, Rslt__month = 1
, Rslt__day = 2

View File

@@ -90,7 +90,7 @@ class Pft_fmt_itm_am_pm implements Pft_fmt_itm {
else if (!am && lower) val = Ary_pm_lower;
else if (!am && !lower) val = Ary_pm_upper;
bfr.Add(val);
} static final byte[] Ary_am_upper = Bry_.new_a7("AM"), Ary_pm_upper = Bry_.new_a7("PM"), Ary_am_lower = Bry_.new_a7("am"), Ary_pm_lower = Bry_.new_a7("pm");
} private static final byte[] Ary_am_upper = Bry_.new_a7("AM"), Ary_pm_upper = Bry_.new_a7("PM"), Ary_am_lower = Bry_.new_a7("am"), Ary_pm_lower = Bry_.new_a7("pm");
public Pft_fmt_itm_am_pm(boolean lower) {this.lower = lower;} private boolean lower;
}
class Pft_fmt_itm_dow_base0 implements Pft_fmt_itm {
@@ -120,7 +120,7 @@ class Pft_fmt_itm_rfc_5322 implements Pft_fmt_itm {
bfr.Add_byte(Byte_ascii.Comma).Add_byte(Byte_ascii.Space);
bfr.Add_str_a7(date.XtoStr_fmt("dd MMM yyyy HH:mm:ss")); // NOTE: always UTC time
bfr.Add(CONST_timezone); // NOTE: always UTC time zone
} static final byte[] CONST_timezone = Bry_.new_a7(" +0000");
} private static final byte[] CONST_timezone = Bry_.new_a7(" +0000");
}
class Pft_fmt_itm_timezone_offset implements Pft_fmt_itm {
public Pft_fmt_itm_timezone_offset() {}

View File

@@ -178,7 +178,7 @@ class Pxd_parser_ {
Init();
}
return trie;
} static Btrie_slim_mgr trie;
} private static Btrie_slim_mgr trie;
private static final String[] Names_month_full = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"};
private static final String[] Names_month_abrv = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
private static final String[] Names_month_roman = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"};

View File

@@ -16,91 +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.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.core.brys.*; import gplx.core.btries.*; import gplx.langs.htmls.encoders.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.tmpls.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
public class Pfunc_anchorencode extends Pf_func_base { // EX: {{anchorencode:a b}} -> a+b
@Override public boolean Func_require_colon_arg() {return true;}
@Override public int Id() {return Xol_kwd_grp_.Id_url_anchorencode;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_anchorencode().Name_(name);}
public static void Func_init(Xop_ctx ctx) {
if (anchor_ctx != null) return;// NOTE: called by Scrib_uri
encode_trie.Add(Byte_ascii.Colon, Bfr_arg_.New_byte(Byte_ascii.Colon));
encode_trie.Add(Byte_ascii.Space, Bfr_arg_.New_byte(Byte_ascii.Underline));
anchor_ctx = Xop_ctx.New__sub__reuse_page(ctx);
anchor_ctx.Para().Enabled_n_();
anchor_tkn_mkr = anchor_ctx.Tkn_mkr();
anchor_parser = ctx.Wiki().Parser_mgr().Anchor_encoder();
}
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
if (anchor_ctx == null) Func_init(ctx);
byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return;
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
try {Anchor_encode(val_ary, bfr, tmp_bfr);}
finally {tmp_bfr.Mkr_rls();}
byte[] raw_bry = Eval_argx(ctx, src, caller, self); if (raw_bry == Bry_.Empty) return;
Anchor_encode(bfr, ctx, raw_bry);
}
public static void Anchor_encode(byte[] src, Bry_bfr bfr, Bry_bfr tmp_bfr) {
Xop_root_tkn root = anchor_ctx.Tkn_mkr().Root(src);
anchor_parser.Parse_wtxt_to_wdom(root, anchor_ctx, anchor_tkn_mkr, src, Xop_parser_.Doc_bgn_bos);
// anchor_parser.Parse_page_tmpl(root, anchor_ctx, anchor_tkn_mkr, src);
int subs_len = root.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm sub = root.Subs_get(i);
Tkn(src, sub, root, i, tmp_bfr);
}
byte[] unencoded = tmp_bfr.To_bry_and_clear();
Gfo_url_encoder_.Id.Encode(tmp_bfr, unencoded);
bfr.Add_bfr_and_clear(tmp_bfr);
public static void Anchor_encode(Bry_bfr bfr, Xop_ctx ctx, byte[] raw) {
Pfunc_anchorencode_mgr mgr = ctx.Wiki().Parser_mgr().Anchor_encoder_mgr__dflt_or_new(ctx);
try {mgr.Encode_anchor(bfr, ctx, raw);}
finally {mgr.Used_(Bool_.N);}
}
private static void Tkn(byte[] src, Xop_tkn_itm sub, Xop_tkn_grp grp, int sub_idx, Bry_bfr tmp_bfr) {
switch (sub.Tkn_tid()) {
case Xop_tkn_itm_.Tid_lnke: Lnke(src, (Xop_lnke_tkn)sub, tmp_bfr); break; // FUTURE: need to move number to lnke_tkn so that number will be correct/consistent?
case Xop_tkn_itm_.Tid_lnki: Lnki(src, (Xop_lnki_tkn)sub, tmp_bfr); break;
case Xop_tkn_itm_.Tid_apos: break; // noop
case Xop_tkn_itm_.Tid_xnde: Xnde(src, (Xop_xnde_tkn)sub, tmp_bfr); break;
case Xop_tkn_itm_.Tid_html_ncr: tmp_bfr.Add_u8_int(((Xop_amp_tkn_num)sub).Val()); break;
case Xop_tkn_itm_.Tid_html_ref: tmp_bfr.Add_u8_int(((Xop_amp_tkn_ent)sub).Char_int()); break;
case Xop_tkn_itm_.Tid_tmpl_invk:
Xot_invk_tkn invk_tkn = (Xot_invk_tkn)sub;
Arg_itm_tkn name_tkn = invk_tkn.Name_tkn().Key_tkn();
int name_ary_bgn = name_tkn.Src_bgn() + 1, name_ary_end = name_tkn.Src_end();
byte[] name_ary = Bry_.Mid(src, name_ary_bgn, name_ary_end); // + 1 to skip :
int name_ary_len = name_ary_end - name_ary_bgn;
if (name_ary_len > 0 && name_ary[0] == Byte_ascii.Colon) // has initial colon; EX: {{:a}
tmp_bfr.Add_mid(name_ary, 1, name_ary_len); // 1 to skip initial colon
else // regular tmpl; EX: {{a}}
tmp_bfr.Add(anchor_ctx.Wiki().Ns_mgr().Ns_template().Gen_ttl(name_ary));
break;
default: tmp_bfr.Add_mid(src, sub.Src_bgn_grp(grp, sub_idx), sub.Src_end_grp(grp, sub_idx)); break;
}
}
private static void Lnke(byte[] src, Xop_lnke_tkn lnke, Bry_bfr tmp_bfr) {
int subs_len = lnke.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm lnke_sub = lnke.Subs_get(i);
tmp_bfr.Add_mid(src, lnke_sub.Src_bgn_grp(lnke, i), lnke_sub.Src_end_grp(lnke, i));
}
}
private static void Lnki(byte[] src, Xop_lnki_tkn lnki, Bry_bfr tmp_bfr) {
int src_end = lnki.Src_end();
int trg_end = lnki.Trg_tkn().Src_end();
if (trg_end == src_end - Xop_tkn_.Lnki_end_len) { // only trg
int trg_bgn = lnki.Trg_tkn().Src_bgn();
if (lnki.Ttl().ForceLiteralLink()) ++trg_bgn; // literal link; skip colon; EX: [[:a]] -> a
tmp_bfr.Add_mid(src, trg_bgn, trg_end);
}
else {
tmp_bfr.Add_mid(src, trg_end + 1, src_end - Xop_tkn_.Lnki_end_len); //+1 is len of pipe
}
}
private static void Xnde(byte[] src, Xop_xnde_tkn xnde, Bry_bfr tmp_bfr) {
int subs_len = xnde.Subs_len();
for (int i = 0; i < subs_len; i++) {
Tkn(src, xnde.Subs_get(i), xnde, i, tmp_bfr);
}
}
private static Btrie_fast_mgr encode_trie = Btrie_fast_mgr.cs();
private static Xop_ctx anchor_ctx; static Xop_tkn_mkr anchor_tkn_mkr;
private static Xop_parser anchor_parser;
}

View File

@@ -0,0 +1,100 @@
/*
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.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.core.brys.*; import gplx.core.btries.*;
import gplx.langs.htmls.encoders.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.tmpls.*;
public class Pfunc_anchorencode_mgr { // TS
private final Xop_parser parser; // create a special-parser for handling wikitext inside {{anchorencode:}}
private final Bry_bfr tmp_bfr = Bry_bfr_.Reset(255);
public Pfunc_anchorencode_mgr(Xowe_wiki wiki) {
this.parser = Xop_parser.new_(wiki, wiki.Parser_mgr().Main().Tmpl_lxr_mgr(), Xop_lxr_mgr.new_anchor_encoder());
parser.Init_by_wiki(wiki);
parser.Init_by_lang(wiki.Lang());
}
public boolean Used() {return used;} private boolean used;
public void Used_(boolean v) {used = v;}
public void Encode_anchor(Bry_bfr bfr, Xop_ctx ctx, byte[] src) {
// parse {{anchorencode:}}; note that wikitext inside anchorencode gets serialized by different rules
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
boolean para_enabled = ctx.Para().Enabled();
ctx.Para().Enabled_n_(); // HACK: disable para
try {
Xop_root_tkn root = tkn_mkr.Root(src);
parser.Parse_wtxt_to_wdom(root, ctx, tkn_mkr, src, Xop_parser_.Doc_bgn_bos);
int subs_len = root.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm sub = root.Subs_get(i);
Tkn(ctx, src, sub, root, i, tmp_bfr);
}
} finally {ctx.Para().Enabled_(para_enabled);}
// write to bfr and encode it
byte[] unencoded = tmp_bfr.To_bry_and_clear();
Gfo_url_encoder_.Id.Encode(tmp_bfr, unencoded);
bfr.Add_bfr_and_clear(tmp_bfr);
}
private static void Tkn(Xop_ctx ctx, byte[] src, Xop_tkn_itm sub, Xop_tkn_grp grp, int sub_idx, Bry_bfr tmp_bfr) {
switch (sub.Tkn_tid()) {
case Xop_tkn_itm_.Tid_lnke: Lnke(src, (Xop_lnke_tkn)sub, tmp_bfr); break; // FUTURE: need to move number to lnke_tkn so that number will be correct/consistent?
case Xop_tkn_itm_.Tid_lnki: Lnki(src, (Xop_lnki_tkn)sub, tmp_bfr); break;
case Xop_tkn_itm_.Tid_apos: break; // noop
case Xop_tkn_itm_.Tid_xnde: Xnde(ctx, src, (Xop_xnde_tkn)sub, tmp_bfr); break;
case Xop_tkn_itm_.Tid_html_ncr: tmp_bfr.Add_u8_int(((Xop_amp_tkn_num)sub).Val()); break;
case Xop_tkn_itm_.Tid_html_ref: tmp_bfr.Add_u8_int(((Xop_amp_tkn_ent)sub).Char_int()); break;
case Xop_tkn_itm_.Tid_tmpl_invk:
Xot_invk_tkn invk_tkn = (Xot_invk_tkn)sub;
Arg_itm_tkn name_tkn = invk_tkn.Name_tkn().Key_tkn();
int name_ary_bgn = name_tkn.Src_bgn() + 1, name_ary_end = name_tkn.Src_end();
byte[] name_ary = Bry_.Mid(src, name_ary_bgn, name_ary_end); // + 1 to skip :
int name_ary_len = name_ary_end - name_ary_bgn;
if (name_ary_len > 0 && name_ary[0] == Byte_ascii.Colon) // has initial colon; EX: {{:a}
tmp_bfr.Add_mid(name_ary, 1, name_ary_len); // 1 to skip initial colon
else // regular tmpl; EX: {{a}}
tmp_bfr.Add(ctx.Wiki().Ns_mgr().Ns_template().Gen_ttl(name_ary));
break;
default: tmp_bfr.Add_mid(src, sub.Src_bgn_grp(grp, sub_idx), sub.Src_end_grp(grp, sub_idx)); break;
}
}
private static void Lnke(byte[] src, Xop_lnke_tkn lnke, Bry_bfr tmp_bfr) {
int subs_len = lnke.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm lnke_sub = lnke.Subs_get(i);
tmp_bfr.Add_mid(src, lnke_sub.Src_bgn_grp(lnke, i), lnke_sub.Src_end_grp(lnke, i));
}
}
private static void Lnki(byte[] src, Xop_lnki_tkn lnki, Bry_bfr tmp_bfr) {
int src_end = lnki.Src_end();
int trg_end = lnki.Trg_tkn().Src_end();
if (trg_end == src_end - Xop_tkn_.Lnki_end_len) { // only trg
int trg_bgn = lnki.Trg_tkn().Src_bgn();
if (lnki.Ttl().ForceLiteralLink()) ++trg_bgn; // literal link; skip colon; EX: [[:a]] -> a
tmp_bfr.Add_mid(src, trg_bgn, trg_end);
}
else {
tmp_bfr.Add_mid(src, trg_end + 1, src_end - Xop_tkn_.Lnki_end_len); //+1 is len of pipe
}
}
private static void Xnde(Xop_ctx ctx, byte[] src, Xop_xnde_tkn xnde, Bry_bfr tmp_bfr) {
int subs_len = xnde.Subs_len();
for (int i = 0; i < subs_len; i++) {
Tkn(ctx, src, xnde.Subs_get(i), xnde, i, tmp_bfr);
}
}
}

View File

@@ -29,13 +29,13 @@ public class Pfunc_rel2abs extends Pf_func_base {
qry_bgns_with.Add(Ary_dot_slash, Int_obj_ref.New(Id_dot_slash));
qry_bgns_with.Add(Ary_dot_dot, Int_obj_ref.New(Id_dot_dot));
qry_bgns_with.Add(Ary_dot_dot_slash, Int_obj_ref.New(Id_dot_dot_slash));
} static Btrie_fast_mgr qry_bgns_with;
} private static Btrie_fast_mgr qry_bgns_with;
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {// REF.MW:ParserFunctions_body.php
byte[] qry = Eval_argx(ctx, src, caller, self);
byte[] orig = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self.Args_len(), 0);
if (orig.length == 0) orig = ctx.Page().Ttl().Full_txt_w_ttl_case();
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
try {bfr.Add(Rel2abs(tmp_bfr, qry, orig));}
try {bfr.Add(Rel2abs(tmp_bfr, ctx.Wiki().Parser_mgr().Rel2abs_ary(), qry, orig));}
finally {tmp_bfr.Mkr_rls();}
}
public static boolean Rel2abs_ttl(byte[] ttl, int bgn, int end) {
@@ -59,9 +59,9 @@ public class Pfunc_rel2abs extends Pf_func_base {
}
return rv;
}
private static final Int_obj_ref ignore_rel2abs_tid = Int_obj_ref.New_zero();
public static byte[] Rel2abs(Bry_bfr tmp_bfr, byte[] qry, byte[] src) {return Rel2abs(tmp_bfr, qry, src, ignore_rel2abs_tid);}
public static byte[] Rel2abs(Bry_bfr tmp_bfr, byte[] qry, byte[] src, Int_obj_ref rel2abs_tid) {
private static final Int_obj_ref ignore_rel2abs_tid = Int_obj_ref.New_zero(); // TS:return value not used
public static byte[] Rel2abs(Bry_bfr tmp_bfr, int[] seg_ary, byte[] qry, byte[] src) {return Rel2abs(tmp_bfr, seg_ary, qry, src, ignore_rel2abs_tid);}
public static byte[] Rel2abs(Bry_bfr tmp_bfr, int[] seg_ary, byte[] qry, byte[] src, Int_obj_ref rel2abs_tid) {
if (qry_bgns_with == null) qry_bgns_with_init();
int qry_len = qry.length, src_len = src.length;
@@ -97,6 +97,7 @@ public class Pfunc_rel2abs extends Pf_func_base {
tmp_len = qry_len;
tmp_is_1st = false;
}
// create segs; see NOTE_1 for approach
byte b = Byte_.Zero;
boolean loop = true, dot_mode = true;
@@ -169,7 +170,6 @@ public class Pfunc_rel2abs extends Pf_func_base {
return tmp_bfr.To_bry_and_clear();
}
public static final int Ttl_max = 2048; // ASSUME: max len of 256 * 8 bytes
private static int[] seg_ary = new int[Ttl_max];
@Override public int Id() {return Xol_kwd_grp_.Id_xtn_rel2abs;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_rel2abs().Name_(name);}
public static final int Id_null = 0, Id_slash = 1, Id_dot = 2, Id_dot_slash = 3, Id_dot_dot = 4, Id_dot_dot_slash = 5;

View File

@@ -59,17 +59,22 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 {
public void Xtn_parse(Xowe_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {
// if (!wiki.Xtn_mgr().Xtn_proofread().Enabled()) return;
if (!Init_vars(wiki, ctx, src, xnde)) return;
// set recursing flag
Xoae_page page = ctx.Page();
if (page.Pages_recursed()) return; // moved from Pp_index_parser; DATE:2014-05-21s
page.Pages_recursed_(true);
Bry_bfr full_bfr = wiki.Utl__bfr_mkr().Get_m001();
Hash_adp_bry lst_page_regy = ctx.Lst_page_regy(); if (lst_page_regy == null) lst_page_regy = Hash_adp_bry.cs(); // SEE:NOTE:page_regy; DATE:2014-01-01
page.Html_data().Indicators().Enabled_(Bool_.N); // disable <indicator> b/c <page> should not add to current page; PAGE:en.s:The_Parochial_System_(Wilberforce,_1838); DATE:2015-04-29
byte[] page_bry = Bld_wikitext(full_bfr, wiki.Parser_mgr().Pp_num_parser(), lst_page_regy);
if (page_bry != null)
xtn_root = Bld_root_nde(full_bfr, lst_page_regy, page_bry); // NOTE: this effectively reparses page twice; needed b/c of "if {| : ; # *, auto add new_line" which can build different tokens
page.Pages_recursed_(false);
full_bfr.Mkr_rls();
if (wiki.Parser_mgr().Lst__recursing()) return; // moved from Pp_index_parser; DATE:2014-05-21s
try {
wiki.Parser_mgr().Lst__recursing_(true);
Hash_adp_bry lst_page_regy = ctx.Lst_page_regy(); if (lst_page_regy == null) lst_page_regy = Hash_adp_bry.cs(); // SEE:NOTE:page_regy; DATE:2014-01-01
page.Html_data().Indicators().Enabled_(Bool_.N); // disable <indicator> b/c <page> should not add to current page; PAGE:en.s:The_Parochial_System_(Wilberforce,_1838); DATE:2015-04-29
byte[] page_bry = Bld_wikitext(full_bfr, wiki.Parser_mgr().Pp_num_parser(), lst_page_regy);
if (page_bry != null)
xtn_root = Bld_root_nde(full_bfr, lst_page_regy, page_bry); // NOTE: this effectively reparses page twice; needed b/c of "if {| : ; # *, auto add new_line" which can build different tokens
} finally {
wiki.Parser_mgr().Lst__recursing_(false);
full_bfr.Mkr_rls();
}
page.Html_data().Indicators().Enabled_(Bool_.Y);
}
public void Xtn_write(Bry_bfr bfr, Xoae_app app, Xop_ctx ctx, Xoh_html_wtr html_wtr, Xoh_wtr_ctx hctx, Xoae_page wpg, Xop_xnde_tkn xnde, byte[] src) {
@@ -321,8 +326,6 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 {
Xoa_ttl end_page_ttl = end_page_bry == null ? null : ary[ary_len - 1];
Bry_bfr page_bfr = wiki.Utl__bfr_mkr().Get_m001();
ctx.Tmpl_output_(page_bfr);
Lst_pfunc_wkr lst_pfunc_wkr = new Lst_pfunc_wkr();
for (int i = 0; i < ary_len; i++) {
Xoa_ttl ttl = ary[i];
byte[] ttl_page_db = ttl.Page_db();
@@ -330,7 +333,7 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 {
lst_page_regy.Add(ttl_page_db, ttl_page_db);
else
continue;
byte[] cur_sect_bgn = Lst_pfunc_wkr.Null_arg, cur_sect_end = Lst_pfunc_wkr.Null_arg;
byte[] cur_sect_bgn = Lst_pfunc_itm.Null_arg, cur_sect_end = Lst_pfunc_itm.Null_arg;
if (ttl.Eq_page_db(bgn_page_ttl)) {
if (bgn_sect_bry != null)
cur_sect_bgn = bgn_sect_bry;
@@ -344,13 +347,13 @@ public class Pp_pages_nde implements Xox_xnde, Mwh_atr_itm_owner1 {
cur_sect_end = end_sect_bry;
}
Xopg_tmpl_prepend_mgr prepend_mgr = ctx.Page().Tmpl_prepend_mgr().Bgn(full_bfr);
lst_pfunc_wkr.Init_include(ttl.Full_db(), cur_sect_bgn, cur_sect_end).Exec(page_bfr, ctx);
Lst_pfunc_itm lst_itm = Lst_pfunc_itm.New_sect_or_null(ctx, ttl.Full_db());
if (lst_itm != null) Lst_pfunc_lst_.Sect_include(page_bfr, lst_itm.Sec_mgr(), lst_itm.Itm_src(), cur_sect_bgn, cur_sect_end);
prepend_mgr.End(ctx, full_bfr, page_bfr.Bfr(), page_bfr.Len(), Bool_.Y);
full_bfr.Add_bfr_and_clear(page_bfr);
full_bfr.Add(gplx.langs.htmls.entitys.Gfh_entity_.Space_bry); // $out.= "&#32;"; REF.MW:ProofreadPageRenderer.pn
}
page_bfr.Mkr_rls();
ctx.Tmpl_output_(null);
return full_bfr.To_bry_and_clear();
}
private Xop_root_tkn Bld_root_nde(Bry_bfr page_bfr, Hash_adp_bry lst_page_regy, byte[] wikitext) {

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.xtns.proofreadPage; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Pp_pages_nde_recursion_tst {
private final Xop_fxt fxt = new Xop_fxt();
private final Xop_fxt fxt = new Xop_fxt();
@Before public void Init() {fxt.Init_xtn_pages();}
@After public void term() {
fxt.Wiki().Cache_mgr().Free_mem_all();

View File

@@ -35,7 +35,7 @@ public class Scrib_invoke_func extends Pf_func_base {
Xop_log_invoke_wkr invoke_wkr = ctx.Xtn__scribunto__invoke_wkr();
long log_time_bgn = 0;
if (invoke_wkr != null) {
log_time_bgn = Env_.TickCount();
log_time_bgn = System_.Ticks();
if (!invoke_wkr.Eval_bgn(ctx.Page(), mod_name, fnc_name)) return;
}
Scrib_core core = wiki.Parser_mgr().Scrib().Core();
@@ -70,7 +70,7 @@ public class Scrib_invoke_func extends Pf_func_base {
if ( err_filter_mgr == null // no err_filter_mgr defined;
|| err_filter_mgr.Count_eq_0( ) // err_filter_mgr exists, but no definitions
|| !err_filter_mgr.Match(String_.new_u8(mod_name), String_.new_u8(fnc_name), err.To_str__msg_only())) // NOTE: must be To_str__msg_only; err_filter_mgr has defintion and it doesn't match current; print warn; DATE:2015-07-24
ctx.App().Usr_dlg().Warn_many("", "", "invoke failed: ~{0} ~{1} ~{2}", ctx.Page().Ttl().Raw(), Bry_.Replace(Bry_.Mid(src, self.Src_bgn(), self.Src_end()), Byte_ascii.Nl, Byte_ascii.Tab), err.To_str__log());
ctx.App().Usr_dlg().Warn_many("", "", "invoke failed: ~{0} ~{1} ~{2}", ctx.Page().Ttl().Raw(), Bry_.Replace_nl_w_tab(src, self.Src_bgn(), self.Src_end()), err.To_str__log());
wiki.Parser_mgr().Scrib().Terminate_when_page_changes_y_(); // NOTE: terminate core when page changes; not terminating now, else page with many errors will be very slow due to multiple remakes of core; PAGE:th.d:all; DATE:2014-10-03
}
}

View File

@@ -53,7 +53,7 @@ public class Process_send_wtr {
bfr.Add_int_variable(prc.Id());
bfr.Add_byte(Byte_ascii.Brack_end);
return true;
} static final byte[] Prc_bgn = Bry_.new_a7("chunks[");
} private static final byte[] Prc_bgn = Bry_.new_a7("chunks[");
private boolean Encode_ary(Bry_bfr bfr, Keyval[] ary) {
int len = ary.length;
bfr.Add_byte(Byte_ascii.Curly_bgn);

View File

@@ -264,7 +264,7 @@ public class Scrib_lib_mw implements Scrib_lib {
Bry_bfr bfr = cur_wiki.Utl__bfr_mkr().Get_k004();
Xop_ctx fnc_ctx = Xop_ctx.New__sub__reuse_page(core.Ctx());
fnc_ctx.Parse_tid_(Xop_parser_tid_.Tid__tmpl); // default xnde names to template; needed for test, but should be in place; DATE:2014-06-27
Xot_invk_tkn.Eval_func(fnc_ctx, src, parent_frame, frame, bfr, defn, argx_ref.Val());
Xot_invk_tkn_.Eval_func(fnc_ctx, src, parent_frame, frame, bfr, defn, argx_ref.Val());
bfr.Mkr_rls();
return rslt.Init_obj(bfr.To_str_and_clear());
}

View File

@@ -48,10 +48,10 @@ public class Scrib_lib_uri implements Scrib_lib {
public boolean AnchorEncode(Scrib_proc_args args, Scrib_proc_rslt rslt) {
byte[] raw_bry = args.Pull_bry(0);
Bry_bfr bfr = core.Wiki().Utl__bfr_mkr().Get_b512();
Bry_bfr tmp_bfr = core.Wiki().Utl__bfr_mkr().Get_b512();
Pfunc_anchorencode.Func_init(core.Ctx());
Pfunc_anchorencode.Anchor_encode(raw_bry, bfr, tmp_bfr);
tmp_bfr.Clear_and_rls();
// Pfunc_anchorencode.Func_init(core.Ctx());
Pfunc_anchorencode.Anchor_encode(bfr, core.Ctx(), raw_bry);
// Bry_bfr tmp_bfr = core.Wiki().Utl__bfr_mkr().Get_b512();
// tmp_bfr.Clear_and_rls();
return rslt.Init_obj(bfr.To_str_and_rls());
}
public boolean Url_func(Scrib_proc_args args, Scrib_proc_rslt rslt, byte url_tid) {

View File

@@ -16,6 +16,8 @@ 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.xtns.wbases; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.langs.jsons.*;
import gplx.xowa.wikis.pages.*;
public class Wbase_doc_mgr {
private final Xoae_app app;
private final Wdata_wiki_mgr wbase_mgr;
@@ -42,23 +44,58 @@ public class Wbase_doc_mgr {
return qid_bry == null ? null : this.Get_by_bry_or_null(qid_bry);
}
public Wdata_doc Get_by_xid_or_null(byte[] xid) {return Get_by_bry_or_null(Prepend_property_if_needed(xid));}// scribunto passes either p1 or q1; convert p1 to "Property:P1"
public Wdata_doc Get_by_bry_or_null(byte[] full_db) { // must be correct format; EX:"Q2" or "Property:P1"
Wdata_doc rv = hash.Get_or_null(full_db);
public Wdata_doc Get_by_bry_or_null(byte[] ttl_bry) {// must be correct format; EX:"Q2" or "Property:P1"
Wdata_doc rv = hash.Get_or_null(ttl_bry);
if (rv == null) {
byte[] page_src = Load_or_null(full_db); if (page_src == null) return null; // page not found
synchronized (hash) { // LOCK:app-level; both hash and jdoc_parser
rv = new Wdata_doc(full_db, wbase_mgr, wbase_mgr.Jdoc_parser().Parse(page_src));
rv = Load_wdoc_or_null(ttl_bry); if (rv == null) return null; // page not found
synchronized (hash) { // LOCK:app-level; hash;
Add(ttl_bry, rv);// NOTE: use ttl_bry, not rv.Qid; allows subsequent lookups to skip this redirect cycle
}
Add(full_db, rv);
}
return rv;
}
private byte[] Load_or_null(byte[] full_db) {
public Wdata_doc Load_wdoc_or_null(byte[] src_ttl_bry) {
if (!enabled) return null;
Xoa_ttl page_ttl = Xoa_ttl.Parse(wbase_mgr.Wdata_wiki(), full_db); if (page_ttl == null) {app.Usr_dlg().Warn_many("", "", "invalid qid for ttl: qid=~{0}", full_db); return null;}
Xoae_page page_itm = wbase_mgr.Wdata_wiki().Data_mgr().Load_page_by_ttl(page_ttl);
return page_itm.Db().Page().Exists() ? page_itm.Db().Text().Text_bry() : null;
byte[] cur_ttl_bry = src_ttl_bry;
int load_count = -1;
while (load_count < 2) { // limit to 2 tries (i.e.: 1 redirect)
// parse ttl
Xoa_ttl cur_ttl = wbase_mgr.Wdata_wiki().Ttl_parse(cur_ttl_bry);
if (cur_ttl == null) {
app.Usr_dlg().Warn_many("", "", "invalid wbase ttl: orig=~{0} cur=~{1}", src_ttl_bry, cur_ttl_bry);
return null;
}
// get page
Xoae_page page = wbase_mgr.Wdata_wiki().Data_mgr().Load_page_by_ttl(cur_ttl);
if (!page.Db().Page().Exists()) return null;
// parse jdoc
byte[] jdoc_bry = page.Db().Text().Text_bry();
Json_doc jdoc = null;
synchronized (hash) { // LOCK:app-level; jdoc_parser
jdoc = wbase_mgr.Jdoc_parser().Parse(jdoc_bry);
}
if (jdoc == null) {
app.Usr_dlg().Warn_many("", "", "invalid jdoc for ttl: orig=~{0} cur=~{1}", src_ttl_bry, cur_ttl_bry);
return null;
}
// check for redirect; EX: {"entity":"Q22350516","redirect":"Q21006972"}; PAGE:fr.w:Tour_du_Táchira_2016; DATE:2016-08-13
Json_nde jdoc_root = jdoc.Root_nde();
byte[] redirect_ttl = jdoc_root.Get_as_bry_or(Bry__redirect, null);
if (redirect_ttl != null) {
cur_ttl_bry = redirect_ttl;
continue;
}
// is json doc, and not a redirect; return
return new Wdata_doc(cur_ttl_bry, wbase_mgr, jdoc);
}
app.Usr_dlg().Warn_many("", "", "too many redirects for ttl: orig=~{0} cur=~{1}", src_ttl_bry, cur_ttl_bry);
return null;
}
private static final byte[] Bry__redirect = Bry_.new_a7("redirect");
private static byte[] Prepend_property_if_needed(byte[] bry) {
int len = bry == null ? 0 : bry.length;

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.wbases; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*; import gplx.core.tests.*;
import gplx.langs.jsons.*; import gplx.xowa.wikis.pages.*;
public class Wbase_doc_mgr__tst {
@Before public void init() {fxt.Init();} private final Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt();
@Test public void Redirect() {
// create 2 pages; Q1 redirects to Q2
Wdata_wiki_mgr wbase_mgr = fxt.App().Wiki_mgr().Wdata_mgr();
fxt.Parser_fxt().Init_page_create(wbase_mgr.Wdata_wiki(), "Q1", Json_doc.Make_str_by_apos("{'entity':'q1','redirect':'Q2'}"));
fxt.Parser_fxt().Init_page_create(wbase_mgr.Wdata_wiki(), "Q2", Json_doc.Make_str_by_apos("{'entity':'q2','links':{'enwiki':'q2_en','dewiki':'q2_de'}}"));
// fetch Q1; assert Q2 comes back
Wdata_doc actl = wbase_mgr.Doc_mgr.Load_wdoc_or_null(Bry_.new_u8("Q1"));
Gftest.Eq__str("Q2", String_.new_u8(actl.Qid()));
}
}

View File

@@ -40,8 +40,9 @@ public class Wdata_wiki_mgr_fxt {
parser_fxt.Reset();
}
return this;
} private Xoae_app app; private Xowe_wiki wiki; private Wdata_wiki_mgr wdata_mgr; private Wdata_doc_bldr wdoc_bldr; private Xop_fxt parser_fxt;
} private Xoae_app app; private Xowe_wiki wiki; private Wdata_wiki_mgr wdata_mgr; private Wdata_doc_bldr wdoc_bldr;
public Xoae_app App() {return app;}
public Xop_fxt Parser_fxt() {return parser_fxt;} private Xop_fxt parser_fxt;
public void Init_lang_fallbacks(String... fallbacks) {
wiki.Lang().Fallback_bry_(Bry_.new_a7(String_.Concat_with_str(",", fallbacks)));
}

View File

@@ -31,7 +31,7 @@ public class Wdata_pf_property extends Pf_func_base {
Xop_log_property_wkr property_wkr = ctx.Xtn__wikidata__property_wkr();
long log_time_bgn = 0;
if (property_wkr != null) {
log_time_bgn = Env_.TickCount();
log_time_bgn = System_.Ticks();
if (!property_wkr.Eval_bgn(ctx.Page(), pid_ttl)) return;
}
Xoae_app app = ctx.App();

View File

@@ -38,9 +38,12 @@ public class Wdata_pf_property_data {
int key_bgn = nde_key.Src_bgn(), key_end = nde_key.Src_end();
if (key_bgn == key_end && key_bgn == -1) continue; // null arg; ignore, else will throw warning below; EX: {{#property:p1|}}; DATE:2013-11-15
byte key_tid = atrs_hash.Get_as_byte_or(src, key_bgn, key_end, Byte_.Max_value_127);
if (key_tid == Byte_.Max_value_127) {
ctx.App().Usr_dlg().Warn_many("", "", "unknown key for property: ~{0} ~{1}", String_.new_u8(ctx.Page().Ttl().Full_txt_w_ttl_case()), String_.new_u8(src, self.Src_bgn(), self.Src_end()));
continue;
switch (key_tid) {
case Byte_.Max_value_127:
ctx.App().Usr_dlg().Warn_many("", "", "unknown key for property: ~{0} ~{1}", String_.new_u8(ctx.Page().Ttl().Full_txt_w_ttl_case()), String_.new_u8(src, self.Src_bgn(), self.Src_end()));
continue;
case Tid__id: // same as "not-found", but don't warn;
continue;
}
// get val
@@ -56,10 +59,11 @@ public class Wdata_pf_property_data {
tmp_bfr.Mkr_rls();
return new Wdata_pf_property_data(of, q, from);
}
private static final byte Tid__of = 0, Tid__q = 1, Tid__from = 2;
private static final byte Tid__of = 0, Tid__q = 1, Tid__from = 2, Tid__id = 3;
private static final Hash_adp_bry atrs_hash = Hash_adp_bry.ci_a7()
.Add_str_byte("of" , Tid__of)
.Add_str_byte("q" , Tid__q)
.Add_str_byte("from" , Tid__from) // "from" is alias as "q" except it seems to handle properties; EX: {{#property:p1|from=Q2}} == {{#property:p1|q=Q2}}; EX: {{#property:p1|from=p2}}
.Add_str_byte("id" , Tid__id) // "id" has no effect, but appears in articles; ignore and don't warn; EX:{{#property:P277|id=Q1322933}} PAGE:en.w:Symfony; DATE:2016-08-13
;
}