1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2014-07-28 01:40:51 -04:00
parent e882217c62
commit 7b6e65b088
247 changed files with 2985 additions and 1618 deletions

View File

@@ -16,22 +16,22 @@ 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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.xtns.gallery.*; import gplx.xowa.xtns.cite.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.poems.*; import gplx.xowa.xtns.hiero.*;
import gplx.xowa.xtns.scores.*; import gplx.xowa.xtns.listings.*; import gplx.xowa.xtns.titleBlacklists.*; import gplx.xowa.xtns.pfuncs.scribunto.*;
import gplx.xowa.xtns.cite.*;
public class Xow_xtn_mgr implements GfoInvkAble {
private OrderedHash regy = OrderedHash_.new_bry_();
public int Count() {return regy.Count();}
public Cite_xtn_mgr Xtn_cite() {return xtn_cite;} private Cite_xtn_mgr xtn_cite;
public Xow_xtn_mgr Ctor_by_app(Xoa_app app) { // NOTE: needed for options
Add(app, new Cite_xtn_mgr());
Add(app, new Scrib_xtn_mgr());
Add(app, new Gallery_xtn_mgr());
Add(app, new Poem_xtn_mgr());
Add(app, new Hiero_xtn_mgr());
Add(app, new Score_xtn_mgr());
Add(app, new Listing_xtn_mgr());
Add(app, new Blacklist_xtn_mgr());
Add(app, new Pfunc_xtn_mgr());
Add(app, new gplx.xowa.xtns.scribunto.Scrib_xtn_mgr());
Add(app, new gplx.xowa.xtns.gallery.Gallery_xtn_mgr());
Add(app, new gplx.xowa.xtns.imaps.Imap_xtn_mgr());
Add(app, new gplx.xowa.xtns.poems.Poem_xtn_mgr());
Add(app, new gplx.xowa.xtns.hieros.Hiero_xtn_mgr());
Add(app, new gplx.xowa.xtns.scores.Score_xtn_mgr());
Add(app, new gplx.xowa.xtns.listings.Listing_xtn_mgr());
Add(app, new gplx.xowa.xtns.titleBlacklists.Blacklist_xtn_mgr());
Add(app, new gplx.xowa.xtns.pfuncs.scribunto.Pfunc_xtn_mgr());
return this;
}
public Xow_xtn_mgr Ctor_by_wiki(Xow_wiki wiki) {

View File

@@ -18,7 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.xtns.cite; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public class Cite_xtn_mgr extends Xox_mgr_base {
@Override public byte[] Xtn_key() {return XTN_KEY;} public static final byte[] XTN_KEY = Bry_.new_ascii_("cite");
public byte[] Group_default_name() {return group_default_name;} private byte[] group_default_name = Bry_.new_ascii_("lower-alpha");
// public byte[] Group_default_name() {return group_default_name;} private byte[] group_default_name = Bry_.new_ascii_("lower-alpha");
public static byte[] Group_default_name() {return group_default_name;} private static byte[] group_default_name = Bry_.new_ascii_("lower-alpha");
@Override public Xox_mgr Clone_new() {return new Cite_xtn_mgr();}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_group_default_name)) return String_.new_utf8_(group_default_name);

View File

@@ -25,12 +25,14 @@ public class Ref_html_wtr {
Ref_nde itm = (Ref_nde)xnde.Xnde_xtn();
if (itm == null) return;
if (itm.Follow_y()) return; // NOTE: "follow" is always appended to preceding ref; will never generate its own ^ a
byte[] itm_group = itm.Group();
boolean itm_group_is_default = Bry_.Eq(itm_group, Bry_.Empty) || Bry_.Eq(itm_group, Cite_xtn_mgr.Group_default_name()); // do not show "lower-alpha"; PAGE:en.w:Moon; DATE:2014-07-21
cfg.Itm_html().Bld_bfr_many(bfr
, Itm_id(itm, true)
, Grp_id(itm)
, itm.Group() == Bry_.Empty // grp_key
? itm.Idx_major() + 1
: (Object)grp_key_fmtr.Atrs_(cfg.Itm_grp_text(), itm.Group(), itm.Idx_major() + 1)
, itm_group_is_default
? itm.Idx_major() + 1
: (Object)grp_key_fmtr.Atrs_(cfg.Itm_grp_text(), itm.Group(), itm.Idx_major() + 1)
);
} private Bry_fmtr_arg_fmtr_objs grp_key_fmtr = Bry_fmtr_arg_.fmtr_null_();
public Ref_html_wtr_cfg Cfg() {return cfg;} private Ref_html_wtr_cfg cfg;

View File

@@ -36,11 +36,7 @@ public class Ref_nde implements Xox_xnde, Xop_xnde_atr_parser {
switch (xatr_key.Val()) {
case Xatr_id_name: name = wiki.App().Sanitizer().Escape_id(xatr.Val_as_bry(src)); break;
case Xatr_id_follow: follow = xatr.Val_as_bry(src); break;
case Xatr_id_group: {
group = xatr.Val_as_bry(src);
// if (Bry_.Eq(group, wiki.Xtn_mgr().Xtn_cite().Group_default_name())) group = Bry_.Empty; // if group == default, make it same as empty; DATE:2014-07-03
break;
}
case Xatr_id_group: group = xatr.Val_as_bry(src); break;
}
}
public void Xtn_parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {

View File

@@ -24,11 +24,7 @@ public class References_nde implements Xox_xnde, Xop_xnde_atr_parser {
if (xatr_key_obj == null) return;
Byte_obj_val xatr_key = (Byte_obj_val)xatr_key_obj;
switch (xatr_key.Val()) {
case Xatr_id_group: {
group = xatr.Val_as_bry(src);
// if (Bry_.Eq(group, wiki.Xtn_mgr().Xtn_cite().Group_default_name())) group = Bry_.Empty; // if group == default, make it same as empty; DATE:2014-07-03
break;
}
case Xatr_id_group: group = xatr.Val_as_bry(src); break;
}
}
public void Xtn_parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn cur_root, byte[] src, Xop_xnde_tkn xnde) {

View File

@@ -41,29 +41,26 @@ public class References_nde_group_tst {
, ""
));
}
// @Test public void Lower_alpha_is_ignored() {
// String expd =
// String_.Concat_lines_nl_skip_last
// ( "<sup id=\"cite_ref-0\" class=\"reference\"><a href=\"#cite_note-0\">[1]</a></sup>"
// , "<sup id=\"cite_ref-1\" class=\"reference\"><a href=\"#cite_note-1\">[2]</a></sup>"
// , "<ol class=\"references\">"
// , "<li id=\"cite_note-0\"><span class=\"mw-cite-backlink\"><a href=\"#cite_ref-0\">^</a></span> <span class=\"reference-text\">x</span></li>"
// , "<li id=\"cite_note-1\"><span class=\"mw-cite-backlink\"><a href=\"#cite_ref-1\">^</a></span> <span class=\"reference-text\">y</span></li>"
// , "</ol>"
// , ""
// );
// fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
// ( "<ref group='lower-alpha'>x</ref>"
// , "<ref>y</ref>" // note: no group name, but still goes in "lower-alpha" group
// , "<references group='lower-alpha'/>"
// ), expd);
// fxt.Clear_ref_mgr();
// fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
// ( "<ref group='lower-alpha'>x</ref>" // note: "lower-alpha" group name, but goes in default group
// , "<ref>y</ref>"
// , "<references/>"
// ), expd);
// }
@Test public void Lower_alpha_is_ignored() {
String expd =
String_.Concat_lines_nl_skip_last
( "<sup id=\"cite_ref-0\" class=\"reference\"><a href=\"#cite_note-0\">[1]</a></sup>" // note:do not show lower-alpha; DATE:2014-07-21
, "<sup id=\"cite_ref-1\" class=\"reference\"><a href=\"#cite_note-1\">[1]</a></sup>"
, "<ol class=\"references\">"
, "<li id=\"cite_note-0\"><span class=\"mw-cite-backlink\"><a href=\"#cite_ref-0\">^</a></span> <span class=\"reference-text\">x</span></li>"
, "</ol>"
, "<ol class=\"references\">"
, "<li id=\"cite_note-1\"><span class=\"mw-cite-backlink\"><a href=\"#cite_ref-1\">^</a></span> <span class=\"reference-text\">y</span></li>"
, "</ol>"
, ""
);
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "<ref group='lower-alpha'>x</ref>"
, "<ref>y</ref>"
, "<references group='lower-alpha'/>"
, "<references group=''/>"
), expd);
}
@Test public void Empty() { // PURPOSE: <references group=""/> is same as <references/>; DATE:2013-02-06
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "<ref>b</ref>"

View File

@@ -43,7 +43,7 @@ public class Gallery_itm implements Js_img_wkr {
this.xnde = xnde; this.xfer_itm = xfer_itm;;
this.wiki = wiki; this.ctx = ctx; this.src = src; this.gallery_li_id_bry = gallery_li_id_bry; this.gallery_itm_idx = gallery_itm_idx;
} private Gallery_xnde xnde; private Xof_xfer_itm xfer_itm; private Xow_wiki wiki; private Xop_ctx ctx; private byte[] src; private byte[] gallery_li_id_bry; private int gallery_itm_idx;
public void Html_update(Xog_html_itm html_itm, int w, int h, String view_src, String orig_src) {
public void Html_update(Xoa_page page, Xog_html_itm html_itm, int w, int h, String view_src, String orig_src) {
Gallery_mgr_base gallery_mgr = xnde.Gallery_mgr();
Bry_bfr bfr = wiki.Utl_bry_bfr_mkr().Get_k004(), tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_k004();
try {
@@ -52,7 +52,7 @@ public class Gallery_itm implements Js_img_wkr {
String itm_html = bfr.XtoStrAndClear();
html_itm.Html_elem_replace_html(String_.new_utf8_(gallery_li_id_bry), itm_html);
if (gallery_itm_idx == xnde.Itms_len() - 1 && Gallery_mgr_base_.Mode_is_packed(xnde.Mode()))
html_itm.Html_gallery_packed_exec();
page.Html_data().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

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.geoCrumbs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Geoc_isin_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_geoCrumbs_isin;}
@Override public Pf_func New(int id, byte[] name) {return new Geoc_isin_func().Name_(name);}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.geodata; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Geo_coordinates_func extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {} // NOOP: MW uses to save coordinates for API retrieval
@Override public int Id() {return Xol_kwd_grp_.Id_xtn_geodata_coordinates;}

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.srls.dsvs.*;
class Hiero_file_mgr implements GfoInvkAble {
private OrderedHash hash = OrderedHash_.new_bry_();

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.html.*;
class Hiero_html_mgr {
private Bry_bfr html_bfr = Bry_bfr.reset_(Io_mgr.Len_kb), content_bfr = Bry_bfr.reset_(255), tbl_content_bfr = Bry_bfr.reset_(Io_mgr.Len_kb), temp_bfr = Bry_bfr.reset_(255);
@@ -239,7 +239,7 @@ class Hiero_html_wtr {
private Hiero_phoneme_mgr phoneme_mgr;
private Bry_bfr temp_bfr = Bry_bfr.reset_(255);
public Hiero_html_wtr(Hiero_html_mgr mgr, Hiero_phoneme_mgr phoneme_mgr) {this.phoneme_mgr = phoneme_mgr;}
public void Hr(Bry_bfr bfr) {bfr.Add(Html_tag_.Hr_bry).Add_byte_nl();}
public void Hr(Bry_bfr bfr) {bfr.Add(Html_tag_.Hr_inl).Add_byte_nl();}
public void Tbl_eol(Bry_bfr bfr) {bfr.Add(Tbl_eol_bry);}
private static final String
Tbl_bgn_str = "<table class=\"mw-hiero-table\">"

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Hiero_html_mgr_tst {
@Before public void init() {fxt.Reset();} private Hiero_html_mgr_fxt fxt = new Hiero_html_mgr_fxt();

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.php.*; import gplx.srls.dsvs.*;
public class Hiero_mw_tables_parser {
private Php_parser parser = new Php_parser(); private Php_evaluator evaluator;

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
import gplx.intl.*;
public class Hiero_mw_tables_parser_tst {

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.btries.*; import gplx.html.*; import gplx.xowa.html.*;
class Hiero_parser {
private Btrie_slim_mgr trie = Btrie_slim_mgr.cs_();

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Hiero_parser_tst {
@Before public void init() {fxt.Reset();} private Hiero_parser_fxt fxt = new Hiero_parser_fxt();

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.srls.dsvs.*;
class Hiero_phoneme_mgr implements GfoInvkAble {
private OrderedHash hash = OrderedHash_.new_bry_();

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.srls.dsvs.*;
class Hiero_prefab_mgr implements GfoInvkAble {
private OrderedHash hash = OrderedHash_.new_bry_();

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.parsers.logs.*;
import gplx.xowa.html.*;
public class Hiero_xnde implements Xox_xnde, Xop_xnde_atr_parser {

View File

@@ -15,7 +15,7 @@ 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.hiero; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.hieros; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.wikis.*; import gplx.xowa.html.modules.*;
public class Hiero_xtn_mgr extends Xox_mgr_base implements GfoInvkAble {
@Override public boolean Enabled_default() {return true;}
@@ -31,7 +31,6 @@ public class Hiero_xtn_mgr extends Xox_mgr_base implements GfoInvkAble {
Xoa_app app = wiki.App();
Io_url ext_root_dir = app.Fsys_mgr().Bin_extensions_dir().GenSubDir("Wikihiero");
Img_src_dir = Bry_.new_utf8_(ext_root_dir.GenSubDir("img").To_http_file_str());
// Module_css = new Xoh_module_itm("wikihiero.css").Css_mgr_init(ext_root_dir.GenSubFil_nest("modules", "ext.wikihiero.css"));
app.Gfs_mgr().Run_url_for(this, ext_root_dir.GenSubFil_nest("data", "tables.gfs"));
html_wtr = new Hiero_html_mgr(this);
parser.Init();
@@ -54,5 +53,4 @@ public class Hiero_xtn_mgr extends Xox_mgr_base implements GfoInvkAble {
else return super.Invk(ctx, ikey, k, m);
}
public static final String Invk_prefabs = "prefabs", Invk_files = "files", Invk_phonemes = "phonemes";
// public static Xoh_module_itm Module_css;
}

View File

@@ -1,56 +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.imageMap; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
class Imap_html_bldr {
private Pts_fmtr_arg pts_fmtr_arg = new Pts_fmtr_arg();
public void Bld_map(Bry_bfr rslt_bfr, Xow_wiki wiki, Imap_itm[] itms) {
int itms_len = itms.length;
// Imap_itm img_itm = itms[0];
for (int i = 0; i < itms_len; ++i) {
Imap_itm itm = itms[i];
switch (itm.Itm_tid()) {
case Imap_itm_.Tid_shape_dflt:
case Imap_itm_.Tid_shape_rect:
case Imap_itm_.Tid_shape_circle:
case Imap_itm_.Tid_shape_poly:
Bld_map_shape(rslt_bfr, wiki, (Imap_itm_shape)itm);
break;
}
}
}
private void Bld_map_shape(Bry_bfr rslt_bfr, Xow_wiki wiki, Imap_itm_shape itm) {
byte[] shape_name = Imap_itm_.Xto_str(itm.Itm_tid());
pts_fmtr_arg.Init(itm.Shape_pts());
area_fmtr.Bld_bfr_many(rslt_bfr, itm.Shape_link_href(), itm.Shape_link_caption(), shape_name, pts_fmtr_arg);
}
private static final Bry_fmtr area_fmtr = Bry_fmtr.new_
( "<area href=\"~{href}\" shape=\"~{shape}\" coords=\"~{pts}\" alt=\"{caption}\" title=\"~{caption}\"/>"
, "href", "caption", "shape", "pts"
);
}
class Pts_fmtr_arg implements Bry_fmtr_arg {
private Double_obj_val[] pts;
public void Init(Double_obj_val[] pts) {this.pts = pts;}
public void XferAry(Bry_bfr bfr, int idx) {
int pts_len = pts.length;
for (int i = 0; i < pts_len; ++i) {
if (i != 0) bfr.Add_byte(Byte_ascii.Comma);
bfr.Add_double(pts[i].Val());
}
}
}

View File

@@ -1,177 +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.imageMap; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.btries.*;
class Imap_itm_parser {
private Xoa_url page_url; private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_._;
private ListAdp itms = ListAdp_.new_();
private ListAdp pts = ListAdp_.new_();
private ListAdp errs = ListAdp_.new_();
private byte[] src; // private int src_bgn, src_end;
private int itm_idx; private int itm_bgn, itm_end;
private Xoa_app app; private Xow_wiki wiki; private Xop_ctx imap_ctx; private Xop_root_tkn imap_root;
public void Init(Xow_wiki wiki, Xoa_url page_url, Gfo_usr_dlg usr_dlg) {
this.app = wiki.App(); this.wiki = wiki; this.page_url = page_url; this.usr_dlg = usr_dlg;
if (imap_ctx == null) {
imap_ctx = Xop_ctx.new_(wiki);
imap_root = app.Tkn_mkr().Root(Bry_.Empty);
}
}
public void Clear() {
this.itm_idx = 0; itms.Clear();
pts.Clear();
errs.Clear();
}
public ListAdp Errs() {return errs;}
public Imap_itm[] Parse(byte[] src, int src_bgn, int src_end) {
this.Clear();
this.src = src; // this.src_bgn = src_bgn; this.src_end = src_end;
itm_bgn = src_bgn; itm_end = src_bgn - 1;
while (true) {
if (itm_end == src_end) break;
itm_bgn = Bry_finder.Trim_fwd_space_tab(src, itm_end + 1, src_end); // trim ws at start, and look for first char
if (itm_bgn == src_end) break; // line is entirely ws and terminated by eos; EX: "\n EOS"
itm_end = Bry_finder.Find_fwd_until(src, itm_bgn, src_end, Byte_ascii.NewLine); // look for \n
if (itm_end == Bry_finder.Not_found) itm_end = src_end; // no \n; make EOS = \n
itm_end = Bry_finder.Trim_bwd_space_tab(src, itm_end, itm_bgn); // trim any ws at end
if (itm_end - itm_bgn == 0) continue; // line is entirely ws; continue;
byte b = src[itm_bgn];
if (b == Byte_ascii.Hash) {
Parse_comment(itm_bgn, itm_end);
continue;
}
if (itm_idx == 0)
Parse_img(itm_bgn, itm_end);
else {
Object tid_obj = tid_trie.Match_bgn_w_byte(b, src, itm_bgn, itm_end);
byte tid_val = tid_obj == null ? Imap_itm_.Tid_invalid : ((Byte_obj_val)tid_obj).Val();
int tid_end_pos = tid_trie.Match_pos();
switch (tid_val) {
case Imap_itm_.Tid_desc: Parse_desc(itm_bgn, itm_end); break;
case Imap_itm_.Tid_shape_dflt: Parse_shape(tid_val, tid_end_pos, itm_end, Reqd_dflt); break;
case Imap_itm_.Tid_shape_rect: Parse_shape(tid_val, tid_end_pos, itm_end, 4); break;
case Imap_itm_.Tid_shape_poly: Parse_shape(tid_val, tid_end_pos, itm_end, Reqd_poly); break;
case Imap_itm_.Tid_shape_circle: Parse_shape(tid_val, tid_end_pos, itm_end, 3); break;
default:
case Imap_itm_.Tid_invalid: Parse_invalid(itm_bgn, itm_end); break;
}
}
++itm_idx;
}
return (Imap_itm[])itms.XtoAryAndClear(Imap_itm.class);
}
private void Parse_comment(int itm_bgn, int itm_end) {} // noop comments; EX: "# comment\n"
private void Parse_invalid(int itm_bgn, int itm_end) {usr_dlg.Warn_many("", "", "imap has invalid line: page=~{0} line=~{1}", page_url.Xto_full_str_safe(), String_.new_utf8_(src, itm_bgn, itm_end));}
private void Parse_desc(int itm_bgn, int itm_end) {itms.Add(new Imap_itm_desc(itm_idx, itm_bgn, itm_end));}
private void Parse_shape(byte shape_tid, int itm_bgn, int itm_end, int reqd_pts) {
int num_bgn = -1; // differs from MW parser which looks for link via regx, and then chops off rest; regx is difficult due to lnke; doing opposite approach which is eat numbers until something else
int pos = Bry_finder.Trim_fwd_space_tab(src, itm_bgn, itm_end);
boolean reading_numbers = true;
while (reading_numbers) {
boolean last = pos == itm_end;
byte b = last ? Byte_ascii.Space : src[pos];
switch (b) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
case Byte_ascii.Dash: case Byte_ascii.Dot:
if (num_bgn == -1)
num_bgn = pos;
++pos;
break;
default:
int new_pos = Parse_shape_num(num_bgn, pos, itm_end);
if (new_pos == -1) {Add_err("imagemap_invalid_coord", itm_bgn, itm_end); return;}
if (new_pos == pos)
reading_numbers = false;
else
pos = Bry_finder.Trim_fwd_space_tab(src, new_pos, itm_end);
num_bgn = -1;
break;
}
if (last) reading_numbers = false;
}
int pts_len = pts.Count();
switch (reqd_pts) {
case Reqd_poly: {
if (pts_len == 0) {Add_err("imagemap_missing_coord", itm_bgn, itm_end); return;}
else if (pts_len % 2 != 0) {Add_err("imagemap_poly_odd", itm_bgn, itm_end); return;}
break;
}
case Reqd_dflt: {
pts.Clear(); // dflt should have 0 points; if any defined, ignore them; clearing list for purpose of test
break;
}
default: {
if (reqd_pts != pts_len) {Add_err("imagemap_missing_coord", itm_bgn, itm_end); return;}
break;
}
}
pos = Bry_finder.Trim_fwd_space_tab(src, pos, itm_end);
Imap_itm_shape shape_itm = new Imap_itm_shape(itm_idx, itm_bgn, itm_end, shape_tid, (Double_obj_val[])pts.XtoAryAndClear(Double_obj_val.class));
Xop_tkn_itm link_tkn = Parse_link(pos, itm_end);
shape_itm.Shape_link_(app, wiki, src, link_tkn);
itms.Add(shape_itm);
}
private void Add_err(String err_key, int bgn, int end) {
usr_dlg.Warn_many("", "", err_key + ": page=~{0} line=~{1}", page_url.Xto_full_str_safe(), String_.new_utf8_(src, bgn, end));
errs.Add(new Imap_itm_err(itm_idx, err_key));
}
private Xop_tkn_itm Parse_link(int link_bgn, int link_end) {
imap_root.Clear();
imap_ctx.Clear();
wiki.Parser().Parse_to_src_end(imap_root, imap_ctx, wiki.App().Tkn_mkr(), src, wiki.Parser().Wtxt_trie(), link_bgn, link_end);
int subs_len = imap_root.Subs_len();
for (int i = 0; i < subs_len; ++i) {
Xop_tkn_itm sub = imap_root.Subs_get(i);
switch (sub.Tkn_tid()) {
case Xop_tkn_itm_.Tid_lnki:
case Xop_tkn_itm_.Tid_lnke:
return sub;
}
}
return null;
}
private int Parse_shape_num(int num_bgn, int num_end, int itm_end) {
if (num_bgn == -1) return num_end;
double num = Bry_.XtoDoubleByPosOr(src, num_bgn, num_end, Double_.NaN);
if (Double_.IsNaN(num)) return -1; // invalid number; EX: "1.2.3"
pts.Add(Double_obj_val.new_(num));
return Bry_finder.Trim_fwd_space_tab(src, num_end, itm_end);
}
private void Parse_img(int itm_bgn, int itm_end) {
int pos = Bry_finder.Trim_fwd_space_tab(src, itm_bgn, itm_end);
Xop_tkn_itm link_tkn = Parse_link(pos, itm_end);
Imap_itm_img itm = new Imap_itm_img(itm_idx, itm_bgn, itm_end, link_tkn);
itms.Add(itm);
}
private static Btrie_slim_mgr tid_trie = Btrie_slim_mgr.ci_ascii_() // NOTE: names are not i18n'd; // NOTE:ci.ascii:MW_const.en
.Add_str_byte("desc" , Imap_itm_.Tid_desc)
.Add_str_byte("#" , Imap_itm_.Tid_comment)
.Add_bry_bval(Imap_itm_.Tid_name_default , Imap_itm_.Tid_shape_dflt)
.Add_bry_bval(Imap_itm_.Tid_name_rect , Imap_itm_.Tid_shape_rect)
.Add_bry_bval(Imap_itm_.Tid_name_circle , Imap_itm_.Tid_shape_circle)
.Add_bry_bval(Imap_itm_.Tid_name_poly , Imap_itm_.Tid_shape_poly)
;
private static final int Reqd_poly = -1, Reqd_dflt = -2;
}
class Imap_itm_err {
public Imap_itm_err(int itm_idx, String err_key) {this.itm_idx = itm_idx; this.err_key = err_key;}
public int Itm_idx() {return itm_idx;} private int itm_idx;
public String Err_key() {return err_key;} private String err_key;
}

View File

@@ -1,95 +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.imageMap; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
interface Imap_itm {
byte Itm_tid();
int Itm_idx();
int Src_bgn();
int Src_end();
}
class Imap_itm_ {
public static final byte Tid_invalid = 0, Tid_img = 1, Tid_desc = 2, Tid_comment = 3, Tid_shape_dflt = 4, Tid_shape_rect = 5, Tid_shape_circle = 6, Tid_shape_poly = 7;
public static final byte[]
Tid_name_default = Bry_.new_ascii_("default")
, Tid_name_rect = Bry_.new_ascii_("rect")
, Tid_name_circle = Bry_.new_ascii_("circle")
, Tid_name_poly = Bry_.new_ascii_("poly")
;
public static byte[] Xto_str(byte v) {
switch (v) {
case Tid_shape_dflt : return Tid_name_default;
case Tid_shape_rect : return Tid_name_rect;
case Tid_shape_circle : return Tid_name_circle;
case Tid_shape_poly : return Tid_name_poly;
default : throw Err_.unhandled(v);
}
}
}
abstract class Imap_itm_base implements Imap_itm {
public abstract byte Itm_tid();
public void Ctor(int itm_idx, int src_bgn, int src_end) {this.itm_idx = itm_idx; this.src_bgn = src_bgn; this.src_end = src_end;}
public int Itm_idx() {return itm_idx;} private int itm_idx;
public int Src_bgn() {return src_bgn;} private int src_bgn;
public int Src_end() {return src_end;} private int src_end;
}
class Imap_itm_img extends Imap_itm_base {
public Imap_itm_img(int itm_idx, int src_bgn, int src_end, Xop_tkn_itm img_link) {
this.Ctor(itm_idx, src_bgn, src_end);
this.img_link = img_link;
}
public Xop_tkn_itm Img_link() {return img_link;} private Xop_tkn_itm img_link;
@Override public byte Itm_tid() {return Imap_itm_.Tid_img;}
}
class Imap_itm_desc extends Imap_itm_base {
public Imap_itm_desc(int itm_idx, int src_bgn, int src_end) {this.Ctor(itm_idx, src_bgn, src_end);}
@Override public byte Itm_tid() {return Imap_itm_.Tid_desc;}
}
// class Imap_itm_comment : Imap_itm_base {
// public override byte Itm_tid() {return Imap_itm_.Tid_comment;}
// }
class Imap_itm_shape extends Imap_itm_base {
public Imap_itm_shape(int itm_idx, int src_bgn, int src_end, byte shape_tid, Double_obj_val[] shape_pts) {
this.Ctor(itm_idx, src_bgn, src_end);
this.shape_tid = shape_tid;
this.shape_pts = shape_pts;
}
@Override public byte Itm_tid() {return shape_tid;} private byte shape_tid;
public Double_obj_val[] Shape_pts() {return shape_pts;} private Double_obj_val[] shape_pts;
public Xop_tkn_itm Shape_link() {return shape_link;} private Xop_tkn_itm shape_link;
public byte[] Shape_link_href() {return shape_link_href;} private byte[] shape_link_href;
public byte[] Shape_link_caption() {return shape_link_caption;} private byte[] shape_link_caption;
public void Shape_link_(Xoa_app app, Xow_wiki wiki, byte[] src, Xop_tkn_itm tkn) {
this.shape_link = tkn;
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_lnki: {
Xop_lnki_tkn lnki_tkn = (Xop_lnki_tkn)tkn;
shape_link_href = app.Href_parser().Build_to_bry(wiki, lnki_tkn.Ttl());
shape_link_caption = Bry_.Mid(src, lnki_tkn.Src_bgn(), lnki_tkn.Src_end());
break;
}
case Xop_tkn_itm_.Tid_lnke: {
// gplx.xowa.parsers.lnkes.Xop_lnke_tkn lnke_tkn = (gplx.xowa.parsers.lnkes.Xop_lnke_tkn)tkn;
// shape_link_href = lnke_tkn.
// shape_link_caption = Bry_.Mid(src, lnki_tkn.Src_bgn(), lnki_tkn.Src_end());
break;
}
}
}
public static final byte Tid_default = 0, Tid_rect = 4, Tid_circle = 3, Tid_poly = 5;
public static final Imap_itm_shape Shape_dflt = new Imap_itm_shape(-1, -1, -1, Imap_itm_.Tid_shape_dflt, null);
}

View File

@@ -1,144 +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.imageMap; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.btries.*; import gplx.xowa.html.*;
import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.parsers.logs.*;
public class Xop_imageMap_xnde implements Xox_xnde {
private boolean first = true;
public byte[] Xtn_src() {return lnki_src;} private byte[] lnki_src;
private Xop_root_tkn xtn_root;
public ListAdp Shape_list() {return shape_list;} ListAdp shape_list = ListAdp_.new_();
public void Xtn_parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {
ctx.Para().Process_block__xnde(xnde.Tag(), Xop_xnde_tag.Block_end);
int content_bgn = xnde.Tag_open_end(), content_end = xnde.Tag_close_bgn();
int nl_0_pos = Bry_finder.Find_fwd_while_not_ws(src, content_bgn, content_end);
int cur_pos = nl_0_pos, nl_1_pos = -1;//, ws_pos_bgn = -1;
int src_len = src.length;
Xop_ctx imageMap_ctx = Xop_ctx.new_sub_(wiki).Tid_is_image_map_(true);
imageMap_ctx.Para().Enabled_n_();
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
while (true) {
boolean last = cur_pos == content_end;
if (last) nl_1_pos = cur_pos;
if (nl_1_pos != -1 || last) {
Object typeId_obj = TypeTrie.Match_bgn(src, nl_0_pos, nl_1_pos);
if (typeId_obj == null) { // flag itm
if (!first && nl_1_pos - nl_0_pos > 0)
ctx.Msg_log().Add_itm_none(Xtn_imageMap_msg.Line_type_unknown, src, nl_0_pos, nl_1_pos);
}
else {
byte typeId = ((Byte_obj_val)typeId_obj).Val();
switch (typeId) {
case TypeId_comment: break; // NOOP
case TypeId_desc: break; // FUTURE: flag; TODO: desc show info icon; top-right, bottom-right, bottom-left, top-left, none
case TypeId_default:
case TypeId_rect:
case TypeId_circle:
case TypeId_poly:
// GfoLogWkr logWkr = new GfoLogWkr();
// logWkr.Add_args(Xtn_imageMap_msg.Coords_count_invalid, TypeName[typeId], TypeCoords[typeId], coords.length);
Xtn_imageMap_shape shape = Xtn_imageMap_shape.parse_(typeId, src, nl_0_pos + TypeTrie.Match_pos(), nl_1_pos);
shape_list.Add(shape);
break;
}
}
//int bgn = ws_pos_bgn = -1 ? nl_0_pos : ws
ParseLine(ctx, imageMap_ctx, wiki, tkn_mkr, root, src, src_len, xnde, nl_0_pos, nl_1_pos);
nl_0_pos = nl_1_pos + 1;
nl_1_pos = -1;
}
if (last) break;
byte b = src[cur_pos];
switch (b) {
case Byte_ascii.Space:
case Byte_ascii.Tab:
break;
case Byte_ascii.NewLine:
nl_1_pos = cur_pos;
break;
default:
// ws_pos_bgn = cur_pos;;
break;
}
++cur_pos;
}
ctx.Para().Process_block__xnde(xnde.Tag(), Xop_xnde_tag.Block_end);
ctx.Para().Process_nl(ctx, root, src, xnde.Tag_close_end(), xnde.Tag_close_end()); // NOTE: this should create an extra stub "p" so that remaining text gets enclosed in <p>; DATE:2014-05-08
boolean log_wkr_enabled = Log_wkr != Xop_log_basic_wkr.Null; if (log_wkr_enabled) Log_wkr.Log_end_xnde(ctx.Cur_page(), Xop_log_basic_wkr.Tid_imageMap, src, xnde);
} public static Xop_log_basic_wkr Log_wkr = Xop_log_basic_wkr.Null;
public void Xtn_write(Xoa_app app, Xoh_html_wtr html_wtr, Xoh_html_wtr_ctx opts, Xop_ctx ctx, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) {
html_wtr.Write_tkn(bfr, ctx, opts, xtn_root.Root_src(), xnde, Xoh_html_wtr.Sub_idx_null, xtn_root);
}
private void ParseLine(Xop_ctx orig_ctx, Xop_ctx image_map_ctx, Xow_wiki wiki, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, Xop_xnde_tkn xnde, int nl_0_pos, int nl_1_pos) {
int line_len = nl_1_pos - nl_0_pos;
if (line_len == 0 || src[nl_0_pos + 1] == Byte_ascii.Hash) return;
if (first) {
byte[] lnki_raw = Bry_.Add(Xop_tkn_.Lnki_bgn, Bry_.Mid(src, nl_0_pos, nl_1_pos), Xop_tkn_.Lnki_end);
xtn_root = tkn_mkr.Root(lnki_src);
image_map_ctx.Wiki().Parser().Parse_text_to_wdom(xtn_root, image_map_ctx, tkn_mkr, lnki_raw, 0);
lnki_src = xtn_root.Root_src(); // NOTE: html_wtr will write based on parsed mid (not raw)
xtn_root.Root_src_(lnki_src); // HACK: Xoh_html_wtr uses raw (instead of mid); put data in raw in order to conform to other xtns
Xop_lnki_logger file_wkr = orig_ctx.Lnki().File_wkr(); // NOTE: do not do image_map_ctx.Lnki(); image_map_ctx is brand new
Xop_lnki_tkn lnki_tkn = null;
int subs_len = xtn_root.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm sub_tkn = xtn_root.Subs_get(i);
if (sub_tkn.Tkn_tid() == Xop_tkn_itm_.Tid_lnki) {
lnki_tkn = (Xop_lnki_tkn)sub_tkn;
break;
}
}
if (lnki_tkn == null) {
image_map_ctx.Wiki().App().Usr_dlg().Warn_many("", "", "image_map failed to find lnki; page=~{0} imageMap=~{1}", String_.new_utf8_(image_map_ctx.Cur_page().Ttl().Full_txt()), String_.new_utf8_(lnki_raw));
}
else {
orig_ctx.Cur_page().Lnki_list().Add(lnki_tkn);
if (file_wkr != null) file_wkr.Wkr_exec(orig_ctx, src, lnki_tkn, gplx.xowa.bldrs.files.Xob_lnki_src_tid.Tid_imageMap);
}
first = false;
}
else {
}
}
public static final byte TypeId_default = 0, TypeId_rect = 4, TypeId_circle = 3, TypeId_poly = 5, TypeId_desc = 6, TypeId_comment = 7;
public static Btrie_mgr TypeTrie = Btrie_slim_mgr.ci_ascii_() // NOTE: names are not i18n'd; // NOTE:ci.ascii:MW_const.en
.Add_obj("default" , Byte_obj_val.new_(TypeId_default))
.Add_obj("rect" , Byte_obj_val.new_(TypeId_rect))
.Add_obj("circle" , Byte_obj_val.new_(TypeId_circle))
.Add_obj("poly" , Byte_obj_val.new_(TypeId_poly))
.Add_obj("desc" , Byte_obj_val.new_(TypeId_desc))
.Add_obj("#" , Byte_obj_val.new_(TypeId_comment))
;
}
class Xtn_imageMap_shape {
public byte TypeId() {return typeId;} private byte typeId;
public int[] Coord_ary() {return coord_ary;} private int[] coord_ary = null;
public Xop_lnki_tkn Lnki_tkn() {return lnki_tkn;} private Xop_lnki_tkn lnki_tkn = null;
public static Xtn_imageMap_shape parse_(byte typeId, byte[] src, int bgn, int end) {
Xtn_imageMap_shape rv = new Xtn_imageMap_shape();
rv.typeId = typeId;
return rv;
}
}
class Xtn_imageMap_msg {
public static final Gfo_msg_grp Nde = Gfo_msg_grp_.new_(Xoa_app_.Nde, "image_map");
public static final Gfo_msg_itm
Line_type_unknown = Gfo_msg_itm_.new_warn_(Nde, "line_type_unknown", "Line type is unknown")
, Coords_count_invalid = Gfo_msg_itm_.new_warn_(Nde, "coords_count_invalid", "Coordinate counts are invalid for shape: shape=~{0} expd=~{1} actl=~{2}")
;
}

View File

@@ -1,62 +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.imageMap; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Xop_imageMap_xnde_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Basic() {
fxt.Test_parse_page_wiki_str("<imagemap>File:A.png</imagemap>", html_img_none("File:A.png", ""));
}
@Test public void Caption() {
fxt.Test_parse_page_wiki_str("<imagemap>File:A.png|thumb|bcde</imagemap>", String_.Concat_lines_nl_skip_last
( Xop_para_wkr_basic_tst.File_html("File", "A.png", "7/0", "bcde")
, ""
));
}
@Test public void Err_trailing_ws() { // PURPOSE: empty 1st line causes failure
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "<imagemap> "
, "File:A.png"
, "</imagemap>"
), html_img_none("File:A.png", ""));
}
@Test public void Coords_one() {
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "<imagemap>"
, "File:A.png"
, "circle 1 3 5 [[b|c]]"
// , "rect 2 4 6 8"
// , "poly 1 2 3 4 5"
, "</imagemap>"
), html_img_none("File:A.png", ""));
}
@Test public void Para_omitted() { // PURPOSE: imagemap should not be automatically enclosed in para; cs.w:Seznam_clenu_ctrn<72>ct<63>ho_Knesetu; DATE:2014-05-08
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str("<imagemap>File:A.png</imagemap> a", html_img_none("File:A.png", "") + String_.Concat_lines_nl_skip_last
( ""
, ""
, "<p> a"
, "</p>"
));
fxt.Init_para_n_();
}
private static String html_img_none(String trg, String alt) {
return String_.Format("<a href=\"/wiki/{0}\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>", trg, alt);
}
}

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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.btries.*;
class Imap_desc_tid {
public static final byte Tid_tr = 0, Tid_br = 1, Tid_bl = 2, Tid_tl = 3, Tid_none = 4, Tid_null = 5;
public static final byte[]
Key_tr = Bry_.new_ascii_("top-right")
, Key_br = Bry_.new_ascii_("bottom-right")
, Key_bl = Bry_.new_ascii_("bottom-left")
, Key_tl = Bry_.new_ascii_("top-left")
, Key_none = Bry_.new_ascii_("none")
;
public static Btrie_slim_mgr trie_(Xow_wiki wiki) {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_utf_8_();
trie_add(rv, Key_tr, Key_br, Key_bl, Key_tl, Key_none);
// if (wiki.Lang().Lang_id() != Xol_lang_itm_.Id_en) {
byte[][] lang_types = Parse_lang_types(wiki);
if (lang_types != null)
trie_add(rv, lang_types);
// }
return rv;
}
private static void trie_add(Btrie_slim_mgr trie, byte[]... ary) {
trie.Add_bry_bval(ary[0] ,Tid_tr);
trie.Add_bry_bval(ary[1] ,Tid_br);
trie.Add_bry_bval(ary[2] ,Tid_bl);
trie.Add_bry_bval(ary[3] ,Tid_tl);
trie.Add_bry_bval(ary[4] ,Tid_none);
}
private static byte[][] Parse_lang_types(Xow_wiki wiki) {
byte[] val = wiki.Msg_mgr().Val_by_key_obj("imagemap_desc_types");
if (Bry_.Len_eq_0(val)) return null; // no msg in lang; return;
byte[][] ary = Bry_.Split(val, Byte_ascii.Comma);
int ary_len = ary.length;
if (ary_len != 5) wiki.App().Usr_dlg().Warn_many("", "", "imap_desc does not have 5 items; wiki=~{0} val=~{1}", wiki.Domain_bry(), val);
for (int i = 0; i < 5; ++i)
ary[i] = Bry_.Trim(ary[i]); // note that items will have trailing ws; EX: "top-right, bottom-right, bottom-left, top-left, none"
return ary;
}
public static byte parse_(Btrie_slim_mgr trie, byte[] src, int bgn, int end) {
Object rv = trie.Match_bgn(src, bgn, end);
return rv == null ? Tid_null : ((Byte_obj_val)rv).Val();
}
public static void calc_desc_margins(Int_2_ref rv, byte tid, int html_w, int html_h) {
int margin_l
= tid == Tid_tl || tid == Tid_bl
? 0
: html_w - 20
;
int margin_t
= tid == Tid_tl || tid == Tid_tr
? -html_h + 1 // 1px hack for IE, to stop it poking out the top
: -20
;
rv.Val_all_(margin_l, margin_t);
}
}

View File

@@ -0,0 +1,61 @@
/*
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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
class Imap_html_fmtrs {
public static final Bry_fmtr
Map = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "<div class=\"noresize\"~{desc_style}>"
, " <map name=\"imageMap_1_~{imap_id}\">~{shapes}"
, " </map>~{img}"
, " </div>"
), "imap_id", "desc_style", "img", "shapes"
)
, Area = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( "\n <area href=\"~{href}\" shape=\"~{shape}\" coords=\"~{coords}\" alt=\"~{title}\" title=\"~{title}\"/>"
), "href", "shape", "coords", "title")
, Img_anchor_none = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <img id=\"xowa_file_img_~{img_elem_id}\" alt=\"~{img_alt}\" src=\"~{img_src}\" width=\"~{img_w}\" height=\"~{img_h}\"~{img_cls} usemap=\"#imageMap_1_~{imap_id}\"/>"
), "imap_id", "img_elem_id", "img_alt", "img_src", "img_w", "img_h", "img_cls", "anchor_href", "anchor_title"
)
, Img_anchor_lnki = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <a href=\"~{anchor_href}\" title=\"~{anchor_title}\">"
, " <img id=\"xowa_file_img_~{img_elem_id}\" alt=\"~{img_alt}\" src=\"~{img_src}\" width=\"~{img_w}\" height=\"~{img_h}\"~{img_cls} usemap=\"#imageMap_1_~{imap_id}\"/>"
, " </a>"
), "imap_id", "img_elem_id", "img_alt", "img_src", "img_w", "img_h", "img_cls", "anchor_href", "anchor_title"
)
, Img_anchor_lnke = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <a href=\"~{anchor_href}\" title=~{anchor_title} class=\"plainlinks\" rel=\"nofollow\">"
, " <img id=\"xowa_file_img_~{img_elem_id}\" alt=\"~{img_alt}\" src=\"~{img_src}\" width=\"~{img_w}\" height=\"~{img_h}\"~{img_cls} usemap=\"#imageMap_1_~{imap_id}\"/>"
, " </a>"
), "imap_id", "img_elem_id", "img_alt", "img_src", "img_w", "img_h", "img_cls", "anchor_href", "anchor_title"
)
, Desc_style = Bry_fmtr.new_(" style=\"height:~{div_h}px; width: ~{div_w}px;\"", "div_h", "div_w")
, Desc_main = Bry_fmtr.new_(String_.Concat_lines_nl_skip_last
( ""
, " <div style=\"margin-left:~{margin_left}px; margin-top:~{margin_top}px; text-align:left;\">"
, " <a href=\"~{img_href}\" title=\"~{msg_desc}\">"
, " <img alt=\"~{msg_desc}\" src=\"~{icon_url}\" style=\"border: none;\" />"
, " </a>"
, " </div>"
), "margin_left", "margin_top", "img_href", "msg_desc", "icon_url"
)
;
}

View File

@@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
class Imap_img_fmtr_arg implements Bry_fmtr_arg {
private Imap_map map;
private int img_elem_id, img_w, img_h;
private byte[] img_alt, img_src, img_cls, img_href;
private Int_2_ref margin_calc = new Int_2_ref();
public void Init(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) {
this.map = map;
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;
}
public void XferAry(Bry_bfr bfr, int idx) {
Bry_fmtr fmtr = Imap_html_fmtrs.Img_anchor_none;
byte[] anchor_href = Bry_.Empty, anchor_text = Bry_.Empty;
Imap_itm_dflt itm_dflt = map.Dflt();
if (itm_dflt != null) {
fmtr = itm_dflt.Link_tid() == Xop_tkn_itm_.Tid_lnki ? Imap_html_fmtrs.Img_anchor_lnki : Imap_html_fmtrs.Img_anchor_lnke;
anchor_href = itm_dflt.Link_href();
anchor_text = itm_dflt.Link_text();
}
fmtr.Bld_bfr_many(bfr, map.Id(), img_elem_id, img_alt, img_src, img_w, img_h, img_cls, anchor_href, anchor_text);
Imap_itm_desc itm_desc = map.Desc();
if (itm_desc != null) {
Imap_desc_tid.calc_desc_margins(margin_calc, itm_desc.Desc_tid(), img_w, img_h);
Imap_xtn_mgr xtn_mgr = map.Xtn_mgr();
Imap_html_fmtrs.Desc_main.Bld_bfr_many(bfr, margin_calc.Val_0(), margin_calc.Val_1(), img_href, xtn_mgr.Desc_msg(), xtn_mgr.Desc_icon_url());
}
}
}

View File

@@ -0,0 +1,59 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
interface Imap_itm {
byte Itm_tid();
}
class Imap_itm_ {
public static final byte Tid_invalid = 0, Tid_img = 1, Tid_desc = 2, Tid_comment = 3, Tid_dflt = 4, Tid_shape_rect = 5, Tid_shape_circle = 6, Tid_shape_poly = 7;
public static final byte[]
Key_dflt = Bry_.new_ascii_("default")
, Key_shape_rect = Bry_.new_ascii_("rect")
, Key_shape_circle = Bry_.new_ascii_("circle")
, Key_shape_poly = Bry_.new_ascii_("poly")
;
public static byte[] Xto_key(byte v) {
switch (v) {
case Tid_shape_rect : return Key_shape_rect;
case Tid_shape_circle : return Key_shape_circle;
case Tid_shape_poly : return Key_shape_poly;
default : throw Err_.unhandled(v);
}
}
}
class Imap_itm_img implements Imap_itm {
public Imap_itm_img(Xop_lnki_tkn img_link) {this.img_link = img_link;}
public byte Itm_tid() {return Imap_itm_.Tid_img;}
public Xop_lnki_tkn Img_link() {return img_link;} private Xop_lnki_tkn img_link;
}
class Imap_itm_desc implements Imap_itm {
public Imap_itm_desc(byte desc_tid) {this.desc_tid = desc_tid;}
public byte Itm_tid() {return Imap_itm_.Tid_desc;}
public byte Desc_tid() {return desc_tid;} private byte desc_tid;
}
class Imap_itm_dflt implements Imap_itm, Imap_link_owner {
public byte Itm_tid() {return Imap_itm_.Tid_dflt;}
public int Link_tid() {return link_tid;} public void Link_tid_(int v) {link_tid = v;} private int link_tid;
public byte[] Link_href() {return link_href;} public void Link_href_(byte[] v) {this.link_href = v;} private byte[] link_href;
public byte[] Link_text() {return link_text;} public void Link_text_(byte[] v) {this.link_text = v;} private byte[] link_text;
}
class Imap_err {
public Imap_err(int itm_idx, String err_key) {this.itm_idx = itm_idx; this.err_key = err_key;}
public int Itm_idx() {return itm_idx;} private int itm_idx;
public String Err_key() {return err_key;} private String err_key;
}

View File

@@ -0,0 +1,64 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.parsers.lnkes.*; import gplx.xowa.html.*; import gplx.xowa.net.*;
interface Imap_link_owner {
void Link_tid_(int v);
void Link_href_(byte[] v);
void Link_text_(byte[] v);
}
class Imap_link_owner_ {
public static void Init(Imap_link_owner link_owner, Xoa_app app, Xow_wiki wiki, byte[] src, Xop_tkn_itm tkn) {
Bry_bfr bfr = wiki.Utl_bry_bfr_mkr().Get_b512();
int tkn_tid = tkn.Tkn_tid();
link_owner.Link_tid_(tkn_tid);
switch (tkn_tid) {
case Xop_tkn_itm_.Tid_lnki: {
Xop_lnki_tkn lnki_tkn = (Xop_lnki_tkn)tkn;
link_owner.Link_href_(app.Href_parser().Build_to_bry(wiki, lnki_tkn.Ttl()));
wiki.Html_mgr().Html_wtr().Lnki_wtr().Write_caption(bfr, Xoh_html_wtr_ctx.Alt, src, lnki_tkn, lnki_tkn.Ttl());
link_owner.Link_text_(bfr.XtoAryAndClear());
break;
}
case Xop_tkn_itm_.Tid_lnke: {
Xop_lnke_tkn lnke = (Xop_lnke_tkn)tkn;
Xop_ctx ctx = wiki.Ctx();
int lnke_bgn = lnke.Lnke_bgn(), lnke_end = lnke.Lnke_end(); boolean proto_is_xowa = lnke.Proto_tid() == Xoo_protocol_itm.Tid_xowa;
Xoh_lnke_wtr lnke_wtr = wiki.Html_mgr().Html_wtr().Lnke_wtr();
lnke_wtr.Write_href(bfr, ctx, src, lnke, lnke_bgn, lnke_end, proto_is_xowa);
link_owner.Link_href_(bfr.XtoAryAndClear());
lnke_wtr.Write_caption(bfr, wiki.Html_mgr().Html_wtr(), Xoh_html_wtr_ctx.Basic, ctx, src, lnke, lnke_bgn, lnke_end, proto_is_xowa);
link_owner.Link_text_(bfr.XtoAryAndClear());
break;
}
}
bfr.Mkr_rls();
}
}
class Imap_itm_shape implements Imap_itm, Imap_link_owner {
public Imap_itm_shape(byte shape_tid, Double_obj_val[] shape_pts) {
this.shape_tid = shape_tid;
this.shape_pts = shape_pts;
}
public byte Itm_tid() {return shape_tid;} private byte shape_tid;
public Double_obj_val[] Shape_pts() {return shape_pts;} private Double_obj_val[] shape_pts;
public int Link_tid() {return link_tid;} public void Link_tid_(int v) {link_tid = v;} private int link_tid;
public byte[] Link_href() {return link_href;} public void Link_href_(byte[] v) {this.link_href = v;} private byte[] link_href;
public byte[] Link_text() {return link_text;} public void Link_text_(byte[] v) {this.link_text = v;} private byte[] link_text;
public static final byte Tid_default = 0, Tid_rect = 4, Tid_circle = 3, Tid_poly = 5;
}

View File

@@ -0,0 +1,69 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.files.*; import gplx.xowa.html.*;
class Imap_map implements Bry_fmtr_arg, Xoh_lnki_file_wkr {
public Imap_xtn_mgr Xtn_mgr() {return xtn_mgr;} private Imap_xtn_mgr xtn_mgr;
public void Init(Imap_xtn_mgr xtn_mgr, int id, byte[] img_src, Imap_itm_img img, Imap_itm_dflt dflt, Imap_itm_desc desc, Imap_itm_shape[] shapes, Imap_err[] errs) {
this.xtn_mgr = xtn_mgr;
this.id = id; this.img_src = img_src; this.img = img; this.dflt = dflt; this.desc = desc; this.shapes = shapes; this.errs = errs;
}
public int Id() {return id;} private int id;
public byte[] Img_src() {return img_src;} private byte[] img_src;
public Imap_itm_img Img() {return img;} private Imap_itm_img img;
public Imap_itm_dflt Dflt() {return dflt;} private Imap_itm_dflt dflt;
public Imap_itm_desc Desc() {return desc;} private Imap_itm_desc desc;
public Imap_itm_shape[] Shapes() {return shapes;} private Imap_itm_shape[] shapes;
public Imap_err[] Errs() {return errs;} private Imap_err[] errs;
public void Write_img_full(Bry_bfr bfr, Xof_xfer_itm xfer_itm, int elem_id, byte[] lnki_href, byte[] html_view_src, int html_w, int html_h, byte[] lnki_alt_text, byte[] lnki_ttl, byte[] anchor_cls, byte[] anchor_rel, byte[] anchor_title, byte[] itm_cls) {
pts_fmtr_arg.Scale_(Calc_scale(xfer_itm.Orig_w(), xfer_itm.Orig_h(), html_w, html_h));
img_fmtr_arg.Init(this, elem_id, lnki_alt_text, html_view_src, html_w, html_h, itm_cls, lnki_href);
byte[] desc_style = Calc_desc_style(html_w, html_h);
Imap_html_fmtrs.Map.Bld_bfr_many(bfr, id, desc_style, img_fmtr_arg, this);
}
private byte[] Calc_desc_style(int html_w, int html_h) {
if (desc == null) return Bry_.Empty;
Bry_bfr tmp_bfr = xtn_mgr.Wiki().Utl_bry_bfr_mkr().Get_b128().Mkr_rls();
return Imap_html_fmtrs.Desc_style.Bld_bry_many(tmp_bfr, html_w, html_h);
}
public void XferAry(Bry_bfr bfr, int idx) {
int shapes_len = shapes.length;
Bry_fmtr fmtr = Imap_html_fmtrs.Area;
for (int i = 0; i < shapes_len; ++i) {
Imap_itm_shape shape = shapes[i];
Fmt_shape(bfr, fmtr, pts_fmtr_arg, shape);
}
}
public static void Fmt_shape(Bry_bfr bfr, Bry_fmtr fmtr, Imap_pts_fmtr_arg pts_fmtr, Imap_itm_shape shape) {
pts_fmtr_arg.Pts_(shape.Shape_pts());
fmtr.Bld_bfr_many(bfr
, shape.Link_href()
, Imap_itm_.Xto_key(shape.Itm_tid())
, pts_fmtr_arg
, shape.Link_text()
);
}
private static final Imap_pts_fmtr_arg pts_fmtr_arg = new Imap_pts_fmtr_arg();
private static final Imap_img_fmtr_arg img_fmtr_arg = new Imap_img_fmtr_arg();
private static double Calc_scale(int orig_w, int orig_h, int html_w, int html_h) {
int denominator = orig_w + orig_h;
int numerator = html_w + html_h;
if (denominator <= 0 || numerator <= 0) return 1; // return identity; note that MW does "return self::error( 'imagemap_invalid_image' );"
return (double)numerator / (double)denominator;
}
}

View File

@@ -0,0 +1,222 @@
/*
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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.core.btries.*; import gplx.xowa.parsers.lnkis.redlinks.*;
class Imap_parser {
private Imap_xtn_mgr xtn_mgr; private Xoa_url page_url; private Gfo_usr_dlg usr_dlg = Gfo_usr_dlg_._;
private byte[] imap_img_src;
private Imap_itm_img imap_img;
private Imap_itm_dflt imap_dflt;
private Imap_itm_desc imap_desc;
private ListAdp shapes = ListAdp_.new_(), pts = ListAdp_.new_(), errs = ListAdp_.new_();
private byte[] src;
private int itm_idx; private int itm_bgn, itm_end;
private Xoa_app app; private Xow_wiki wiki; private Xop_ctx wiki_ctx, imap_ctx; private Xop_root_tkn imap_root;
public Imap_parser(Imap_xtn_mgr xtn_mgr) {this.xtn_mgr = xtn_mgr;}
public void Init(Xow_wiki wiki, Xoa_url page_url, Gfo_usr_dlg usr_dlg) {
this.app = wiki.App(); this.wiki = wiki; this.page_url = page_url; this.usr_dlg = usr_dlg;
this.wiki_ctx = wiki.Ctx();
if (imap_ctx == null) {
imap_ctx = Xop_ctx.new_(wiki);
imap_root = app.Tkn_mkr().Root(Bry_.Empty);
}
}
public void Clear() {
this.itm_idx = 0;
imap_img = null; imap_img_src = null; imap_desc = null; imap_dflt = null;
shapes.Clear(); pts.Clear(); errs.Clear();
}
public Imap_map Parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {
Imap_map rv = new Imap_map();
Init(wiki, ctx.Cur_page().Url(), wiki.App().Usr_dlg());
this.Parse(rv, ctx.Cur_page().Html_data().Imap_id_next(), src, xnde.Tag_open_end(), xnde.Tag_close_bgn());
return rv;
}
public void Parse(Imap_map rv, int imap_id, byte[] src, int src_bgn, int src_end) {
this.Clear();
this.src = src;
itm_bgn = src_bgn; itm_end = src_bgn - 1;
while (true) {
if (itm_end == src_end) break;
itm_bgn = Bry_finder.Trim_fwd_space_tab(src, itm_end + 1, src_end); // trim ws at start, and look for first char
if (itm_bgn == src_end) break; // line is entirely ws and terminated by eos; EX: "\n EOS"
itm_end = Bry_finder.Find_fwd_until(src, itm_bgn, src_end, Byte_ascii.NewLine); // look for \n
if (itm_end == Bry_finder.Not_found) itm_end = src_end; // no \n; make EOS = \n
itm_end = Bry_finder.Trim_bwd_space_tab(src, itm_end, itm_bgn); // trim any ws at end
if (itm_end - itm_bgn == 0) continue; // line is entirely ws; continue;
byte b = src[itm_bgn];
if (b == Byte_ascii.Hash) {
Parse_comment(itm_bgn, itm_end);
continue;
}
try {
if (itm_idx == 0)
Parse_img(rv, itm_bgn, itm_end);
else {
Object tid_obj = tid_trie.Match_bgn_w_byte(b, src, itm_bgn, itm_end);
byte tid_val = tid_obj == null ? Imap_itm_.Tid_invalid : ((Byte_obj_val)tid_obj).Val();
int tid_end_pos = tid_trie.Match_pos();
switch (tid_val) {
case Imap_itm_.Tid_desc: Parse_desc(tid_end_pos, itm_end); break;
case Imap_itm_.Tid_dflt: Parse_dflt(tid_end_pos, itm_end); break;
case Imap_itm_.Tid_shape_rect: Parse_shape(tid_val, tid_end_pos, itm_bgn, itm_end, 4); break;
case Imap_itm_.Tid_shape_poly: Parse_shape(tid_val, tid_end_pos, itm_bgn, itm_end, Reqd_poly); break;
case Imap_itm_.Tid_shape_circle: Parse_shape(tid_val, tid_end_pos, itm_bgn, itm_end, 3); break;
default:
case Imap_itm_.Tid_invalid: Parse_invalid(itm_bgn, itm_end); break;
}
}
} catch (Exception e) {usr_dlg.Warn_many("", "", "imap.parse:skipping line; page=~{0} line=~{1} err=~{2}", page_url.Xto_full_str_safe(), Bry_.Mid_by_len_safe(src, itm_bgn, itm_end), Err_.Message_gplx(e));}
++itm_idx;
}
rv.Init(xtn_mgr, imap_id, imap_img_src, imap_img, imap_dflt, imap_desc, (Imap_itm_shape[])shapes.XtoAryAndClear(Imap_itm_shape.class), (Imap_err[])errs.XtoAryAndClear(Imap_err.class));
}
private void Parse_comment(int itm_bgn, int itm_end) {} // noop comments; EX: "# comment\n"
private void Parse_invalid(int itm_bgn, int itm_end) {usr_dlg.Warn_many("", "", "imap has invalid line: page=~{0} line=~{1}", page_url.Xto_full_str_safe(), String_.new_utf8_(src, itm_bgn, itm_end));}
private boolean Parse_desc(int itm_bgn, int itm_end) {
xtn_mgr.Desc_assert();
Btrie_slim_mgr trie = xtn_mgr.Desc_trie();
byte tid_desc = Imap_desc_tid.parse_(trie, src, Bry_finder.Trim_fwd_space_tab(src, itm_bgn, itm_end), Bry_finder.Trim_bwd_space_tab(src, itm_bgn, itm_end));
switch (tid_desc) {
case Imap_desc_tid.Tid_null: return Add_err(Bool_.N, itm_bgn, itm_end, "imagemap_invalid_coord");
case Imap_desc_tid.Tid_none: return true;
}
if (imap_img == null || imap_img.Img_link().Lnki_type() == Xop_lnki_type.Id_thumb) return true; // thumbs don't get desc
imap_desc = new Imap_itm_desc(tid_desc);
return true;
}
private void Parse_dflt(int itm_bgn, int itm_end) {
imap_dflt = new Imap_itm_dflt();
Init_link_owner(imap_dflt, src, itm_bgn, itm_end);
}
private boolean Parse_shape(byte shape_tid, int tid_end_pos, int itm_bgn, int itm_end, int reqd_pts) {
int num_bgn = -1; // differs from MW parser which looks for link via regx, and then chops off rest; regx is difficult due to lnke; doing opposite approach which is eat numbers until something else
int pos = Bry_finder.Trim_fwd_space_tab(src, tid_end_pos, itm_end);
boolean reading_numbers = true;
while (reading_numbers) {
boolean last = pos == itm_end;
byte b = last ? Byte_ascii.Space : src[pos];
switch (b) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
case Byte_ascii.Dash: case Byte_ascii.Dot:
if (num_bgn == -1)
num_bgn = pos;
++pos;
break;
default:
int new_pos = Parse_shape_num(shape_tid, b, pos, num_bgn, pos, itm_end);
if (new_pos == -1) return Add_err(Bool_.Y, itm_bgn, itm_end, "imagemap_invalid_coord");
if (new_pos == pos)
reading_numbers = false;
else
pos = Bry_finder.Trim_fwd_space_tab(src, new_pos, itm_end);
num_bgn = -1;
break;
}
if (last) reading_numbers = false;
}
int pts_len = pts.Count();
if (reqd_pts == Reqd_poly) {
if (pts_len == 0) return Add_err(Bool_.Y, itm_bgn, itm_end, "imagemap_missing_coord");
else if (pts_len % 2 != 0) return Add_err(Bool_.Y, itm_bgn, itm_end, "imagemap_poly_odd");
}
else {
if (pts_len < reqd_pts ) return Add_err(Bool_.Y, itm_bgn, itm_end, "imagemap_missing_coord");
}
pos = Bry_finder.Trim_fwd_space_tab(src, pos, itm_end);
Imap_itm_shape shape_itm = new Imap_itm_shape(shape_tid, (Double_obj_val[])pts.XtoAryAndClear(Double_obj_val.class));
Init_link_owner(shape_itm, src, pos, itm_end);
shapes.Add(shape_itm);
return true;
}
private boolean Add_err(boolean clear_pts, int bgn, int end, String err_key) {
usr_dlg.Warn_many("", "", err_key + ": page=~{0} line=~{1}", page_url.Xto_full_str_safe(), String_.new_utf8_(src, bgn, end));
errs.Add(new Imap_err(itm_idx, err_key));
if (clear_pts) pts.Clear();
return false;
}
private void Init_link_owner(Imap_link_owner link_owner, byte[] src, int bgn, int end) {
byte[] link_tkn_src = Bry_.Mid(src, bgn, end);
Xop_tkn_itm link_tkn = Parse_link(link_tkn_src);
Imap_link_owner_.Init(link_owner, app, wiki, link_tkn_src, link_tkn);
}
private Xop_tkn_itm Parse_link(byte[] raw) {
imap_root.Clear();
imap_ctx.Clear();
wiki.Parser().Parse_text_to_wdom(imap_root, imap_ctx, wiki.App().Tkn_mkr(), raw, 0);
int subs_len = imap_root.Subs_len();
for (int i = 0; i < subs_len; ++i) {
Xop_tkn_itm sub = imap_root.Subs_get(i);
switch (sub.Tkn_tid()) {
case Xop_tkn_itm_.Tid_lnki:
case Xop_tkn_itm_.Tid_lnke:
return sub;
}
}
return null;
}
private int Parse_shape_num(byte shape_tid, byte b, int pos, int num_bgn, int num_end, int itm_end) {
double num = 0;
if (num_bgn == -1) { // 1st char is non-numeric; EX: "poly a"
if ( shape_tid == Imap_itm_.Tid_shape_poly // poly code in ImageMap_body.php accepts invalid words and converts to 0; EX:"poly1"; PAGE:uk.w:Стратосфера; DATE:2014-07-26
&& b != Byte_ascii.Brack_bgn // skip logic if "[" which may be beginning of lnki / lnke
) {
num_end = Bry_finder.Find_fwd_until_space_or_tab(src, pos, itm_end); // gobble up rest of word and search forward for space / tab to
if (num_end == Bry_finder.Not_found) return -1; // space / tab not found; return -1 (fail)
num = 0;
}
else
return num_end;
}
else
num = Bry_.XtoDoubleByPosOr(src, num_bgn, num_end, Double_.NaN);
if (Double_.IsNaN(num)) {
if (shape_tid == Imap_itm_.Tid_shape_poly) // poly code in ImageMap_body.php accepts invalid words and converts to 0; EX:"poly 1a"
num = 0;
else
return -1; // invalid number; EX: "1.2.3"
}
pts.Add(Double_obj_val.new_(num));
return Bry_finder.Trim_fwd_space_tab(src, num_end, itm_end);
}
private void Parse_img(Imap_map imap, int itm_bgn, int itm_end) {
int pos = Bry_finder.Trim_fwd_space_tab(src, itm_bgn, itm_end);
imap_img_src = Bry_.Add(Xop_tkn_.Lnki_bgn, Bry_.Mid(src, pos, itm_end), Xop_tkn_.Lnki_end);
Xop_lnki_tkn lnki_tkn = (Xop_lnki_tkn)Parse_link(imap_img_src);
imap_img_src = imap_root.Data_mid(); // NOTE: need to re-set src to pick up templates; EX: <imagemap>File:A.png|thumb|{{Test_template}}\n</imagemap>; PAGE:en.w:Kilauea; DATE:2014-07-27
Xop_lnki_logger file_wkr = wiki_ctx.Lnki().File_wkr(); // NOTE: do not do imap_ctx.Lnki(); imap_ctx is brand new
if (lnki_tkn == null)
imap_ctx.Wiki().App().Usr_dlg().Warn_many("", "", "image_map failed to find lnki; page=~{0} imageMap=~{1}", String_.new_utf8_(imap_ctx.Cur_page().Ttl().Full_txt()), String_.new_utf8_(imap_img_src));
else {
imap_img = new Imap_itm_img(lnki_tkn);
lnki_tkn.Lnki_file_wkr_(imap);
wiki_ctx.Cur_page().Lnki_list().Add(lnki_tkn);
if (file_wkr != null) file_wkr.Wkr_exec(wiki_ctx, src, lnki_tkn, gplx.xowa.bldrs.files.Xob_lnki_src_tid.Tid_imageMap);
}
}
private static Btrie_slim_mgr tid_trie = Btrie_slim_mgr.ci_ascii_() // NOTE: names are not i18n'd; // NOTE:ci.ascii:MW_const.en
.Add_str_byte("desc" , Imap_itm_.Tid_desc)
.Add_str_byte("#" , Imap_itm_.Tid_comment)
.Add_bry_bval(Imap_itm_.Key_dflt , Imap_itm_.Tid_dflt)
.Add_bry_bval(Imap_itm_.Key_shape_rect , Imap_itm_.Tid_shape_rect)
.Add_bry_bval(Imap_itm_.Key_shape_circle , Imap_itm_.Tid_shape_circle)
.Add_bry_bval(Imap_itm_.Key_shape_poly , Imap_itm_.Tid_shape_poly)
;
private static final int Reqd_poly = -1;
}

View File

@@ -15,32 +15,27 @@ 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.imageMap; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
package gplx.xowa.xtns.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Imap_itm_parser_tst {
@Before public void init() {fxt.Reset();} private Imap_itm_parser_fxt fxt = new Imap_itm_parser_fxt();
@Test public void Dflt_pass() {fxt.Test_shape("default [[A]]" , fxt.itm_dflt_("[[A]]"));}
@Test public void Dflt_ignore_points() {fxt.Test_shape("default 1 2 3 [[A]]" , fxt.itm_dflt_("[[A]]"));}
public class Imap_parser_tst {
@Before public void init() {fxt.Reset();} private Imap_parser_fxt fxt = new Imap_parser_fxt();
@Test public void Rect_pass() {fxt.Test_shape("rect 1 2 3 4 [[A]]" , fxt.itm_rect_("[[A]]", 1, 2, 3, 4));}
@Test public void Circle_pass() {fxt.Test_shape("circle 1 2 3 [[A]]" , fxt.itm_circle_("[[A]]", 1, 2, 3));}
@Test public void Poly_pass() {fxt.Test_shape("poly 1 2 3 4 5 6 [[A]]" , fxt.itm_poly_("[[A]]", 1, 2, 3, 4, 5, 6));}
@Test public void Poly_pass_chars() {fxt.Test_shape("poly a b [[A]]" , fxt.itm_poly_("[[A]]", 0, 0));} // PURPOSE: non-numeric should be converted to 0; PAGE:uk.w:Стратосфера; DATE:2014-07-26
@Test public void Rect_fail() {fxt.Test_shape_err("rect 1 2 3 [[A]]" , "imagemap_missing_coord");}
@Test public void Circle_fail() {fxt.Test_shape_err("circle 1 2 [[A]]" , "imagemap_missing_coord");}
@Test public void Poly_fail_odd() {fxt.Test_shape_err("poly 1 2 3 [[A]]" , "imagemap_poly_odd");}
@Test public void Poly_fail_zero() {fxt.Test_shape_err("poly [[A]]" , "imagemap_missing_coord");}
@Test public void Poly_fail_invalid() {fxt.Test_shape_err("poly 1 2..3 [[A]]" , "imagemap_invalid_coord");}
@Test public void Circle_fail_invalid() {fxt.Test_shape_err("rect 1 2..3 4 [[A]]" , "imagemap_invalid_coord");}
}
class Imap_itm_parser_fxt {
private Xoa_app app; private Xow_wiki wiki;
private Imap_itm_parser parser = new Imap_itm_parser();
public void Reset() {
class Imap_fxt_base {
protected Xoa_app app; protected Xow_wiki wiki;
@gplx.Virtual public void Reset() {
app = Xoa_app_fxt.app_();
wiki = Xoa_app_fxt.wiki_tst_(app);
Xoa_url url = Xoa_url.new_(wiki.Domain_bry(), Bry_.new_ascii_("Test_1"));
parser.Init(wiki, url, Gfo_usr_dlg_.Null);
parser.Clear();
wiki.Ctx().Para().Enabled_n_();
}
public Imap_itm_shape itm_dflt_(String link) {return itm_shape_(Imap_itm_.Tid_shape_dflt, link);}
public Imap_itm_shape itm_rect_(String link, int... pts_ary) {return itm_shape_(Imap_itm_.Tid_shape_rect, link, pts_ary);}
public Imap_itm_shape itm_circle_(String link, int... pts_ary) {return itm_shape_(Imap_itm_.Tid_shape_circle, link, pts_ary);}
public Imap_itm_shape itm_poly_(String link, int... pts_ary) {return itm_shape_(Imap_itm_.Tid_shape_poly, link, pts_ary);}
@@ -50,34 +45,50 @@ class Imap_itm_parser_fxt {
for (int i = 0; i < pts_len; ++i)
pts_doubles[i] = Double_obj_val.new_(pts_ary[i]);
byte[] link_bry = Bry_.new_utf8_(link);
Xop_tkn_itm link_tkn = app.Tkn_mkr().Bry(-1, -1, link_bry);
Imap_itm_shape rv = new Imap_itm_shape(0, 0, link_bry.length, tid, pts_doubles);
rv.Shape_link_(app, wiki, link_bry, link_tkn);
Imap_itm_shape rv = new Imap_itm_shape(tid, pts_doubles);
Imap_link_owner_.Init(rv, app, wiki, link_bry, Make_link_tkn(link_bry));
return rv;
}
private Xop_tkn_itm Make_link_tkn(byte[] src) {
Xop_root_tkn root_tkn = new Xop_root_tkn();
wiki.Parser().Parse_text_to_wdom(root_tkn, wiki.Ctx(), app.Tkn_mkr(), src, Xop_parser_.Doc_bgn_bos);
return root_tkn.Subs_get(0);
}
}
class Imap_parser_fxt extends Imap_fxt_base {
private Imap_parser parser;
private Imap_map imap;
@Override public void Reset() {
super.Reset();
Xoa_url url = Xoa_url.new_(wiki.Domain_bry(), Bry_.new_ascii_("Test_1"));
Imap_xtn_mgr xtn_mgr = new Imap_xtn_mgr();
parser = new Imap_parser(xtn_mgr);
parser.Init(wiki, url, Gfo_usr_dlg_.Null);
parser.Clear();
imap = new Imap_map();
}
public void Test_shape(String raw_str, Imap_itm_shape expd) {
raw_str = "File:A.png\n" + raw_str;
byte[] raw = Bry_.new_utf8_(raw_str);
Imap_itm[] actl_ary = parser.Parse(raw, 0, raw.length);
Imap_itm_shape actl = actl_ary == null | actl_ary.length != 2 ? null : (Imap_itm_shape)actl_ary[1];
byte[] raw = Bry_.new_utf8_(raw_str);
parser.Parse(imap, 1, raw, 0, raw.length);
Imap_itm_shape[] actl_ary = imap.Shapes();
Imap_itm_shape actl = actl_ary == null | actl_ary.length != 1 ? null : (Imap_itm_shape)actl_ary[0];
if (actl == null && expd == null) {} // noop; test passed
else if (actl == null && expd != null) {Tfds.Fail("actl should not be null", raw);}
else if (actl != null && expd == null) {Tfds.Fail("actl should be null", raw);}
else {
Tfds.Eq(expd.Itm_tid(), actl.Itm_tid(), "tid");
Tfds.Eq_ary(expd.Shape_pts(), actl.Shape_pts(), "pts");
Xop_bry_tkn expd_link_tkn = ((Xop_bry_tkn)expd.Shape_link());
String expd_link = String_.new_utf8_(expd_link_tkn.Val());
String actl_link = String_.new_utf8_(raw, actl.Shape_link().Src_bgn(), actl.Shape_link().Src_end());
Tfds.Eq(expd_link, actl_link);
Tfds.Eq(String_.new_utf8_(expd.Link_href()), String_.new_utf8_(actl.Link_href()));
Tfds.Eq(String_.new_utf8_(expd.Link_text()), String_.new_utf8_(actl.Link_text()));
}
Tfds.Eq(0, parser.Errs().Count(), "expd 0 errors");
Tfds.Eq(0, imap.Errs().length, "expd 0 errors");
}
public void Test_shape_err(String raw_str, String expd_err) {
raw_str = "File:A.png\n" + raw_str;
byte[] raw = Bry_.new_utf8_(raw_str);
parser.Parse(raw, 0, raw.length);
Imap_itm_err[] err_ary = (Imap_itm_err[])parser.Errs().XtoAryAndClear(Imap_itm_err.class);
parser.Parse(imap, 1, raw, 0, raw.length);
Imap_err[] err_ary = imap.Errs();
Tfds.Eq(1, err_ary.length, "expd 1 err");
Tfds.Eq(expd_err, err_ary[0].Err_key());
}

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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
class Imap_pts_fmtr_arg implements Bry_fmtr_arg {
private double scale = 1; private Double_obj_val[] pts;
public void Scale_(double v) {this.scale = v;}
public void Pts_(Double_obj_val[] v) {this.pts = v;}
public void XferAry(Bry_bfr bfr, int idx) {
int pts_len = pts.length;
for (int i = 0; i < pts_len; ++i) {
Double_obj_val pt = pts[i];
if (i != 0) bfr.Add_byte_comma();
int pt_int = (int)pt.Val();
pt_int = (int)Math_.Round(scale * pt_int, 0);
bfr.Add_int_variable(pt_int);
}
}
}

View File

@@ -0,0 +1,35 @@
/*
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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.html.*; import gplx.xowa.parsers.logs.*;
public class Imap_xnde implements Xox_xnde {
private Imap_xtn_mgr xtn_mgr;
private Imap_map imap_data;
public void Xtn_parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {
xtn_mgr = (Imap_xtn_mgr)wiki.Xtn_mgr().Get_or_fail(Imap_xtn_mgr.Xtn_key_static);
xtn_mgr.Xtn_assert();
ctx.Cur_page().Html_data().Module_mgr().Itm_popups().Bind_hover_area_(true);
ctx.Para().Process_block__xnde(xnde.Tag(), Xop_xnde_tag.Block_end);
imap_data = xtn_mgr.Parser().Parse(wiki, ctx, root, src, xnde);
ctx.Para().Process_block__xnde(xnde.Tag(), Xop_xnde_tag.Block_end);
boolean log_wkr_enabled = Log_wkr != Xop_log_basic_wkr.Null; if (log_wkr_enabled) Log_wkr.Log_end_xnde(ctx.Cur_page(), Xop_log_basic_wkr.Tid_imageMap, src, xnde);
} public static Xop_log_basic_wkr Log_wkr = Xop_log_basic_wkr.Null;
public void Xtn_write(Xoa_app app, Xoh_html_wtr html_wtr, Xoh_html_wtr_ctx opts, Xop_ctx ctx, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) {
html_wtr.Write_tkn(bfr, ctx, opts, imap_data.Img_src(), xnde, Xoh_html_wtr.Sub_idx_null, imap_data.Img().Img_link());
}
}

View File

@@ -0,0 +1,191 @@
/*
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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Imap_xnde_html_all_tst {
@Before public void init() {fxt.Reset();} private Imap_xnde_html_fxt fxt = new Imap_xnde_html_fxt();
@Test public void Basic() {
fxt.Test_html_full_str(String_.Concat_lines_nl_skip_last
( "<imagemap>"
, "File:A.png|thumb|123px|a1"
, "circle 0 0 5 [[B|b1]]"
, "rect 0 0 4 8 [[C|c1]]"
, "desc none"
, "</imagemap>"
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:123px;\">"
, " <div 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 id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" usemap=\"#imageMap_1_1\"/>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a1"
, " </div>"
, " </div>"
, "</div>"
));
}
@Test public void Caption_xml() { // PURPOSE: xnde in caption was being escaped; PAGE:en.w:Council_of_Europe; DATE:2014-07-25
fxt.Test_html_full_frag("<imagemap>File:A.png|thumb|<b>c</b>\n</imagemap>", "<b>c</b>");
}
@Test public void Default() {
fxt.Test_html_full_str(String_.Concat_lines_nl_skip_last
( "<imagemap>"
, "File:A.png|thumb|123px|a1"
, "default [[B|b1]]"
, "</imagemap>"
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:123px;\">"
, " <div class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <a href=\"/wiki/B\" title=\"b1\">"
, " <img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" usemap=\"#imageMap_1_1\"/>"
, " </a>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a1"
, " </div>"
, " </div>"
, "</div>"
));
}
@Test public void Desc() {
fxt.Test_html_full_str(String_.Concat_lines_nl_skip_last
( "<imagemap>"
, "File:A.png|123px|a1"
, "desc top-left"
, "</imagemap>"
), String_.Concat_lines_nl_skip_last
( "<div class=\"noresize\" style=\"height:123px; width: 0px;\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <img id=\"xowa_file_img_0\" alt=\"a1\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" usemap=\"#imageMap_1_1\"/>"
, " <div style=\"margin-left:0px; margin-top:1px; text-align:left;\">"
, " <a href=\"/wiki/File:A.png\" title=\"click here\">"
, " <img alt=\"click here\" src=\"file:///mem/xowa/bin/any/xowa/xtns/ImageMap/imgs/desc-20.png\" style=\"border: none;\" />"
, " </a>"
, " </div>"
, " </div>"
));
}
@Test public void Lnke() { // PURPOSE: handle shapes with lnke; PAGE:en.w:Cholesterolt DATE:2014-07-25
fxt.Test_html_full_str(String_.Concat_lines_nl_skip_last
( "<imagemap>"
, "File:A.png|thumb|123px|a1"
, "circle 0 0 5 [[http://b.org b1]]"
, "desc none"
, "</imagemap>"
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:123px;\">"
, " <div class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " <area href=\"http://b.org\" shape=\"circle\" coords=\"0,0,5\" alt=\"b1\" title=\"b1\"/>"
, " </map>"
, " <img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" usemap=\"#imageMap_1_1\"/>"
, " </div>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " a1"
, " </div>"
, " </div>"
, "</div>"
));
}
@Test public void Err_trailing_ws() { // PURPOSE: empty 1st line causes failure
fxt.Test_html_full_frag(String_.Concat_lines_nl_skip_last
( "<imagemap> "
, "File:A.png|thumb|test_caption"
, "</imagemap>"
), "test_caption" // no error if test_caption appears;
);
}
@Test public void Para_omitted() { // PURPOSE: imagemap should not be automatically enclosed in para; PAGE:cs.w:Seznam_clenu_ctrn<72>ct<63>ho_Knesetu; DATE:2014-05-08;
fxt.Fxt().Init_para_y_();
fxt.Test_html_full_str("<imagemap>File:A.png</imagemap> a", fxt.Frag_html_full() + " a"); // NOTE: "a" no longer enclosed in <p>; DATE:2014-07-25
fxt.Fxt().Init_para_n_();
}
@Test public void Xnde_double_pipe() {// PURPOSE: if || is inside table and imagemap, treat as lnki; EX:w:United_States_presidential_election,_1992; DATE:2014-03-29; DATE:2014-05-06
fxt.Test_html_full_str(String_.Concat_lines_nl_skip_last
( "{|"
, "|-"
, "| z"
, "<imagemap>"
, "File:A.png||123px|b" // NOTE: "||" should not be tblw; also should not be pipe + text; if it is pipe + text, then caption will be "|123px" and width will be -1; DATE:2014-05-06
, "</imagemap>"
, "|}"
) , String_.Concat_lines_nl_skip_last
( "<table>"
, " <tr>"
, " <td> z"
, "<div class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <img id=\"xowa_file_img_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
, " </div>"
, " </td>"
, " </tr>"
, "</table>"
, ""
)
);
}
@Test public void Tmpl() { // PURPOSE: handle templates in caption; PAGE:en.w:Kilauea; DATE:2014-07-27
fxt.Fxt().Init_page_create("Template:Test_template", "xyz");
fxt.Test_html_full_frag("<imagemap>File:A.png|thumb|{{Test_template}}\n</imagemap>", "xyz");
}
}
class Imap_xnde_html_fxt {
public void Reset() {
fxt.Reset();
Xol_msg_itm msg = fxt.Wiki().Msg_mgr().Get_or_make(Bry_.new_ascii_("imagemap_description"));
msg.Atrs_set(Bry_.new_ascii_("click here"), false, false);
}
public Xop_fxt Fxt() {return fxt;} private Xop_fxt fxt = new Xop_fxt();
public void Test_html_full_str(String raw, String expd) {fxt.Test_html_full_str(raw, expd);}
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 class=\"noresize\">"
, " <map name=\"imageMap_1_1\">"
, " </map>"
, " <img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" usemap=\"#imageMap_1_1\"/>"
, " </div>"
);
}
}

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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import org.junit.*;
public class Imap_xnde_html_itm_tst {
@Before public void init() {fxt.Reset();} private Imap_html_bldr_fxt fxt = new Imap_html_bldr_fxt();
@Test public void Rect() {fxt.Test_shape_html(fxt.itm_rect_("[[A|b]]", 1, 2, 3, 4), "\n <area href=\"/wiki/A\" shape=\"rect\" coords=\"1,2,3,4\" alt=\"b\" title=\"b\"/>");}
@Test public void Circle() {fxt.Test_shape_html(fxt.itm_circle_("[[A|b]]", 1, 2, 3 ), "\n <area href=\"/wiki/A\" shape=\"circle\" coords=\"1,2,3\" alt=\"b\" title=\"b\"/>");}
@Test public void Poly() {fxt.Test_shape_html(fxt.itm_poly_("[[A|b]]", 1, 2, 3, 4), "\n <area href=\"/wiki/A\" shape=\"poly\" coords=\"1,2,3,4\" alt=\"b\" title=\"b\"/>");}
}
class Imap_html_bldr_fxt extends Imap_fxt_base {
private Bry_bfr bfr = Bry_bfr.new_();
private Imap_pts_fmtr_arg pts_fmtr_arg = new Imap_pts_fmtr_arg();
public void Test_shape_html(Imap_itm_shape shape, String expd) {
Imap_map.Fmt_shape(bfr, Imap_html_fmtrs.Area, pts_fmtr_arg, shape);
Tfds.Eq(expd, bfr.XtoStrAndClear());
}
}

View File

@@ -0,0 +1,47 @@
/*
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.imaps; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.wikis.*;
import gplx.core.btries.*;
public class Imap_xtn_mgr extends Xox_mgr_base implements GfoInvkAble {
private boolean init;
@Override public boolean Enabled_default() {return true;}
@Override public byte[] Xtn_key() {return Xtn_key_static;} public static final byte[] Xtn_key_static = Bry_.new_ascii_("imageMap");
public Xow_wiki Wiki() {return wiki;} private Xow_wiki wiki;
@gplx.Internal protected Imap_parser Parser() {return parser;} private Imap_parser parser;
public void Desc_assert() {
if (desc_trie != null) return;
desc_trie = Imap_desc_tid.trie_(wiki);
desc_msg = wiki.Msg_mgr().Val_by_key_obj("imagemap_description");
desc_icon_url = wiki.App().Fsys_mgr().Bin_extensions_dir().GenSubFil_nest("ImageMap", "imgs", "desc-20.png").To_http_file_bry();
}
public Btrie_slim_mgr Desc_trie() {return desc_trie;} private Btrie_slim_mgr desc_trie;
public byte[] Desc_msg() {return desc_msg;} private byte[] desc_msg;
public byte[] Desc_icon_url() {return desc_icon_url;} private byte[] desc_icon_url;
@Override public Xox_mgr Clone_new() {return new Imap_xtn_mgr();}
@Override public void Xtn_init_by_wiki(Xow_wiki wiki) {
this.wiki = wiki;
}
public void Xtn_assert() {
if (init) return;
parser = new Imap_parser(this);
init = true;
}
public void Clear() {
}
}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
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);}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.lst; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
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);}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.mapSources; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Map_dd2dms_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_mapSources_dd2dms;}
@Override public Pf_func New(int id, byte[] name) {return new Map_dd2dms_func().Name_(name);}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.mapSources; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Map_deg2dd_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_mapSources_deg2dd;}
@Override public Pf_func New(int id, byte[] name) {return new Map_deg2dd_func().Name_(name);}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.mapSources; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Map_geolink_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_mapSources_geoLink;}
@Override public Pf_func New(int id, byte[] name) {return new Map_geolink_func().Name_(name);}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.massMessage; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Message_target_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_massMessage_target;}
@Override public Pf_func New(int id, byte[] name) {return new Message_target_func().Name_(name);}

View File

@@ -0,0 +1,24 @@
/*
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; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public interface Pf_func extends Xot_defn {
int Id();
void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bb);
boolean Func_require_colon_arg();
Pf_func New(int id, byte[] name);
}

View File

@@ -0,0 +1,374 @@
/*
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; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.ifs.*; import gplx.xowa.xtns.pfuncs.times.*; import gplx.xowa.xtns.pfuncs.numbers.*; import gplx.xowa.xtns.pfuncs.ttls.*; import gplx.xowa.xtns.pfuncs.langs.*; import gplx.xowa.xtns.pfuncs.strings.*; import gplx.xowa.xtns.pfuncs.pages.*; import gplx.xowa.xtns.pfuncs.wikis.*;
public class Pf_func_ {
public static byte[] Eval_arg_or_empty(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, int self_args_len, int i) {return Eval_arg_or(ctx, src, caller, self, self_args_len, i, Bry_.Empty);}
public static final byte Name_dlm = Byte_ascii.Colon;
public static byte[] Eval_arg_or(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, int self_args_len, int i, byte[] or) {
if (i >= self_args_len) return or;
Bry_bfr bfr = Bry_bfr.new_();
Arg_nde_tkn nde = self.Args_get_by_idx(i);
nde.Key_tkn().Tmpl_evaluate(ctx, src, caller, bfr); // NOTE: must add key b/c parser functions do not have keys and some usages pass in xml_tkns; EX: {{#if|<a href='{{{1}}}'|}}; "<a href" should not be interpreted as key
if (nde.KeyTkn_exists()) bfr.Add_byte(Byte_ascii.Eq);
nde.Val_tkn().Tmpl_evaluate(ctx, src, caller, bfr);
return bfr.XtoAryAndClearAndTrim();
}
public static byte[] Eval_val_or(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, int self_args_len, int i, byte[] or) {
if (i >= self_args_len) return or;
Bry_bfr bfr = Bry_bfr.new_();
Arg_nde_tkn nde = self.Args_get_by_idx(i);
nde.Val_tkn().Tmpl_evaluate(ctx, src, caller, bfr);
return bfr.XtoAryAndClearAndTrim();
}
public static byte[] Eval_tkn(Bry_bfr bfr, Xop_ctx ctx, byte[] src, Xot_invk caller, Xop_tkn_itm tkn) {
tkn.Tmpl_evaluate(ctx, src, caller, bfr);
return bfr.XtoAryAndClear();
}
private static final NumberParser lhs_parser = new NumberParser().Hex_enabled_(true), rhs_parser = new NumberParser().Hex_enabled_(true);
public static boolean Eq_(byte[] lhs, byte[] rhs) { // PATCH.PHP: php allows "003" == "3.0"; ASSUME: numbers are either int or int-like decimal; long, float, decimal not supported
int lhs_len = lhs.length, rhs_len = rhs.length;
boolean rv = true;
if (lhs_len == rhs_len) {
for (int i = 0; i < lhs_len; i++) {
if (lhs[i] != rhs[i]) {
rv = false;
break;
}
}
if (rv) return true;
}
else if (lhs_len == 0 || rhs_len == 0) // one side is empty String and the other side is String; return false;
return false;
lhs_parser.Parse(lhs, 0, lhs_len);
if (lhs_parser.HasErr()) return false;
rhs_parser.Parse(rhs, 0, rhs_len);
if (rhs_parser.HasErr()) return false;
return lhs_parser.HasFrac() || rhs_parser.HasFrac() ? lhs_parser.AsDec().Eq(rhs_parser.AsDec()) : lhs_parser.AsInt() == rhs_parser.AsInt();
}
public static void Reg(gplx.xowa.langs.Xol_func_name_regy func_regy, Xol_lang lang) {
Xol_kwd_mgr kwd_mgr = lang.Kwd_mgr();
int len = Ary__.length;
for (int i = 0; i < len; i++) {
int id = Ary__[i];
func_regy.Reg_defn(kwd_mgr, id, Get_prototype(id));
}
}
public static final int[] Ary__ = new int[]
{ Xol_kwd_grp_.Id_utc_year
, Xol_kwd_grp_.Id_utc_month_int_len2
, Xol_kwd_grp_.Id_utc_month_int
, Xol_kwd_grp_.Id_utc_day_int_len2
, Xol_kwd_grp_.Id_utc_day_int
, Xol_kwd_grp_.Id_utc_hour
, Xol_kwd_grp_.Id_utc_time
, Xol_kwd_grp_.Id_utc_timestamp
, Xol_kwd_grp_.Id_utc_week
, Xol_kwd_grp_.Id_utc_dow
, Xol_kwd_grp_.Id_utc_month_abrv
, Xol_kwd_grp_.Id_utc_month_name
, Xol_kwd_grp_.Id_utc_month_gen
, Xol_kwd_grp_.Id_utc_day_name
, Xol_kwd_grp_.Id_lcl_year
, Xol_kwd_grp_.Id_lcl_month_int_len2
, Xol_kwd_grp_.Id_lcl_month_int
, Xol_kwd_grp_.Id_lcl_day_int_len2
, Xol_kwd_grp_.Id_lcl_day_int
, Xol_kwd_grp_.Id_lcl_hour
, Xol_kwd_grp_.Id_lcl_time
, Xol_kwd_grp_.Id_lcl_timestamp
, Xol_kwd_grp_.Id_lcl_week
, Xol_kwd_grp_.Id_lcl_dow
, Xol_kwd_grp_.Id_lcl_month_abrv
, Xol_kwd_grp_.Id_lcl_month_name
, Xol_kwd_grp_.Id_lcl_month_gen
, Xol_kwd_grp_.Id_lcl_day_name
, Xol_kwd_grp_.Id_rev_year
, Xol_kwd_grp_.Id_rev_month_int_len2
, Xol_kwd_grp_.Id_rev_month_int
, Xol_kwd_grp_.Id_rev_day_int_len2
, Xol_kwd_grp_.Id_rev_day_int
, Xol_kwd_grp_.Id_rev_timestamp
, Xol_kwd_grp_.Id_ns_txt
, Xol_kwd_grp_.Id_ns_url
, Xol_kwd_grp_.Id_ns_subj_txt
, Xol_kwd_grp_.Id_ns_subj_url
, Xol_kwd_grp_.Id_ns_talk_txt
, Xol_kwd_grp_.Id_ns_talk_url
, Xol_kwd_grp_.Id_ttl_full_txt
, Xol_kwd_grp_.Id_ttl_full_url
, Xol_kwd_grp_.Id_ttl_page_txt
, Xol_kwd_grp_.Id_ttl_base_txt
, Xol_kwd_grp_.Id_ttl_page_url
, Xol_kwd_grp_.Id_ttl_base_url
, Xol_kwd_grp_.Id_ttl_leaf_txt
, Xol_kwd_grp_.Id_ttl_leaf_url
, Xol_kwd_grp_.Id_ttl_subj_txt
, Xol_kwd_grp_.Id_ttl_subj_url
, Xol_kwd_grp_.Id_ttl_talk_txt
, Xol_kwd_grp_.Id_ttl_talk_url
, Xol_kwd_grp_.Id_site_sitename
, Xol_kwd_grp_.Id_site_servername
, Xol_kwd_grp_.Id_site_server
, Xol_kwd_grp_.Id_site_articlepath
, Xol_kwd_grp_.Id_site_scriptpath
, Xol_kwd_grp_.Id_site_stylepath
, Xol_kwd_grp_.Id_site_contentlanguage
, Xol_kwd_grp_.Id_site_directionmark
, Xol_kwd_grp_.Id_site_currentversion
, Xol_kwd_grp_.Id_num_pages
, Xol_kwd_grp_.Id_num_articles
, Xol_kwd_grp_.Id_num_files
, Xol_kwd_grp_.Id_num_edits
, Xol_kwd_grp_.Id_num_views
, Xol_kwd_grp_.Id_num_users
, Xol_kwd_grp_.Id_num_users_active
, Xol_kwd_grp_.Id_num_admins
, Xol_kwd_grp_.Id_rev_id
, Xol_kwd_grp_.Id_rev_pagesize
, Xol_kwd_grp_.Id_rev_user
, Xol_kwd_grp_.Id_rev_protectionlevel
, Xol_kwd_grp_.Id_page_displaytitle
, Xol_kwd_grp_.Id_page_defaultsort
, Xol_kwd_grp_.Id_noeditsection
, Xol_kwd_grp_.Id_site_pagesincategory
, Xol_kwd_grp_.Id_url_ns
, Xol_kwd_grp_.Id_url_nse
, Xol_kwd_grp_.Id_url_urlencode
, Xol_kwd_grp_.Id_str_lc
, Xol_kwd_grp_.Id_str_lcfirst
, Xol_kwd_grp_.Id_str_uc
, Xol_kwd_grp_.Id_str_ucfirst
, Xol_kwd_grp_.Id_str_padleft
, Xol_kwd_grp_.Id_str_padright
, Xol_kwd_grp_.Id_str_formatnum
, Xol_kwd_grp_.Id_str_formatdate
, Xol_kwd_grp_.Id_url_localurl
, Xol_kwd_grp_.Id_url_localurle
, Xol_kwd_grp_.Id_url_fullurl
, Xol_kwd_grp_.Id_url_fullurle
, Xol_kwd_grp_.Id_url_filepath
, Xol_kwd_grp_.Id_url_anchorencode
, Xol_kwd_grp_.Id_i18n_plural
, Xol_kwd_grp_.Id_misc_tag
, Xol_kwd_grp_.Id_i18n_language
, Xol_kwd_grp_.Id_i18n_int
, Xol_kwd_grp_.Id_i18n_grammar
, Xol_kwd_grp_.Id_xtn_expr
, Xol_kwd_grp_.Id_xtn_if
, Xol_kwd_grp_.Id_xtn_ifeq
, Xol_kwd_grp_.Id_xtn_iferror
, Xol_kwd_grp_.Id_xtn_ifexpr
, Xol_kwd_grp_.Id_xtn_ifexist
, Xol_kwd_grp_.Id_xtn_rel2abs
, Xol_kwd_grp_.Id_xtn_switch
, Xol_kwd_grp_.Id_xtn_time
, Xol_kwd_grp_.Id_xtn_timel
, Xol_kwd_grp_.Id_xtn_titleparts
, Xol_kwd_grp_.Id_subst
, Xol_kwd_grp_.Id_safesubst
, Xol_kwd_grp_.Id_raw
, Xol_kwd_grp_.Id_msg
, Xol_kwd_grp_.Id_msgnw
, Xol_kwd_grp_.Id_xowa_dbg
, Xol_kwd_grp_.Id_xtn_geodata_coordinates
, Xol_kwd_grp_.Id_url_canonicalurl
, Xol_kwd_grp_.Id_url_canonicalurle
, Xol_kwd_grp_.Id_lst
, Xol_kwd_grp_.Id_lstx
, Xol_kwd_grp_.Id_invoke
, Xol_kwd_grp_.Id_property
, Xol_kwd_grp_.Id_noexternallanglinks
, Xol_kwd_grp_.Id_ns_num
, Xol_kwd_grp_.Id_page_id
, Xol_kwd_grp_.Id_xowa
, Xol_kwd_grp_.Id_mapSources_deg2dd
, Xol_kwd_grp_.Id_mapSources_dd2dms
, Xol_kwd_grp_.Id_mapSources_geoLink
, Xol_kwd_grp_.Id_geoCrumbs_isin
, Xol_kwd_grp_.Id_relatedArticles
, Xol_kwd_grp_.Id_relatedSites
, Xol_kwd_grp_.Id_massMessage_target
, Xol_kwd_grp_.Id_cascadingSources
, Xol_kwd_grp_.Id_pendingChangesLevel
};
public static Xot_defn Get_prototype(int id) {
switch (id) {
case Xol_kwd_grp_.Id_utc_year:
case Xol_kwd_grp_.Id_utc_month_int_len2:
case Xol_kwd_grp_.Id_utc_month_int:
case Xol_kwd_grp_.Id_utc_day_int_len2:
case Xol_kwd_grp_.Id_utc_day_int:
case Xol_kwd_grp_.Id_utc_hour:
case Xol_kwd_grp_.Id_utc_time:
case Xol_kwd_grp_.Id_utc_timestamp:
case Xol_kwd_grp_.Id_utc_week:
case Xol_kwd_grp_.Id_utc_dow: return Pft_func_date_int.Utc;
case Xol_kwd_grp_.Id_utc_month_abrv: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_utc, DateAdp_.SegIdx_month, Xol_msg_itm_.Id_dte_month_abrv_jan - Int_.Base1);
case Xol_kwd_grp_.Id_utc_month_name: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_utc, DateAdp_.SegIdx_month, Xol_msg_itm_.Id_dte_month_name_january - Int_.Base1);
case Xol_kwd_grp_.Id_utc_month_gen: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_utc, DateAdp_.SegIdx_month, Xol_msg_itm_.Id_dte_month_gen_january - Int_.Base1);
case Xol_kwd_grp_.Id_utc_day_name: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_utc, DateAdp_.SegIdx_dayOfWeek, Xol_msg_itm_.Id_dte_dow_name_sunday);
case Xol_kwd_grp_.Id_lcl_year:
case Xol_kwd_grp_.Id_lcl_month_int_len2:
case Xol_kwd_grp_.Id_lcl_month_int:
case Xol_kwd_grp_.Id_lcl_day_int_len2:
case Xol_kwd_grp_.Id_lcl_day_int:
case Xol_kwd_grp_.Id_lcl_hour:
case Xol_kwd_grp_.Id_lcl_time:
case Xol_kwd_grp_.Id_lcl_timestamp:
case Xol_kwd_grp_.Id_lcl_week:
case Xol_kwd_grp_.Id_lcl_dow: return Pft_func_date_int.Lcl;
case Xol_kwd_grp_.Id_lcl_month_abrv: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_lcl, DateAdp_.SegIdx_month, Xol_msg_itm_.Id_dte_month_abrv_jan - Int_.Base1);
case Xol_kwd_grp_.Id_lcl_month_name: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_lcl, DateAdp_.SegIdx_month, Xol_msg_itm_.Id_dte_month_name_january - Int_.Base1);
case Xol_kwd_grp_.Id_lcl_month_gen: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_lcl, DateAdp_.SegIdx_month, Xol_msg_itm_.Id_dte_month_gen_january - Int_.Base1);
case Xol_kwd_grp_.Id_lcl_day_name: return new Pft_func_date_name(-1, Pft_func_date_int.Date_tid_lcl, DateAdp_.SegIdx_dayOfWeek, Xol_msg_itm_.Id_dte_dow_name_sunday);
case Xol_kwd_grp_.Id_rev_year:
case Xol_kwd_grp_.Id_rev_month_int_len2:
case Xol_kwd_grp_.Id_rev_month_int:
case Xol_kwd_grp_.Id_rev_day_int_len2:
case Xol_kwd_grp_.Id_rev_day_int:
case Xol_kwd_grp_.Id_rev_timestamp: return Pft_func_date_int.Rev;
case Xol_kwd_grp_.Id_ns_num:
case Xol_kwd_grp_.Id_ns_txt:
case Xol_kwd_grp_.Id_ns_url:
case Xol_kwd_grp_.Id_ns_subj_txt:
case Xol_kwd_grp_.Id_ns_subj_url:
case Xol_kwd_grp_.Id_ns_talk_txt:
case Xol_kwd_grp_.Id_ns_talk_url:
case Xol_kwd_grp_.Id_ttl_full_txt:
case Xol_kwd_grp_.Id_ttl_full_url:
case Xol_kwd_grp_.Id_ttl_page_txt:
case Xol_kwd_grp_.Id_ttl_base_txt:
case Xol_kwd_grp_.Id_ttl_page_url:
case Xol_kwd_grp_.Id_ttl_base_url:
case Xol_kwd_grp_.Id_ttl_leaf_txt:
case Xol_kwd_grp_.Id_ttl_leaf_url:
case Xol_kwd_grp_.Id_ttl_subj_txt:
case Xol_kwd_grp_.Id_ttl_subj_url:
case Xol_kwd_grp_.Id_ttl_talk_txt:
case Xol_kwd_grp_.Id_ttl_talk_url: return Pfunc_ttl._;
case Xol_kwd_grp_.Id_site_sitename:
case Xol_kwd_grp_.Id_site_servername:
case Xol_kwd_grp_.Id_site_server:
case Xol_kwd_grp_.Id_site_articlepath:
case Xol_kwd_grp_.Id_site_scriptpath:
case Xol_kwd_grp_.Id_site_stylepath:
case Xol_kwd_grp_.Id_site_contentlanguage:
case Xol_kwd_grp_.Id_site_directionmark:
case Xol_kwd_grp_.Id_site_currentversion: return Pfunc_wiki_props._;
case Xol_kwd_grp_.Id_num_pages:
case Xol_kwd_grp_.Id_num_articles:
case Xol_kwd_grp_.Id_num_files:
case Xol_kwd_grp_.Id_num_edits:
case Xol_kwd_grp_.Id_num_views:
case Xol_kwd_grp_.Id_num_users:
case Xol_kwd_grp_.Id_num_users_active:
case Xol_kwd_grp_.Id_num_admins: return Pfunc_wiki_stats._;
case Xol_kwd_grp_.Id_page_id:
case Xol_kwd_grp_.Id_rev_id:
case Xol_kwd_grp_.Id_rev_pagesize:
case Xol_kwd_grp_.Id_rev_user:
case Xol_kwd_grp_.Id_rev_protectionlevel: return Pfunc_rev_props._;
case Xol_kwd_grp_.Id_page_displaytitle: return Pfunc_displaytitle._;
case Xol_kwd_grp_.Id_page_defaultsort: return Pfunc_defaultsort._;
case Xol_kwd_grp_.Id_noeditsection: return Pfunc_noeditsection._;
case Xol_kwd_grp_.Id_site_pagesincategory: return Pfunc_pagesincategory._;
case Xol_kwd_grp_.Id_url_ns: return new Pfunc_ns(false);
case Xol_kwd_grp_.Id_url_nse: return new Pfunc_ns(true);
case Xol_kwd_grp_.Id_url_urlencode: return new Pfunc_urlencode();
case Xol_kwd_grp_.Id_str_lc: return new Pfunc_case(Xol_lang.Tid_lower, false);
case Xol_kwd_grp_.Id_str_lcfirst: return new Pfunc_case(Xol_lang.Tid_lower, true);
case Xol_kwd_grp_.Id_str_uc: return new Pfunc_case(Xol_lang.Tid_upper, false);
case Xol_kwd_grp_.Id_str_ucfirst: return new Pfunc_case(Xol_lang.Tid_upper, true);
case Xol_kwd_grp_.Id_str_padleft: return new Pfunc_pad(Xol_kwd_grp_.Id_str_padleft, false);
case Xol_kwd_grp_.Id_str_padright: return new Pfunc_pad(Xol_kwd_grp_.Id_str_padright, true);
case Xol_kwd_grp_.Id_str_formatnum: return new Pf_formatnum();
case Xol_kwd_grp_.Id_str_formatdate: return new Pft_func_formatdate();
case Xol_kwd_grp_.Id_url_localurl: return new Pfunc_urlfunc(Xol_kwd_grp_.Id_url_localurl, Pfunc_urlfunc.Tid_local, false);
case Xol_kwd_grp_.Id_url_localurle: return new Pfunc_urlfunc(Xol_kwd_grp_.Id_url_localurle, Pfunc_urlfunc.Tid_local, true);
case Xol_kwd_grp_.Id_url_fullurl: return new Pfunc_urlfunc(Xol_kwd_grp_.Id_url_fullurl, Pfunc_urlfunc.Tid_full, false);
case Xol_kwd_grp_.Id_url_fullurle: return new Pfunc_urlfunc(Xol_kwd_grp_.Id_url_fullurle, Pfunc_urlfunc.Tid_full, true);
case Xol_kwd_grp_.Id_url_canonicalurl: return new Pfunc_urlfunc(Xol_kwd_grp_.Id_url_canonicalurl, Pfunc_urlfunc.Tid_canonical, false);
case Xol_kwd_grp_.Id_url_canonicalurle: return new Pfunc_urlfunc(Xol_kwd_grp_.Id_url_canonicalurle, Pfunc_urlfunc.Tid_canonical, false);
case Xol_kwd_grp_.Id_url_filepath: return new Pfunc_filepath();
case Xol_kwd_grp_.Id_url_anchorencode: return new Pfunc_anchorencode();
case Xol_kwd_grp_.Id_i18n_plural: return new Pfunc_plural();
case Xol_kwd_grp_.Id_i18n_language: return new Pfunc_language();
case Xol_kwd_grp_.Id_i18n_int: return new Pfunc_int();
case Xol_kwd_grp_.Id_i18n_grammar: return new Pfunc_grammar();
case Xol_kwd_grp_.Id_misc_tag: return new Pfunc_tag();
case Xol_kwd_grp_.Id_xtn_expr: return new gplx.xowa.xtns.pfuncs.exprs.Pfunc_expr();
case Xol_kwd_grp_.Id_xtn_if: return new Pfunc_if();
case Xol_kwd_grp_.Id_xtn_ifeq: return new Pfunc_ifeq();
case Xol_kwd_grp_.Id_xtn_iferror: return new Pfunc_iferror();
case Xol_kwd_grp_.Id_xtn_ifexpr: return new Pfunc_ifexpr();
case Xol_kwd_grp_.Id_xtn_ifexist: return new Pfunc_ifexist();
case Xol_kwd_grp_.Id_xtn_rel2abs: return new Pfunc_rel2abs();
case Xol_kwd_grp_.Id_xtn_switch: return new Pfunc_switch();
case Xol_kwd_grp_.Id_xtn_time: return Pft_func_time._Utc;
case Xol_kwd_grp_.Id_xtn_timel: return Pft_func_time._Lcl;
case Xol_kwd_grp_.Id_xtn_titleparts: return new Pfunc_titleparts();
case Xol_kwd_grp_.Id_subst:
case Xol_kwd_grp_.Id_safesubst:
case Xol_kwd_grp_.Id_msg:
case Xol_kwd_grp_.Id_msgnw:
case Xol_kwd_grp_.Id_raw: return new Xot_defn_subst((byte)id, Bry_.Empty);
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._;
case Xol_kwd_grp_.Id_lst: return gplx.xowa.xtns.lst.Lst_pfunc_lst._;
case Xol_kwd_grp_.Id_lstx: return gplx.xowa.xtns.lst.Lst_pfunc_lstx._;
case Xol_kwd_grp_.Id_invoke: return new gplx.xowa.xtns.scribunto.Scrib_invoke_func();
case Xol_kwd_grp_.Id_property: return new gplx.xowa.xtns.wdatas.Wdata_pf_property();
case Xol_kwd_grp_.Id_noexternallanglinks: return new gplx.xowa.xtns.wdatas.Wdata_pf_noExternalLangLinks();
case Xol_kwd_grp_.Id_mapSources_deg2dd: return gplx.xowa.xtns.mapSources.Map_deg2dd_func._;
case Xol_kwd_grp_.Id_mapSources_dd2dms: return gplx.xowa.xtns.mapSources.Map_dd2dms_func._;
case Xol_kwd_grp_.Id_mapSources_geoLink: return gplx.xowa.xtns.mapSources.Map_geolink_func._;
case Xol_kwd_grp_.Id_geoCrumbs_isin: return gplx.xowa.xtns.geoCrumbs.Geoc_isin_func._;
case Xol_kwd_grp_.Id_relatedArticles: return gplx.xowa.xtns.relatedArticles.Articles_func._;
case Xol_kwd_grp_.Id_relatedSites: return gplx.xowa.xtns.relatedSites.Sites_func._;
case Xol_kwd_grp_.Id_massMessage_target: return gplx.xowa.xtns.massMessage.Message_target_func._;
case Xol_kwd_grp_.Id_cascadingSources:
case Xol_kwd_grp_.Id_pendingChangesLevel:
return new Pf_func_noop(id);
default: throw Err_mgr._.unhandled_(id);
}
}
}
class Pf_func_noop extends Pf_func_base {
public Pf_func_noop(int id) {this.id = id;} private int id;
@Override public int Id() {return id;}
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {}
@Override public Pf_func New(int id, byte[] name) {return new Pf_func_noop(id).Name_(name);}
}

View File

@@ -0,0 +1,71 @@
/*
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; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
public abstract class Pf_func_base implements Pf_func {
public byte Defn_tid() {return Xot_defn_.Tid_func;}
public byte[] Name() {return name;} public Pf_func_base Name_(byte[] v) {name = v; name_len = v.length; return this;} private byte[] name = Bry_.Empty; int name_len = 0;
@gplx.Virtual public boolean Func_require_colon_arg() {return false;}
public boolean Defn_require_colon_arg() {return this.Func_require_colon_arg();}
public int Cache_size() {return 1024;} // arbitrary size
public abstract int Id();
public void Rls() {name = null; argx_dat = null;}
public abstract Pf_func New(int id, byte[] name);
public Xot_defn Clone(int id, byte[] name) {return New(id, name);}
public abstract void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr);
public byte[] Argx_dat() {return argx_dat;} public void Argx_dat_(byte[] v) {argx_dat = v;} private byte[] argx_dat = Bry_.Empty;
public byte[] Eval_argx(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self) {
if (argx_dat == Bry_.Empty) {
Arg_itm_tkn name_val_tkn = self.Name_tkn().Val_tkn();
int subs_len = name_val_tkn.Subs_len();
if (subs_len > 0) {
Bry_bfr tmp = Bry_bfr.new_();
for (int i = 0; i < subs_len; i++)
name_val_tkn.Subs_get(i).Tmpl_evaluate(ctx, src, caller, tmp);
argx_dat = tmp.XtoAryAndClearAndTrim();
}
}
return argx_dat;
}
public byte[] Eval_argx_or_null(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, byte[] func_name) {
if (argx_dat == Bry_.Empty) {
Arg_nde_tkn name_tkn = self.Name_tkn();
Arg_itm_tkn name_val_tkn = name_tkn.Val_tkn();
int subs_len = name_val_tkn.Subs_len();
if (subs_len == 0) { // no subs; either {{#func}} or {{#func:}}
int src_bgn = name_tkn.Src_bgn();
int colon_pos = Bry_finder.Find_bwd(src, Byte_ascii.Colon, self.Src_end(), src_bgn); // look for ":"; NOTE: used to be src_bgn - 1, but this would always search one character too many; DATE:2014-02-11
if (colon_pos == Bry_.NotFound) // no colon; EX: {{#func}}
return Eval_arg_or_null_is_null;
else { // colon found; EX: {{#func:}}
if (Bry_.Match_bwd_any(src, colon_pos - 1, src_bgn - 1, func_name)) // #func == func_name; EX: {{NAMESPACE:}}
return Eval_arg_or_null_is_empty;
else // #func != func_name; assume subst: or safesubst:; EX: {{safesubst:NAMESPACE}}; NOTE: can check subst / safesubs trie, but will be expensive; also, only Pfunc_ttl calls this function
return Eval_arg_or_null_is_null;
}
}
else {
Bry_bfr tmp = Bry_bfr.new_();
for (int i = 0; i < subs_len; i++)
name_val_tkn.Subs_get(i).Tmpl_evaluate(ctx, src, caller, tmp);
argx_dat = tmp.XtoAryAndClearAndTrim();
}
}
return argx_dat;
}
public static final byte[] Eval_arg_or_null_is_null = null, Eval_arg_or_null_is_empty = Bry_.Empty;
}

View File

@@ -0,0 +1,24 @@
/*
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.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
public class Pfunc_defaultsort extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bb) {}
@Override public int Id() {return Xol_kwd_grp_.Id_page_defaultsort;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_defaultsort().Name_(name);}
public static final Pfunc_defaultsort _ = new Pfunc_defaultsort(); Pfunc_defaultsort() {}
}

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.pfuncs.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
public class Pfunc_displaytitle extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_page_displaytitle;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_displaytitle().Name_(name);}
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {
byte[] val_dat_ary = Eval_argx(ctx, src, caller, self);
Xow_wiki wiki = ctx.Wiki(); Xop_parser parser = wiki.Parser();
Xop_ctx new_ctx = Xop_ctx.new_sub_(wiki);
Xop_root_tkn new_root = parser.Parse_text_to_wdom(new_ctx, val_dat_ary, false);
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_b512();
wiki.Html_mgr().Html_wtr().Write_tkn(tmp_bfr, new_ctx, gplx.xowa.html.Xoh_html_wtr_ctx.Display_title, new_root.Data_mid(), new_root, 0, new_root);
byte[] val_html = tmp_bfr.Mkr_rls().XtoAryAndClear();
ctx.Cur_page().Display_ttl_(val_html);
}
public static final Pfunc_displaytitle _ = new Pfunc_displaytitle(); Pfunc_displaytitle() {}
}

View File

@@ -0,0 +1,41 @@
/*
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.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_displaytitle_tst {
@Before public void init() {fxt.Reset();} private Pfunc_displaytitle_fxt fxt = new Pfunc_displaytitle_fxt();
@Test public void Basic() {fxt.Test("{{DISPLAYTITLE:a}}" , "a");}
@Test public void Apos_italic() {fxt.Test("{{DISPLAYTITLE:''a''}}" , "<i>a</i>");}
@Test public void Strip_display() {
String expd_fail = "<span style='/* attempt to bypass $wgRestrictDisplayTitle */'>a</span>";
fxt.Test("{{DISPLAYTITLE:<span style='display:none;'>a</span>}}" , expd_fail);
fxt.Test("{{DISPLAYTITLE:<span style='user-select:n;'>a</span>}}" , expd_fail);
fxt.Test("{{DISPLAYTITLE:<span style='visibility:n;'>a</span>}}" , expd_fail);
fxt.Test("{{DISPLAYTITLE:<span style=''>display:none</span>}}" , "<span style=''>display:none</span>");
}
}
class Pfunc_displaytitle_fxt {
private Xop_fxt fxt = new Xop_fxt();
public void Reset() {
fxt.Reset();
}
public void Test(String raw, String expd) {
fxt.Test_parse_tmpl_str_test(raw, "{{test}}", "");
Tfds.Eq(expd, String_.new_utf8_(fxt.Page().Display_ttl()));
}
}

View File

@@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_misc_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void CascadingSources() {fxt.Test_parse_page_all_str("{{CASCADINGSOURCES}}", "");} // PURPOSE: noop; DATE:2014-04-09
@Test public void PendingChangesLevel() {fxt.Test_parse_page_all_str("{{PENDINGCHANGESLEVEL}}", "");} // PURPOSE: noop; DATE:2014-04-09
}

View File

@@ -0,0 +1,24 @@
/*
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.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
public class Pfunc_noeditsection extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bb) {}
@Override public int Id() {return Xol_kwd_grp_.Id_noeditsection;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_noeditsection().Name_(name);}
public static final Pfunc_noeditsection _ = new Pfunc_noeditsection(); Pfunc_noeditsection() {}
}

View File

@@ -0,0 +1,50 @@
/*
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.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
public class Pfunc_rev_props extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {
byte[] argx = Eval_argx(ctx, src, caller, self);
Xoa_revision_data revision_data = ctx.Cur_page().Revision_data();
switch (id) {
case Xol_kwd_grp_.Id_page_id:
case Xol_kwd_grp_.Id_rev_id: bfr.Add_int_variable(ctx.Cur_page().Revision_data().Id()); break; // NOTE: making rev_id and page_id interchangeable; XOWA does not store rev_id
case Xol_kwd_grp_.Id_rev_user: bfr.Add(revision_data.User()); break;
case Xol_kwd_grp_.Id_rev_pagesize:
if (argx.length > 0) {
Xoa_ttl argx_ttl = Xoa_ttl.parse_(ctx.Wiki(), argx);
if (argx_ttl == null) { // invalid ttl; EX: {{PAGESIZE:{{{bad}}}}}
bfr.Add_byte(Byte_ascii.Num_0);
return;
}
Xoa_page argx_page = ctx.Wiki().Data_mgr().Get_page(argx_ttl, false);
if (!argx_page.Missing()) {
bfr.Add_int_variable(argx_page.Data_raw().length);
return;
}
}
bfr.Add_byte(Byte_ascii.Num_0);
break;
case Xol_kwd_grp_.Id_rev_protectionlevel: bfr.Add(revision_data.Protection_level()); break;
default: throw Err_.unhandled(id);
}
}
public Pfunc_rev_props(int id) {this.id = id;}
@Override public int Id() {return id;} private int id;
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_rev_props(id).Name_(name);}
public static final Pfunc_rev_props _ = new Pfunc_rev_props(-1);
}

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.pfuncs.pages; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_rev_props_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void setup() {fxt.Reset(); fxt.Page().Revision_data().User_(Bry_.new_ascii_("user")).Protection_level_(Bry_.new_ascii_("normal"));}
@After public void teardown() {}
@Test public void RevisionID() {fxt.Page().Revision_data().Id_(1); fxt.Test_parse_tmpl_str_test("{{REVISIONID}}" , "{{test}}", "1");}
@Test public void PageID() {fxt.Page().Revision_data().Id_(1); fxt.Test_parse_tmpl_str_test("{{PAGEID}}" , "{{test}}", "1");}
@Test public void RevisionUser() {fxt.Test_parse_tmpl_str_test("{{REVISIONUSER}}" , "{{test}}", "user");}
@Test public void PageSize() {fxt.Test_parse_tmpl_str_test("{{PAGESIZE:Test page}}" , "{{test}}", "0");}
@Test public void ProtectionLevel() {fxt.Test_parse_tmpl_str_test("{{PROTECTIONLEVEL}}" , "{{test}}", "normal");}
@Test public void PageSize_invalid_ttl() {
fxt.Init_log_(Xop_ttl_log.Invalid_char);
fxt.Test_parse_tmpl_str_test("{{PAGESIZE:{{{100}}}|R}}" , "{{test}}", "0");
}
}

View File

@@ -0,0 +1,127 @@
/*
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.strings; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.xowa.html.*;
public class Pfunc_tag extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_misc_tag;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_tag().Name_(name);}
@Override public boolean Func_require_colon_arg() {return true;}
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {
byte[] tag_name = Eval_argx(ctx, src, caller, self); if (tag_name.length == 0) return;
int args_len = self.Args_len();
Xoa_app app = ctx.App();
Bry_bfr tmp = app.Utl_bry_bfr_mkr().Get_b512();
try {
int tag_idx = ctx.Cur_page().Ref_mgr().Tag__next_id();
Xop_xnde_tag tag = (Xop_xnde_tag)app.Xnde_tag_regy().XndeNames(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;
if (tag_is_ref) // <ref>; add <xtag_bgn> to handle nested refs; PAGE:en.w:Battle_of_Midway; DATE:2014-06-27
tmp.Add(Xtag_bgn_lhs).Add_int_pad_bgn(Byte_ascii.Num_0, 10, tag_idx).Add(Xtag_rhs);
tmp.Add_byte(Byte_ascii.Lt).Add(tag_name);
if (args_len > 1) {
for (int i = 1; i < args_len; i++) {
byte[] arg = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, args_len, i); // NOTE: must evaluate arg; don't try to parse arg_tkn's key / val separately; EX:{{#tag:pre|a|{{#switch:a|a=id}}=c}}
if (arg.length == 0) continue; // skip empty atrs
tmp.Add_byte(Byte_ascii.Space);
Pfunc_tag_kv_bldr.Add_arg_as_html_atr(arg, tmp);
}
}
tmp.Add_byte(Byte_ascii.Gt);
if (args_len > 0) // TODO: trim should not be called on content; WHEN: adding src[] back to tmpl_eval
tmp.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, args_len, 0));
tmp.Add_byte(Byte_ascii.Lt).Add_byte(Byte_ascii.Slash).Add(tag_name).Add_byte(Byte_ascii.Gt);
if (tag_is_ref) // <ref>; add <xtag_end> to handle nested refs; PAGE:en.w:Battle_of_Midway; DATE:2014-06-27
tmp.Add(Xtag_end_lhs).Add_int_pad_bgn(Byte_ascii.Num_0, 10, tag_idx).Add(Xtag_rhs);
bfr.Add_bfr_and_clear(tmp);
}
finally {tmp.Mkr_rls();}
}
public static final int
Xtag_len = 27 // <xtag_bgn id='1234567890'/>
, Xtag_bgn = 14 // <xtag_bgn id='
;
public static final byte[]
Xtag_bgn_lhs = Bry_.new_ascii_("<xtag_bgn id='")
, Xtag_end_lhs = Bry_.new_ascii_("<xtag_end id='")
, Xtag_rhs = Bry_.new_ascii_("'/>")
;
}
class Pfunc_tag_kv_bldr {
public int Key_bgn() {return key_bgn;} private int key_bgn;
public int KeyEnd() {return key_end;} private int key_end;
public Pfunc_tag_kv_bldr Key_rng_(int bgn, int end) {key_bgn = bgn; key_end = end; return this;}
public int Val_bgn() {return val_bgn;} private int val_bgn;
public int Val_end() {return val_end;} private int val_end;
public Pfunc_tag_kv_bldr Val_rng_(int bgn, int end) {val_bgn = bgn; val_end = end; return this;}
public boolean Valid() {
return key_bgn != -1 && key_end != -1 && val_bgn != -1 && val_end != -1 && key_bgn <= key_end && val_bgn <= val_end;
}
public void Clear() {
key_bgn = key_end = val_bgn = val_end = -1;
}
public static void Add_arg_as_html_atr(byte[] src, Bry_bfr tmp) {
synchronized (kv_bldr) {
ParseKeyVal(src, kv_bldr);
if (kv_bldr.Val_bgn() == -1) return; // ignore atrs with empty vals: EX:{{#tag:ref||group=}} PAGE:ru.w:Колчак,_Александр_Васильевич DATE:2014-07-03
if (kv_bldr.Key_bgn() != -1)
tmp.Add(Bry_.Mid(src, kv_bldr.Key_bgn(), kv_bldr.KeyEnd()));
if (kv_bldr.Val_bgn() != -1) {
if (kv_bldr.Key_bgn() != -1) {
tmp.Add_byte(Byte_ascii.Eq);
}
tmp.Add_byte(Byte_ascii.Quote);
tmp.Add(Bry_.Mid(src, kv_bldr.Val_bgn(), kv_bldr.Val_end()));
tmp.Add_byte(Byte_ascii.Quote);
}
kv_bldr.Clear();
}
}
private static void ParseKeyVal(byte[] src, Pfunc_tag_kv_bldr kv_bldr) {
kv_bldr.Clear(); // do not forget to clear; DATE:2014-07-20
int itm_bgn = -1, itm_end = -1, src_len = src.length;
boolean mode_is_key = true;
for (int i = 0; i < src_len; i++) {
byte b = src[i];
switch (b) {
case Byte_ascii.Eq:
if (mode_is_key) {
mode_is_key = false;
if (itm_end == -1) itm_end = i;
kv_bldr.Key_rng_(itm_bgn, itm_end);
itm_bgn = itm_end = -1;
}
break;
case Byte_ascii.Quote:
case Byte_ascii.Apos: // NOTE: quotes cannot be escaped; regx takes first two quotes; REF:MW:CoreParserFunctions.php|tagObj
if (itm_bgn == -1)
itm_bgn = i + 1;
else if (itm_end == -1)
itm_end = i;
break;
case Byte_ascii.Space: case Byte_ascii.Tab: case Byte_ascii.NewLine:// NOTE: do not need to handle ws, b/c argBldr will trim it EX: {{#tag|a| b = c }}; " b " and " c " are automatically trimmed
break;
default:
if (itm_bgn == -1) itm_bgn = i;
break;
}
}
if (itm_end == -1) itm_end = src_len;
kv_bldr.Val_rng_(itm_bgn, itm_end);
}
private static Pfunc_tag_kv_bldr kv_bldr = new Pfunc_tag_kv_bldr();
}

View File

@@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.strings; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_tag_tst {
@Before public void init() {fxt.Reset();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Basic() {fxt.Test_html_full_str("{{#tag:pre|a|id=b|style=c}}" , "<pre id=\"b\" style=\"c\">a</pre>");}
// @Test public void Missing_val() {fxt.ini_Msg(Mwl_tag_rsc._.Invalid).Test_parse_tmpl_str_test("{{#tag:pre|a|id=}}" , "{{test}}" , "");} // see {{Reflist|colwidth=30em}} -> <ref group=a>a</ref>{{#tag:references||group=}} -> ""
@Test public void Atr2_empty() {fxt.Test_html_full_str("{{#tag:pre|a|id=b|}}" , "<pre id=\"b\">a</pre>");} // see {{Reflist|colwidth=30em}} -> <ref group=a>a</ref>{{#tag:references||group=a|}} -> "<references group=a/>"
@Test public void Val_apos() {fxt.Test_html_full_str("{{#tag:pre|a|id='b'}}" , "<pre id=\"b\">a</pre>");}
@Test public void Val_quote() {fxt.Test_html_full_str("{{#tag:pre|a|id=\"b\"}}" , "<pre id=\"b\">a</pre>");}
@Test public void Val_empty() {fxt.Test_html_full_str("{{#tag:pre|a|id=}}" , "<pre>a</pre>");} // PURPOSE: ignore atrs with no val; EX:{{#ref||group=}} PAGE:ru.w:Колчак,_Александр_Васильевич; DATE:2014-07-03
@Test public void Tmpl() {fxt.Test_html_full_str("{{#tag:pre|a|{{#switch:a|a=id}}=c}}" , "<pre id=\"c\">a</pre>");} // PURPOSE: args must be evaluated
@Test public void Ws_all() {fxt.Test_html_full_str("{{#tag:pre|a| id = b }}" , "<pre id=\"b\">a</pre>");}
@Test public void Ws_quoted() {fxt.Test_html_full_str("{{#tag:pre|a| id = ' b ' }}" , "<pre id=\"_b_\">a</pre>");}
@Test public void Err_bad_key() {fxt.Test_html_full_str("{{#tag:pre|a|id=val|b}}" , "<pre id=\"val\">a</pre>");} // PURPOSE: b was failing b/c id was larger and key_end set to 4 (whereas b was len=1)
// @Test public void Exc() {
// fxt.Test_parse_tmpl_str_test("{{#tag:ref|George Robertson announced in January 2003 that he would be stepping down in December.<ref> {{cite news|title =NATO Secretary General to Leave His Post in December After 4 Years |first = Craig | last = Smith | work = The New York Times | date = January 23, 2003| url = http://www.nytimes.com/2003/01/23/world/nato-secretary-general-to-leave-his-post-in-december-after-4-years.html?scp=2&sq=lord+robertson&st=nyt|accessdate = 2009-03-29}}</ref> Jaap de Hoop Scheffer was selected as his successor, but could not assume the office until January 2004 because of his commitment in the Dutch Parliament.<ref> {{cite news|title = Jaap de Hoop Scheffer | work = Newsmakers | issue = 1 | publisher = Thomson Gale | date = January 1, 2005}}</ref> Robertson was asked to extend his term until Scheffer was ready, but declined, so Minuto-Rizzo, the Deputy Secretary General, took over in the interim.<ref name =\"ncsd\" /> |group=N|}}"
// , "{{test}}" , "<pre id=\" b \">a</pre>");}
@Test public void Nested_tmpl() { // PURPOSE: nested template must get re-evaluated; EX:de.wikipedia.org/wiki/Freiburg_im_Breisgau; DATE:2013-12-18;
fxt.Init_page_create("Template:!", "|");
fxt.Init_page_create("Template:A", "{{#ifeq:{{{1}}}|expd|pass|fail}}");
fxt.Test_html_full_frag("{{#tag:ref|{{A{{!}}expd}}}}<references/>", "<span class=\"reference-text\">pass</span>");
}
}

View File

@@ -0,0 +1,51 @@
/*
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.*;
public class Pfunc_ttl extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {
byte[] val_dat_ary = Eval_argx_or_null(ctx, src, caller, self, this.Name());
if (val_dat_ary == Bry_.Empty) return; // if argx is empty, return EX: {{PAGENAME:}}; DATE:2013-02-20
Xoa_ttl ttl = val_dat_ary == null ? ctx.Cur_page().Ttl() : Xoa_ttl.parse_(ctx.Wiki(), val_dat_ary);
if (ttl == null) return;
switch (id) {
case Xol_kwd_grp_.Id_ttl_page_txt: bfr.Add(ttl.Page_txt()); break;
case Xol_kwd_grp_.Id_ttl_page_url: bfr.Add(ttl.Page_url()); break;
case Xol_kwd_grp_.Id_ttl_full_txt: bfr.Add(ttl.Full_txt()); break;
case Xol_kwd_grp_.Id_ttl_full_url: bfr.Add(ttl.Full_url()); break;
case Xol_kwd_grp_.Id_ttl_leaf_txt: bfr.Add(ttl.Leaf_txt()); break;
case Xol_kwd_grp_.Id_ttl_leaf_url: bfr.Add(ttl.Leaf_url()); break;
case Xol_kwd_grp_.Id_ttl_base_txt: bfr.Add(ttl.Base_txt()); break;
case Xol_kwd_grp_.Id_ttl_base_url: bfr.Add(ttl.Base_url()); break;
case Xol_kwd_grp_.Id_ttl_subj_txt: bfr.Add(ttl.Subj_txt()); break;
case Xol_kwd_grp_.Id_ttl_subj_url: bfr.Add(ttl.Subj_url()); break;
case Xol_kwd_grp_.Id_ttl_talk_txt: bfr.Add(ttl.Talk_txt()); break;
case Xol_kwd_grp_.Id_ttl_talk_url: bfr.Add(ttl.Talk_url()); break;
case Xol_kwd_grp_.Id_ns_num: bfr.Add_int_variable(ttl.Ns().Id()); break;
case Xol_kwd_grp_.Id_ns_txt: bfr.Add(ttl.Ns().Name_txt()); break;
case Xol_kwd_grp_.Id_ns_url: bfr.Add(ttl.Ns().Name_enc()); break;
case Xol_kwd_grp_.Id_ns_subj_txt: bfr.Add(ctx.Wiki().Ns_mgr().Ords_get_at(ttl.Ns().Ord_subj_id()).Name_txt()); break;
case Xol_kwd_grp_.Id_ns_subj_url: bfr.Add(ctx.Wiki().Ns_mgr().Ords_get_at(ttl.Ns().Ord_subj_id()).Name_enc()); break;
case Xol_kwd_grp_.Id_ns_talk_txt: bfr.Add(ctx.Wiki().Ns_mgr().Ords_get_at(ttl.Ns().Ord_talk_id()).Name_txt()); break;
case Xol_kwd_grp_.Id_ns_talk_url: bfr.Add(ctx.Wiki().Ns_mgr().Ords_get_at(ttl.Ns().Ord_talk_id()).Name_enc()); break;
}
}
public Pfunc_ttl(int id) {this.id = id;}
@Override public int Id() {return id;} private int id;
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_ttl(id).Name_(name);}
public static final Pfunc_ttl _ = new Pfunc_ttl(-1);
}

View File

@@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_ttl_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Ttl_page_txt() {fxt.Page_ttl_("a b"); fxt.Test_parse_tmpl_str_test("{{PAGENAME}}" , "{{test}}", "A b");}
@Test public void Ttl_page_txt_empty() {fxt.Page_ttl_("a b"); fxt.Test_parse_tmpl_str_test("{{PAGENAME:}}" , "{{test}}", "");}
@Test public void Ttl_page_txt_empty_2() {fxt.Page_ttl_("a b"); fxt.Test_parse_tmpl_str_test("{{PAGENAME:{{{a|}}}}}" , "{{test}}", "");} // PURPOSE.fix: {{PAGENAME:{{{nom|}}}}} should return ""; pt.wikipedia.org/wiki/Nicholas Kratzer; DATE:2013-02-20
@Test public void Ttl_page_txt_arg() {fxt.Page_ttl_("a b"); fxt.Test_parse_tmpl_str_test("{{PAGENAME:c d}}" , "{{test}}", "C d");}
@Test public void Ttl_page_txt_amp() {fxt.Page_ttl_("a b"); fxt.Test_parse_tmpl_str_test("{{PAGENAME:c & d}}" , "{{test}}", "C & d");}
@Test public void Ttl_page_url() {fxt.Page_ttl_("a b"); fxt.Test_parse_tmpl_str_test("{{PAGENAMEE}}" , "{{test}}", "A_b");}
@Test public void Ttl_full_txt() {fxt.Page_ttl_("Help:a b"); fxt.Test_parse_tmpl_str_test("{{FULLPAGENAME}}" , "{{test}}", "Help:A b");}
@Test public void Ttl_full_url() {fxt.Page_ttl_("Help:a b"); fxt.Test_parse_tmpl_str_test("{{FULLPAGENAMEE}}" , "{{test}}", "Help:A_b");}
@Test public void Ttl_leaf_txt() {fxt.Page_ttl_("a b/c/d e"); fxt.Test_parse_tmpl_str_test("{{SUBPAGENAME}}" , "{{test}}", "d e");}
@Test public void Ttl_leaf_url() {fxt.Page_ttl_("a b/c/d e"); fxt.Test_parse_tmpl_str_test("{{SUBPAGENAMEE}}" , "{{test}}", "d_e");}
@Test public void Ttl_base_txt() {fxt.Page_ttl_("a b/c/d e"); fxt.Test_parse_tmpl_str_test("{{BASEPAGENAME}}" , "{{test}}", "A b/c");}
@Test public void Ttl_base_url() {fxt.Page_ttl_("a b/c/d e"); fxt.Test_parse_tmpl_str_test("{{BASEPAGENAMEE}}" , "{{test}}", "A_b/c");}
@Test public void Ttl_subj_txt() {fxt.Page_ttl_("Help talk:a b"); fxt.Test_parse_tmpl_str_test("{{SUBJECTPAGENAME}}" , "{{test}}", "Help:A b");}
@Test public void Ttl_subj_url() {fxt.Page_ttl_("Help talk:a b"); fxt.Test_parse_tmpl_str_test("{{SUBJECTPAGENAMEE}}" , "{{test}}", "Help:A_b");}
@Test public void Ttl_talk_txt() {fxt.Page_ttl_("Help:a b"); fxt.Test_parse_tmpl_str_test("{{TALKPAGENAME}}" , "{{test}}", "Help talk:A b");}
@Test public void Ttl_talk_url() {fxt.Page_ttl_("Help:a b"); fxt.Test_parse_tmpl_str_test("{{TALKPAGENAMEE}}" , "{{test}}", "Help_talk:A_b");}
@Test public void Ns_num() {fxt.Page_ttl_("Help:A"); fxt.Test_parse_tmpl_str_test("{{NAMESPACENUMBER}}" , "{{test}}", "12");}
@Test public void Ns_txt() {fxt.Page_ttl_("Help talk:a b"); fxt.Test_parse_tmpl_str_test("{{NAMESPACE}}" , "{{test}}", "Help talk");}
@Test public void Ns_url() {fxt.Page_ttl_("Help talk:a b"); fxt.Test_parse_tmpl_str_test("{{NAMESPACEE}}" , "{{test}}", "Help_talk");}
@Test public void Ns_subj_txt() {fxt.Page_ttl_("Help talk:a b"); fxt.Test_parse_tmpl_str_test("{{SUBJECTSPACE}}" , "{{test}}", "Help");}
@Test public void Ns_subj_url() {fxt.Page_ttl_("Help talk:a b"); fxt.Test_parse_tmpl_str_test("{{SUBJECTSPACEE}}" , "{{test}}", "Help");}
@Test public void Ns_talk_txt() {fxt.Page_ttl_("Help:a b"); fxt.Test_parse_tmpl_str_test("{{TALKSPACE}}" , "{{test}}", "Help talk");}
@Test public void Ns_talk_url() {fxt.Page_ttl_("Help:a b"); fxt.Test_parse_tmpl_str_test("{{TALKSPACEE}}" , "{{test}}", "Help_talk");}
@Test public void Ns_safesubst() {fxt.Page_ttl_("Help:a"); fxt.Test_parse_tmpl_str_test("{{{{{|safesubst:}}}NAMESPACE}}" , "{{test}}", "Help");} // PURPOSE: "safesubst:NAMESPACE" was being interpreted as "NAMESPACE:" due to false colon detection; DATE:2013-11-11
@Test public void Ns_safesubst2() {fxt.Page_ttl_("Help:a"); fxt.Test_parse_tmpl_str_test("{{{{{|safesubst:}}}NAMESPACE:}}" , "{{test}}", "");} //PURPOSE: makes sure "safesubst:NAMESPACE:" still returns ""
@Test public void Exc_empty2() {fxt.Page_ttl_("Test"); fxt.Test_parse_tmpl_str_test("{{NAMESPACE:<noinclude>x</noinclude>}}" , "{{test}}", "");} // {{NMS:<ni>x</ni>}} -> {{NMS:}}
}

View File

@@ -0,0 +1,45 @@
/*
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.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.core.btries.*; import gplx.xowa.langs.numbers.*;
public class Pfunc_pagesincategory extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bb) {
byte[] val_dat_ary = Eval_argx(ctx, src, caller, self); if (Bry_.Len_eq_0(val_dat_ary)) {bb.Add_int_fixed(0, 1); return;}
val_dat_ary = Xoa_ttl.Replace_spaces(val_dat_ary);
Xow_wiki wiki = ctx.Wiki();
int ctg_len = wiki.Db_mgr().Load_mgr().Load_ctg_count(val_dat_ary);
if (ctg_len == 0) {bb.Add_int_fixed(0, 1); return;}
Xol_lang lang = wiki.Lang();
if (trie == null) trie = Xol_kwd_mgr.trie_(lang.Kwd_mgr(), Xol_kwd_grp_.Id_str_rawsuffix);
int self_args_len = self.Args_len();
boolean fmt_num = true;
if (self_args_len == 1) {
byte[] arg1 = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0);
if (arg1 != Bry_.Empty && trie.Match_exact(arg1, 0, arg1.length) != null)
fmt_num = false;
}
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_b128().Mkr_rls();
byte[] ctg_len_bry = tmp_bfr.Add_int_variable(ctg_len).XtoAryAndClear();
byte[] rslt = fmt_num ? lang.Num_mgr().Format_num(ctg_len_bry) : lang.Num_mgr().Raw(ctg_len_bry);
bb.Add(rslt);
} private Btrie_slim_mgr trie;
@Override public int Id() {return Xol_kwd_grp_.Id_site_pagesincategory;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_pagesincategory().Name_(name);}
public static final Pfunc_pagesincategory _ = new Pfunc_pagesincategory(); Pfunc_pagesincategory() {}
}

View File

@@ -0,0 +1,39 @@
/*
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.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
public class Pfunc_wiki_props extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr rslt_bfr) {
Xow_wiki_props props = ctx.Wiki().Props();
switch (id) {
case Xol_kwd_grp_.Id_site_sitename: rslt_bfr.Add(props.SiteName()); break;
case Xol_kwd_grp_.Id_site_server: rslt_bfr.Add(props.Server()); break;
case Xol_kwd_grp_.Id_site_servername: rslt_bfr.Add(props.ServerName()); break;
case Xol_kwd_grp_.Id_site_articlepath: rslt_bfr.Add(props.ArticlePath()); break;
case Xol_kwd_grp_.Id_site_scriptpath: rslt_bfr.Add(props.ScriptPath()); break;
case Xol_kwd_grp_.Id_site_stylepath: rslt_bfr.Add(props.StylePath()); break;
case Xol_kwd_grp_.Id_site_contentlanguage: rslt_bfr.Add(ctx.Cur_page().Lang().Key_bry()); break;
case Xol_kwd_grp_.Id_site_directionmark: rslt_bfr.Add(props.DirectionMark()); break; // FUTURE: find page that uses it
case Xol_kwd_grp_.Id_site_currentversion: rslt_bfr.Add(props.CurrentVersion()); break;
default: throw Err_.unhandled(id);
}
}
public Pfunc_wiki_props(int id) {this.id = id;}
@Override public int Id() {return id;} private int id;
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_wiki_props(id).Name_(name);}
public static final Pfunc_wiki_props _ = new Pfunc_wiki_props(-1);
}

View File

@@ -0,0 +1,39 @@
/*
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.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_wiki_props_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void setup() {fxt.Reset(); fxt.Wiki().Stats().NumPages_(1).NumArticles_(2).NumFiles_(3).NumEdits_(4).NumViews_(5).NumUsers_(6).NumUsersActive_(7).NumAdmins_(8);}
@Test public void NumPages() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFPAGES}}" , "{{test}}", "1");}
@Test public void NumArticles() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFARTICLES}}" , "{{test}}", "2");}
@Test public void NumFiles() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFFILES}}" , "{{test}}", "3");}
@Test public void NumEdits() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFEDITS}}" , "{{test}}", "4");}
@Test public void NumViews() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFVIEWS}}" , "{{test}}", "5");}
@Test public void NumUsers() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFUSERS}}" , "{{test}}", "6");}
@Test public void NumUsersActive() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFACTIVEUSERS}}" , "{{test}}", "7");}
@Test public void NumAdmins() {fxt.Test_parse_tmpl_str_test("{{NUMBEROFADMINS}}" , "{{test}}", "8");}
@Test public void NumArticles_raw() {Init_numArticles(1234); fxt.Test_parse_tmpl_str_test("{{NUMBEROFARTICLES:R}}" , "{{test}}", "1234"); Init_numArticles(2);}
@Test public void NumArticles_fmt() {Init_numArticles(1234); fxt.Test_parse_tmpl_str_test("{{NUMBEROFARTICLES}}" , "{{test}}", "1,234"); Init_numArticles(2);}
@Test public void NumArticles_fmt_i18n() { // PURPOSE: use lang's num_mgr; PAGE:ru.u:Main_Page; DATE:2014-07-03
fxt.Lang_by_id_(Xol_lang_itm_.Id_ru);
Init_numArticles(1234); fxt.Test_parse_tmpl_str_test("{{NUMBEROFARTICLES}}" , "{{test}}", "1234"); Init_numArticles(2);
}
private Pfunc_wiki_props_tst Init_numArticles(int v) {fxt.Wiki().Stats().NumArticles_(v); return this;}
}

View File

@@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
public class Pfunc_wiki_stats extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr rslt_bfr) {
byte[] argx = Eval_argx(ctx, src, caller, self);
boolean raw = false;
if (argx.length == 1) {
byte argx_0 = argx[0];
switch (argx_0) {case Byte_ascii.Ltr_R: case Byte_ascii.Ltr_r: raw = true; break;}
}
Xow_wiki_stats stats = ctx.Wiki().Stats();
int v = 0;
switch (id) {
case Xol_kwd_grp_.Id_num_pages: v = stats.NumPages(); break;
case Xol_kwd_grp_.Id_num_articles: v = stats.NumArticles(); break;
case Xol_kwd_grp_.Id_num_files: v = stats.NumFiles(); break;
case Xol_kwd_grp_.Id_num_edits: v = stats.NumEdits(); break;
case Xol_kwd_grp_.Id_num_views: v = stats.NumViews(); break;
case Xol_kwd_grp_.Id_num_users: v = stats.NumUsers(); break;
case Xol_kwd_grp_.Id_num_users_active: v = stats.NumUsersActive(); break;
case Xol_kwd_grp_.Id_num_admins: v = stats.NumAdmins(); break;
default: throw Err_.unhandled(id);
}
if (raw)
rslt_bfr.Add_int_variable(v);
else
rslt_bfr.Add(ctx.Cur_page().Lang().Num_mgr().Format_num(v));
}
public Pfunc_wiki_stats(int id) {this.id = id;}
@Override public int Id() {return id;} private int id;
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_wiki_stats(id).Name_(name);}
public static final Pfunc_wiki_stats _ = new Pfunc_wiki_stats(-1);
}

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_wiki_stats_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void setup() {fxt.Reset();}
@Test public void SiteName() {fxt.Test_parse_tmpl_str_test("{{SITENAME}}" , "{{test}}", "Wikipedia");}
@Test public void ServerName() {fxt.Test_parse_tmpl_str_test("{{SERVERNAME}}" , "{{test}}", "en.wikipedia.org");}
@Test public void Server() {fxt.Test_parse_tmpl_str_test("{{SERVER}}" , "{{test}}", "http://en.wikipedia.org");}
@Test public void ArticlePath() {fxt.Test_parse_tmpl_str_test("{{ARTICLEPATH}}" , "{{test}}", "/wiki/");} // FUTURE: should be /wiki/$1
@Test public void ScriptPath() {fxt.Test_parse_tmpl_str_test("{{SCRIPTPATH}}" , "{{test}}", "/wiki");}
@Test public void StylePath() {fxt.Test_parse_tmpl_str_test("{{STYLEPATH}}" , "{{test}}", "/wiki/skins");}
@Test public void ContentLanguage() {fxt.Test_parse_tmpl_str_test("{{CONTENTLANG}}" , "{{test}}", "en");}
@Test public void DirectionMark() {fxt.Test_parse_tmpl_str_test("{{DIRECTIONMARK}}" , "{{test}}", "");}
@Test public void CurrentVersion() {fxt.Test_parse_tmpl_str_test("{{CURRENTVERSION}}" , "{{test}}", "1.21wmf11");}
}

View File

@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.relatedArticles; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.html.*;
import gplx.xowa.xtns.pfuncs.*;
public class Articles_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_relatedArticles;}
@Override public Pf_func New(int id, byte[] name) {return new Articles_func().Name_(name);}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.relatedSites; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Sites_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_relatedSites;}
@Override public Pf_func New(int id, byte[] name) {return new Sites_func().Name_(name);}

View File

@@ -101,6 +101,7 @@ public class Scrib_core {
}
lib_uri.Notify_page_changed();
lib_title.Notify_page_changed();
lib_wikibase.Notify_page_changed();
}
public byte[] Cur_wiki() {return cur_wiki;} private byte[] cur_wiki = Bry_.Empty;
public byte[] Cur_lang() {return cur_lang;} private byte[] cur_lang = Bry_.Empty;
@@ -155,7 +156,7 @@ public class Scrib_core {
lib_mw.Invoke_bgn(wiki, ctx, src);
Xot_invk old_frame_parent = this.frame_parent; Xot_invk old_frame_current = this.frame_current;
this.frame_parent = parent_frame; this.frame_current = current_frame;
parent_frame.Scrib_frame_tid_(Scrib_frame_.Tid_parent); current_frame.Scrib_frame_tid_(Scrib_frame_.Tid_current);
parent_frame.Frame_tid_(Scrib_frame_.Tid_parent); current_frame.Frame_tid_(Scrib_frame_.Tid_current);
try {
Scrib_lua_mod mod = Mods_get_or_new(mod_name, mod_text);
KeyVal[] func_args = Scrib_kv_utl_.base1_many_(mod.Init_chunk_func(), String_.new_utf8_(fnc_name));
@@ -168,7 +169,7 @@ public class Scrib_core {
}
finally {
lib_mw.Invoke_end();
parent_frame.Scrib_frame_tid_(Scrib_frame_.Tid_null); current_frame.Scrib_frame_tid_(Scrib_frame_.Tid_null);
parent_frame.Frame_tid_(Scrib_frame_.Tid_null); current_frame.Frame_tid_(Scrib_frame_.Tid_null);
this.frame_parent = old_frame_parent; this.frame_current = old_frame_current; // NOTE: reset template frame; PAGE:en.w:Constantine_the_Great {{Christianity}}; DATE:2014-06-26
frame_created_list.Clear();
}

View File

@@ -19,6 +19,7 @@ package gplx.xowa.xtns.scribunto; import gplx.*; import gplx.xowa.*; import gplx
import gplx.html.*;
import gplx.xowa.html.*;
import gplx.xowa.parsers.logs.*;
import gplx.xowa.xtns.pfuncs.*;
public class Scrib_invoke_func extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_invoke;}
@Override public Pf_func New(int id, byte[] name) {return new Scrib_invoke_func().Name_(name);}

View File

@@ -114,7 +114,7 @@ public class Scrib_invoke_func_fxt {
fxt = new Xop_fxt(); // NOTE: don't try to cache fxt on func_fxt level; causes errors in Language_lib
core_fxt = new Scrib_core_fxt(fxt);
core = core_fxt.Core();
Xot_invk parent_frame = new Xot_invk_temp(true); parent_frame.Scrib_frame_tid_(Scrib_frame_.Tid_null);
Xot_invk parent_frame = new Xot_invk_temp(true); parent_frame.Frame_tid_(Scrib_frame_.Tid_null);
Xot_invk current_frame = Xot_invk_mock.test_(); current_frame.Frame_ttl_(Bry_.new_ascii_("Module:Mod_0"));
core.Invoke_init(core.Wiki(), core.Ctx(), Bry_.Empty, parent_frame, current_frame);
core.When_page_changed(fxt.Page());

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.scribunto.lib; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
import gplx.xowa.html.*;
import gplx.html.*;
public class Scrib_lib_message implements Scrib_lib {
public Scrib_lib_message(Scrib_core core) {this.core = core;} private Scrib_core core;
public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod;
@@ -139,7 +139,7 @@ class Scrib_lib_message_data {
break;
case Fmt_tid_parseAsBlock: // NOTE: MW passes msg_val through parser and strips <p> if tid==parse; XOWA does the opposite, so add <p> if parseAsBlock requested
Bry_bfr bfr = wiki.Utl_bry_bfr_mkr().Get_b512();
msg_val = bfr.Add(Xoh_consts.P_bgn).Add(msg_val).Add(Xoh_consts.P_end).Mkr_rls().XtoAryAndClear();
msg_val = bfr.Add(Html_tag_.P_lhs).Add(msg_val).Add(Html_tag_.P_rhs).Mkr_rls().XtoAryAndClear();
break;
case Fmt_tid_escaped:
msg_val = gplx.html.Html_utl.Escape_html_as_bry(msg_val);

View File

@@ -99,7 +99,7 @@ public class Scrib_lib_mw implements Scrib_lib {
public boolean GetExpandedArgument(Scrib_proc_args args, Scrib_proc_rslt rslt) {
String frame_id = args.Pull_str(0);
Xot_invk frame = Scrib_frame_.Get_frame(core, frame_id);
int frame_arg_adj = Scrib_frame_.Get_arg_adj(frame.Scrib_frame_tid());
int frame_arg_adj = Scrib_frame_.Get_arg_adj(frame.Frame_tid());
String idx_str = args.Pull_str(1);
int idx_int = Int_.parse_or_(idx_str, Int_.MinValue); // NOTE: should not receive int value < -1; idx >= 0
Bry_bfr tmp_bfr = Bry_bfr.new_(); // NOTE: do not make modular level variable, else random failures; DATE:2013-10-14
@@ -151,7 +151,7 @@ public class Scrib_lib_mw implements Scrib_lib {
public boolean GetAllExpandedArguments(Scrib_proc_args args, Scrib_proc_rslt rslt) {
String frame_id = args.Pull_str(0);
Xot_invk frame = Scrib_frame_.Get_frame(core, frame_id);
byte frame_tid = frame.Scrib_frame_tid();
byte frame_tid = frame.Frame_tid();
Xot_invk parent_frame = Scrib_frame_.Get_parent(core, frame_tid);
int frame_arg_adj = Scrib_frame_.Get_arg_adj(frame_tid);
int args_len = frame.Args_len() - frame_arg_adj;
@@ -203,12 +203,12 @@ public class Scrib_lib_mw implements Scrib_lib {
return rslt.Init_obj(frame != null);
}
public boolean ParentFrameExists(Scrib_proc_args args, Scrib_proc_rslt rslt) {
return rslt.Init_obj(!core.Frame_parent().Root_frame());
return rslt.Init_obj(!core.Frame_parent().Frame_is_root());
}
public boolean Preprocess(Scrib_proc_args args, Scrib_proc_rslt rslt) {
String frame_id = args.Pull_str(0);
Xot_invk frame = Scrib_frame_.Get_frame(core, frame_id);
byte frame_tid = frame.Scrib_frame_tid();
byte frame_tid = frame.Frame_tid();
Xot_invk parent_frame = Scrib_frame_.Get_parent(core, frame_tid);
String text_str = args.Pull_str(1);
byte[] text_bry = Bry_.new_utf8_(text_str);

View File

@@ -25,8 +25,9 @@ public class Scrib_lib_wikibase implements Scrib_lib {
public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) {
Init();
mod = core.RegisterInterface(this, script_dir.GenSubFil("mw.wikibase.lua"));
notify_page_changed_fnc = mod.Fncs_get_by_key("notify_page_changed");
return mod;
}
} private Scrib_lua_proc notify_page_changed_fnc;
public Scrib_proc_mgr Procs() {return procs;} private Scrib_proc_mgr procs = new Scrib_proc_mgr();
public boolean Procs_exec(int key, Scrib_proc_args args, Scrib_proc_rslt rslt) {
switch (key) {
@@ -39,6 +40,7 @@ public class Scrib_lib_wikibase implements Scrib_lib {
private static final int Proc_getEntity = 0, Proc_getEntityId = 1, Proc_getGlobalSiteId = 2;
public static final String Invk_getEntity = "getEntity", Invk_getEntityId = "getEntityId", Invk_getGlobalSiteId = "getGlobalSiteId";
private static final String[] Proc_names = String_.Ary(Invk_getEntity, Invk_getEntityId, Invk_getGlobalSiteId);
public void Notify_page_changed() {if (notify_page_changed_fnc != null) core.Interpreter().CallFunction(notify_page_changed_fnc.Id(), KeyVal_.Ary_empty);}
public boolean GetEntity(Scrib_proc_args args, Scrib_proc_rslt rslt) {
byte[] ttl_bry = args.Pull_bry(0);
if (Bry_.Len_eq_0(ttl_bry)) return rslt.Init_empty(); // NOTE: some Modules do not pass in an argument; return early, else spurious warning "invalid qid for ttl" (since ttl is blank); EX:w:Module:Authority_control; DATE:2013-10-27

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.syntaxHighlight; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.html.*;
import gplx.html.*; import gplx.xowa.html.*;
public class Xtn_syntaxHighlight_nde implements Xox_xnde, Xop_xnde_atr_parser {
private byte[] lang = Bry_.Empty; private byte[] style = null; private byte[] enclose = Bry_.Empty;
private boolean line_enabled = false; private int start = 1; private Int_rng_mgr highlight_idxs = Int_rng_mgr_null._;
@@ -83,7 +83,7 @@ public class Xtn_syntaxHighlight_nde implements Xox_xnde, Xop_xnde_atr_parser {
Xox_mgr_base.Xtn_write_escape(app, bfr, line);
bfr.Add(Xoh_consts.Span_end);
if (enclose_is_none)
bfr.Add(Xoh_consts.Br);
bfr.Add(Html_tag_.Br_inl);
bfr.Add_byte_nl();
}
}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.wdatas; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Wdata_external_lang_links_data {
private ListAdp langs_list = ListAdp_.new_(); private Hash_adp_bry langs_hash = Hash_adp_bry.ci_ascii_(); // ASCII:lang_code
public boolean Enabled() {return enabled;} private boolean enabled; public Wdata_external_lang_links_data Enabled_(boolean v) {enabled = v; return this;}

View File

@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.wdatas; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.json.*;
import gplx.xowa.xtns.pfuncs.*;
public class Wdata_pf_noExternalLangLinks extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_noexternallanglinks;}
@Override public Pf_func New(int id, byte[] name) {return new Wdata_pf_noExternalLangLinks().Name_(name);}

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.wdatas; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.json.*; import gplx.xowa.parsers.logs.*;
import gplx.json.*; import gplx.xowa.parsers.logs.*; import gplx.xowa.xtns.pfuncs.*;
public class Wdata_pf_property extends Pf_func_base {
@Override public int Id() {return Xol_kwd_grp_.Id_property;}
@Override public Pf_func New(int id, byte[] name) {return new Wdata_pf_property().Name_(name);}

View File

@@ -42,22 +42,21 @@ public class Wdata_wiki_mgr implements GfoInvkAble {
byte[] qids_key = bfr.Add_byte(Byte_ascii.Pipe).Add(ns_num).Add_byte(Byte_ascii.Pipe).Add(ttl).XtoAry();
qids_cache.Add(qids_key, qid);
}
public byte[] Qids_get(Xow_wiki wiki, Xoa_ttl ttl) {return Qids_get(wiki.Wdata_wiki_lang(), wiki.Wdata_wiki_tid(), ttl.Ns().Num_bry(), ttl.Page_db());}
public byte[] Qids_get(byte[] lang_key, byte wiki_tid, byte[] ns_num, byte[] ttl) {
public byte[] Qids_get(Xow_wiki wiki, Xoa_ttl ttl) {return Qids_get(wiki.Wdata_wiki_abrv(), ttl);}
private byte[] Qids_get(byte[] wiki_abrv, Xoa_ttl ttl) {
if (!enabled) return null;
if (wiki_tid == Xow_wiki_domain_.Tid_other) return null; // "other" wikis will never call wikidata
Bry_bfr bfr = app.Utl_bry_bfr_mkr().Get_b512();
Xob_bz2_file.Build_alias_by_lang_tid(bfr, lang_key, wiki_tid_ref.Val_(wiki_tid));
int xwiki_key_len = bfr.Len();
byte[] qids_key = bfr.Add_byte(Byte_ascii.Pipe).Add(ns_num).Add_byte(Byte_ascii.Pipe).Add(ttl).XtoAry();
byte[] rv = (byte[])qids_cache.Fetch(qids_key);
if (rv == null) {
rv = this.Wdata_wiki().Db_mgr().Load_mgr().Load_qid(Bry_.Mid(bfr.Bfr(), 0, xwiki_key_len), ns_num, ttl); if (rv == null) {bfr.Mkr_rls(); return null;}
qids_cache.Add(qids_key, rv);
if (Bry_.Len_eq_0(wiki_abrv)) return null; // "other" wikis will never call wikidata
synchronized (qid_key) {
qid_key.Init(wiki_abrv, ttl);
byte[] rv = (byte[])qids_cache.Fetch(qid_key.Cache_key());
if (rv == null) { // not in cache
rv = this.Wdata_wiki().Db_mgr().Load_mgr().Load_qid(qid_key.Wiki_abrv(), qid_key.Ns_num_bry(), qid_key.Ttl_bry());
byte[] add_val = rv == null ? Bry_.Empty : rv; // JAVA: hashtable does not accept null as value; use Bry_.Empty
qids_cache.Add(qid_key.Cache_key(), add_val); // NOTE: if not in db, will insert a null value for cache_key; DATE:2014-07-23
}
return Bry_.Len_eq_0(rv) ? null : rv; // JAVA: convert Bry_.Empty to null
}
bfr.Mkr_rls().Clear();
return rv;
} private Byte_obj_ref wiki_tid_ref = Byte_obj_ref.zero_();
} private Byte_obj_ref wiki_tid_ref = Byte_obj_ref.zero_(); private Wdata_qid_key qid_key = new Wdata_qid_key();
public Int_obj_val Pids_add(byte[] pids_key, int pid_id) {Int_obj_val rv = Int_obj_val.new_(pid_id); pids_cache.Add(pids_key, rv); return rv;}
public int Pids_get(byte[] lang_key, byte[] pid_name) {
if (!enabled) return Pid_null;
@@ -76,7 +75,7 @@ public class Wdata_wiki_mgr implements GfoInvkAble {
if (data.Q() != null) return Pages_get(data.Q());
else if (data.Of() != null) {
Xoa_ttl of_ttl = Xoa_ttl.parse_(wiki, data.Of()); if (of_ttl == null) return null;
byte[] qid = Qids_get(wiki.Wdata_wiki_lang(), wiki.Wdata_wiki_tid(), of_ttl.Ns().Num_bry(), of_ttl.Page_db()); if (qid == null) return null; // NOTE: for now, use wiki.Lang_key(), not page.Lang()
byte[] qid = Qids_get(wiki, of_ttl); if (qid == null) return null; // NOTE: for now, use wiki.Lang_key(), not page.Lang()
return Pages_get(qid);
}
else return Pages_get(wiki, ttl);
@@ -213,3 +212,24 @@ public class Wdata_wiki_mgr implements GfoInvkAble {
ctx.Wiki().App().Usr_dlg().Log_many("", "", "qid not found in wikidata; qid=~{0} page=~{1}", String_.new_utf8_(qid), String_.new_utf8_(ctx.Cur_page().Ttl().Page_db()));
}
}
class Wdata_qid_key {
public byte[] Wiki_abrv() {return wiki_abrv;} private byte[] wiki_abrv;
public byte[] Ns_num_bry() {return ns_num_bry;} private byte[] ns_num_bry;
public byte[] Ttl_bry() {return ttl_bry;} private byte[] ttl_bry;
public byte[] Cache_key() {return cache_key;} private byte[] cache_key;
public void Init(byte[] wiki_abrv, Xoa_ttl ttl) {
this.wiki_abrv = wiki_abrv;
Xow_ns ns = ttl.Ns();
boolean ns_is_canonical = Xow_ns_.Canonical_id(ns.Name_bry()) != Xow_ns_.Id_null; // handle titles with non-canoncial ns; PAGE:uk.s:Автор:Богдан_Гаврилишин DATE:2014-07-23
if (ns_is_canonical) { // canonical ns; EX: Category:A
ns_num_bry = ns.Num_bry(); // use ns's number; EX: 14
ttl_bry = ttl.Page_db(); // use page_db EX: A
}
else { // not a canonical ns; EX: Author:A
ns_num_bry = Ns_num_bry_main; // use main ns EX: 0
ttl_bry = ttl.Full_db(); // use full_db EX: Author:A
}
this.cache_key = Bry_.Add(wiki_abrv, Byte_ascii.Pipe_bry, ns_num_bry, Byte_ascii.Pipe_bry, ttl_bry);
}
public static final byte[] Ns_num_bry_main = Bry_.new_ascii_("000");
}

View File

@@ -58,10 +58,11 @@ public class Wdata_wiki_mgr_fxt {
tmp_bfr.Mkr_rls();
}
public void Init_pids_add(String lang_key, String pid_name, int pid) {wdata_mgr.Pids_add(Bry_.new_utf8_(lang_key + "|" + pid_name), pid);}
public void Init_links_add(String wiki, String ttl, String qid) {
public void Init_links_add(String wiki, String ttl, String qid) {Init_links_add(wiki, "000", ttl, qid);}
public void Init_links_add(String wiki, String ns_num, String ttl, String qid) {
byte[] ttl_bry = Bry_.new_utf8_(ttl);
Xowd_regy_mgr regy_mgr = app.Hive_mgr().Regy_mgr();
Io_url regy_fil = wdata_mgr.Wdata_wiki().Fsys_mgr().Site_dir().GenSubDir_nest("data", "qid").GenSubFil_nest(wiki, "000", "reg.csv");
Io_url regy_fil = wdata_mgr.Wdata_wiki().Fsys_mgr().Site_dir().GenSubDir_nest("data", "qid").GenSubFil_nest(wiki, ns_num, "reg.csv");
regy_mgr.Init(regy_fil);
regy_mgr.Create(ttl_bry);
regy_mgr.Save();
@@ -70,7 +71,7 @@ public class Wdata_wiki_mgr_fxt {
byte[] itm = bfr.Add(ttl_bry).Add_byte(Byte_ascii.Pipe).Add(Bry_.new_ascii_(qid)).Add_byte_nl().XtoAryAndClear();
Xob_xdat_file xdat_file = new Xob_xdat_file();
xdat_file.Insert(bfr, itm);
Io_url file_orig = Xob_wdata_qid_base_tst.ttl_(app.Wiki_mgr().Wdata_mgr().Wdata_wiki(), wiki, "000", 0);
Io_url file_orig = Xob_wdata_qid_base_tst.ttl_(app.Wiki_mgr().Wdata_mgr().Wdata_wiki(), wiki, ns_num, 0);
xdat_file.Save(file_orig);
}
public void Init_external_links_mgr_clear() {wiki.Ctx().Cur_page().Wdata_external_lang_links().Reset();}
@@ -89,8 +90,10 @@ public class Wdata_wiki_mgr_fxt {
public void Test_get_low_qid(String qid, String expd) {
Tfds.Eq(expd, String_.new_ascii_(Wdata_wiki_mgr.Get_low_qid(Bry_.new_ascii_(qid))));
}
public void Test_link(String lang, String page, String expd) {
Tfds.Eq(expd, String_.new_utf8_(wdata_mgr.Qids_get(Bry_.new_ascii_(lang), Xow_wiki_domain_.Tid_wikipedia, Bry_.new_ascii_("000"), Bry_.new_utf8_(page))));
public void Test_link(String ttl_str, String expd) {Test_link(Xoa_ttl.parse_(wiki, Xow_ns_.Id_main, Bry_.new_utf8_(ttl_str)), expd);}
public void Test_link(Xoa_ttl ttl, String expd) {
byte[] qid_ttl = wdata_mgr.Qids_get(wiki, ttl);
Tfds.Eq(expd, String_.new_utf8_(qid_ttl));
}
public void Test_parse_pid_null(String val) {Test_parse_pid(val, Wdata_wiki_mgr.Pid_null);}
public void Test_parse_pid(String val, int expd) {Tfds.Eq(expd, Wdata_pf_property.Parse_pid(num_parser, Bry_.new_ascii_(val)));} private NumberParser num_parser = new NumberParser();

View File

@@ -20,15 +20,23 @@ import org.junit.*; import gplx.xowa.xtns.wdatas.imports.*;
public class Wdata_wiki_mgr_tst {
@Test public void Basic() {
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
fxt.Init_links_add("enwiki", "q1", "q1_en");
fxt.Test_link("en", "q1", "q1_en");
fxt.Test_link("en", "q2", null);
fxt.Init_links_add("enwiki", "Q1", "Q1_en");
fxt.Test_link("Q1", "Q1_en");
fxt.Test_link("Q2", null);
}
@Test public void Case_sensitive() { // PURPOSE: wikidata lkp should be case_sensitive; a vs A DATE:2013-09-03
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
fxt.Init_links_add("enwiki", "q1", "q1_lc");
fxt.Test_link("en", "q1", "q1_lc");
fxt.Test_link("en", "Q1", null); // Q1 should not match q1
fxt.Init_links_add("enwiki", "Page", "Page_data");
fxt.Test_link("Page", "Page_data");
fxt.Test_link("PAGE", null);
}
@Test public void Non_canonical_ns() { // PURPOSE: handle wikidata entries in non-canonical ns; EX:ukwikisource and Author; PAGE:uk.s:Автор:Богдан_Гаврилишин DATE:2014-07-23
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();
Xow_wiki wiki = fxt.Wiki();
wiki.Ns_mgr().Add_new(124, "Test_ns");
fxt.Init_links_add("enwiki", "000", "Test_ns:Test_page", "pass"); // NOTE: wdata will save to "000" ns, b/c "124" ns is not canonical
Xoa_ttl ttl = Xoa_ttl.parse_(fxt.Wiki(), 124, Bry_.new_ascii_("Test_page"));
fxt.Test_link(ttl, "pass");
}
@Test public void Write_json_as_html() {
Wdata_wiki_mgr_fxt fxt = new Wdata_wiki_mgr_fxt().Init();

View File

@@ -40,9 +40,8 @@ public abstract class Xob_wdata_qid_base extends Xob_itm_dump_base implements Xo
Json_itm_nde links_nde = Json_itm_nde.cast_(doc.Get_grp(Wdata_doc_consts.Key_atr_links_bry)); if (links_nde == null) return; // no links; ignore
int len = links_nde.Subs_len(); if (len == 0) return; // no subs; return;
Wdata_qid_data data_core = null;
links.Clear();
// iterate links; find data_core (hopefully enwiki)
for (int i = 0; i < len; i++) {
links.Clear();
for (int i = 0; i < len; i++) { // iterate links; find data_core (hopefully enwiki)
Json_itm_kv kv = (Json_itm_kv)links_nde.Subs_get_at(i);
byte[] xwiki_key = kv.Key().Data_bry();
byte[] ttl_bry = Wdata_doc_.Link_extract(kv);
@@ -52,15 +51,11 @@ public abstract class Xob_wdata_qid_base extends Xob_itm_dump_base implements Xo
if (Bry_.Eq(xwiki_key, Xwiki_key_en)) data_core = data;
}
// get core_ns; warn if not enwiki
// if (!Bry_.Eq(data_core.Xwiki_key(), Xwiki_key_en) && Bry_finder.Find_fwd(data_core.Ttl(), Byte_ascii.Colon) != Bry_.NotFound)
// bldr.App().Usr_dlg().Log_many(GRP_KEY, "enwiki_not_found", "enwiki not found; namespace parsing may be inaccurate; ~{0} ~{1}", String_.new_ascii_(qid), String_.new_ascii_(data_core.Ttl()));
Xoa_ttl core_ttl = Xoa_ttl.parse_(wiki, data_core.Ttl()); // parse ttl to get ns; this may still be inaccurate as it is using wikidata's ns, not enwiki's;
Xoa_ttl core_ttl = Xoa_ttl.parse_(wiki, data_core.Ttl()); // NOTE: parse ttl to get ns; this may still be inaccurate as it is using wikidata's ns, not enwiki's;; DATE:2014-07-23
Xow_ns core_ns = core_ttl.Ns();
boolean core_ns_is_main = core_ns.Id_main();
// iterate links again; do parsing, but assume any ns is same as enwiki
for (int i = 0; i < len; i++) {
for (int i = 0; i < len; i++) { // iterate links again; do parsing, but assume any ns is same as enwiki
Wdata_qid_data data = (Wdata_qid_data)links.FetchAt(i);
byte[] data_ttl_bry = data.Ttl();
byte[] actl_ttl = null;

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.xowa_cmds; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
import gplx.xowa.xtns.pfuncs.*;
public class Xop_xowa_func extends Pf_func_base {
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {
if (ctx.Wiki().Sys_cfg().Xowa_cmd_enabled()) { // only exec if enabled for wiki