mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v1.7.3.1
This commit is contained in:
@@ -31,7 +31,7 @@ public abstract class Xox_mgr_base implements Xox_mgr {
|
||||
@gplx.Virtual public void Xtn_init_by_app(Xoa_app app) {}
|
||||
@gplx.Virtual public void Xtn_init_by_wiki(Xow_wiki wiki) {}
|
||||
@gplx.Virtual public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_enabled)) return Yn.X_to_str(enabled);
|
||||
if (ctx.Match(k, Invk_enabled)) return Yn.Xto_str(enabled);
|
||||
else if (ctx.Match(k, Invk_enabled_)) enabled = m.ReadYn("v");
|
||||
else return GfoInvkAble_.Rv_unhandled;
|
||||
return this;
|
||||
@@ -40,15 +40,22 @@ public abstract class Xox_mgr_base implements Xox_mgr {
|
||||
public static void Xtn_write_escape(Xoa_app app, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) {Xtn_write_escape(app, bfr, src, xnde.Src_bgn(), xnde.Src_end());}
|
||||
public static void Xtn_write_escape(Xoa_app app, Bry_bfr bfr, byte[] src) {Xtn_write_escape(app, bfr, src, 0, src.length);}
|
||||
public static void Xtn_write_escape(Xoa_app app, Bry_bfr bfr, byte[] src, int bgn, int end) {Xoh_html_wtr_escaper.Escape(app, bfr, src, bgn, end, true, false);}
|
||||
public static void Xtn_write_unsupported(Xoa_app app, Xop_ctx ctx, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde, boolean parse_content) {
|
||||
public static void Xtn_write_unsupported(Xoa_app app, Xop_ctx ctx, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde, byte parse_content_tid) {
|
||||
bfr.Add(Xowa_not_implemented);
|
||||
Xox_mgr_base.Xtn_write_escape(app, bfr, src, xnde.Tag_open_bgn(), xnde.Tag_open_end());
|
||||
if (xnde.CloseMode() != Xop_xnde_tkn.CloseMode_pair) return; // inline node
|
||||
if (parse_content)
|
||||
bfr.Add(ctx.Wiki().Parser().Parse_text_to_html(ctx, Bry_.Mid(src, xnde.Tag_open_end(), xnde.Tag_close_bgn())));
|
||||
else
|
||||
Xox_mgr_base.Xtn_write_escape(app, bfr, src, xnde.Tag_open_end(), xnde.Tag_close_bgn());
|
||||
switch (parse_content_tid) {
|
||||
case Parse_content_tid_escape:
|
||||
Xox_mgr_base.Xtn_write_escape(app, bfr, src, xnde.Tag_open_end(), xnde.Tag_close_bgn());
|
||||
break;
|
||||
case Parse_content_tid_html:
|
||||
bfr.Add(ctx.Wiki().Parser().Parse_text_to_html(ctx, Bry_.Mid(src, xnde.Tag_open_end(), xnde.Tag_close_bgn())));
|
||||
break;
|
||||
case Parse_content_tid_none: default:
|
||||
break;
|
||||
}
|
||||
Xox_mgr_base.Xtn_write_escape(app, bfr, src, xnde.Tag_close_bgn(), xnde.Tag_close_end());
|
||||
}
|
||||
private static final byte[] Xowa_not_implemented = Bry_.new_ascii_("XOWA does not support this extension: ");
|
||||
public static final byte Parse_content_tid_none = 0, Parse_content_tid_escape = 1, Parse_content_tid_html = 2;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class Ref_nde implements Xox_xnde, Xop_xnde_atr_parser {
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class References_nde implements Xox_xnde, Xop_xnde_atr_parser {
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ public class References_nde_basic_tst {
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Key_ignore_nl_tab() { // PURPOSE: \n in ref_name should be escaped to \s; EX.WP:Self-Transcendence 3100 Mile Race
|
||||
@Test public void Key_ignore_nl_tab() { // PURPOSE: \n in ref_name should be escaped to \s; PAGE:en.w:Self-Transcendence 3100 Mile Race
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<ref name=\"name\na\">b</ref>"
|
||||
, "<references/>"
|
||||
|
||||
@@ -41,29 +41,29 @@ 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>"
|
||||
// , "<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 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>"
|
||||
|
||||
@@ -108,11 +108,11 @@ class Dpl_itm {
|
||||
case Dpl_itm_keys.Key_stablepages: stable_pages = Dpl_stable_tid.Parse(val); break;
|
||||
case Dpl_itm_keys.Key_qualitypages: quality_pages = Dpl_redirect.Parse(val); break;
|
||||
case Dpl_itm_keys.Key_addfirstcategorydate: Parse_ctg_date(val); break;
|
||||
case Dpl_itm_keys.Key_count: count = Bry_.X_to_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_offset: offset = Bry_.X_to_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_imagesperow: gallery_imgs_per_row = Bry_.X_to_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_imagewidth: gallery_img_w = Bry_.X_to_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_imageheight: gallery_img_h = Bry_.X_to_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_count: count = Bry_.Xto_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_offset: offset = Bry_.Xto_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_imagesperow: gallery_imgs_per_row = Bry_.Xto_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_imagewidth: gallery_img_w = Bry_.Xto_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_imageheight: gallery_img_h = Bry_.Xto_int_or(val, Int_.MinValue); break;
|
||||
case Dpl_itm_keys.Key_gallerycaption: gallery_caption = val; break; // FUTURE: parse for {{int:}}?
|
||||
case Dpl_itm_keys.Key_galleryshowfilesize: gallery_filesize = Dpl_itm_keys.Parse_as_bool(val, true); break;
|
||||
case Dpl_itm_keys.Key_galleryshowfilename: gallery_filename = Dpl_itm_keys.Parse_as_bool(val, true); break;
|
||||
|
||||
@@ -162,7 +162,7 @@ public class Gallery_itm_parser {
|
||||
case Fld_ttl:
|
||||
cur_itm.Ttl_end_(fld_end);
|
||||
byte[] ttl_bry = Bry_.Mid(src, cur_itm.Ttl_bgn(), fld_end);
|
||||
ttl_bry = ctx.App().Url_converter_url_ttl().Decode(ttl_bry); // NOTE: must decode url-encoded entries; EX: "A%28b%29.png" -> "A(b).png"; DATE:2014-01-01
|
||||
ttl_bry = ctx.App().Encoder_mgr().Url_ttl().Decode(ttl_bry); // NOTE: must decode url-encoded entries; EX: "A%28b%29.png" -> "A(b).png"; DATE:2014-01-01
|
||||
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry);
|
||||
if ( ttl == null // invalid ttl; EX: "<invalid>"
|
||||
|| ttl.Anch_bgn() == 1 // anchor-only ttl; EX: "#invalid"; DATE:2014-03-18
|
||||
|
||||
@@ -88,9 +88,9 @@ class Gallery_itm_parser_fxt {
|
||||
ListAdp actl = ListAdp_.new_();
|
||||
byte[] src = Bry_.new_ascii_(raw);
|
||||
parser.Parse_all(actl, Gallery_mgr_base_.New_by_mode(Gallery_mgr_base_.Traditional_tid), new Gallery_xnde(), src, 0, src.length);
|
||||
Tfds.Eq_ary(String_.Ary_flatten(expd), String_.Ary_flatten(X_to_str_ary(src, actl)));
|
||||
Tfds.Eq_ary(String_.Ary_flatten(expd), String_.Ary_flatten(Xto_str_ary(src, actl)));
|
||||
}
|
||||
private String[][] X_to_str_ary(byte[] src, ListAdp list) {
|
||||
private String[][] Xto_str_ary(byte[] src, ListAdp list) {
|
||||
int len = list.Count();
|
||||
String[][] rv = new String[len][];
|
||||
for (int i = 0; i < len; i++) {
|
||||
@@ -98,15 +98,15 @@ class Gallery_itm_parser_fxt {
|
||||
String[] ary = new String[5];
|
||||
rv[i] = ary;
|
||||
ary[0] = String_.new_utf8_(itm.Ttl().Full_txt());
|
||||
ary[2] = X_to_str_ary_itm(src, itm.Alt_bgn(), itm.Alt_end());
|
||||
ary[3] = X_to_str_ary_itm(src, itm.Link_bgn(), itm.Link_end());
|
||||
ary[4] = X_to_str_ary_itm(src, itm.Page_bgn(), itm.Page_end());
|
||||
ary[2] = Xto_str_ary_itm(src, itm.Alt_bgn(), itm.Alt_end());
|
||||
ary[3] = Xto_str_ary_itm(src, itm.Link_bgn(), itm.Link_end());
|
||||
ary[4] = Xto_str_ary_itm(src, itm.Page_bgn(), itm.Page_end());
|
||||
byte[] caption = itm.Caption_bry();
|
||||
ary[1] = caption == null ? null : String_.new_utf8_(caption);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
private String X_to_str_ary_itm(byte[] src, int bgn, int end) {
|
||||
private String Xto_str_ary_itm(byte[] src, int bgn, int end) {
|
||||
return bgn == Bry_.NotFound && end == Bry_.NotFound ? null : String_.new_utf8_(src, bgn, end);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class Gallery_xnde_tst {
|
||||
)
|
||||
));
|
||||
}
|
||||
@Test public void Err_pre() { // PURPOSE: leading ws was failing; EX.WP: Vlaardingen; "\nA.jpg| <center>Visbank</center>\n"
|
||||
@Test public void Err_pre() { // PURPOSE: leading ws was failing; PAGE:en.w:Vlaardingen; "\nA.jpg| <center>Visbank</center>\n"
|
||||
raw_src = " <center>a</center>";
|
||||
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "<gallery>"
|
||||
@@ -121,7 +121,7 @@ public class Gallery_xnde_tst {
|
||||
)
|
||||
));
|
||||
}
|
||||
@Test public void Err_comment() { // PURPOSE: comment was being rendered; EX.WP: Perpetual motion; <!-- removed A.jpg|bcde -->
|
||||
@Test public void Err_comment() { // PURPOSE: comment was being rendered; PAGE:en.w:Perpetual motion; <!-- removed A.jpg|bcde -->
|
||||
raw_src = "b";
|
||||
fxt.Init_log_(Xop_ttl_log.Comment_eos).Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "<gallery>"
|
||||
|
||||
@@ -39,7 +39,7 @@ class Imap_html_bldr {
|
||||
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}\"/>"
|
||||
( "<area href=\"~{href}\" shape=\"~{shape}\" coords=\"~{pts}\" alt=\"{caption}\" title=\"~{caption}\"/>"
|
||||
, "href", "caption", "shape", "pts"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class Imap_itm_parser {
|
||||
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
|
||||
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];
|
||||
@@ -79,7 +79,7 @@ class Imap_itm_parser {
|
||||
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 loks 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 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) {
|
||||
|
||||
@@ -72,7 +72,7 @@ public class Listing_xnde implements Xox_xnde, Xop_xnde_atr_parser {
|
||||
Html_wtr hwtr = xtn_mgr.Hwtr();
|
||||
if (!Bld_by_template(xnde, atrs, src)) {
|
||||
Bld_by_args(xtn_mgr, hwtr, xnde, src);
|
||||
html_output = hwtr.X_to_bry_and_clear();
|
||||
html_output = hwtr.Xto_bry_and_clear();
|
||||
}
|
||||
}
|
||||
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) {
|
||||
@@ -108,7 +108,7 @@ public class Listing_xnde implements Xox_xnde, Xop_xnde_atr_parser {
|
||||
private void Bld_by_args(Listing_xtn_mgr xtn_mgr, Html_wtr wtr, Xop_xnde_tkn xnde, byte[] src) {
|
||||
wtr.Nde_full(Tag_strong, xatr_name); // <strong>name</strong>
|
||||
if (xatr_url != null)
|
||||
wtr.Nde_full_atrs(Tag_a, wtr.X_to_bry_and_clear(), false
|
||||
wtr.Nde_full_atrs(Tag_a, wtr.Xto_bry_and_clear(), false
|
||||
, Atr_a_href , xatr_url
|
||||
, Atr_a_class , Atr_a_class_external_text
|
||||
, Atr_a_rel , Atr_a_rel_nofollow
|
||||
|
||||
@@ -61,7 +61,7 @@ public class Listing_xtn_mgr extends Xox_mgr_base {
|
||||
hwtr.Nde_full_atrs(Listing_xnde.Tag_abbr, symbol_text, true
|
||||
, Listing_xnde.Atr_a_title, Html_utl.Escape_html_as_bry(template_text)
|
||||
);
|
||||
rv = hwtr.X_to_bry_and_clear();
|
||||
rv = hwtr.Xto_bry_and_clear();
|
||||
}
|
||||
else {
|
||||
rv = template_text;
|
||||
|
||||
@@ -43,7 +43,7 @@ public class Lst_pfunc_wkr {
|
||||
defn_tmpl = wiki.Parser().Parse_text_to_defn_obj(sub_ctx, sub_ctx.Tkn_mkr(), src_ttl.Ns(), src_ttl_bry, src_page_bry); // NOTE: parse as tmpl to ignore <noinclude>
|
||||
Bry_bfr tmp_bfr = wiki.Utl_bry_bfr_mkr().Get_m001();
|
||||
page.Tmpl_stack_del(); // take template off stack; evaluate will never recurse, and will fail if ttl is still on stack; DATE:2014-03-10
|
||||
defn_tmpl.Tmpl_evaluate(sub_ctx, Xot_invk_temp.PageIsCaller, tmp_bfr);
|
||||
defn_tmpl.Tmpl_evaluate(sub_ctx, Xot_invk_temp.Page_is_caller, tmp_bfr);
|
||||
src = tmp_bfr.Mkr_rls().XtoAryAndClear();
|
||||
if (!page.Tmpl_stack_add(src_ttl.Full_db())) return; // put template back on stack;
|
||||
Xop_root_tkn root = wiki.Parser().Parse_text_to_wdom(sub_ctx, src, true); // NOTE: pass sub_ctx as old_ctx b/c entire document will be parsed, and references outside the section should be ignored;
|
||||
|
||||
@@ -22,4 +22,10 @@ public class Lst_section_nde_tst {
|
||||
@Test public void Basic() {
|
||||
fxt.Test_parse_page_all_str("a<section name=\"b\">c</section>d", "ad");
|
||||
}
|
||||
@Test public void German() { // PURPOSE: non-english tags for section DATE:2014-07-18
|
||||
fxt.Lang_by_id_(Xol_lang_itm_.Id_de);
|
||||
fxt.Test_parse_page_all_str("a<abschnitt name=\"b\">c</abschnitt>d" , "ad"); // check that German works
|
||||
fxt.Test_parse_page_all_str("a<section name=\"b\">c</section>d" , "ad"); // check that English still works
|
||||
fxt.Test_parse_page_all_str("a<trecho name=\"b\">c</trecho>d" , "a<trecho name="b">c</trecho>d"); // check that Portuguese does not work
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class Map_dd2dms_func extends Pf_func_base {
|
||||
switch (((Byte_obj_val)key_tid_obj).Val()) {
|
||||
case Key_tid_plus: plus = val; break;
|
||||
case Key_tid_minus: minus = val; break;
|
||||
case Key_tid_precision: prec = Bry_.X_to_int_or(val, prec); break;
|
||||
case Key_tid_precision: prec = Bry_.Xto_int_or(val, prec); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class Map_deg2dd_func extends Pf_func_base {
|
||||
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {
|
||||
byte[] coord = Eval_argx(ctx, src, caller, self);
|
||||
byte[] precision_bry = Pf_func_.Eval_val_or(ctx, src, caller, self, self.Args_len(), 0, null);
|
||||
int prec = precision_bry == null ? -1 : Bry_.X_to_int_or(precision_bry, -1);
|
||||
int prec = precision_bry == null ? -1 : Bry_.Xto_int_or(precision_bry, -1);
|
||||
Map_math map_math = Map_math._;
|
||||
if (map_math.Ctor(coord, prec, Bry_.Empty, 2))
|
||||
bfr.Add_double(map_math.Coord_dec());
|
||||
|
||||
@@ -39,7 +39,7 @@ public class Map_geolink_func extends Pf_func_base {
|
||||
case Key_tid_lat_neg: mer_x_neg = val; break;
|
||||
case Key_tid_long_pos: mer_y_pos = val; break;
|
||||
case Key_tid_long_min: mer_y_neg = val; break;
|
||||
case Key_tid_prec: prec = Bry_.X_to_int_or(val, prec); break;
|
||||
case Key_tid_prec: prec = Bry_.Xto_int_or(val, prec); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,29 +56,29 @@ public class Map_geolink_func extends Pf_func_base {
|
||||
return;
|
||||
}
|
||||
Object[] args = new Object[6];
|
||||
args[0] = X_to_coord(tmp_bfr, mer_x_math, mer_x_pass, mer_x_math.Coord_dir_ns(), Bry_arg_0_fail);
|
||||
args[1] = X_to_coord(tmp_bfr, mer_y_math, mer_y_pass, mer_y_math.Coord_dir_ew(), Bry_arg_1_fail);
|
||||
args[2] = X_to_dms(mer_x_math, mer_x_pass, mer_x_pos, mer_x_neg);
|
||||
args[3] = X_to_dms(mer_y_math, mer_y_pass, mer_y_pos, mer_y_neg);
|
||||
args[4] = X_to_dec(tmp_bfr, mer_x_math, mer_x_pass);
|
||||
args[5] = X_to_dec(tmp_bfr, mer_y_math, mer_y_pass);
|
||||
args[0] = Xto_coord(tmp_bfr, mer_x_math, mer_x_pass, mer_x_math.Coord_dir_ns(), Bry_arg_0_fail);
|
||||
args[1] = Xto_coord(tmp_bfr, mer_y_math, mer_y_pass, mer_y_math.Coord_dir_ew(), Bry_arg_1_fail);
|
||||
args[2] = Xto_dms(mer_x_math, mer_x_pass, mer_x_pos, mer_x_neg);
|
||||
args[3] = Xto_dms(mer_y_math, mer_y_pass, mer_y_pos, mer_y_neg);
|
||||
args[4] = Xto_dec(tmp_bfr, mer_x_math, mer_x_pass);
|
||||
args[5] = Xto_dec(tmp_bfr, mer_y_math, mer_y_pass);
|
||||
bfr.Add(Xol_msg_itm_.eval_(tmp_bfr, tmp_msg_itm, pattern, args));
|
||||
} finally {tmp_bfr.Mkr_rls();}
|
||||
}
|
||||
private static final Xol_msg_itm tmp_msg_itm = new Xol_msg_itm(-1, Bry_.Empty);
|
||||
private static byte[] X_to_coord(Bry_bfr bfr, Map_math math, boolean pass, byte[] dir, byte[] or) {
|
||||
private static byte[] Xto_coord(Bry_bfr bfr, Map_math math, boolean pass, byte[] dir, byte[] or) {
|
||||
return pass
|
||||
? bfr.Add_double(Math_.Abs_double(math.Dec())).Add_byte(Byte_ascii.Underline).Add(dir).XtoAryAndClear()
|
||||
: or
|
||||
;
|
||||
}
|
||||
private static byte[] X_to_dms(Map_math math, boolean pass, byte[] pos, byte[] neg) {
|
||||
private static byte[] Xto_dms(Map_math math, boolean pass, byte[] pos, byte[] neg) {
|
||||
return pass
|
||||
? math.Get_dms(pos, neg)
|
||||
: Bry_.Empty // mapsources-math-incorrect-input
|
||||
;
|
||||
}
|
||||
private static byte[] X_to_dec(Bry_bfr bfr, Map_math math, boolean pass) {
|
||||
private static byte[] Xto_dec(Bry_bfr bfr, Map_math math, boolean pass) {
|
||||
return pass
|
||||
? bfr.Add_double(math.Dec()).XtoAryAndClear()
|
||||
: Bry_arg_5_fail
|
||||
|
||||
@@ -55,8 +55,8 @@ public class Xof_math_html_wtr {
|
||||
switch (b) {
|
||||
case Byte_ascii.Lt: if (mathjax) escaped = gplx.html.Html_entity_.Lt_bry; break;
|
||||
case Byte_ascii.Gt: if (mathjax) escaped = gplx.html.Html_entity_.Gt_bry; break;
|
||||
case Byte_ascii.Amp: escaped = Const_amp; break;
|
||||
case Byte_ascii.Quote: if (mathjax) escaped = gplx.html.Html_entity_.Quote_bry; break;
|
||||
// case Byte_ascii.Amp: escaped = Const_amp; break; // TOMBSTONE:never escape ampersand; PAGE:s.w:Matrix_(mathematics); DATE:2014-07-19
|
||||
// case Byte_ascii.Quote: if (mathjax) escaped = gplx.html.Html_entity_.Quote_bry; break; // TOMBSTONE:do not escape quote; PAGE:s.w:Matrix_(mathematics); DATE:2014-07-19
|
||||
default:
|
||||
if (dirty || write_to_bfr)
|
||||
bfr.Add_byte(b);
|
||||
@@ -81,5 +81,4 @@ public class Xof_math_html_wtr {
|
||||
else
|
||||
return dirty ? bfr.XtoAryAndClear() : bry;
|
||||
}
|
||||
private static final byte[] Const_amp = Bry_.new_ascii_("\\&");
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class Xof_math_mgr implements GfoInvkAble {
|
||||
return pass;
|
||||
}
|
||||
private String_bldr tmp_sb = String_bldr_.new_();
|
||||
private String Latex_wrap(byte[] math) {return Latex_doc_fmtr.Bld_str_many(String_.Replace(String_.new_utf8_(math), "\n\n", "\n"));} // NOTE: remove lines that are completely blank; not sure if this is right; EX.WP: Standard Model (mathematical formulation); <math>(\mathbf{1},\mathbf\n\n{1},0)</math>
|
||||
private String Latex_wrap(byte[] math) {return Latex_doc_fmtr.Bld_str_many(String_.Replace(String_.new_utf8_(math), "\n\n", "\n"));} // NOTE: remove lines that are completely blank; not sure if this is right; PAGE:en.w:Standard Model (mathematical formulation); <math>(\mathbf{1},\mathbf\n\n{1},0)</math>
|
||||
private static Bry_fmtr Latex_doc_fmtr = new Bry_fmtr()
|
||||
.Fmt_(String_.Concat_lines_nl_skip_last
|
||||
( "\\documentclass{article}"
|
||||
@@ -92,7 +92,7 @@ public class Xof_math_mgr implements GfoInvkAble {
|
||||
));
|
||||
public boolean Enabled() {return enabled;} public Xof_math_mgr Enabled_(boolean v) {enabled = v; return this;} private boolean enabled = true;
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_enabled)) return Yn.X_to_str(enabled);
|
||||
if (ctx.Match(k, Invk_enabled)) return Yn.Xto_str(enabled);
|
||||
else if (ctx.Match(k, Invk_enabled_)) enabled = m.ReadYn("v");
|
||||
else if (ctx.Match(k, Invk_renderer)) return renderer_is_mathjax ? "mathjax" : "latex";
|
||||
else if (ctx.Match(k, Invk_renderer_)) renderer_is_mathjax = String_.Eq(m.ReadStr("v"), "mathjax");
|
||||
|
||||
@@ -19,12 +19,18 @@ package gplx.xowa.xtns.math; import gplx.*; import gplx.xowa.*; import gplx.xowa
|
||||
import org.junit.*;
|
||||
public class Xof_math_mgr_html_tst {
|
||||
@Before public void init() {} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Escape_mathjax() { // PURPOSE: escape <>&"; EX:de.w:Vergleich_(Zahlen); DATE:2014-05-10
|
||||
fxt.Test_html_full_str("<math>a<>&\"b</math>", "<span id='xowa_math_txt_0'>a<>\\&"b</span>");
|
||||
@Test public void Escape_lt_gt_mathjax() { // PURPOSE: escape <>&"; EX:de.w:Vergleich_(Zahlen); DATE:2014-05-10; PAGE:s.w:Matrix_(mathematics) DATE:2014-07-19
|
||||
fxt.Test_html_full_str("<math>a<>b</math>", "<span id='xowa_math_txt_0'>a<>b</span>");
|
||||
}
|
||||
@Test public void Escape_latex() {
|
||||
@Test public void Escape_lt_gt_latex() {
|
||||
fxt.App().File_mgr().Math_mgr().Renderer_is_mathjax_(false);
|
||||
fxt.Test_html_full_str("<math>a<>&\"b</math>", "<img id='xowa_math_img_0' src='' width='' height=''/><span id='xowa_math_txt_0'>a<>\\&\"b</span>");
|
||||
fxt.Test_html_full_str("<math>a<>b</math>", "<img id='xowa_math_img_0' src='' width='' height=''/><span id='xowa_math_txt_0'>a<>b</span>");
|
||||
fxt.App().File_mgr().Math_mgr().Renderer_is_mathjax_(true);
|
||||
}
|
||||
@Test public void Amp() { // PURPOSE: assert that amp is not escaped; DATE:2014-07-20
|
||||
fxt.Test_html_full_str("<math>a&b</math>", "<span id='xowa_math_txt_0'>a&b</span>");
|
||||
}
|
||||
@Test public void Quote() { // PURPOSE: assert that quote is not escaped; DATE:2014-07-20
|
||||
fxt.Test_html_full_str("<math>a\"b</math>", "<span id='xowa_math_txt_0'>a\"b</span>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public class Xof_math_mgr_tst {
|
||||
@Before public void init() {} Xof_math_subst_regy subst_regy = new Xof_math_subst_regy().Init();
|
||||
@Test public void Basic() {tst("a\\plusmn b" , "a\\pm b");}
|
||||
@Test public void Match_fails() {tst("a\\plusmna b" , "a\\plusmna b");}
|
||||
@Test public void Part() {tst("a\\part_t b" , "a\\partial_t b");} // EX.WP: Faraday's law of induction
|
||||
@Test public void Part() {tst("a\\part_t b" , "a\\partial_t b");} // PAGE:en.w:Faraday's law of induction
|
||||
@Test public void Partial() {tst("a\\partial_{x_i}" , "a\\partial_{x_i}");} // DEFECT: partial -> partialial
|
||||
private void tst(String src, String expd) {Tfds.Eq(expd, String_.new_utf8_(subst_regy.Subst(Bry_.new_utf8_(src))));}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ public class Pfunc_expr_tst {
|
||||
@Test public void Atan() {fxt.Test_parse_tmpl_str_test("{{#expr:atan(0)}}" , "{{test}}" , "0");}
|
||||
@Test public void Round() {fxt.Test_parse_tmpl_str_test("{{#expr:1.5 round 0}}" , "{{test}}" , "2");}
|
||||
@Test public void Round_0() {fxt.Test_parse_tmpl_str_test("{{#expr:0 round 1}}" , "{{test}}" , "0");} // PURPOSE: 0 round 1 should be 0, not 0.0; DATE:2013-11-09
|
||||
@Test public void Round_ex_1() {fxt.Test_parse_tmpl_str_test("{{#expr:(0.03937007874015)round(3)}}" , "{{test}}" , "0.039");} // PURPOSE: rounding results in excessive decimal places; EX.WP:Milky Way (light year conversions)
|
||||
@Test public void Round_ex_1() {fxt.Test_parse_tmpl_str_test("{{#expr:(0.03937007874015)round(3)}}" , "{{test}}" , "0.039");} // PURPOSE: rounding results in excessive decimal places; PAGE:en.w:Milky Way (light year conversions)
|
||||
@Test public void Mod_frac() {fxt.Test_parse_tmpl_str_test("{{#expr:0.00999999mod10}}" , "{{test}}" , "0");}
|
||||
@Test public void Mod_large() {fxt.Test_parse_tmpl_str_test("{{#expr:39052000900mod100}}" , "{{test}}" , "0");} // PURPOSE: JAVA was failing in converting to int and converted to Int_.MaxValue instead; DATE:2013-01-26
|
||||
@Test public void Fmod() {fxt.Test_parse_tmpl_str_test("{{#expr:1.25 fmod .5}}" , "{{test}}" , "0.25");}
|
||||
@@ -86,10 +86,10 @@ public class Pfunc_expr_tst {
|
||||
@Test public void Esc_xml_entRef() {fxt.Test_parse_tmpl_str_test("{{#expr:−1 < 5}}" , "{{test}}" , "1");}
|
||||
@Test public void Ex_1() {fxt.Test_parse_tmpl_str_test("{{#expr:1e2round0}}" , "{{test}}" , "100");} // PURPOSE: used in Convert
|
||||
@Test public void Floating() {fxt.Test_parse_tmpl_str_test("{{#expr:27.321582}}" , "{{test}}" , "27.321582");}
|
||||
@Test public void Floating_2() {fxt.Test_parse_tmpl_str_test("{{#expr:0.1*41}}" , "{{test}}" , "4.1");} // PURPOSE: division results in expanded floating-point; EX.WP:Wikipedia
|
||||
@Test public void Floating_3() {fxt.Test_parse_tmpl_str_test("{{#expr:111/10^(-1)}}" , "{{test}}" , "1110");} // PURPOSE: division by pow; EX.WP:Wikipedia:Featured articles
|
||||
@Test public void Floating_2() {fxt.Test_parse_tmpl_str_test("{{#expr:0.1*41}}" , "{{test}}" , "4.1");} // PURPOSE: division results in expanded floating-point; PAGE:en.w:Wikipedia
|
||||
@Test public void Floating_3() {fxt.Test_parse_tmpl_str_test("{{#expr:111/10^(-1)}}" , "{{test}}" , "1110");} // PURPOSE: division by pow; PAGE:en.w:Wikipedia:Featured articles
|
||||
@Test public void Floating_4() {fxt.Test_parse_tmpl_str_test("{{#expr:abs(-73.9023)}}" , "{{test}}" , "73.9023");} // PURPOSE: Abs;
|
||||
@Test public void Unicode_8722() {fxt.Test_parse_tmpl_str_test("{{#expr:2−1}}" , "{{test}}" , "1");} // PURPOSE: handle alternate minus; EX.WP: Australian krill
|
||||
@Test public void Unicode_8722() {fxt.Test_parse_tmpl_str_test("{{#expr:2−1}}" , "{{test}}" , "1");} // PURPOSE: handle alternate minus; PAGE:en.w:Australian krill
|
||||
@Test public void Exp_large_neg() {fxt.Test_parse_tmpl_str_test("{{#expr:418400000000000000000000E-23}}" , "{{test}}" , "4.184");} // PURPOSE: handle large neg; EX: w:Chicxulub_crater; {{convert|100|TtonTNT|J|lk=on}}
|
||||
@Test public void Exp_large_neg2() {fxt.Test_parse_tmpl_str_test("{{#expr:210000000000000000E-17}}" , "{{test}}" , "2.1");} // PURPOSE: handle large neg2; EX: w:Chicxulub_crater; {{convert|50|MtonTNT|J|lk=on}}
|
||||
@Test public void Fix_transclusion() {fxt.Test_parse_tmpl_str_test("{{#expr:{{#if:||1}}/.2}}" , "{{test}}" , "5");} // PURPOSE: /. was invoking transclusion; DATE:2013-04-26
|
||||
|
||||
@@ -37,12 +37,12 @@ public class Pfunc_ifeq_tst {
|
||||
@Test public void Ifeq_exc_args_1() {fxt.Test_parse_tmpl_str_test("{{#ifeq:1|1}}" , "{{test}}" , "");}
|
||||
@Test public void Ifeq_exc_args_2() {fxt.Test_parse_tmpl_str_test("{{#ifeq:1|1|a}}" , "{{test}}" , "a");}
|
||||
@Test public void Ifeq_exp() {fxt.Test_parse_tmpl_str_test("{{#ifeq:0.006|+6.0E-3|y|n}}" , "{{test}}" , "y");}
|
||||
@Test public void Ifeq_plus_minus() {fxt.Test_parse_tmpl_str_test("{{#ifeq:+|-|y}}" , "{{test}}" , "");} // PURPOSE: was evaluating to y; EX.WP:Permian-Triassic extinction
|
||||
@Test public void Tab_ent() { // PURPOSE: hack; tabs are materialized as "	" which causes trimming problems; EX.WP: Template:Cretaceous_graphical_timeline and "|period11= Campanian\s\t"
|
||||
@Test public void Ifeq_plus_minus() {fxt.Test_parse_tmpl_str_test("{{#ifeq:+|-|y}}" , "{{test}}" , "");} // PURPOSE: was evaluating to y; PAGE:en.w:Permian-Triassic extinction
|
||||
@Test public void Tab_ent() { // PURPOSE: hack; tabs are materialized as "	" which causes trimming problems; PAGE:en.w:Template:Cretaceous_graphical_timeline and "|period11= Campanian\s\t"
|
||||
fxt.Test_parse_page_all_str("{{#ifeq:a|a 	|y|n}}", "y"); // note that "|a\s\t" gets trimmed to "a"
|
||||
}
|
||||
@Test public void Ifeq_hex() {fxt.Test_parse_tmpl_str_test("{{#ifeq:44|0X002C|y|n}}" , "{{test}}" , "y");} // PURPOSE: hex compares to int; EX:w:Comma
|
||||
@Test public void Colon_2() { // PURPOSE: 2nd colon causes error b/c of bad whitespace evaluation; EX.WP:de.wiktionary.org/wiki/glitschig; DATE:2013-12-10
|
||||
@Test public void Colon_2() { // PURPOSE: 2nd colon causes error b/c of bad whitespace evaluation; PAGE:en.w:de.wiktionary.org/wiki/glitschig; DATE:2013-12-10
|
||||
fxt.Test_parse_tmpl_str_test("{{#ifeq: :|a|b|c}}" , "{{test}}" , "c");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,14 +30,14 @@ public class Pfunc_ifexist_mgr {
|
||||
regy.Add(ttl_bry, exists_itm);
|
||||
db_page.Clear();
|
||||
Xow_ns ttl_ns = ttl.Ns();
|
||||
boolean rv = false;
|
||||
switch (ttl_ns.Id()) {
|
||||
case Xow_ns_.Id_special:
|
||||
wiki.App().Usr_dlg().Warn_many("", "", "ifexist.special ns page; page=~{0} ifexist=~{1}", wiki.Ctx().Cur_page().Url().Xto_full_str_safe(), String_.new_utf8_(raw_bry));
|
||||
exists_itm.Exists_(true);
|
||||
return true;
|
||||
case Xow_ns_.Id_media: return Find_ttl_for_media_ns(exists_itm, wiki, ttl_ns, ttl_bry);
|
||||
default: return Find_ttl_in_db(exists_itm, wiki, ttl_ns, ttl_bry);
|
||||
case Xow_ns_.Id_special: rv = true; break; // NOTE: some pages call for [[Special]]; always return true for now; DATE:2014-07-17
|
||||
case Xow_ns_.Id_media: rv = Find_ttl_for_media_ns(exists_itm, wiki, ttl_ns, ttl_bry); break;
|
||||
default: rv = Find_ttl_in_db(exists_itm, wiki, ttl_ns, ttl_bry); break;
|
||||
}
|
||||
exists_itm.Exists_(rv);
|
||||
return rv;
|
||||
}
|
||||
private boolean Find_ttl_in_db(Pfunc_ifexist_itm itm, Xow_wiki wiki, Xow_ns ns, byte[] ttl_bry) {
|
||||
boolean rv = wiki.Db_mgr().Load_mgr().Load_by_ttl(db_page, ns, ttl_bry);
|
||||
|
||||
31
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_grammar.java
Normal file
31
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_grammar.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
public class Pfunc_grammar extends Pf_func_base {
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_i18n_grammar;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_grammar().Name_(name);}
|
||||
@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);
|
||||
byte[] word = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self.Args_len(), 0);
|
||||
Xol_lang lang = ctx.Cur_page().Lang();
|
||||
boolean pass = false;
|
||||
try {pass = lang.Grammar().Grammar_eval(bfr, lang, word, argx);}
|
||||
catch (Exception e) {Err_.Noop(e);}
|
||||
if (!pass) Xot_invk_tkn.Print_not_found(bfr, ctx.Wiki().Ns_mgr(), this.Name());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_grammar_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void English() {// for now, mark unimplemented langs by returning not_found; [[Template:grammar]]; wait for users to report
|
||||
fxt.Test_parse_tmpl_str_test("{{grammar:a|b}}" , "{{test}}" , "[[:Template:grammar]]");
|
||||
}
|
||||
@Test public void Finnish() {
|
||||
fxt.Lang_by_id_(Xol_lang_itm_.Id_fi);
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:elative|Wikiuutiset}}" , "{{test}}" , "Wikiuutisista");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:talo}}" , "{{test}}" , "");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|talo}}" , "{{test}}" , "talon");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:elative|talo}}" , "{{test}}" , "talosta");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:inessive|talo}}" , "{{test}}" , "talossa");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:partitive|talo}}" , "{{test}}" , "taloa");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:illative|talo}}" , "{{test}}" , "taloon");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|sängy}}" , "{{test}}" , "sängyn");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:elative|sängy}}" , "{{test}}" , "sängystä");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:inessive|sängy}}" , "{{test}}" , "sängyssä");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:partitive|sängy}}" , "{{test}}" , "sängyä");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:illative|sängy}}" , "{{test}}" , "sängyyn");
|
||||
}
|
||||
@Test public void Russian() {
|
||||
fxt.Lang_by_id_(Xol_lang_itm_.Id_ru);
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:unknown}}" , "{{test}}" , "");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aвики}}" , "{{test}}" , "aвики");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aВики}}" , "{{test}}" , "aВики");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aь}}" , "{{test}}" , "aя");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aия}}" , "{{test}}" , "aии");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aка}}" , "{{test}}" , "aки");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aти}}" , "{{test}}" , "aтей");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aды}}" , "{{test}}" , "aдов");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:genitive|aник}}" , "{{test}}" , "aника");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:dative|a}}" , "{{test}}" , "a");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:accusative|a}}" , "{{test}}" , "a");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:instrumental|a}}" , "{{test}}" , "a");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{grammar:prepositional|a}}" , "{{test}}" , "a");
|
||||
}
|
||||
}
|
||||
56
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_i18n_tst.java
Normal file
56
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_i18n_tst.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_i18n_tst {
|
||||
@Before public void init() {fxt.Clear();} private Pfunc_i18n_fxt fxt = new Pfunc_i18n_fxt();
|
||||
@Test public void Casing() {fxt.lang_("de").Ini().Reg_func("fullurl", false, "VOLLSTÄNDIGE_URL").Load().Fxt().Test_parse_tmpl_str_test("{{vollstÄndige_url:a}}", "{{test}}" , "//de.wikipedia.org/wiki/A");}
|
||||
@Test public void Time() {fxt.lang_("de").Ini().Reg_msg("march", "März").Load().Fxt().Test_parse_tmpl_str_test("{{#time: d F Y|1 Mar 2013}}", "{{test}}" , "01 März 2013");}
|
||||
}
|
||||
class Pfunc_i18n_fxt {
|
||||
public void Clear() {}
|
||||
public Xop_fxt Fxt() {return fxt;}
|
||||
public Pfunc_i18n_fxt lang_(String v) {lang_key = v; return this;} private String lang_key;
|
||||
public Pfunc_i18n_fxt Ini() {
|
||||
if (app == null) app = Xoa_app_fxt.app_();
|
||||
app.Lang_mgr().Clear(); // else lang values retained from last run
|
||||
app.Free_mem(false); // else tmpl_result_cache will get reused from last run for {{test}}
|
||||
lang = app.Lang_mgr().Get_by_key_or_new(Bry_.new_ascii_(lang_key));
|
||||
wiki = Xoa_app_fxt.wiki_(app, lang_key + ".wikipedia.org", lang);
|
||||
fxt = new Xop_fxt(app, wiki);
|
||||
return this;
|
||||
} private Xoa_app app; private Xop_fxt fxt; Xol_lang lang; Xow_wiki wiki;
|
||||
public Pfunc_i18n_fxt Reg_func(String name, boolean case_match, String word) {
|
||||
Io_url url = Io_url_.mem_fil_("mem/xowa/user/test_user/lang/xowa/" + lang_key + ".gfs");
|
||||
String func = "keywords.load_text('" + name + "|" + (case_match ? "1" : "0") + "|" + name + "~" + word + "~');";
|
||||
Io_mgr._.SaveFilStr(url, func);
|
||||
return this;
|
||||
}
|
||||
public Pfunc_i18n_fxt Reg_msg(String key, String val) {
|
||||
Io_url url = Io_url_.mem_fil_("mem/xowa/user/test_user/lang/xowa/" + lang_key + ".gfs");
|
||||
String func = "messages.load_text('" + key + "|" + val + "');";
|
||||
Io_mgr._.SaveFilStr(url, func);
|
||||
return this;
|
||||
}
|
||||
public Pfunc_i18n_fxt Load() {
|
||||
lang.Init_by_load();
|
||||
wiki.Fragment_mgr().Evt_lang_changed(lang);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
38
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_int.java
Normal file
38
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_int.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import gplx.php.*; import gplx.xowa.langs.msgs.*;
|
||||
public class Pfunc_int extends Pf_func_base {
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_i18n_int;}
|
||||
@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[] msg_key = Eval_argx(ctx, src, caller, self);
|
||||
Xow_wiki wiki = ctx.Wiki();
|
||||
Xol_lang page_lang = ctx.Cur_page().Lang();
|
||||
byte[][] args_ary = Bry_.Ary_empty;
|
||||
int args_len = self.Args_len();
|
||||
if (args_len > 0) {
|
||||
args_ary = new byte[args_len][];
|
||||
for (int i = 0; i < args_len; i++)
|
||||
args_ary[i] = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self.Args_len(), i);
|
||||
}
|
||||
byte[] msg_val = Xol_msg_mgr_.Get_msg_val(wiki, page_lang, msg_key, args_ary);
|
||||
bfr.Add(msg_val);
|
||||
}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_int().Name_(name);}
|
||||
}
|
||||
112
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_int_tst.java
Normal file
112
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_int_tst.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_int_tst {
|
||||
@Before public void init() {fxt.Reset();} private Pf_msg_mgr_fxt fxt = new Pf_msg_mgr_fxt();
|
||||
@Test public void Basic() {fxt.Test_parse_en("{{int:january}}" , "January");}
|
||||
@Test public void Upper() {fxt.Test_parse_en("{{int:JANUARY}}" , "January");}
|
||||
@Test public void Unknown() {fxt.Test_parse_en("{{int:unknown_msg}}" , "<unknown_msg>");}
|
||||
@Test public void Fmt() {fxt.Test_parse_en("{{int:pfunc_expr_unrecognised_word|1a}}" , "Expression error: Unrecognised word \"1a\"");}
|
||||
@Test public void Tmpl_txt() {
|
||||
fxt.Init_msg_gfs("tst_msg", "{{#expr:1}}", false, true);
|
||||
fxt.Test_parse_en("{{int:tst_msg}}", "1");
|
||||
}
|
||||
@Test public void Lang_current_defaults_to_en() { // PURPOSE: specifying same language as current returns same; ie: int:january/en -> int:january
|
||||
fxt.Test_parse_en("{{int:january/en}}", "January");
|
||||
}
|
||||
@Test public void Lang_specified_by_page() {
|
||||
fxt.Test_parse_lang("fr", "{{int:Lang}}", "fr"); // NOTE: "Lang" msg is added by Xol_lang; message_mgr.Itm_by_key_or_new(Bry_.new_utf8_("Lang")).Atrs_set(key_bry, false, false);
|
||||
}
|
||||
@Test public void Lang_missing_msg_return_en() { // PURPOSE: if key does not exist in non-english language, use English; EX: la.w:Fasciculus:HannibalFrescoCapitolinec1510.jpg; DATE:2013-09-10
|
||||
fxt.Init_msg_gfs("en_only_key", "en_only_val", false, false);
|
||||
fxt.Test_parse_lang("fr", "{{int:en_only_key}}", "en_only_val");
|
||||
}
|
||||
@Test public void Err_fmt_failed() { // PURPOSE: if no args passed to msg, return "$1", not "~{0}"
|
||||
fxt.Init_msg_gfs("tst_msg", "a~{0}b", true, false);
|
||||
fxt.Test_parse_en("{{int:tst_msg}}" , "a$1b");
|
||||
}
|
||||
@Test public void Mediawiki_overrides_gfs() {
|
||||
fxt.Init_msg_gfs("mw_overrides", "gfs", false, false);
|
||||
fxt.Init_msg_db("mw_overrides", "mw");
|
||||
fxt.Test_parse_en("{{int:mw_overrides}}", "mw");
|
||||
}
|
||||
@Test public void Convert_php() {
|
||||
fxt.Init_msg_db("convert_php", "a\\\\b\\$c$1e");
|
||||
fxt.Test_parse_en("{{int:convert_php|d}}", "a\\b$cde");
|
||||
}
|
||||
@Test public void Convert_php_tilde() { // PURPOSE: tildes should be escaped, else will fail inside ByteAryBfrFmtr; DATE:2013-11-11
|
||||
fxt.Init_msg_db("convert_php_tilde", "$1~u");
|
||||
fxt.Test_parse_en("{{int:convert_php_tilde|a}}", "a~u");
|
||||
}
|
||||
@Test public void Unknown_val_returns_en() { // PURPOSE: if no "january" in "fr.gfs" and no "january/fr" in mw, use january in "en.gfs"; EX:none
|
||||
fxt.Test_parse_lang("fr", "{{int:january/fr}}", "January");
|
||||
}
|
||||
@Test public void Unknown_lang_returns_en() { // PURPOSE: unknown lang default to english; EX:none; DATE:2014-05-09
|
||||
fxt.Test_parse_en("{{int:january/unknown}}", "January");
|
||||
}
|
||||
@Test public void Transclude_mw_do_not_strip_lang() { // PURPOSE: if /lang matches wiki.lang, do not strip it, else stack overflow; EX:pl.d:Wikislownik:Bar/Archiwum_6; newarticletext/pl; DATE:2014-05-13
|
||||
fxt.Init_msg_db("january/en", "January_en");
|
||||
fxt.Test_parse_en("{{MediaWiki:january/en}}", "January_en");
|
||||
}
|
||||
@Test public void Transclude_gfs() { // PURPOSE: transclusion of {{MediaWiki}} pages should call {{int}} instead; EX:zh.w:Main_Page; DATE:2014-05-09
|
||||
fxt.Test_parse_en("{{MediaWiki:january/en}}", "January"); // NOTE: no page exists called "MediaWiki:january/en", but returns "{{int:january/en}}" value
|
||||
}
|
||||
@Test public void Create_msg_in_wiki_not_lang() { // PURPOSE: if two wikis share same language and msg is missing from one, do not mark it missing in the other; EX: home/wiki/Main_Page and en.w:Main_Page; DATE:2014-05-13
|
||||
Xow_wiki enwiktionary = fxt.Make_wiki("en.wiktionary.org");
|
||||
fxt.Init_msg_db(enwiktionary, "wiki_only_msg", "enwiktionary_msg");
|
||||
fxt.Init_msg_gfs("wiki_only_msg", "en_gfs_msg", false, false);
|
||||
fxt.Test_parse_en("{{int:wiki_only_msg}}", "en_gfs_msg");
|
||||
fxt.Test_parse_wiki(enwiktionary, "{{int:wiki_only_msg}}", "enwiktionary_msg");
|
||||
}
|
||||
}
|
||||
class Pf_msg_mgr_fxt {
|
||||
private Xop_fxt fxt;
|
||||
private Xol_lang en_lang;
|
||||
private Xow_wiki en_wiki;
|
||||
public void Reset() {
|
||||
fxt = new Xop_fxt(); // new fxt, else transclude tests will fail
|
||||
en_wiki = fxt.Wiki();
|
||||
en_lang = en_wiki.Lang();
|
||||
}
|
||||
public void Init_msg_gfs(String key, String val, boolean fmt, boolean tmpl) {Init_msg_gfs(en_lang, key, val, fmt, tmpl);}
|
||||
public void Init_msg_gfs(Xol_lang lang, String key, String val, boolean fmt, boolean tmpl) {
|
||||
Xol_msg_itm msg_itm = lang.Msg_mgr().Itm_by_key_or_new(Bry_.new_utf8_(key));
|
||||
msg_itm.Atrs_set(Bry_.new_utf8_(val), fmt, tmpl);
|
||||
}
|
||||
public void Init_msg_db(String ttl, String val) {Init_msg_db(en_wiki, ttl, val);}
|
||||
public void Init_msg_db(Xow_wiki wiki, String ttl, String val) {
|
||||
fxt.Init_page_create(wiki, "MediaWiki:" + ttl, val);
|
||||
}
|
||||
public Xow_wiki Make_wiki(String domain) {return fxt.App().Wiki_mgr().Get_by_key_or_make(Bry_.new_utf8_(domain));}
|
||||
public void Test_parse_en(String raw, String expd) {
|
||||
fxt.Test_parse_tmpl_str_test(raw, "{{test}}" , expd);
|
||||
}
|
||||
public void Test_parse_wiki(Xow_wiki alt_wiki, String raw, String expd) {
|
||||
Xop_fxt alt_fxt = new Xop_fxt(fxt.App(), alt_wiki);
|
||||
alt_fxt.Test_parse_tmpl_str_test(raw, "{{test}}" , expd);
|
||||
}
|
||||
public void Test_parse_lang(String other_lang_id, String raw, String expd) {
|
||||
Xol_lang other_lang = fxt.App().Lang_mgr().Get_by_key_or_new(Bry_.new_ascii_(other_lang_id));
|
||||
other_lang.Init_by_load();
|
||||
fxt.Page().Lang_(other_lang);
|
||||
fxt.Test_parse_tmpl_str_test(raw, "{{test}}", expd);
|
||||
fxt.Page().Lang_(en_lang); // NOTE: must reset back to en_lang, else rest of tests will look up under fr
|
||||
}
|
||||
}
|
||||
|
||||
34
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_language.java
Normal file
34
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_language.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
public class Pfunc_language extends Pf_func_base {
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_i18n_language;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_language().Name_(name);}
|
||||
@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);
|
||||
Hash_adp_bry regy = Xol_lang_itm_.Regy();
|
||||
if (argx.length == 0) return; // {{#language:}} should return ""; note that byte[0] will fail in Match_exact
|
||||
Object o = regy.Get_by_bry(argx);
|
||||
if (o == null)
|
||||
bfr.Add(argx);
|
||||
else {
|
||||
Xol_lang_itm lang_itm = (Xol_lang_itm)o;
|
||||
bfr.Add(lang_itm.Canonical_name());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_language_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void English() {fxt.Test_parse_tmpl_str_test("{{#language:en}}" , "{{test}}" , "English");}
|
||||
@Test public void English_case() {fxt.Test_parse_tmpl_str_test("{{#language:eN}}" , "{{test}}" , "English");}
|
||||
@Test public void Arabic() {fxt.Test_parse_tmpl_str_test("{{#language:ar}}" , "{{test}}" , "العربية");}
|
||||
@Test public void Unknown() {fxt.Test_parse_tmpl_str_test("{{#language:unknown}}" , "{{test}}" , "unknown");}
|
||||
@Test public void Foreign() {fxt.Test_parse_tmpl_str_test("{{#language:anp}}" , "{{test}}" , "अङ्गिका");}
|
||||
@Test public void Foreign_2() {fxt.Test_parse_tmpl_str_test("{{#language:no}}" , "{{test}}" , "Norsk (bokmål)");} // PURPOSE: Names.php have bookend "pipes" (\xE2\x80\xAA)
|
||||
@Test public void Empty() {fxt.Test_parse_tmpl_str_test("{{#language:}}" , "{{test}}" , "");}
|
||||
}
|
||||
31
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_plural.java
Normal file
31
400_xowa/src/gplx/xowa/xtns/pfuncs/langs/Pfunc_plural.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
public class Pfunc_plural extends Pf_func_base {
|
||||
@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) {// REF.MW: CoreParserFunctions.php
|
||||
byte[] number = Eval_argx(ctx, src, caller, self);
|
||||
int self_args_len = self.Args_len();
|
||||
int arg_idx = Pf_func_.Eq_(number, Ary_Num_1) ? 0 : 1;
|
||||
if (arg_idx == 1 && self_args_len == 1) arg_idx = 0; // number is plural, but plural_arg not present; use singular; see test
|
||||
byte[] word = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, arg_idx);
|
||||
bfr.Add(word);
|
||||
} static final byte[] Ary_Num_1 = new byte[] {Byte_ascii.Num_1};
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_i18n_plural;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_plural().Name_(name);}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.pfuncs.langs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_plural_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Singular() {fxt.Test_parse_tmpl_str_test("{{plural:1|wiki|wikis}}" , "{{test}}" , "wiki");}
|
||||
@Test public void Plural() {fxt.Test_parse_tmpl_str_test("{{plural:2|wiki|wikis}}" , "{{test}}" , "wikis");}
|
||||
@Test public void Plural_but_one_arg() {fxt.Test_parse_tmpl_str_test("{{plural:2|wiki}}" , "{{test}}" , "wiki");}
|
||||
@Test public void Null() {fxt.Test_parse_tmpl_str_test("{{plural:|wiki|wikis}}" , "{{test}}" , "wikis");}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import org.junit.*;
|
||||
import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.lib.*;
|
||||
public class Pfunc_scrib_lib_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = new Pfunc_scrib_lib();
|
||||
lib.Init();
|
||||
lib.Core_(fxt.Core());
|
||||
|
||||
39
400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_case.java
Normal file
39
400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_case.java
Normal 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.strings; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
public class Pfunc_case extends Pf_func_base { // EX: {{lc:A}} -> a
|
||||
private boolean first; private int case_type;
|
||||
public Pfunc_case(int case_type, boolean first) {this.case_type = case_type; this.first = first;}
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_str_lc;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_case(case_type, first).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 trg) {
|
||||
byte[] val_dat_ary = Eval_argx(ctx, src, caller, self); if (val_dat_ary == Bry_.Empty) return;
|
||||
int val_dat_ary_len = val_dat_ary.length; if (val_dat_ary_len == 0) return; // nothing to uc / lc; just return
|
||||
Xol_lang lang = ctx.Wiki().Lang();
|
||||
boolean upper = case_type == Xol_lang.Tid_upper;
|
||||
if (first) {
|
||||
Bry_bfr tmp_bfr = ctx.App().Utl_bry_bfr_mkr().Get_b512();
|
||||
val_dat_ary = lang.Case_mgr().Case_build_1st(tmp_bfr, upper, val_dat_ary, 0, val_dat_ary_len);
|
||||
tmp_bfr.Mkr_rls();
|
||||
}
|
||||
else
|
||||
val_dat_ary = lang.Case_mgr().Case_build(upper, val_dat_ary, 0, val_dat_ary_len);
|
||||
trg.Add(val_dat_ary);
|
||||
}
|
||||
}
|
||||
@@ -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.*;
|
||||
import gplx.xowa.langs.cases.*;
|
||||
public class Pfunc_case_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Lc() {fxt.Test_parse_tmpl_str_test("{{lc:ABC}}" , "{{test}}", "abc");}
|
||||
@Test public void Lc_first() {fxt.Test_parse_tmpl_str_test("{{lcfirst:ABC}}" , "{{test}}", "aBC");}
|
||||
@Test public void Uc() {fxt.Test_parse_tmpl_str_test("{{uc:abc}}" , "{{test}}", "ABC");}
|
||||
@Test public void Uc_first() {fxt.Test_parse_tmpl_str_test("{{ucfirst:abc}}" , "{{test}}", "Abc");}
|
||||
@Test public void Multi_byte() {// NOTE: separate test b/c will sometimes fail in suite
|
||||
fxt.Wiki().Lang().Case_mgr_utf8_();
|
||||
fxt.Test_parse_tmpl_str_test("{{uc:ĉ}}" , "{{test}}", "Ĉ"); // upper all
|
||||
}
|
||||
@Test public void Multi_byte_asymmetric() {
|
||||
fxt.Wiki().Lang().Case_mgr_utf8_();
|
||||
fxt.Test_parse_tmpl_str_test("{{uc:ⱥ}}" , "{{test}}", "Ⱥ"); // handle multi-byte asymmetry (lc is 3 bytes; uc is 2 bytes)
|
||||
}
|
||||
@Test public void Multi_byte_first() {
|
||||
fxt.Wiki().Lang().Case_mgr_utf8_();
|
||||
fxt.Test_parse_tmpl_str_test("{{ucfirst:провинция}}" , "{{test}}", "Провинция"); // upper first; DATE:2014-02-04
|
||||
}
|
||||
}
|
||||
60
400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_pad.java
Normal file
60
400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_pad.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
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.*;
|
||||
public class Pfunc_pad extends Pf_func_base {
|
||||
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {// REF.MW: CoreParserFunctions.php|pad
|
||||
int self_args_len = self.Args_len();
|
||||
byte[] val = Eval_argx(ctx, src, caller, self);
|
||||
int val_len = val.length;
|
||||
|
||||
byte[] pad_len = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0);
|
||||
int pad_len_int = Bry_.Xto_int_or(pad_len, 0, pad_len.length, -1);
|
||||
if (pad_len_int == -1) {bfr.Add(val); return;}// NOTE: if pad_len is non-int, add val and exit silently; EX: {{padleft: a|bad|0}}
|
||||
if (pad_len_int > 500) pad_len_int = 500; // MW: force to be <= 500
|
||||
|
||||
byte[] pad_str = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 1, Ary_pad_dflt);
|
||||
int pad_str_len = pad_str.length;
|
||||
if (pad_str_len == 0) {bfr.Add(val); return;}// NOTE: pad_str is entirely empty or whitespace; add val and return; SEE:NOTE_1
|
||||
|
||||
int pad_idx = 0;
|
||||
if (pad_dir_right) bfr.Add(val);
|
||||
for (int val_idx = val_len; val_idx < pad_len_int; val_idx++) {
|
||||
byte b = pad_str[pad_idx];
|
||||
int b_len = gplx.intl.Utf8_.Len_of_char_by_1st_byte(b);
|
||||
if (b_len == 1)
|
||||
bfr.Add_byte(b);
|
||||
else
|
||||
bfr.Add_mid(pad_str, pad_idx, pad_idx + b_len);
|
||||
pad_idx += b_len;
|
||||
if (pad_idx >= pad_str_len) pad_idx = 0;
|
||||
}
|
||||
if (!pad_dir_right) bfr.Add(val);
|
||||
}
|
||||
boolean pad_dir_right; static final byte[] Ary_pad_dflt = Bry_.new_ascii_("0");
|
||||
public Pfunc_pad(int id, boolean pad_dir_right) {this.id = id; this.pad_dir_right = pad_dir_right;}
|
||||
@Override public int Id() {return id;} private int id;
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_pad(id, pad_dir_right).Name_(name);}
|
||||
}
|
||||
/*
|
||||
NOTE_1
|
||||
difference between following:
|
||||
- {{padleft:a|4}} -> 000a
|
||||
Pad_arg omitted: default to 0
|
||||
- {{padleft:a|4| \n\t}} -> a
|
||||
Pad_arg specified, but empty: add val only
|
||||
*/
|
||||
@@ -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.strings; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_pad_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void L_len_3() {fxt.Test_parse_tmpl_str_test("{{padleft: a|4|0}}" , "{{test}}" , "000a");}
|
||||
@Test public void L_str_ab() {fxt.Test_parse_tmpl_str_test("{{padleft: a|4|01}}" , "{{test}}" , "010a");}
|
||||
@Test public void L_len_neg1() {fxt.Test_parse_tmpl_str_test("{{padleft: a|-1|01}}" , "{{test}}" , "a");}
|
||||
@Test public void L_val_null() {fxt.Test_parse_tmpl_str_test("{{padleft: |4|0}}" , "{{test}}" , "0000");}
|
||||
@Test public void L_word_3() {fxt.Test_parse_tmpl_str_test("{{padleft: abc|4}}" , "{{test}}" , "0abc");}
|
||||
@Test public void L_exc_len_bad1() {fxt.Test_parse_tmpl_str_test("{{padleft:a|bad|01}}" , "{{test}}" , "a");}
|
||||
@Test public void L_exc_pad_ws() {fxt.Test_parse_tmpl_str_test("{{padleft:a|4|\n \t}}" , "{{test}}" , "a");}
|
||||
@Test public void R_len_3() {fxt.Test_parse_tmpl_str_test("{{padright:a|4|0}}" , "{{test}}" , "a000");}
|
||||
@Test public void R_str_ab() {fxt.Test_parse_tmpl_str_test("{{padright:a|4|01}}" , "{{test}}" , "a010");}
|
||||
@Test public void R_str_intl() {fxt.Test_parse_tmpl_str_test("{{padright:|6|devanā}}" , "{{test}}" , "devanā");}
|
||||
}
|
||||
@@ -19,25 +19,33 @@ package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import g
|
||||
import gplx.core.btries.*;
|
||||
public class Pft_fmt_itm_ {
|
||||
public static final int
|
||||
Tid_seg_int = 1
|
||||
, Tid_hour_base12 = 2
|
||||
, Tid_dow_base0 = 3
|
||||
, Tid_seg_str = 4
|
||||
, Tid_year_isLeap = 5
|
||||
, Tid_timestamp_unix = 6
|
||||
, Tid_raw_ary = 7
|
||||
, Tid_raw_byt = 8
|
||||
, Tid_dayOfYear = 9
|
||||
, Tid_daysInMonth = 10
|
||||
, Tid_AmPm = 11
|
||||
, Tid_roman = 12
|
||||
, Tid_iso_fmt = 13
|
||||
, Tid_rfc_5322 = 14
|
||||
, Tid_raw = 15
|
||||
, Tid_timezone_offset = 16
|
||||
, Tid_thai = 17
|
||||
, Tid_minguo = 18
|
||||
Tid_seg_int = 1
|
||||
, Tid_hour_base12 = 2
|
||||
, Tid_dow_base0 = 3
|
||||
, Tid_seg_str = 4
|
||||
, Tid_year_isLeap = 5
|
||||
, Tid_timestamp_unix = 6
|
||||
, Tid_raw_ary = 7
|
||||
, Tid_raw_byt = 8
|
||||
, Tid_dayOfYear = 9
|
||||
, Tid_daysInMonth = 10
|
||||
, Tid_AmPm = 11
|
||||
, Tid_roman = 12
|
||||
, Tid_iso_fmt = 13
|
||||
, Tid_rfc_5322 = 14
|
||||
, Tid_raw = 15
|
||||
, Tid_timezone_offset = 16
|
||||
, Tid_thai = 17
|
||||
, Tid_minguo = 18
|
||||
, Tid_hebrew_year_num = 21
|
||||
, Tid_hebrew_month_num = 20
|
||||
, Tid_hebrew_day_num = 19
|
||||
, Tid_hebrew_month_days_count = 22
|
||||
, Tid_hebrew_month_name_full = 23
|
||||
, Tid_hebrew_month_name_gen = 24
|
||||
, Tid_hebrew_numeral = 25
|
||||
;
|
||||
|
||||
public static final Pft_fmt_itm
|
||||
Year_len4 = new Pft_fmt_itm_seg_int(DateAdp_.SegIdx_year , 4, Bool_.Y)
|
||||
, Year_len2 = new Pft_fmt_itm_seg_int(DateAdp_.SegIdx_year , 2, Bool_.Y)
|
||||
@@ -67,11 +75,18 @@ public class Pft_fmt_itm_ {
|
||||
, Byte_dash = new Pft_fmt_itm_raw_byt(Byte_ascii.Dash)
|
||||
, DayOfYear_int = new Pft_fmt_itm_dayOfYear()
|
||||
, DaysInMonth_int = new Pft_fmt_itm_daysInMonth()
|
||||
, AmPm_lower = new Pft_fmt_itm_AmPm(true)
|
||||
, AmPm_upper = new Pft_fmt_itm_AmPm(false)
|
||||
, AmPm_lower = new Pft_fmt_itm_am_pm(true)
|
||||
, AmPm_upper = new Pft_fmt_itm_am_pm(false)
|
||||
, Roman = new Pft_fmt_itm_roman()
|
||||
, Thai = new Pft_fmt_itm_thai()
|
||||
, Minguo = new Pft_fmt_itm_minguo()
|
||||
, Hebrew_year_num = new Pft_fmt_itm_hebrew_year_num()
|
||||
, Hebrew_month_num = new Pft_fmt_itm_hebrew_month_num()
|
||||
, Hebrew_day_num = new Pft_fmt_itm_hebrew_day_num()
|
||||
, Hebrew_month_days_count = new Pft_fmt_itm_hebrew_month_days_count()
|
||||
, Hebrew_month_name_full = new Pft_fmt_itm_hebrew_month_name_full()
|
||||
, Hebrew_month_name_gen = new Pft_fmt_itm_hebrew_month_name_gen()
|
||||
, Hebrew_numeral = new Pft_fmt_itm_hebrew_numeral()
|
||||
, Raw = new Pft_fmt_itm_raw()
|
||||
, Iso_fmt = new Pft_fmt_itm_iso_fmt()
|
||||
, Rfc_5322 = new Pft_fmt_itm_rfc_5322()
|
||||
@@ -113,6 +128,13 @@ public class Pft_fmt_itm_ {
|
||||
.Add("xoY" , Pft_fmt_itm_.Minguo) // Year -= 1911
|
||||
.Add("xn" , Pft_fmt_itm_.Raw) // NOTE: really does nothing; REF.MW: Language.php|sprintfdate does $s .= $num; DATE:2013-12-31
|
||||
.Add("xN" , Pft_fmt_itm_.Raw)
|
||||
.Add("xjj" , Pft_fmt_itm_.Hebrew_day_num)
|
||||
.Add("xjn" , Pft_fmt_itm_.Hebrew_month_num)
|
||||
.Add("xjt" , Pft_fmt_itm_.Hebrew_month_days_count)
|
||||
.Add("xjF" , Pft_fmt_itm_.Hebrew_month_name_full)
|
||||
.Add("xjx" , Pft_fmt_itm_.Hebrew_month_name_gen)
|
||||
.Add("xjY" , Pft_fmt_itm_.Hebrew_year_num)
|
||||
.Add("xh" , Pft_fmt_itm_.Hebrew_numeral)
|
||||
// TODO: foreign; space; "
|
||||
;
|
||||
public static Pft_fmt_itm[] Parse(Xop_ctx ctx, byte[] fmt) {
|
||||
|
||||
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
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.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
class Pft_fmt_itm_roman implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_roman;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
int nxt_idx = bldr.Idx_cur() + 1;
|
||||
Pft_fmt_itm[] ary = bldr.Fmt_itms();
|
||||
if (nxt_idx < ary.length) {
|
||||
Pft_fmt_itm itm = (Pft_fmt_itm)ary[nxt_idx];
|
||||
if (itm.TypeId() == Pft_fmt_itm_.Tid_seg_int) {
|
||||
Pft_fmt_itm_seg_int nxt_int = (Pft_fmt_itm_seg_int)ary[nxt_idx]; // FUTURE: should check tkn type
|
||||
int v = date.Segment(nxt_int.SegIdx());
|
||||
Pfxtp_roman.ToRoman(v, bfr);
|
||||
bldr.Idx_nxt_(nxt_idx + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bfr.Add_str("xf");
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_thai implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_thai;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
bfr.Add_int_variable(date.Year() + 543);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_minguo implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_minguo;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
bfr.Add_int_variable(date.Year() - 1911);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_year_num implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_hebrew_year_num;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
int[] hebrew_date = Pft_fmt_itm_hebrew_.Calc_hebrew_date(date);
|
||||
bfr.Add_int_variable(hebrew_date[Pft_fmt_itm_hebrew_.Rslt_year_num]);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_month_num implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_hebrew_month_num;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
int[] hebrew_date = Pft_fmt_itm_hebrew_.Calc_hebrew_date(date);
|
||||
bfr.Add_int_variable(hebrew_date[Pft_fmt_itm_hebrew_.Rslt_month_num]);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_day_num implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_hebrew_day_num;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
int[] hebrew_date = Pft_fmt_itm_hebrew_.Calc_hebrew_date(date);
|
||||
bfr.Add_int_variable(hebrew_date[Pft_fmt_itm_hebrew_.Rslt_day_num]);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_month_days_count implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_hebrew_month_days_count;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
int[] hebrew_date = Pft_fmt_itm_hebrew_.Calc_hebrew_date(date);
|
||||
bfr.Add_int_variable(hebrew_date[Pft_fmt_itm_hebrew_.Rslt_month_days_count]);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_month_name_full implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_hebrew_month_name_full;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
bfr.Add(Pft_fmt_itm_hebrew_.Get_hebrew_month_name_full(wiki, date));
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_month_name_gen implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_hebrew_month_name_gen;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
bfr.Add(Pft_fmt_itm_hebrew_.Get_hebrew_month_name_gen(wiki, date));
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_numeral implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_hebrew_numeral;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
bfr.Add_str(Pft_fmt_itm_hebrew_.Calc_hebrew_numeral(date.Year()));
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_hebrew_ {
|
||||
public static int Calc_hebrew_year_num_start(int year) {
|
||||
int year_minus_1 = year - 1;
|
||||
int a = (12 * year_minus_1 + 17) % 19;
|
||||
int b = year_minus_1 % 4;
|
||||
double m = 32.044093161144d + 1.5542417966212d * a + b / 4.0 - 0.0031777940220923d * year_minus_1;
|
||||
if (m < 0)
|
||||
m--;
|
||||
int mar = (int)m;
|
||||
if (m < 0)
|
||||
m++;
|
||||
m -= mar;
|
||||
int c = (mar + 3 * year_minus_1 + 5 * b + 5) % 7;
|
||||
if (c == 0 && a > 11 && m >= 0.89772376543210d)
|
||||
mar++;
|
||||
else if (c == 1 && a > 6 && m >= 0.63287037037037d)
|
||||
mar += 2;
|
||||
else if (c == 2 || c == 4 || c == 6)
|
||||
mar++;
|
||||
double year_minus_3761 = year - 3761;
|
||||
mar += (int)(year_minus_3761 / 100 ) - (int)(year_minus_3761 / 400) - 24;
|
||||
return mar;
|
||||
}
|
||||
private static final int[] Hebrew_date_rslt = new int[4];
|
||||
public static int[] Calc_hebrew_date(DateAdp date) {
|
||||
synchronized (Hebrew_date_rslt) {
|
||||
Calc_hebrew_date(Hebrew_date_rslt, date.Year(), date.Month(), date.Day());
|
||||
return Hebrew_date_rslt;
|
||||
}
|
||||
}
|
||||
public static boolean Calc_hebrew_date(int[] rv, int year, int month, int day) { // REF.MW:Language.php|tsToHebrew
|
||||
// Calculate Hebrew year
|
||||
int hebrewYear = year + 3760;
|
||||
|
||||
// Month number when September = 1, August = 12
|
||||
month += 4;
|
||||
if (month > 12) {
|
||||
// Next year
|
||||
month -= 12;
|
||||
year++;
|
||||
hebrewYear++;
|
||||
}
|
||||
|
||||
// Calculate day of year from 1 September
|
||||
int dayOfYear = day;
|
||||
for (int i = 1; i < month; i++) {
|
||||
if (i == 6) {
|
||||
// February
|
||||
dayOfYear += 28;
|
||||
// Check if the year is leap
|
||||
if (year % 400 == 0 || (year % 4 == 0 && year % 100 > 0)) {
|
||||
dayOfYear++;
|
||||
}
|
||||
} else if (i == 8 || i == 10 || i == 1 || i == 3) {
|
||||
dayOfYear += 30;
|
||||
} else {
|
||||
dayOfYear += 31;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the start of the Hebrew year
|
||||
int start = Calc_hebrew_year_num_start(hebrewYear);
|
||||
|
||||
// Calculate next year's start
|
||||
int nextStart = 0;
|
||||
if (dayOfYear <= start) {
|
||||
// Day is before the start of the year - it is the previous year
|
||||
// Next year's start
|
||||
nextStart = start;
|
||||
// Previous year
|
||||
year--;
|
||||
hebrewYear--;
|
||||
// Add days since previous year's 1 September
|
||||
dayOfYear += 365;
|
||||
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
|
||||
// Leap year
|
||||
dayOfYear++;
|
||||
}
|
||||
// Start of the new (previous) year
|
||||
start = Calc_hebrew_year_num_start(hebrewYear);
|
||||
} else {
|
||||
// Next year's start
|
||||
nextStart = Calc_hebrew_year_num_start(hebrewYear + 1);
|
||||
}
|
||||
|
||||
// Calculate Hebrew day of year
|
||||
int hebrewDayOfYear = dayOfYear - start;
|
||||
|
||||
// Difference between year's days
|
||||
int diff = nextStart - start;
|
||||
// Add 12 (or 13 for leap years) days to ignore the difference between
|
||||
// Hebrew and Gregorian year (353 at least vs. 365/6) - now the
|
||||
// difference is only about the year type
|
||||
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
|
||||
diff += 13;
|
||||
} else {
|
||||
diff += 12;
|
||||
}
|
||||
|
||||
// Check the year pattern, and is leap year
|
||||
// 0 means an incomplete year, 1 means a regular year, 2 means a complete year
|
||||
// This is mod 30, to work on both leap years (which add 30 days of Adar I)
|
||||
// and non-leap years
|
||||
int yearPattern = diff % 30;
|
||||
// Check if leap year
|
||||
boolean isLeap = diff >= 30;
|
||||
|
||||
// Calculate day in the month from number of day in the Hebrew year
|
||||
// Don't check Adar - if the day is not in Adar, we will stop before;
|
||||
// if it is in Adar, we will use it to check if it is Adar I or Adar II
|
||||
int hebrewDay = hebrewDayOfYear;
|
||||
int hebrewMonth = 1;
|
||||
int days = 0;
|
||||
|
||||
while (hebrewMonth <= 12) {
|
||||
// Calculate days in this month
|
||||
if (isLeap && hebrewMonth == 6) {
|
||||
// Adar in a leap year
|
||||
if (isLeap) {
|
||||
// Leap year - has Adar I, with 30 days, and Adar II, with 29 days
|
||||
days = 30;
|
||||
if (hebrewDay <= days) {
|
||||
// Day in Adar I
|
||||
hebrewMonth = 13;
|
||||
} else {
|
||||
// Subtract the days of Adar I
|
||||
hebrewDay -= days;
|
||||
// Try Adar II
|
||||
days = 29;
|
||||
if (hebrewDay <= days) {
|
||||
// Day in Adar II
|
||||
hebrewMonth = 14;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (hebrewMonth == 2 && yearPattern == 2) {
|
||||
// Cheshvan in a complete year (otherwise as the rule below)
|
||||
days = 30;
|
||||
} else if (hebrewMonth == 3 && yearPattern == 0) {
|
||||
// Kislev in an incomplete year (otherwise as the rule below)
|
||||
days = 29;
|
||||
} else {
|
||||
// Odd months have 30 days, even have 29
|
||||
days = 30 - (hebrewMonth - 1) % 2;
|
||||
}
|
||||
if (hebrewDay <= days) {
|
||||
// In the current month
|
||||
break;
|
||||
} else {
|
||||
// Subtract the days of the current month
|
||||
hebrewDay -= days;
|
||||
// Try in the next month
|
||||
hebrewMonth++;
|
||||
}
|
||||
}
|
||||
rv[0] = hebrewYear;
|
||||
rv[1] = hebrewMonth;
|
||||
rv[2] = hebrewDay;
|
||||
rv[3] = days;
|
||||
return true;
|
||||
}
|
||||
public static byte[] Get_hebrew_month_name_full(Xow_wiki wiki, DateAdp date) {return Get_hebrew_month_name(wiki, date, Month_name_full_ary);}
|
||||
public static byte[] Get_hebrew_month_name_gen(Xow_wiki wiki, DateAdp date) {return Get_hebrew_month_name(wiki, date, Month_name_gen_ary);}
|
||||
private static byte[] Get_hebrew_month_name(Xow_wiki wiki, DateAdp date, byte[][] name_ary) {
|
||||
int[] hebrew_date = Pft_fmt_itm_hebrew_.Calc_hebrew_date(date);
|
||||
int hebrew_month = hebrew_date[Pft_fmt_itm_hebrew_.Rslt_month_num] - ListAdp_.Base1;
|
||||
byte[] msg_key = name_ary[hebrew_month];
|
||||
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
|
||||
}
|
||||
private static final byte[][] Month_name_full_ary = new byte[][]
|
||||
{ Bry_.new_ascii_("hebrew-calendar-m1"), Bry_.new_ascii_("hebrew-calendar-m2"), Bry_.new_ascii_("hebrew-calendar-m3")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m4"), Bry_.new_ascii_("hebrew-calendar-m5"), Bry_.new_ascii_("hebrew-calendar-m6")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m7"), Bry_.new_ascii_("hebrew-calendar-m8"), Bry_.new_ascii_("hebrew-calendar-m9")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m10"), Bry_.new_ascii_("hebrew-calendar-m11"), Bry_.new_ascii_("hebrew-calendar-m12")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m6a"), Bry_.new_ascii_("hebrew-calendar-m6b")
|
||||
};
|
||||
private static final byte[][] Month_name_gen_ary = new byte[][]
|
||||
{ Bry_.new_ascii_("hebrew-calendar-m1-gen"), Bry_.new_ascii_("hebrew-calendar-m2-gen"), Bry_.new_ascii_("hebrew-calendar-m3-gen")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m4-gen"), Bry_.new_ascii_("hebrew-calendar-m5-gen"), Bry_.new_ascii_("hebrew-calendar-m6-gen")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m7-gen"), Bry_.new_ascii_("hebrew-calendar-m8-gen"), Bry_.new_ascii_("hebrew-calendar-m9-gen")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m10-gen"), Bry_.new_ascii_("hebrew-calendar-m11-gen"), Bry_.new_ascii_("hebrew-calendar-m12-gen")
|
||||
, Bry_.new_ascii_("hebrew-calendar-m6a-gen"), Bry_.new_ascii_("hebrew-calendar-m6b-gen")
|
||||
};
|
||||
public static final int
|
||||
Rslt_year_num = 0
|
||||
, Rslt_month_num = 1
|
||||
, Rslt_day_num = 2
|
||||
, Rslt_month_days_count = 3
|
||||
;
|
||||
|
||||
private static final String[][] Numeral_tbls = new String[][]
|
||||
{ new String[] {"", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י"}
|
||||
, new String[] {"", "י", "כ", "ל", "מ", "נ", "ס", "ע", "פ", "צ", "ק"}
|
||||
, new String[] {"", "ק", "ר", "ש", "ת", "תק", "תר", "תש", "תת", "תתק", "תתר"}
|
||||
, new String[] {"", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י"}
|
||||
};
|
||||
public static String Calc_hebrew_numeral(int num) {
|
||||
if (num > 9999 || num <= 0)
|
||||
return Int_.XtoStr(num);
|
||||
|
||||
String tmp = "";
|
||||
int pow10 = 1000;
|
||||
for (int i = 3; i >= 0; pow10 /= 10, i--) {
|
||||
if (num >= pow10) {
|
||||
if (num == 15 || num == 16) {
|
||||
tmp += Numeral_tbls[0][9] + Numeral_tbls[0][num - 9];
|
||||
num = 0;
|
||||
} else {
|
||||
tmp += Numeral_tbls[i][(int)(num / pow10)];
|
||||
if (pow10 == 1000)
|
||||
tmp += "'";
|
||||
}
|
||||
}
|
||||
num = num % pow10;
|
||||
}
|
||||
String rv = "";
|
||||
int tmp_len = String_.Len(tmp);
|
||||
if (tmp_len == 2) {
|
||||
rv = tmp + "'";
|
||||
}
|
||||
else {
|
||||
rv = String_.Mid(tmp, 0, tmp_len - 1) + "\"";
|
||||
rv += String_.Mid(tmp, tmp_len - 1);
|
||||
}
|
||||
int rv_len = String_.Len(rv);
|
||||
String start = String_.Mid(rv, 0, rv_len - 1);
|
||||
String end = String_.Mid(rv, rv_len - 1);
|
||||
if (String_.Eq(end, "כ"))
|
||||
rv = start + "ך";
|
||||
else if (String_.Eq(end, "מ"))
|
||||
rv = start + "ם";
|
||||
else if (String_.Eq(end, "נ"))
|
||||
rv = start + "ן";
|
||||
else if (String_.Eq(end, "פ"))
|
||||
rv = start + "ף";
|
||||
else if (String_.Eq(end, "צ"))
|
||||
rv = start + "ץ";
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ class Pft_fmt_itm_dayOfYear implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_dayOfYear;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {bfr.Add_int_variable(date.DayOfYear() - Int_.Base1);} // php is base1; .net/java is base0
|
||||
}
|
||||
class Pft_fmt_itm_AmPm implements Pft_fmt_itm {
|
||||
class Pft_fmt_itm_am_pm implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_AmPm;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
boolean am = date.Hour() < 13;
|
||||
@@ -90,7 +90,7 @@ class Pft_fmt_itm_AmPm implements Pft_fmt_itm {
|
||||
else if (!am && !lower) val = Ary_pm_upper;
|
||||
bfr.Add(val);
|
||||
} static final byte[] Ary_am_upper = Bry_.new_ascii_("AM"), Ary_pm_upper = Bry_.new_ascii_("PM"), Ary_am_lower = Bry_.new_ascii_("am"), Ary_pm_lower = Bry_.new_ascii_("pm");
|
||||
public Pft_fmt_itm_AmPm(boolean lower) {this.lower = lower;} private boolean lower;
|
||||
public Pft_fmt_itm_am_pm(boolean lower) {this.lower = lower;} private boolean lower;
|
||||
}
|
||||
class Pft_fmt_itm_dow_base0 implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_dow_base0;}
|
||||
@@ -100,36 +100,6 @@ class Pft_fmt_itm_dow_base0 implements Pft_fmt_itm {
|
||||
bfr.Add_int_fixed(dow, 1);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_roman implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_roman;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
int nxt_idx = bldr.Idx_cur() + 1;
|
||||
Pft_fmt_itm[] ary = bldr.Fmt_itms();
|
||||
if (nxt_idx < ary.length) {
|
||||
Pft_fmt_itm itm = (Pft_fmt_itm)ary[nxt_idx];
|
||||
if (itm.TypeId() == Pft_fmt_itm_.Tid_seg_int) {
|
||||
Pft_fmt_itm_seg_int nxt_int = (Pft_fmt_itm_seg_int)ary[nxt_idx]; // FUTURE: should check tkn type
|
||||
int v = date.Segment(nxt_int.SegIdx());
|
||||
Pfxtp_roman.ToRoman(v, bfr);
|
||||
bldr.Idx_nxt_(nxt_idx + 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bfr.Add_str("xf");
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_thai implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_thai;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
bfr.Add_int_variable(date.Year() + 543);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_minguo implements Pft_fmt_itm {
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_minguo;}
|
||||
public void Fmt(Bry_bfr bfr, Xow_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
|
||||
bfr.Add_int_variable(date.Year() - 1911);
|
||||
}
|
||||
}
|
||||
class Pft_fmt_itm_iso_fmt implements Pft_fmt_itm {
|
||||
public Pft_fmt_itm_iso_fmt() {}
|
||||
public int TypeId() {return Pft_fmt_itm_.Tid_iso_fmt;}
|
||||
|
||||
@@ -27,9 +27,14 @@ public class Pft_func_formatdate_bldr {
|
||||
this.fmt_itms = fmt_itms;
|
||||
int len = fmt_itms.length;
|
||||
idx_cur = 0; idx_nxt = -1;
|
||||
Pft_fmt_itm last = null;
|
||||
while (idx_cur < len) {
|
||||
Pft_fmt_itm fmt_itm = fmt_itms[idx_cur];
|
||||
fmt_itm.Fmt(bfr, wiki, lang, date, this);
|
||||
if (fmt_itm.TypeId() == Pft_fmt_itm_.Tid_hebrew_numeral)
|
||||
last = fmt_itm;
|
||||
else {
|
||||
fmt_itm.Fmt(bfr, wiki, lang, date, this);
|
||||
}
|
||||
if (idx_nxt == -1)
|
||||
++idx_cur;
|
||||
else {
|
||||
@@ -37,5 +42,12 @@ public class Pft_func_formatdate_bldr {
|
||||
idx_nxt = -1;
|
||||
}
|
||||
}
|
||||
if (last != null) {
|
||||
int year_int = bfr.XtoIntAndClear(-1);
|
||||
if (year_int != -1) { // handle no format; EX:{{#time:xh}} DATE:2014-07-20
|
||||
date = DateAdp_.seg_(new int[] {year_int, date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), date.Frac()});
|
||||
last.Fmt(bfr, wiki, lang, date, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,17 +44,17 @@ public class Pft_func_time_basic_tst {
|
||||
@Test public void Error() {fxt.Test_parse_tmpl_str_test("{{#time:M|2}}" , "{{test}}" , "<strong class=\"error\">Invalid year: 2</strong>");}
|
||||
@Test public void Error2() {fxt.Test_parse_tmpl_str_test("{{#time:Y|July 28 - August 1, 1975}}" , "{{test}}" , "<strong class=\"error\">Invalid time</strong>");}
|
||||
@Test public void Error3() {fxt.Test_parse_tmpl_str_test("{{#time:Y|106BC-43BC}}" , "{{test}}" , "<strong class=\"error\">Invalid time</strong>");}
|
||||
@Test public void Timestamp() {fxt.Test_parse_tmpl_str_test("{{#time:F j, Y|20060827072854}}" , "{{test}}" , "August 27, 2006");} // EX.WP: Great Fire of London
|
||||
@Test public void Timestamp() {fxt.Test_parse_tmpl_str_test("{{#time:F j, Y|20060827072854}}" , "{{test}}" , "August 27, 2006");} // PAGE:en.w:Great Fire of London
|
||||
@Test public void Unixtime_read() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d h:i:s A|@0}}" , "{{test}}" , "1970-01-01 12:00:00 AM");} // EX:w:Wikipedia:WikiProject_Articles_for_creation/BLD_Preload
|
||||
@Test public void Unixtime_read_neg() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d h:i:s A|@-3600}}" , "{{test}}" , "1969-12-31 11:00:00 PM");} // EX:w:Wikipedia:WikiProject_Articles_for_creation/October_-_November_2012_Backlog_Elimination_Drive; DATE:2014-05-10
|
||||
@Test public void Unixtime_8_digit() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d h:i:s A|@20120304}}" , "{{test}}" , "1970-08-21 08:58:24 PM");} // PURPOSE: make sure yyyy-MM-dd is gobbled by "@" and not evaluated again as date; EX:w:Wikipedia:WikiProject_Articles_for_creation/October_-_November_2012_Backlog_Elimination_Drive; DATE:2014-05-10
|
||||
@Test public void Unixtime_write() {fxt.Test_parse_tmpl_str_test("{{#time:U|2012-08-02}}" , "{{test}}" , "1343865600");} // EX.WP: Opa (programming language)
|
||||
@Test public void Year_4_digit() {fxt.Test_parse_tmpl_str_test("{{#time:Y|June 20, 451}}" , "{{test}}" , "0451");} // EX.WP: Battle of the Catalaunian Plains
|
||||
@Test public void Year_month() {fxt.Test_parse_tmpl_str_test("{{#time:F Y|November 2012}}" , "{{test}}" , "November 2012");} // EX.WP: Project:Current events
|
||||
@Test public void Day_addition_with_dash(){fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|2011-11-13 +1 day}}" , "{{test}}" , "2011-11-14");} // PURPOSE: +1 day was becoming -1 day b/c it was picking up - at -13; EX.WP: Template:POTD/2012-10-09
|
||||
@Test public void Fmt_time_before_day() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d H:i|04:50, 17 December 2010}}" , "{{test}}" , "2010-12-17 04:50");} // PURPOSE: strange day time format; EX.WP:Talk:Battle of Fort Washington
|
||||
@Test public void Unixtime_write() {fxt.Test_parse_tmpl_str_test("{{#time:U|2012-08-02}}" , "{{test}}" , "1343865600");} // PAGE:en.w:Opa (programming language)
|
||||
@Test public void Year_4_digit() {fxt.Test_parse_tmpl_str_test("{{#time:Y|June 20, 451}}" , "{{test}}" , "0451");} // PAGE:en.w:Battle of the Catalaunian Plains
|
||||
@Test public void Year_month() {fxt.Test_parse_tmpl_str_test("{{#time:F Y|November 2012}}" , "{{test}}" , "November 2012");} // PAGE:en.w:Project:Current events
|
||||
@Test public void Day_addition_with_dash(){fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|2011-11-13 +1 day}}" , "{{test}}" , "2011-11-14");} // PURPOSE: +1 day was becoming -1 day b/c it was picking up - at -13; PAGE:en.w:Template:POTD/2012-10-09
|
||||
@Test public void Fmt_time_before_day() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d H:i|04:50, 17 December 2010}}" , "{{test}}" , "2010-12-17 04:50");} // PURPOSE: strange day time format; PAGE:en.w:Talk:Battle of Fort Washington
|
||||
@Test public void Fmt_time_before_day_2() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d H:i|04:50, December 11, 2010}}", "{{test}}" , "2010-12-11 04:50");} // PURPOSE: handle hh:nn ymd; PAGE:en.w:Wikipedia:WikiProject_Maine/members; DATE:2014-06-25
|
||||
@Test public void Hour_zero() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d H:i|August 18 2006 00:14}}" , "{{test}}" , "2006-08-18 00:14");} // PURPOSE: fix; invalid hour; EX.WP:Talk:Martin Luther
|
||||
@Test public void Hour_zero() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d H:i|August 18 2006 00:14}}" , "{{test}}" , "2006-08-18 00:14");} // PURPOSE: fix; invalid hour; PAGE:en.w:Talk:Martin Luther
|
||||
@Test public void Iso() {fxt.Test_parse_tmpl_str_test("{{#time:c|2012-01-02 03:04:05}}" , "{{test}}" , "2012-01-02T03:04:05-05:00");}
|
||||
@Test public void Ymdh() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|2012-01-02-99}}" , "{{test}}" , "2012-01-06");} // PURPOSE: "99" is treated as 99th hour; EX:w:LimeWire; DATE:2014-03-24
|
||||
@Test public void Ymdh_noop() {fxt.Test_parse_tmpl_str_test("{{#time:Y-m-d|2012-01-02-100}}" , "{{test}}" , "2012-01-02");} // PURPOSE: "100" is ignored
|
||||
|
||||
@@ -18,32 +18,57 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pft_func_time_foreign_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset(); Tfds.Now_set(DateAdp_.new_(2012, 1, 2, 3, 4, 5, 6));}
|
||||
@After public void term() {Tfds.Now_enabled_n_();}
|
||||
@Test public void Roman() {fxt.Test_parse_tmpl_str_test("{{#time:xrY|2012}}" , "{{test}}" , "MMXII");}
|
||||
@Test public void Thai() {fxt.Test_parse_tmpl_str_test("{{#time:xkY|2012}}" , "{{test}}" , "2555");}
|
||||
@Test public void Minguo() {fxt.Test_parse_tmpl_str_test("{{#time:xoY|2012}}" , "{{test}}" , "101");}
|
||||
@Before public void init() {fxt.Clear();} private Pft_func_time_foreign_fxt fxt = new Pft_func_time_foreign_fxt();
|
||||
@After public void term() {fxt.Term();}
|
||||
@Test public void Roman() {fxt.Test_parse("{{#time:xrY|2012}}" , "MMXII");}
|
||||
@Test public void Thai() {fxt.Test_parse("{{#time:xkY|2012}}" , "2555");}
|
||||
@Test public void Minguo() {fxt.Test_parse("{{#time:xoY|2012}}" , "101");}
|
||||
@Test public void Hebrew_year_num() {fxt.Test_parse("{{#time:xjY|2012-01-02}}" , "5772");}
|
||||
@Test public void Hebrew_month_num() {fxt.Test_parse("{{#time:xjn|2012-01-02}}" , "4");}
|
||||
@Test public void Hebrew_day_num() {fxt.Test_parse("{{#time:xjj|2012-01-02}}" , "7");}
|
||||
@Test public void Hebrew_month_days_count() {fxt.Test_parse("{{#time:xjt|2012-01-02}}" , "29");}
|
||||
@Test public void Hebrew_month_name_full() {fxt.Init_msg("hebrew-calendar-m4" , "Tevet").Test_parse("{{#time:xjF|2012-01-02}}" , "Tevet");}
|
||||
@Test public void Hebrew_month_name_gen() {fxt.Init_msg("hebrew-calendar-m4-gen" , "Tevet").Test_parse("{{#time:xjx|2012-01-02}}" , "Tevet");}
|
||||
@Test public void Hebrew_numeral() {fxt.Test_parse("{{#time:xh}}" , "");}
|
||||
@Test public void Hebrew_numeral_2() {fxt.Test_parse("{{#time:xhxjY|2014}}" , "ה'תשע\"ד");}
|
||||
@Test public void Roman_various() {
|
||||
tst_Roman( 1, "I");
|
||||
tst_Roman( 2, "II");
|
||||
tst_Roman( 3, "III");
|
||||
tst_Roman( 4, "IV");
|
||||
tst_Roman( 5, "V");
|
||||
tst_Roman( 6, "VI");
|
||||
tst_Roman( 7, "VII");
|
||||
tst_Roman( 8, "VIII");
|
||||
tst_Roman( 9, "IX");
|
||||
tst_Roman( 10, "X");
|
||||
tst_Roman( 11, "XI");
|
||||
tst_Roman( 100, "C");
|
||||
tst_Roman( 101, "CI");
|
||||
tst_Roman( 111, "CXI");
|
||||
tst_Roman(1000, "M");
|
||||
tst_Roman(1001, "MI");
|
||||
tst_Roman(4000, "4000");
|
||||
fxt.Test_Roman( 1, "I");
|
||||
fxt.Test_Roman( 2, "II");
|
||||
fxt.Test_Roman( 3, "III");
|
||||
fxt.Test_Roman( 4, "IV");
|
||||
fxt.Test_Roman( 5, "V");
|
||||
fxt.Test_Roman( 6, "VI");
|
||||
fxt.Test_Roman( 7, "VII");
|
||||
fxt.Test_Roman( 8, "VIII");
|
||||
fxt.Test_Roman( 9, "IX");
|
||||
fxt.Test_Roman( 10, "X");
|
||||
fxt.Test_Roman( 11, "XI");
|
||||
fxt.Test_Roman( 100, "C");
|
||||
fxt.Test_Roman( 101, "CI");
|
||||
fxt.Test_Roman( 111, "CXI");
|
||||
fxt.Test_Roman(1000, "M");
|
||||
fxt.Test_Roman(1001, "MI");
|
||||
fxt.Test_Roman(4000, "4000");
|
||||
}
|
||||
private void tst_Roman(int v, String expd) {
|
||||
}
|
||||
class Pft_func_time_foreign_fxt {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
public void Clear() {
|
||||
fxt.Reset();
|
||||
Tfds.Now_set(DateAdp_.new_(2012, 1, 2, 3, 4, 5, 6));
|
||||
}
|
||||
public void Term() {
|
||||
Tfds.Now_enabled_n_();
|
||||
}
|
||||
public Pft_func_time_foreign_fxt Init_msg(String key, String val) {
|
||||
Xol_msg_itm msg = fxt.Wiki().Msg_mgr().Get_or_make(Bry_.new_utf8_(key));
|
||||
msg.Atrs_set(Bry_.new_utf8_(val), false, false);
|
||||
return this;
|
||||
}
|
||||
public void Test_parse(String raw, String expd) {
|
||||
fxt.Test_parse_tmpl_str_test(raw, "{{test}}", expd);
|
||||
}
|
||||
public void Test_Roman(int v, String expd) {
|
||||
Bry_bfr bfr = Bry_bfr.new_(16);
|
||||
Pfxtp_roman.ToRoman(v, bfr);
|
||||
String actl = bfr.XtoStrAndClear();
|
||||
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
interface Pxd_itm_int_interface extends Pxd_itm {
|
||||
int X_to_int_or(int or);
|
||||
int Xto_int_or(int or);
|
||||
}
|
||||
class Pxd_itm_int extends Pxd_itm_base implements Pxd_itm_int_interface {
|
||||
public Pxd_itm_int(int ary_idx, int digits, int val) {
|
||||
@@ -39,7 +39,7 @@ class Pxd_itm_int extends Pxd_itm_base implements Pxd_itm_int_interface {
|
||||
@Override public byte Tkn_tid() {return Pxd_itm_.TypeId_int;}
|
||||
@Override public int Eval_idx() {return eval_idx;} private int eval_idx = 99;
|
||||
public int Val() {return val;} public Pxd_itm_int Val_(int v) {val = v; return this;} private int val;
|
||||
public int X_to_int_or(int or) {return val;}
|
||||
public int Xto_int_or(int or) {return val;}
|
||||
public int Digits() {return digits;} private int digits;
|
||||
@Override public void Time_ini(DateAdpBldr bldr) {
|
||||
if (this.Seg_idx() == Pxd_itm_base.Seg_idx_skip) return;
|
||||
@@ -291,7 +291,7 @@ class Pxd_itm_int_ {
|
||||
factor = -1;
|
||||
}
|
||||
state.Seg_idxs_((Pxd_itm_base)itm, Pxd_itm_base.Seg_idx_skip, -1);
|
||||
return itm_int.X_to_int_or(or) * factor;
|
||||
return itm_int.Xto_int_or(or) * factor;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -306,7 +306,7 @@ class Pxd_itm_int_ {
|
||||
itm.Val_(val + (val > 69 ? 1900 : 2000)); // ASSUME that 70 refers to 1970 and 69 refers to 2069
|
||||
state.Seg_idxs_(itm, DateAdp_.SegIdx_year);
|
||||
return false;
|
||||
case 3: // NOTE: 3 digit numbers are valid years; MW relies on PHP time parse which always zero-pad numbers; EX.WP: Battle of the Catalaunian Plains; {{#time:Y|June 20, 451}}
|
||||
case 3: // NOTE: 3 digit numbers are valid years; MW relies on PHP time parse which always zero-pad numbers; PAGE:en.w:Battle of the Catalaunian Plains; {{#time:Y|June 20, 451}}
|
||||
case 4:
|
||||
state.Seg_idxs_(itm, DateAdp_.SegIdx_year);
|
||||
return false;
|
||||
|
||||
@@ -74,21 +74,21 @@ class Pxd_itm_sym extends Pxd_itm_base {
|
||||
}
|
||||
class Pxd_itm_int_dmy_14 extends Pxd_itm_base implements Pxd_itm_int_interface {
|
||||
public Pxd_itm_int_dmy_14(int ary_idx, byte[] src, int digits) {this.Ctor(ary_idx); this.src = src; this.digits = digits;} private byte[] src; int digits;
|
||||
public int X_to_int_or(int or) {return Bry_.X_to_int_or(src, or);}
|
||||
public int Xto_int_or(int or) {return Bry_.Xto_int_or(src, or);}
|
||||
@Override public byte Tkn_tid() {return Pxd_itm_.TypeId_int_dmy_14;}
|
||||
@Override public int Eval_idx() {return eval_idx;} private int eval_idx = 20;
|
||||
@Override public void Time_ini(DateAdpBldr bldr) {
|
||||
if (this.Seg_idx() != Pxd_itm_base.Seg_idx_null) return; // has seg_idx; already eval'd by something else
|
||||
bldr.Seg_set(DateAdp_.SegIdx_year , Bry_.X_to_int_or(src, 0, 4, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_month , Bry_.X_to_int_or(src, 4, 6, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_year , Bry_.Xto_int_or(src, 0, 4, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_month , Bry_.Xto_int_or(src, 4, 6, 0));
|
||||
if (digits > 6) {
|
||||
bldr.Seg_set(DateAdp_.SegIdx_day , Bry_.X_to_int_or(src, 6, 8, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_day , Bry_.Xto_int_or(src, 6, 8, 0));
|
||||
if (digits > 8) {
|
||||
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.X_to_int_or(src, 8, 10, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.Xto_int_or(src, 8, 10, 0));
|
||||
if (digits > 10) {
|
||||
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.X_to_int_or(src, 10, 12, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.Xto_int_or(src, 10, 12, 0));
|
||||
if (digits > 12)
|
||||
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.X_to_int_or(src, 12, 14, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.Xto_int_or(src, 12, 14, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,14 +96,14 @@ class Pxd_itm_int_dmy_14 extends Pxd_itm_base implements Pxd_itm_int_interface {
|
||||
}
|
||||
class Pxd_itm_int_mhs_6 extends Pxd_itm_base implements Pxd_itm_int_interface {
|
||||
public Pxd_itm_int_mhs_6(int ary_idx, byte[] src) {this.Ctor(ary_idx); this.src = src;} private byte[] src;
|
||||
public int X_to_int_or(int or) {return Bry_.X_to_int_or(src, or);}
|
||||
public int Xto_int_or(int or) {return Bry_.Xto_int_or(src, or);}
|
||||
@Override public byte Tkn_tid() {return Pxd_itm_.TypeId_int_hms_6;}
|
||||
@Override public int Eval_idx() {return eval_idx;} private int eval_idx = 20;
|
||||
@Override public void Time_ini(DateAdpBldr bldr) {
|
||||
if (this.Seg_idx() != Pxd_itm_base.Seg_idx_null) return; // has seg_idx; already eval'd by something else
|
||||
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.X_to_int_or(src, 0, 2, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.X_to_int_or(src, 2, 4, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.X_to_int_or(src, 4, 6, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.Xto_int_or(src, 0, 2, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.Xto_int_or(src, 2, 4, 0));
|
||||
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.Xto_int_or(src, 4, 6, 0));
|
||||
}
|
||||
}
|
||||
class Pxd_itm_sorter implements gplx.lists.ComparerAble {
|
||||
|
||||
@@ -98,7 +98,7 @@ class Pxd_parser {
|
||||
Pxd_itm itm = null;
|
||||
switch (tkn_type) {
|
||||
case Pxd_itm_.TypeId_int:
|
||||
int int_val = Bry_.X_to_int_or(src, tkn_bgn_pos, cur_pos, Int_.MinValue);
|
||||
int int_val = Bry_.Xto_int_or(src, tkn_bgn_pos, cur_pos, Int_.MinValue);
|
||||
if (int_val == Int_.MinValue) {} // FUTURE: warn
|
||||
int digits = cur_pos - tkn_bgn_pos;
|
||||
switch (digits) {
|
||||
|
||||
@@ -53,10 +53,10 @@ public class Pxd_parser_tst {
|
||||
@Test public void Time_all() {tst_both_("04-03-05 06:07:08" , "2005-03-04 06:07:08.000");}
|
||||
@Test public void Unit_day_pos() {tst_date_("+ 3 days" , "2012-03-01");}
|
||||
@Test public void Unit_day_neg() {tst_date_("- 3 days" , "2012-02-24");}
|
||||
@Test public void Unit_day_neg_w_day() {tst_date_("30 May 2012 -1 days" , "2012-05-29");} // EX.WP: Main Page
|
||||
@Test public void Unit_day_neg_w_day() {tst_date_("30 May 2012 -1 days" , "2012-05-29");} // PAGE:en.w:Main Page
|
||||
@Test public void Unit_week() {tst_date_("- 1 week" , "2012-02-26");} // PURPOSE.FIX: "week" was not being handled; error on main Page; EX:da.wikipedia.org/Main_Page
|
||||
@Test public void Time_len_6() {tst_time_("041526" , "04:15:26.000");}
|
||||
@Test public void Err_one_num() {tst_time_("2" , "Invalid year: 2");} // occurs on some templates; EX.WP: Voyager 1 and {{date}}
|
||||
@Test public void Err_one_num() {tst_time_("2" , "Invalid year: 2");} // occurs on some templates; PAGE:en.w:Voyager 1 and {{date}}
|
||||
@Test public void Dmy_at_y_dot() {tst_date_("1.2.70" , "1970-02-01");} // PURPOSE: dmy when delimiter is dot
|
||||
@Test public void Mdy_at_y_slash() {tst_date_("1/2/70" , "1970-01-02");} // PURPOSE: mdy when delimiter is slash
|
||||
@Test public void Ago() {tst_date_("1 month ago" , "2012-01-27");}
|
||||
|
||||
104
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_anchorencode.java
Normal file
104
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_anchorencode.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import gplx.core.btries.*;
|
||||
import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*;
|
||||
public class Pfunc_anchorencode extends Pf_func_base { // EX: {{anchorencode:a b}} -> a+b
|
||||
@Override public boolean Func_require_colon_arg() {return true;}
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_url_anchorencode;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_anchorencode().Name_(name);}
|
||||
public static void Func_init(Xop_ctx ctx) {
|
||||
if (anchor_ctx != null) return;// NOTE: called by Scrib_uri
|
||||
encode_trie.Add(Byte_ascii.Colon, Bry_fmtr_arg_.byt_(Byte_ascii.Colon));
|
||||
encode_trie.Add(Byte_ascii.Space, Bry_fmtr_arg_.byt_(Byte_ascii.Underline));
|
||||
anchor_ctx = Xop_ctx.new_sub_(ctx.Wiki());
|
||||
anchor_ctx.Para().Enabled_n_();
|
||||
anchor_tkn_mkr = anchor_ctx.Tkn_mkr();
|
||||
anchor_parser = ctx.Wiki().Utl_mgr().Anchor_encode_parser();
|
||||
}
|
||||
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bfr) {
|
||||
if (anchor_ctx == null) Func_init(ctx);
|
||||
byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return;
|
||||
Anchor_encode(val_ary, bfr, ctx.App().Utl_bry_bfr_mkr().Get_b512().Mkr_rls());
|
||||
}
|
||||
public static void Anchor_encode(byte[] src, Bry_bfr bfr, Bry_bfr tmp_bfr) {
|
||||
Xop_root_tkn root = anchor_ctx.Tkn_mkr().Root(src);
|
||||
anchor_parser.Parse_wtxt_to_wdom(root, anchor_ctx, anchor_tkn_mkr, src, Xop_parser_.Doc_bgn_bos);
|
||||
// anchor_parser.Parse_page_tmpl(root, anchor_ctx, anchor_tkn_mkr, src);
|
||||
int subs_len = root.Subs_len();
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Xop_tkn_itm sub = root.Subs_get(i);
|
||||
Tkn(src, sub, root, i, tmp_bfr);
|
||||
}
|
||||
byte[] unencoded = tmp_bfr.XtoAryAndClear();
|
||||
encoder.Encode(tmp_bfr, unencoded);
|
||||
bfr.Add_bfr_and_clear(tmp_bfr);
|
||||
}
|
||||
private static Url_encoder encoder = Url_encoder.new_html_id_();
|
||||
private static void Tkn(byte[] src, Xop_tkn_itm sub, Xop_tkn_grp grp, int sub_idx, Bry_bfr tmp_bfr) {
|
||||
switch (sub.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_lnke: Lnke(src, (Xop_lnke_tkn)sub, tmp_bfr); break; // FUTURE: need to move number to lnke_tkn so that number will be correct/consistent?
|
||||
case Xop_tkn_itm_.Tid_lnki: Lnki(src, (Xop_lnki_tkn)sub, tmp_bfr); break;
|
||||
case Xop_tkn_itm_.Tid_apos: break; // noop
|
||||
case Xop_tkn_itm_.Tid_xnde: Xnde(src, (Xop_xnde_tkn)sub, tmp_bfr); break;
|
||||
case Xop_tkn_itm_.Tid_html_ncr: tmp_bfr.Add_utf8_int(((Xop_amp_tkn_num)sub).Val()); break;
|
||||
case Xop_tkn_itm_.Tid_html_ref: tmp_bfr.Add_utf8_int(((Xop_amp_tkn_txt)sub).Char_int()); break;
|
||||
case Xop_tkn_itm_.Tid_tmpl_invk:
|
||||
Xot_invk_tkn invk_tkn = (Xot_invk_tkn)sub;
|
||||
Arg_itm_tkn name_tkn = invk_tkn.Name_tkn().Key_tkn();
|
||||
int name_ary_bgn = name_tkn.Src_bgn() + 1, name_ary_end = name_tkn.Src_end();
|
||||
byte[] name_ary = Bry_.Mid(src, name_ary_bgn, name_ary_end); // + 1 to skip :
|
||||
int name_ary_len = name_ary_end - name_ary_bgn;
|
||||
if (name_ary_len > 0 && name_ary[0] == Byte_ascii.Colon) // has initial colon; EX: {{:a}
|
||||
tmp_bfr.Add_mid(name_ary, 1, name_ary_len); // 1 to skip initial colon
|
||||
else // regular tmpl; EX: {{a}}
|
||||
tmp_bfr.Add(anchor_ctx.Wiki().Ns_mgr().Ns_template().Gen_ttl(name_ary));
|
||||
break;
|
||||
default: tmp_bfr.Add_mid(src, sub.Src_bgn_grp(grp, sub_idx), sub.Src_end_grp(grp, sub_idx)); break;
|
||||
}
|
||||
}
|
||||
private static void Lnke(byte[] src, Xop_lnke_tkn lnke, Bry_bfr tmp_bfr) {
|
||||
int subs_len = lnke.Subs_len();
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Xop_tkn_itm lnke_sub = lnke.Subs_get(i);
|
||||
tmp_bfr.Add_mid(src, lnke_sub.Src_bgn_grp(lnke, i), lnke_sub.Src_end_grp(lnke, i));
|
||||
}
|
||||
}
|
||||
private static void Lnki(byte[] src, Xop_lnki_tkn lnki, Bry_bfr tmp_bfr) {
|
||||
int src_end = lnki.Src_end();
|
||||
int trg_end = lnki.Trg_tkn().Src_end();
|
||||
|
||||
if (trg_end == src_end - Xop_tkn_.Lnki_end_len) { // only trg
|
||||
int trg_bgn = lnki.Trg_tkn().Src_bgn();
|
||||
if (lnki.Ttl().ForceLiteralLink()) ++trg_bgn; // literal link; skip colon; EX: [[:a]] -> a
|
||||
tmp_bfr.Add_mid(src, trg_bgn, trg_end);
|
||||
}
|
||||
else {
|
||||
tmp_bfr.Add_mid(src, trg_end + 1, src_end - Xop_tkn_.Lnki_end_len); //+1 is len of pipe
|
||||
}
|
||||
}
|
||||
private static void Xnde(byte[] src, Xop_xnde_tkn xnde, Bry_bfr tmp_bfr) {
|
||||
int subs_len = xnde.Subs_len();
|
||||
for (int i = 0; i < subs_len; i++) {
|
||||
Tkn(src, xnde.Subs_get(i), xnde, i, tmp_bfr);
|
||||
}
|
||||
}
|
||||
private static Btrie_fast_mgr encode_trie = Btrie_fast_mgr.cs_();
|
||||
private static Xop_ctx anchor_ctx; static Xop_tkn_mkr anchor_tkn_mkr;
|
||||
private static Xop_parser anchor_parser;
|
||||
}
|
||||
@@ -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.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_anchorencode_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Lnke() {fxt.Test_parse_tmpl_str_test("{{anchorencode:[irc://a b c]}}" , "{{test}}" , "b_c");}
|
||||
@Test public void Apos_bold() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a ''b'' c}}" , "{{test}}" , "a_b_c");}
|
||||
@Test public void Apos_1() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a 'b c}}" , "{{test}}" , "a_.27b_c");}
|
||||
@Test public void Lnki_trg() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a [[b]] c}}" , "{{test}}" , "a_b_c");}
|
||||
@Test public void Lnki_caption() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a [[b|c]] c}}" , "{{test}}" , "a_c_c");}
|
||||
@Test public void Lnki_file() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a [[Image:b|thumb|c]] d}}" , "{{test}}" , "a_thumb.7Cc_d");}
|
||||
@Test public void Xnde() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a <i>b</i> c}}" , "{{test}}" , "a_b_c");}
|
||||
@Test public void Html_ncr() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a " b}}" , "{{test}}" , "a_.22_b");}
|
||||
@Test public void Html_ref() {fxt.Test_parse_tmpl_str_test("{{anchorencode:a " b}}" , "{{test}}" , "a_.22_b");}
|
||||
@Test public void Tmpl_missing_basic() {fxt.Test_parse_tmpl_str_test("{{anchorencode:{{a}}}}" , "{{test}}" , "Template:a");}
|
||||
@Test public void Tmpl_missing_colon() {fxt.Test_parse_tmpl_str_test("{{anchorencode:{{:a}}}}" , "{{test}}" , "Template:A");}
|
||||
@Test public void Lnki_literal() {fxt.Test_parse_tmpl_str_test("{{anchorencode:[[:a]]}}" , "{{test}}" , "a");}
|
||||
}
|
||||
52
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_filepath.java
Normal file
52
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_filepath.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import gplx.xowa.files.*;
|
||||
public class Pfunc_filepath extends Pf_func_base {
|
||||
@Override public boolean Func_require_colon_arg() {return true;}
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_url_filepath;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_filepath().Name_(name);}
|
||||
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bb) {
|
||||
byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return;
|
||||
Xow_wiki wiki = ctx.Wiki();
|
||||
val_ary = Bry_.Add(Bry_file, val_ary);
|
||||
Xoa_ttl ttl = Xoa_ttl.new_(wiki, ctx.App().Msg_log_null(), val_ary, val_ary, 0, val_ary.length); if (ttl == null) return; // text is not valid ttl; return;
|
||||
Xoa_page page = Load_page(wiki, ttl);
|
||||
if (page.Missing()) return; // page not found in commons; exit;
|
||||
byte[] ttl_bry = page.Ttl().Page_url();
|
||||
Xofw_file_finder_rslt tmp_rslt = wiki.File_mgr().Repo_mgr().Page_finder_locate(ttl_bry);
|
||||
if (tmp_rslt .Repo_idx() == Byte_.MaxValue_127) return;
|
||||
Xof_repo_itm trg_repo = wiki.File_mgr().Repo_mgr().Repos_get_at(tmp_rslt.Repo_idx()).Trg();
|
||||
xfer_itm.Atrs_by_ttl(ttl_bry, Bry_.Empty); // redirect is empty b/c Get_page does all redirect lookups
|
||||
byte[] url = url_bldr.Set_trg_html_(Xof_repo_itm.Mode_orig, trg_repo, ttl_bry, xfer_itm.Lnki_md5(), xfer_itm.Lnki_ext(), Xof_img_size.Size_null_deprecated, Xof_doc_thumb.Null, Xof_doc_page.Null).Xto_bry();
|
||||
bb.Add(url);
|
||||
} private static final byte[] Bry_file = Bry_.new_ascii_("File:");
|
||||
private static final Xof_xfer_itm xfer_itm = new Xof_xfer_itm();
|
||||
private static final Xof_url_bldr url_bldr = new Xof_url_bldr();
|
||||
public static Xoa_page Load_page(Xow_wiki wiki, Xoa_ttl ttl) {
|
||||
Xoa_page page = wiki.Data_mgr().Get_page(ttl, false);
|
||||
if (page.Missing()) { // file not found in current wiki; try commons;
|
||||
Xow_wiki commons_wiki = wiki.App().Wiki_mgr().Get_by_key_or_null(wiki.Commons_wiki_key());
|
||||
if (commons_wiki != null) {; // commons_wiki not installed; exit; DATE:2013-06-08
|
||||
if (!Env_.Mode_testing()) commons_wiki.Init_assert();// must assert load else page_zip never detected; TODO: move to Xoa_wiki_mgr.New_wiki; DATE:2013-03-10
|
||||
page = commons_wiki.Data_mgr().Get_page(ttl, false);
|
||||
}
|
||||
}
|
||||
return page;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
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_filepath_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {
|
||||
fxt.Reset();
|
||||
Io_mgr._.InitEngine_mem();
|
||||
Xoa_app app = fxt.App(); en_wiki = fxt.Wiki();
|
||||
mock_wkr.Clear_commons(); // assume all files are in repo 0
|
||||
en_wiki.File_mgr().Repo_mgr().Page_finder_(mock_wkr);
|
||||
commons_wiki = Xoa_app_fxt.wiki_(app, Xow_wiki_.Domain_commons_str);
|
||||
commons_wiki.Db_mgr().Load_mgr().Clear();
|
||||
en_wiki.Db_mgr().Load_mgr().Clear();
|
||||
app.Wiki_mgr().Add(commons_wiki);
|
||||
app.File_mgr().Repo_mgr().Set("src_commons", "mem/xowa/file/commons/src/", commons_wiki.Domain_str()).Ext_rules_(Xoft_rule_grp.Grp_app_default);
|
||||
app.File_mgr().Repo_mgr().Set("trg_commons", "mem/xowa/file/commons/trg/", commons_wiki.Domain_str()).Ext_rules_(Xoft_rule_grp.Grp_app_default);
|
||||
en_wiki.File_mgr().Repo_mgr().Add_repo(Bry_.new_utf8_("src_commons"), Bry_.new_utf8_("trg_commons"));
|
||||
Io_mgr._.CreateDir(Io_url_.new_dir_("mem/xowa/wiki/commons.wikimedia.org/ns/000/page/")); // HACK: create page_dir so Scan_dirs_zip will not identify commons as zipped; FIX: remove; WHEN: after redoing commons.css download logic
|
||||
} private Xow_wiki en_wiki, commons_wiki; Xofw_wiki_wkr_mock mock_wkr = new Xofw_wiki_wkr_mock();
|
||||
@Test public void Wiki_is_local() {
|
||||
fxt.Init_page_create(en_wiki, "File:A.png", "");
|
||||
mock_wkr.Redirect_("A.png", "A.png").Repo_idx_(0);
|
||||
fxt.Test_parse_tmpl_str_test("{{filepath:A.png}}", "{{test}}", "file:///mem/wiki/repo/trg/orig/7/0/A.png");
|
||||
}
|
||||
@Test public void Wiki_is_commons() {
|
||||
fxt.Init_page_create(commons_wiki, "File:A.png", "");
|
||||
commons_wiki.Fsys_mgr().Dir_regy()[Xow_dir_info_.Tid_page].Ext_tid_(gplx.ios.Io_stream_.Tid_file);
|
||||
mock_wkr.Redirect_("A.png", "A.png").Repo_idx_(1);
|
||||
fxt.Test_parse_tmpl_str_test("{{filepath:A.png}}", "{{test}}", "file:///mem/xowa/file/commons/trg/orig/7/0/1/c/A.png");
|
||||
}
|
||||
@Test public void Not_found() {
|
||||
fxt.Test_parse_tmpl_str_test("{{filepath:B.png}}", "{{test}}", "");
|
||||
}
|
||||
@Test public void Invalid() { // PURPOSE: handle invalid ttls; EX:w:Germicidin
|
||||
fxt.Test_parse_tmpl_str_test("{{filepath:{{{ImageFile}}}}}", "{{test}}", "");
|
||||
}
|
||||
}
|
||||
57
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_ns.java
Normal file
57
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_ns.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
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_ns extends Pf_func_base { // EX: {{ns:6}} -> File
|
||||
private boolean encode;
|
||||
public Pfunc_ns(boolean encode) {this.encode = encode; if (canonical == null) canonical_();}
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_url_ns;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_ns(encode).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 bb) {
|
||||
byte[] val_dat_ary = Eval_argx(ctx, src, caller, self); if (val_dat_ary == Bry_.Empty) return;
|
||||
|
||||
int val_dat_ary_len = val_dat_ary.length;
|
||||
int ns_id = Bry_.Xto_int_or(val_dat_ary, 0, val_dat_ary_len, -1);
|
||||
if (ns_id == -1) {
|
||||
Object o = ctx.Wiki().Ns_mgr().Names_get_or_null(val_dat_ary, 0, val_dat_ary_len);
|
||||
if (o == null
|
||||
&& !Bry_.Eq(ctx.Lang().Key_bry(), Xol_lang_.Key_en)) // foreign language; english canonical names are still valid; REF.MW: Language.php|getNsIndex
|
||||
o = canonical.Get_by_mid(val_dat_ary, 0, val_dat_ary_len);
|
||||
if (o != null) {
|
||||
Xow_ns itm = (Xow_ns)o;
|
||||
if (itm.Id() == Xow_ns_.Id_file) itm = ctx.Wiki().Ns_mgr().Ns_file(); // handles "Image" -> "File"
|
||||
bb.Add(encode ? itm.Name_enc() : itm.Name_txt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
Xow_ns itm = (Xow_ns)ctx.Wiki().Ns_mgr().Ids_get_or_null(ns_id);
|
||||
if (itm == null) return; // occurs when ns_id is not known; EX: {{ns:999}}; SEE: Wiktionary:Grease pit archive/2007/October; "{{ns:114}}"
|
||||
bb.Add(encode ? itm.Name_enc() : itm.Name_txt());
|
||||
}
|
||||
}
|
||||
private static Hash_adp_bry canonical;
|
||||
private static void canonical_() {
|
||||
canonical = Hash_adp_bry.ci_ascii_(); // ASCII:canonical English names
|
||||
for (Xow_ns ns : Xow_ns_.Canonical)
|
||||
canonical_add(ns.Id(), ns.Name_bry());
|
||||
}
|
||||
private static void canonical_add(int ns_id, byte[] ns_name) {
|
||||
Xow_ns ns = new Xow_ns(ns_id, Xow_ns_case_.Id_all, ns_name, false);
|
||||
canonical.Add(ns_name, ns);
|
||||
}
|
||||
}
|
||||
39
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_ns_tst.java
Normal file
39
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_ns_tst.java
Normal 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.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_ns_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Ns_0() {fxt.Test_parse_tmpl_str_test("{{ns:0}}" , "{{test}}", "");}
|
||||
@Test public void Ns_10() {fxt.Test_parse_tmpl_str_test("{{ns:10}}" , "{{test}}", "Template");}
|
||||
@Test public void Ns_11() {fxt.Test_parse_tmpl_str_test("{{ns:11}}" , "{{test}}", "Template talk");}
|
||||
@Test public void Ns_11_ws() {fxt.Test_parse_tmpl_str_test("{{ns: 11 }}" , "{{test}}", "Template talk");}
|
||||
@Test public void Ns_Template() {fxt.Test_parse_tmpl_str_test("{{ns:Template}}" , "{{test}}", "Template");}
|
||||
@Test public void Ns_invalid() {fxt.Test_parse_tmpl_str_test("{{ns:252}}" , "{{test}}", "");}
|
||||
@Test public void Nse_10() {fxt.Test_parse_tmpl_str_test("{{nse:10}}" , "{{test}}", "Template");}
|
||||
@Test public void Nse_11() {fxt.Test_parse_tmpl_str_test("{{nse:11}}" , "{{test}}", "Template_talk");}
|
||||
@Test public void Ns_Image() {fxt.Test_parse_tmpl_str_test("{{ns:Image}}" , "{{test}}", "File");}
|
||||
@Test public void Ns_Templatex() {fxt.Test_parse_tmpl_str_test("{{ns:Templatex}}" , "{{test}}", "");}
|
||||
@Test public void Ns_Talk() { // PURPOSE: non-English wikis may have parameterized Project Talk ($1 talk); swap out with ns:4; REF.MW: Language.php!fixVariableInNamespace
|
||||
Xow_ns_mgr ns_mgr = new Xow_ns_mgr(gplx.xowa.langs.cases.Xol_case_mgr_.Ascii());
|
||||
ns_mgr.Add_new(4, "wiki").Add_new(5, "$1 talk").Add_new(10, "Template").Init();
|
||||
fxt.Wiki().Ns_mgr_(ns_mgr);
|
||||
fxt.Test_parse_tmpl_str_test("{{ns:5}}" , "{{test}}", "wiki talk");
|
||||
}
|
||||
}
|
||||
183
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java
Normal file
183
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_rel2abs.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import gplx.core.btries.*;
|
||||
public class Pfunc_rel2abs extends Pf_func_base {
|
||||
@Override public boolean Func_require_colon_arg() {return true;}
|
||||
private static final byte[] Ary_dot_slash = Bry_.new_ascii_("./"), Ary_dot_dot = Bry_.new_ascii_(".."), Ary_dot_dot_slash = Bry_.new_ascii_("../");
|
||||
private static void qry_bgns_with_init() {
|
||||
qry_bgns_with = Btrie_fast_mgr.cs_();
|
||||
qry_bgns_with.Add(Byte_ascii.Slash, Int_obj_ref.new_(Id_slash));
|
||||
qry_bgns_with.Add(Byte_ascii.Dot, Int_obj_ref.new_(Id_dot));
|
||||
qry_bgns_with.Add(Ary_dot_slash, Int_obj_ref.new_(Id_dot_slash));
|
||||
qry_bgns_with.Add(Ary_dot_dot, Int_obj_ref.new_(Id_dot_dot));
|
||||
qry_bgns_with.Add(Ary_dot_dot_slash, Int_obj_ref.new_(Id_dot_dot_slash));
|
||||
} static Btrie_fast_mgr qry_bgns_with;
|
||||
@Override public void Func_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Xot_invk self, Bry_bfr bb) {// REF.MW:ParserFunctions_body.php
|
||||
byte[] qry = Eval_argx(ctx, src, caller, self);
|
||||
byte[] orig = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self.Args_len(), 0);
|
||||
if (orig.length == 0) orig = ctx.Cur_page().Ttl().Full_txt();
|
||||
bb.Add(Rel2abs(ctx.App().Utl_bry_bfr_mkr().Get_b512().Mkr_rls(), qry, orig));
|
||||
}
|
||||
public static boolean Rel2abs_ttl(byte[] ttl, int bgn, int end) {
|
||||
int last = end - 1;
|
||||
if (end - bgn > Xoa_ttl.Max_len) return false; // NOTE: some tmpls have long #if statements; quicker to fail here than wait for invalid char below
|
||||
boolean rv = false;
|
||||
for (int i = bgn; i < end; ++i) {
|
||||
switch (ttl[i]) {
|
||||
case Byte_ascii.Gt: case Byte_ascii.Pipe: // simplified version of Xoa_ttl parse; note that Xoa_ttl accepts these if anchor is seen; this proc assumes that anything with anchor and invalid char is an invalid rel2abs; EX: "A../b#c[d" is not valid; DATE:2013-03-31
|
||||
case Byte_ascii.Brack_bgn: case Byte_ascii.Brack_end: case Byte_ascii.Curly_bgn: case Byte_ascii.Curly_end:
|
||||
return false;
|
||||
case Byte_ascii.Slash:
|
||||
if ( !rv &&
|
||||
( (i == bgn) // bgns with "/"
|
||||
|| (i > bgn && ttl[i - 1] == Byte_ascii.Dot) // "./"
|
||||
|| (i < last && ttl[i + 1] == Byte_ascii.Dot) // "/."
|
||||
)
|
||||
) rv = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
private static final Int_obj_ref ignore_rel2abs_tid = Int_obj_ref.zero_();
|
||||
public static byte[] Rel2abs(Bry_bfr tmp_bfr, byte[] qry, byte[] src) {return Rel2abs(tmp_bfr, qry, src, ignore_rel2abs_tid);}
|
||||
public static byte[] Rel2abs(Bry_bfr tmp_bfr, byte[] qry, byte[] src, Int_obj_ref rel2abs_tid) {
|
||||
if (qry_bgns_with == null) qry_bgns_with_init();
|
||||
int qry_len = qry.length, src_len = src.length;
|
||||
|
||||
// qry_len = RTrim(qry, Byte_ascii.Slash, qry_bgn, qry_len); // not needed, but test anyway
|
||||
if (qry_len == 0) return src;// no qry; return src; EX:{{#rel2abs:|a/b}} -> a/b
|
||||
|
||||
byte[] tmp = src;
|
||||
int tmp_adj = 0, i = 0, prv_slash_end = 0, tmp_len = src_len, seg_pos = 0;
|
||||
boolean tmp_is_1st = true;
|
||||
Object o = qry_bgns_with.Match_bgn(qry, 0, qry_len); // check if qry begins with ".", "/", "./", "../"; if it doesn't return;
|
||||
if (o != null) {
|
||||
int id = ((Int_obj_ref)o).Val();
|
||||
rel2abs_tid.Val_(id);
|
||||
switch (id) {
|
||||
case Id_dot: // "."
|
||||
break;
|
||||
case Id_slash: // "/"
|
||||
case Id_dot_slash: // "./"
|
||||
case Id_dot_dot_slash: // "../"
|
||||
break; // qry is relative to src; noop
|
||||
case Id_dot_dot: // ".."
|
||||
int match_end = qry_bgns_with.Match_pos();
|
||||
if (match_end < qry_len && qry[match_end] == Byte_ascii.Dot) // NOTE: handles "..."; if "...*" then treat as invalid and return; needed for en.wiktionary.org/wiki/Wiktionary:Requests for cleanup/archive/2006
|
||||
return qry;
|
||||
break;
|
||||
default:
|
||||
return qry; // NOTE: lnki parsing currently has fuzzy logic to try to detect rel2abs; for now, if false match, then return original
|
||||
}
|
||||
}
|
||||
else { // qry is not relative to src; src is ignored; EX:{{#rel2abs:c|a/b}} -> c
|
||||
src_len = 0;
|
||||
tmp = qry;
|
||||
tmp_len = qry_len;
|
||||
tmp_is_1st = false;
|
||||
}
|
||||
// create segs; see NOTE_1 for approach
|
||||
byte b = Byte_.Zero;
|
||||
boolean loop = true, dot_mode = true;
|
||||
while (loop) {
|
||||
if (i == tmp_len) { // finished an ary (either src or qry)
|
||||
if (tmp_is_1st) { // finished src; EX: A/b
|
||||
tmp_is_1st = false;
|
||||
tmp = qry;
|
||||
tmp_adj = src_len + 1;
|
||||
tmp_len = src_len + 1 + qry_len;
|
||||
}
|
||||
else // finished qry; EX: ../c
|
||||
loop = false;
|
||||
b = Byte_ascii.Slash; // fake a slash between ary and src
|
||||
}
|
||||
else // inside ary
|
||||
b = tmp[i - tmp_adj];
|
||||
switch (b) {
|
||||
case Byte_ascii.Dot: // "."; ignore; note that dot_mode defaults to true
|
||||
break;
|
||||
default: // something else besides dot or slash; reset dot_mode
|
||||
dot_mode = false;
|
||||
break;
|
||||
case Byte_ascii.Slash: // "/"; seg finished
|
||||
int seg_len = i - prv_slash_end; // EX: "a/b/c" prv_slash_end = 2; i = 3; len = 1
|
||||
boolean create_seg = false;
|
||||
switch (seg_len) {
|
||||
case 0: // "//"; ignore
|
||||
break;
|
||||
case 1: // "/?/"
|
||||
if (dot_mode) {} // "/./"; current seg; ignore;
|
||||
else create_seg = true; // something else (EX: /A/); create seg;
|
||||
break;
|
||||
case 2:
|
||||
if (dot_mode) { // "/../"; pop seg_ary
|
||||
seg_pos -= 2;
|
||||
if (seg_pos < 0) return Bry_.Empty; // FUTURE: return MediaWiki error
|
||||
}
|
||||
else create_seg = true; // something else; create seg
|
||||
break;
|
||||
default: // something else; create seg
|
||||
create_seg = true;
|
||||
break;
|
||||
}
|
||||
if (create_seg) {
|
||||
seg_ary[seg_pos++] = prv_slash_end;
|
||||
seg_ary[seg_pos++] = i;
|
||||
}
|
||||
prv_slash_end = i + 1; // +1: place after slash
|
||||
dot_mode = true; // reset dot_mode
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// write segs
|
||||
tmp = src; tmp_adj = 0; tmp_is_1st = true; tmp_len = src_len;
|
||||
if (src_len == 0) {
|
||||
tmp = qry;
|
||||
tmp_len = qry_len;
|
||||
tmp_is_1st = false;
|
||||
}
|
||||
for (int j = 0; j < seg_pos; j += 2) {
|
||||
if (j != 0) tmp_bfr.Add_byte(Byte_ascii.Slash);
|
||||
if (seg_ary[j] >= tmp_len) {
|
||||
tmp = qry;
|
||||
tmp_adj = src_len + 1;
|
||||
}
|
||||
tmp_bfr.Add_mid(tmp, seg_ary[j] - tmp_adj, seg_ary[j+1] - tmp_adj);
|
||||
}
|
||||
return tmp_bfr.XtoAryAndClear();
|
||||
}
|
||||
private static int[] seg_ary = new int[Xoa_ttl.Max_len];
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_xtn_rel2abs;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_rel2abs().Name_(name);}
|
||||
public static final int Id_null = 0, Id_slash = 1, Id_dot = 2, Id_dot_slash = 3, Id_dot_dot = 4, Id_dot_dot_slash = 5;
|
||||
}
|
||||
/*
|
||||
NOTE_1:approach (easiest explained with an example)
|
||||
given qry = "../C/./D" and src = "A/B"
|
||||
. combine two into a pseudo-array: "A/B/../C/./D"
|
||||
. iterate over every slash to create "segs_ary"
|
||||
A -> [A] add
|
||||
B -> [A, B] add
|
||||
.. -> [A] pop
|
||||
C -> [A, C] add
|
||||
. -> [A, C] noop
|
||||
D -> [A, C, D] add
|
||||
*/
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
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_rel2abs_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Slash_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d|a/b/c}}" , "{{test}}" , "a/b/c/d");}
|
||||
@Test public void Cur_lvl1() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:./d|a}}" , "{{test}}" , "a/d");}
|
||||
@Test public void Cur_lvl2() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:./d|a/b}}" , "{{test}}" , "a/b/d");}
|
||||
@Test public void Cur_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:./d|a/b/c}}" , "{{test}}" , "a/b/c/d");}
|
||||
@Test public void Owner_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:../d|a/b/c}}" , "{{test}}" , "a/b/d");}
|
||||
@Test public void Owner_cur_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:../.|a/b/c}}" , "{{test}}" , "a/b");}
|
||||
@Test public void Text_lvl3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:d|a/b/c}}" , "{{test}}" , "d");}
|
||||
@Test public void Slash_mult() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d//e|a/b/c}}" , "{{test}}" , "a/b/c/d/e");}
|
||||
@Test public void Slash_cur_mult() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d/./e|a/b/c}}" , "{{test}}" , "a/b/c/d/e");}
|
||||
@Test public void Qry_ends_w_slash() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d/|a/b/c}}" , "{{test}}" , "a/b/c/d");}
|
||||
@Test public void Qry_is_empty() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:|a/b/c}}" , "{{test}}" , "a/b/c");}
|
||||
@Test public void Qry_is_dot() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:.|a/b/c}}" , "{{test}}" , "a/b/c");}
|
||||
@Test public void DotDot_mult2() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/../..|a/b/c}}" , "{{test}}" , "a");}
|
||||
@Test public void DotDot_mult3() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/../../..|a/b/c}}" , "{{test}}" , "");}
|
||||
@Test public void Src_is_empty() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/d|}}" , "{{test}}" , "Test page/d");}
|
||||
@Test public void Err_owner() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:..}}" , "{{test}}" , "");} // PURPOSE.fix: should not fail
|
||||
@Test public void Err_owner_2() {fxt.Test_parse_tmpl_str_test("{{#rel2abs:/../../b|a}}" , "{{test}}" , "");} // PURPOSE.fix: should not fail
|
||||
@Test public void Ns_should_be_included_for_cur_page() {// PURPOSE.fix: current title was not returning ns; EX: de.wikipedia.org/wiki/Hilfe:Vorlagenprogrammierung#Funktion_rel2abs
|
||||
fxt.Page_ttl_("Help:A"); // set page to title with namespace
|
||||
fxt.Test_parse_tmpl_str_test("{{#rel2abs:.}}" , "{{test}}" , "Help:A");
|
||||
}
|
||||
@Test public void Owner_lvl0() {// PURPOSE.fix: old rel2abs was producing "/c"; EX: de.wikipedia.org/wiki/Hilfe:Vorlagenprogrammierung#Funktion_rel2abs
|
||||
fxt.Test_parse_tmpl_str_test("{{#rel2abs:../c|a}}" , "{{test}}" , "c");
|
||||
}
|
||||
@Test public void Rel2abs_slash() {
|
||||
fxt.Page_ttl_("Page_1");
|
||||
fxt.Init_defn_clear();
|
||||
fxt.Init_defn_add("test" , "{{/B}}");
|
||||
fxt.Init_page_create("Page_1/B" , "Page_1/B text");
|
||||
fxt.Test_parse_tmpl_str("{{test}}" , "Page_1/B text");
|
||||
fxt.Init_defn_clear();
|
||||
}
|
||||
@Test public void Rel2abs_dot() {
|
||||
fxt.Page_ttl_("Page_1/A");
|
||||
fxt.Init_defn_clear();
|
||||
fxt.Init_defn_add("test" , "{{../C}}");
|
||||
fxt.Init_page_create("Page_1/C" , "Page_1/C text");
|
||||
fxt.Test_parse_tmpl_str("{{test}}" , "Page_1/C text");
|
||||
fxt.Init_defn_clear();
|
||||
}
|
||||
@Test public void Rel2abs_ttl() {
|
||||
Tst_rel2abs_ttl("a../b", true);
|
||||
Tst_rel2abs_ttl("a../[b", false);
|
||||
}
|
||||
private void Tst_rel2abs_ttl(String raw, boolean expd) {Tfds.Eq(expd, Pfunc_rel2abs.Rel2abs_ttl(Bry_.new_ascii_(raw), 0, String_.Len(raw)));}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import gplx.core.ints.*; import gplx.xowa.xtns.pfuncs.times.*;
|
||||
public class Pfunc_titleparts extends Pf_func_base {
|
||||
@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 bb) {// REF.MW:ParserFunctions_body.php
|
||||
// get argx
|
||||
int args_len = self.Args_len();
|
||||
byte[] argx = Eval_argx(ctx, src, caller, self); if (argx == null) return; // no argx; return empty
|
||||
Xoa_ttl argx_as_ttl = Xoa_ttl.new_(ctx.Wiki(), ctx.App().Msg_log_null(), argx, argx, 0, argx.length); // transform to title in order to upper first, replace _, etc..
|
||||
if (argx_as_ttl == null) {bb.Add(argx); return;} // NOTE: argx_as_ttl will be null if invalid, such as [[a|b]]; PAGE:en.w:owl and {{taxobox/showtaxon|Dinosauria}}
|
||||
else argx = argx_as_ttl.Full_txt();
|
||||
|
||||
// get parts_len
|
||||
byte[] parts_len_ary = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, args_len, 0);
|
||||
int parts_len = parts_len_ary == Bry_.Empty ? Int_.MinValue : Bry_.Xto_int_or(parts_len_ary, Int_.MaxValue);
|
||||
if (parts_len == Int_.MaxValue) {// len is not an int; EX: "a";
|
||||
ctx.Msg_log().Add_itm_none(Pfunc_titleparts_log.Len_is_invalid, src, caller.Src_bgn(), caller.Src_end());
|
||||
bb.Add(argx);
|
||||
return;
|
||||
}
|
||||
|
||||
// get parts_bgn
|
||||
byte[] parts_bgn_arg = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, args_len, 1);
|
||||
int parts_bgn = parts_bgn_arg == Bry_.Empty ? 0 : Bry_.Xto_int_or(parts_bgn_arg, Int_.MinValue);
|
||||
if (parts_bgn == Int_.MinValue) {// parts_bgn is not an int; EX: "a"
|
||||
ctx.Msg_log().Add_itm_none(Pfunc_titleparts_log.Bgn_is_invalid, src, caller.Src_bgn(), caller.Src_end());
|
||||
parts_bgn = 0; // NOTE: do not return
|
||||
}
|
||||
else if (parts_bgn > 0) parts_bgn -= ListAdp_.Base1; // adjust for base1
|
||||
bb.Add(TitleParts(argx, parts_len, parts_bgn));
|
||||
}
|
||||
private byte[] TitleParts(byte[] src, int parts_len, int parts_bgn) {
|
||||
// find dlm positions; EX: ab/cde/f/ will have -1,2,6,8
|
||||
int src_len = src.length; int dlms_ary_len = 1; // 1 b/c dlms_ary[0] will always be -1
|
||||
for (int i = 0; i < src_len; i++) {
|
||||
if (src[i] == Byte_ascii.Slash) dlms_ary[dlms_ary_len++] = i;
|
||||
}
|
||||
dlms_ary[dlms_ary_len] = src_len; // put src_len into last dlms_ary; makes dlms_ary[] logic easier
|
||||
|
||||
// calc bgn_idx; must occur before adjust parts_len
|
||||
int bgn_idx = parts_bgn > -1 ? parts_bgn : parts_bgn + dlms_ary_len; // negative parts_bgn means calc from end of dlms_ary_len; EX a/b/c|1|-1 means start from 2
|
||||
if ( bgn_idx < 0 // bgn_idx can be negative when parts_len is negative and greater than array; EX: {{#titleparts:a/b|-1|-2}} results in dlms_ary_len of 1 and parts_bgn of -2 which will be parts_bgn of -1
|
||||
|| bgn_idx > dlms_ary_len) return Bry_.Empty; // if bgn > len, return ""; EX: {{#titleparts:a/b|1|3}} should return ""
|
||||
|
||||
// adjust parts_len for negative/null
|
||||
if (parts_len == Int_.MinValue) parts_len = dlms_ary_len; // no parts_len; default to dlms_ary_len
|
||||
else if (parts_len < 0) { // neg parts_len; shorten parts now and default to rest of String; EX: a/b/c|-1 -> makes String a/b/c and get 2 parts
|
||||
dlms_ary_len += parts_len;
|
||||
parts_len = dlms_ary_len;
|
||||
if (parts_len < 1) return Bry_.Empty; // NOTE: if zerod'd b/c of neg length, return empty; contrast with line below; EX: a/b/c|-4
|
||||
}
|
||||
if (parts_len == 0) return src; // if no dlms, return orig
|
||||
|
||||
// calc idxs for extraction
|
||||
int bgn_pos = dlms_ary[bgn_idx] + 1; // +1 to start after slash
|
||||
int end_idx = bgn_idx + parts_len;
|
||||
int end_pos = end_idx > dlms_ary_len ? dlms_ary[dlms_ary_len] : dlms_ary[end_idx];
|
||||
if (end_pos < bgn_pos) return Bry_.Empty;
|
||||
return Bry_.Mid(src, bgn_pos, end_pos);
|
||||
} static int[] dlms_ary = new Int_ary_bldr(255).Set(0, -1).Xto_int_ary(); // set pos0 to -1; makes +1 logic easier
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_xtn_titleparts;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_titleparts().Name_(name);}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
|
||||
import org.junit.*;
|
||||
public class Pfunc_titleparts_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Len1() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|1}}" , "{{test}}", "A");}
|
||||
@Test public void Len2() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|2}}" , "{{test}}", "A/b");}
|
||||
@Test public void Len2_Bgn2() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|2|2}}" , "{{test}}", "b/c");}
|
||||
@Test public void LenNeg1() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|-1}}" , "{{test}}", "A/b/c");}
|
||||
@Test public void LenNeg1Bgn2() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|-1|2}}" , "{{test}}", "b/c");}
|
||||
|
||||
@Test public void Exc_len0() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|0}}" , "{{test}}", "A/b/c/d");}
|
||||
@Test public void Exc_lenNeg4() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|-4}}" , "{{test}}", "");}
|
||||
@Test public void Exc_lenNeg5() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|-5}}" , "{{test}}", "");}
|
||||
@Test public void Exc_no_dlm() {fxt.Test_parse_tmpl_str_test("{{#titleparts:abcd|1}}" , "{{test}}", "Abcd");}
|
||||
@Test public void Exc_parts0() {fxt.Test_parse_tmpl_str_test("{{#titleparts:abcd|0}}" , "{{test}}", "Abcd");}
|
||||
@Test public void Exc_many_segs() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b|1|4}}" , "{{test}}", "");} // PURPOSE: bgn=4, len=1 requested; only bgn=1,2 available
|
||||
|
||||
@Test public void Exc_bad_len() {fxt.Init_log_(Pfunc_titleparts_log.Len_is_invalid).Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|bad}}" , "{{test}}", "A/b/c/d");}
|
||||
@Test public void Exc_bad_bgn() {fxt.Init_log_(Pfunc_titleparts_log.Bgn_is_invalid).Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d|1|bad}}" , "{{test}}", "A");}
|
||||
@Test public void Exc_1() {fxt.Test_parse_tmpl_str_test("{{#titleparts:50|1|1}}" , "{{test}}", "50");}
|
||||
@Test public void Exc_2() {fxt.Test_parse_tmpl_str_test("{{#titleparts:50|1|2}}" , "{{test}}", "");}
|
||||
|
||||
@Test public void Lnki() {fxt.Test_parse_tmpl_str_test("{{#titleparts:[[a|b]]|1}}" , "{{test}}", "[[a|b]]");} // PURPOSE: invalid title was not being rendered
|
||||
@Test public void Invalid_table() {// PURPOSE: Template:Taxobox/showtaxon calls #titleparts on table fragments; do not remove new lines; PAGE:en.w:Owl
|
||||
fxt.Init_defn_clear();
|
||||
fxt.Init_defn_add("!", "|");
|
||||
fxt.Init_defn_add("!!", "||");
|
||||
fxt.Test_parse_tmpl_str_test
|
||||
( String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "{{#titleparts:"
|
||||
, "{{!}} Order: {{!!}} '''Strigiformes'''"
|
||||
, "{{!}}-|1}}"
|
||||
, "|}"
|
||||
)
|
||||
, "{{test}}"
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "" // NOTE: don't know why this new line is necessary, but hopefully it is benign
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "| Order: || '''Strigiformes'''"
|
||||
, "|-"
|
||||
, "|}"
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Invalid_xml() {// PURPOSE: handle calls like {{#titleparts:a<span id='b'>c</span>d|1}}; PAGE:en.w:Triceratops
|
||||
fxt.Test_parse_tmpl_str_test
|
||||
( "{{#titleparts:a<span id='b'>c</span>d/e|1}}"
|
||||
, "{{test}}"
|
||||
, "a<span id='b'>c</span>d/e"
|
||||
);
|
||||
}
|
||||
@Test public void Bgn_neg_1() {fxt.Test_parse_tmpl_str_test("{{#titleparts:a/b/c/d||-1}}" , "{{test}}", "d");}
|
||||
@Test public void Bgn_neg_2() { // PURPOSE: EX: Wikisource:Requests for comment/Annotations and derivative works; DATE:2013-12-19
|
||||
fxt.Test_parse_tmpl_str_test
|
||||
( "{{#titleparts:a/b|-1|-2}}"
|
||||
, "{{test}}"
|
||||
, "A"
|
||||
);
|
||||
}
|
||||
}
|
||||
29
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlencode.java
Normal file
29
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlencode.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
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_urlencode extends Pf_func_base { // EX: {{urlencode:a b}} -> a+b
|
||||
@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 bb) {
|
||||
byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return;
|
||||
ctx.App().Encoder_mgr().Url().Encode(urlEncodeBfr, val_ary);
|
||||
bb.Add_bfr_and_preserve(urlEncodeBfr);
|
||||
urlEncodeBfr.Clear();
|
||||
} private Bry_bfr urlEncodeBfr = Bry_bfr.new_(128);
|
||||
@Override public int Id() {return Xol_kwd_grp_.Id_url_urlencode;}
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_urlencode().Name_(name);}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
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_urlencode_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Numbers() {fxt.Test_parse_tmpl_str_test("{{urlencode:0123456789}}" , "{{test}}", "0123456789");}
|
||||
@Test public void Ltrs_lower() {fxt.Test_parse_tmpl_str_test("{{urlencode:abcdefghijklmnopqrstuvwxyz}}" , "{{test}}", "abcdefghijklmnopqrstuvwxyz");}
|
||||
@Test public void Ltrs_upper() {fxt.Test_parse_tmpl_str_test("{{urlencode:ABCDEFGHIJKLMNOPQRSTUVWXYZ}}" , "{{test}}", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");}
|
||||
@Test public void Syms_allowed() {fxt.Test_parse_tmpl_str_test("{{urlencode:-_.}}" , "{{test}}", "-_.");}
|
||||
@Test public void Space() {fxt.Test_parse_tmpl_str_test("{{urlencode:a b}}" , "{{test}}", "a+b");}
|
||||
@Test public void Syms() {fxt.Test_parse_tmpl_str_test("{{urlencode:!?^~:}}" , "{{test}}", "%21%3F%5E%7E%3A");}
|
||||
@Test public void Extended() {fxt.Test_parse_tmpl_str_test("{{urlencode:aéb}}" , "{{test}}", "a%C3%A9b");}
|
||||
}
|
||||
63
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlfunc.java
Normal file
63
400_xowa/src/gplx/xowa/xtns/pfuncs/ttls/Pfunc_urlfunc.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
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_urlfunc extends Pf_func_base { // EX: {{lc:A}} -> a
|
||||
@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 bb) {
|
||||
byte[] val_dat_ary = Eval_argx(ctx, src, caller, self); if (val_dat_ary.length == 0) return;
|
||||
byte[] qry_arg = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self.Args_len(), 0);
|
||||
UrlString(ctx, tid, encode, val_dat_ary, bb, qry_arg);
|
||||
}
|
||||
public static void UrlString(Xop_ctx ctx, byte tid, boolean encode, byte[] src, Bry_bfr trg, byte[] qry_arg) {
|
||||
Xow_wiki wiki = ctx.Wiki();
|
||||
Xoa_ttl ttl = Xoa_ttl.new_(wiki, ctx.Msg_log(), src, src, 0, src.length);
|
||||
if (ttl == null) return; // NOTE: guard against null ttl; EX: {{fullurl:{{transclude|{{{1}}}}}|action=edit}} -> {{fullurl:Template:{{{1}}}|action=edit}} -> Template:{{{1}}} will be a null ttl
|
||||
byte[] ttl_ary = ttl.Full_url();// NOTE: Full_url does encoding; don't encode again
|
||||
Xow_xwiki_itm xwiki = ttl.Wik_itm();
|
||||
if (xwiki != null) { // xwiki exists; add as //commons.wikimedia.org/wiki/A#b?c=d
|
||||
if (tid == Tid_canonical)
|
||||
trg.Add(Xoh_href_parser.Href_http_bry); // "http://"
|
||||
else
|
||||
trg.Add(Xoa_consts.Url_relative_prefix); // "//"
|
||||
trg.Add(xwiki.Domain()) // "commons.wikimedia.org"
|
||||
.Add(Xoh_href_parser.Href_wiki_bry) // "/wiki/"
|
||||
.Add_mid(ttl_ary, xwiki.Key().length + 1, ttl_ary.length); // "A#b?c=d"; +1 for colon after "commons:"; NOTE: ugly way of getting rest of url, but ttl currently does not have Full_wo_wiki
|
||||
}
|
||||
else {
|
||||
Bry_bfr tmp_bfr = ctx.App().Utl_bry_bfr_mkr().Get_b512().Mkr_rls();
|
||||
switch (tid) {
|
||||
case Tid_local: tmp_bfr.Add(ctx.Wiki().Props().ArticlePath());break;
|
||||
case Tid_full: tmp_bfr.Add(Bry_relative_url).Add(ctx.Wiki().Props().ServerName()).Add(ctx.Wiki().Props().ArticlePath()); break;
|
||||
case Tid_canonical: tmp_bfr.Add(ctx.Wiki().Props().Server()).Add(ctx.Wiki().Props().ArticlePath()); break;
|
||||
default: throw Err_.unhandled(tid);
|
||||
}
|
||||
tmp_bfr.Add(ttl_ary);
|
||||
trg.Add_bfr_and_clear(tmp_bfr);
|
||||
}
|
||||
if (qry_arg != Bry_.Empty) trg.Add_byte(Byte_ascii.Question).Add(qry_arg);
|
||||
}
|
||||
public Pfunc_urlfunc(int id, byte tid, boolean encode) {this.id = id; this.tid = tid; this.encode = encode;} private byte tid; boolean encode;
|
||||
@Override public int Id() {return id;} private int id;
|
||||
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_urlfunc(id, tid, encode).Name_(name);}
|
||||
public static final byte Tid_local = 0, Tid_full = 1, Tid_canonical = 2;
|
||||
public static final byte[] Bry_relative_url = Bry_.new_ascii_("//");
|
||||
}
|
||||
/*
|
||||
NOTE: Both fullurle: and localurle: performed additional character escaping on the resulting link, but no example is known where that still has any additional effect.
|
||||
http://meta.wikimedia.org/wiki/Help:Parser_function
|
||||
*/
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
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_urlfunc_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Before public void init() {fxt.Reset();}
|
||||
@Test public void Localurl() {fxt.Test_parse_tmpl_str_test("{{localurl:a&b! c}}" , "{{test}}", "/wiki/A%26b!_c");}
|
||||
@Test public void Fullurl() {fxt.Test_parse_tmpl_str_test("{{fullurl:a&b! c}}" , "{{test}}", "//en.wikipedia.org/wiki/A%26b!_c");}
|
||||
@Test public void Canonicalurl() {fxt.Test_parse_tmpl_str_test("{{canonicalurl:a&b! c}}" , "{{test}}", "http://en.wikipedia.org/wiki/A%26b!_c");}
|
||||
@Test public void Canonicalurl_case() {fxt.Test_parse_tmpl_str_test("{{CANONICALURL:a&b! c}}" , "{{test}}", "http://en.wikipedia.org/wiki/A%26b!_c");}
|
||||
@Test public void Localurle() {fxt.Test_parse_tmpl_str_test("{{localurle:a&b! c}}" , "{{test}}", "/wiki/A%26b!_c");}
|
||||
@Test public void Fullurle() {fxt.Test_parse_tmpl_str_test("{{fullurle:a&b! c}}" , "{{test}}", "//en.wikipedia.org/wiki/A%26b!_c");}
|
||||
@Test public void Canonicalurle() {fxt.Test_parse_tmpl_str_test("{{canonicalurle:a&b! c}}" , "{{test}}", "http://en.wikipedia.org/wiki/A%26b!_c");}
|
||||
@Test public void Fullurl_arg() {fxt.Test_parse_tmpl_str_test("{{fullurle:a&b! c|action=edit}}" , "{{test}}", "//en.wikipedia.org/wiki/A%26b!_c?action=edit");}
|
||||
@Test public void Random() {fxt.Test_parse_tmpl_str_test("{{fullurle:a&b! c|action=edit}}" , "{{test|a|b|c}}", "//en.wikipedia.org/wiki/A%26b!_c?action=edit");}
|
||||
@Test public void Xwiki() {
|
||||
fxt.Wiki().Xwiki_mgr().Add_full("commons", "commons.wikimedia.org");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{localurl:commons:A}}" , "{{test}}", "//commons.wikimedia.org/wiki/A");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{fullurl:commons:A}}" , "{{test}}", "//commons.wikimedia.org/wiki/A");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{canonicalurl:commons:A}}" , "{{test}}", "http://commons.wikimedia.org/wiki/A");
|
||||
}
|
||||
@Test public void Xwiki_qarg_fix() {
|
||||
fxt.Wiki().Xwiki_mgr().Add_full("commons", "commons.wikimedia.org");
|
||||
fxt.Reset().Test_parse_tmpl_str_test("{{fullurl:commons:A|key=val}}" , "{{test}}", "//commons.wikimedia.org/wiki/A?key=val");
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ public class Poem_lxr_pre implements Xop_lxr {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bgn_pos != Xop_parser_.Doc_bgn_bos) { // do not add xnde/nl if \n is BOS \n; EX.WP: Teresa of Ávila; "<poem>\n\s\s"
|
||||
if (bgn_pos != Xop_parser_.Doc_bgn_bos) { // do not add xnde/nl if \n is BOS \n; PAGE:en.w:Teresa of Ávila; "<poem>\n\s\s"
|
||||
ctx.Subs_add(root, tkn_mkr.Xnde(cur_pos, cur_pos).Tag_(Xop_xnde_tag_.Tag_br));
|
||||
ctx.Subs_add(root, tkn_mkr.NewLine(cur_pos, cur_pos, Xop_nl_tkn.Tid_char, 1));
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ class Pp_index_parser {
|
||||
Inspect_tmpl(rv, src, index_root, index_root.Subs_len(), ns_page_id, 1);
|
||||
sub_parser.Parse_wtxt_to_wdom(index_root, sub_ctx, tkn_mkr, mid_text, Xop_parser_.Doc_bgn_bos);
|
||||
rv.Src_(mid_text);
|
||||
Inspect_wiki(rv, src, index_root, index_root.Subs_len(), ns_page_id, 1);
|
||||
Inspect_wiki(rv, mid_text, index_root, index_root.Subs_len(), ns_page_id, 1); // changed from src to mid_text; DATE:2014-07-14
|
||||
return rv;
|
||||
}
|
||||
private static void Inspect_tmpl(Pp_index_page rv, byte[] src, Xop_tkn_itm_base owner, int owner_len, int ns_page_id, int depth) {
|
||||
|
||||
@@ -118,14 +118,16 @@ public class Pp_pages_nde implements Xox_xnde, Xop_xnde_atr_parser {
|
||||
} private static final byte[] Toc_bry = Bry_.new_ascii_("toc");
|
||||
private byte[] Make_lnki(Bry_bfr full_bfr, byte[] index_page_src, Xop_lnki_tkn lnki) {
|
||||
byte[] caption = Get_caption(full_bfr, index_page_src, lnki);
|
||||
return full_bfr
|
||||
.Add(Xop_tkn_.Lnki_bgn)
|
||||
.Add(lnki.Ttl().Full_db())
|
||||
.Add_byte_pipe()
|
||||
full_bfr.Add(Xop_tkn_.Lnki_bgn);
|
||||
Xoa_ttl lnki_ttl = lnki.Ttl();
|
||||
if (lnki_ttl.Wik_bgn() == -1) // no xwiki; just add ns + page
|
||||
full_bfr.Add(lnki_ttl.Full_db());
|
||||
else // xwiki; add entire ttl which also includes xwiki; PAGE:sv.s:Valda_dikter_(Bj<42>rck); EX:[[:Commons:File:Valda dikter (tredje upplagan).djvu|Commons]]; DATE:2014-07-14
|
||||
full_bfr.Add(lnki_ttl.Raw());
|
||||
full_bfr.Add_byte_pipe()
|
||||
.Add(caption)
|
||||
.Add(Xop_tkn_.Lnki_end)
|
||||
.XtoAryAndClear()
|
||||
;
|
||||
.Add(Xop_tkn_.Lnki_end);
|
||||
return full_bfr.XtoAryAndClear();
|
||||
}
|
||||
private byte[] Get_caption(Bry_bfr full_bfr, byte[] index_page_src, Xop_lnki_tkn lnki) {
|
||||
byte[] rv = Bry_.Empty;
|
||||
@@ -262,7 +264,7 @@ public class Pp_pages_nde implements Xox_xnde, Xop_xnde_atr_parser {
|
||||
Xodb_page page = (Xodb_page)rslt.FetchAt(i);
|
||||
Xoa_ttl page_ttl = Xoa_ttl.parse_(wiki, ns_page_id, page.Ttl_wo_ns()); if (page_ttl == null) continue; // page_ttl is not valid; should never happen;
|
||||
byte[] page_ttl_leaf = page_ttl.Leaf_txt(); if (page_ttl_leaf == null) continue; // page is not leaf; should not happen
|
||||
int page_leaf_val = Bry_.X_to_int_or(page_ttl_leaf, Int_.MinValue); if (page_leaf_val == Int_.MinValue) continue; // leaf is not int; ignore
|
||||
int page_leaf_val = Bry_.Xto_int_or(page_ttl_leaf, Int_.MinValue); if (page_leaf_val == Int_.MinValue) continue; // leaf is not int; ignore
|
||||
if (page_leaf_val > page_leaf_max) page_leaf_max = page_leaf_val;
|
||||
}
|
||||
return page_leaf_max;
|
||||
@@ -308,7 +310,7 @@ public class Pp_pages_nde implements Xox_xnde, Xop_xnde_atr_parser {
|
||||
step_int = 1;
|
||||
return true;
|
||||
}
|
||||
step_int = Bry_.X_to_int_or(step_bry, Int_.MinValue);
|
||||
step_int = Bry_.Xto_int_or(step_bry, Int_.MinValue);
|
||||
if (step_int < 1 || step_int > 1000) {
|
||||
Fail_args("pages node does not have a valid 'step': step={0}", String_.new_utf8_(step_bry));
|
||||
return false;
|
||||
|
||||
@@ -137,4 +137,20 @@ public class Pp_pages_nde_hdr_tst {
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
@Test public void Xwiki() { // PURPOSE: Mainspace links should be sent to toc; DATE:2014-01-27
|
||||
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
|
||||
fxt.Init_page_create("Index:A" , String_.Concat_lines_nl_skip_last
|
||||
( "[[Page/1]]"
|
||||
, "[[:commons:File:A.png]]"
|
||||
));
|
||||
// next only
|
||||
fxt.Page_ttl_("Page/1");
|
||||
fxt.Test_parse_page_wiki_str("<pages index='A' />", String_.Concat_lines_nl
|
||||
( "<p>value=toc;current=<b>Page/1</b>;next=<a href=\"/site/commons.wikimedia.org/wiki/File:A.png\">File:A.png</a>;"
|
||||
, "</p>"
|
||||
, ""
|
||||
, "<p><br/>"
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
26
400_xowa/src/gplx/xowa/xtns/quiz/Quiz_xnde.java
Normal file
26
400_xowa/src/gplx/xowa/xtns/quiz/Quiz_xnde.java
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
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.quiz; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.xowa.html.*;
|
||||
import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.logs.*;
|
||||
public class Quiz_xnde implements Xox_xnde {
|
||||
public void Xtn_parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {}
|
||||
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) {
|
||||
Xox_mgr_base.Xtn_write_unsupported(app, ctx, bfr, src, xnde, Xox_mgr_base.Parse_content_tid_none);
|
||||
}
|
||||
}
|
||||
25
400_xowa/src/gplx/xowa/xtns/quiz/Quiz_xnde_tst.java
Normal file
25
400_xowa/src/gplx/xowa/xtns/quiz/Quiz_xnde_tst.java
Normal 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.quiz; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import org.junit.*;
|
||||
public class Quiz_xnde_tst {
|
||||
@Before public void init() {fxt.Reset();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Test_parse_page_all_str("<quiz>test</quiz>", "XOWA does not support this extension: <quiz></quiz>");
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa.xtns.rss; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.xowa.html.*;
|
||||
import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.logs.*;
|
||||
public class Rss_xnde implements Xox_xnde { // TODO: not implemented
|
||||
public class Rss_xnde implements Xox_xnde {
|
||||
public void Xtn_parse(Xow_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {}
|
||||
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) {
|
||||
Xox_mgr_base.Xtn_write_unsupported(app, ctx, bfr, src, xnde, true);
|
||||
Xox_mgr_base.Xtn_write_unsupported(app, ctx, bfr, src, xnde, Xox_mgr_base.Parse_content_tid_html);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,6 +145,11 @@ public class Scrib_core {
|
||||
@gplx.Internal protected void Frame_parent_(Xot_invk v) {frame_parent = v;} // TEST:
|
||||
public Xop_ctx Ctx() {return ctx;} private Xop_ctx ctx;
|
||||
public byte[] Cur_src() {return cur_src;} private byte[] cur_src; // only used for error reporting
|
||||
public void Invoke_init(Xow_wiki wiki, Xop_ctx ctx, byte[] src, Xot_invk parent_frame, Xot_invk current_frame) { // TEST
|
||||
this.wiki = wiki; this.ctx = ctx; this.cur_src = src;
|
||||
lib_mw.Invoke_bgn(wiki, ctx, src);
|
||||
this.frame_parent = parent_frame; this.frame_current = current_frame;
|
||||
}
|
||||
public void Invoke(Xow_wiki wiki, Xop_ctx ctx, byte[] src, Xot_invk parent_frame, Xot_invk current_frame, Bry_bfr bfr, byte[] mod_name, byte[] mod_text, byte[] fnc_name) {
|
||||
this.wiki = wiki; this.ctx = ctx; this.cur_src = src;
|
||||
lib_mw.Invoke_bgn(wiki, ctx, src);
|
||||
@@ -153,14 +158,12 @@ public class Scrib_core {
|
||||
parent_frame.Scrib_frame_tid_(Scrib_frame_.Tid_parent); current_frame.Scrib_frame_tid_(Scrib_frame_.Tid_current);
|
||||
try {
|
||||
Scrib_lua_mod mod = Mods_get_or_new(mod_name, mod_text);
|
||||
// KeyVal[] fnc_args = Scrib_kv_utl_.base1_obj_(mod.Fncs_get_by_key(String_.new_utf8_(fnc_name)));
|
||||
// KeyVal[] rv = engine.CallFunction(lib_mw.Mod().Fncs_get_id("executeFunction"), fnc_args);
|
||||
KeyVal[] fnc_args = Scrib_kv_utl_.base1_many_(mod.Init_chunk_func(), String_.new_utf8_(fnc_name));
|
||||
KeyVal[] rv = engine.CallFunction(lib_mw.Mod().Fncs_get_id("executeModule"), fnc_args);
|
||||
Scrib_lua_proc proc = (Scrib_lua_proc)rv[1].Val();
|
||||
fnc_args = Scrib_kv_utl_.base1_many_(proc);
|
||||
rv = engine.CallFunction(lib_mw.Mod().Fncs_get_id("executeFunction"), fnc_args);
|
||||
String rslt = Scrib_kv_utl_.Val_to_str(rv, 0); // NOTE: expects an array with 1 scalar value
|
||||
KeyVal[] func_args = Scrib_kv_utl_.base1_many_(mod.Init_chunk_func(), String_.new_utf8_(fnc_name));
|
||||
KeyVal[] func_rslt = engine.CallFunction(lib_mw.Mod().Fncs_get_id("executeModule"), func_args); // call init_chunk to get proc dynamically; DATE:2014-07-12
|
||||
Scrib_lua_proc proc = (Scrib_lua_proc)func_rslt[1].Val(); // note that init_chunk should have: [0]:true/false result; [1]:proc
|
||||
func_args = Scrib_kv_utl_.base1_many_(proc);
|
||||
func_rslt = engine.CallFunction(lib_mw.Mod().Fncs_get_id("executeFunction"), func_args); // call function now
|
||||
String rslt = Scrib_kv_utl_.Val_to_str(func_rslt, 0); // rslt expects an array with 1 scalar value
|
||||
bfr.Add_str(rslt);
|
||||
}
|
||||
finally {
|
||||
@@ -178,7 +181,6 @@ public class Scrib_core {
|
||||
rv.LoadString(String_.new_utf8_(mod_text));
|
||||
mods.Add(mod_name, rv);
|
||||
}
|
||||
// rv.Execute(); // TODO: move inside rv == null
|
||||
return rv;
|
||||
}
|
||||
public static Scrib_core Core() {return core;} public static Scrib_core Core_new_(Xoa_app app, Xop_ctx ctx) {core = new Scrib_core(app, ctx); return core;} private static Scrib_core core;
|
||||
|
||||
@@ -131,13 +131,6 @@ public class Scrib_core_fxt {
|
||||
Test_server_logs();
|
||||
return this;
|
||||
}
|
||||
public Scrib_core_fxt Test_ParentFrameExists(boolean init_parent_frame) {
|
||||
if (init_parent_frame)
|
||||
core.Frame_parent_(Xot_invk_mock.new_());
|
||||
core.Interpreter().ExecuteModule(9);
|
||||
Test_server_logs();
|
||||
return this;
|
||||
}
|
||||
public Scrib_core_fxt Test_Invoke(String mod_name, String mod_code, String prc_name, KeyVal... args) {
|
||||
core.Invoke(wiki, core.Ctx(), Bry_.Empty, Xot_invk_mock.Null, Xot_invk_mock.new_(args), tmp_bfr, Bry_.new_utf8_(mod_name), Bry_.new_utf8_(mod_code), Bry_.new_utf8_(prc_name));
|
||||
Test_server_logs();
|
||||
|
||||
@@ -19,7 +19,11 @@ package gplx.xowa.xtns.scribunto; import gplx.*; import gplx.xowa.*; import gplx
|
||||
import gplx.xowa.xtns.scribunto.lib.*;
|
||||
import gplx.xowa.xtns.scribunto.engines.process.*;
|
||||
public class Scrib_invoke_func_fxt {
|
||||
public void Clear() {
|
||||
private Xop_fxt fxt; Bry_bfr tmp_bfr = Bry_bfr.reset_(255); Scrib_core core; Process_server_mock server; Scrib_lua_rsp_bldr rsp_bldr = new Scrib_lua_rsp_bldr();
|
||||
public Xop_fxt Parser_fxt() {return fxt;}
|
||||
public Scrib_core_fxt Core_fxt() {return core_fxt;} Scrib_core_fxt core_fxt;
|
||||
public Scrib_core Core() {return core;}
|
||||
public void Clear_for_invoke() {
|
||||
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();
|
||||
core_fxt.Clear();
|
||||
@@ -33,13 +37,6 @@ public class Scrib_invoke_func_fxt {
|
||||
init_tmpl = init_page = null;
|
||||
fxt.Init_page_create("Module:Mod_0");
|
||||
this.Init_lua_rcvd_loadModule();
|
||||
} private Xop_fxt fxt; Bry_bfr tmp_bfr = Bry_bfr.reset_(255); Scrib_core core; Process_server_mock server; Scrib_lua_rsp_bldr rsp_bldr = new Scrib_lua_rsp_bldr();
|
||||
public Xop_fxt Parser_fxt() {return fxt;}
|
||||
public Scrib_core_fxt Core_fxt() {return core_fxt;} Scrib_core_fxt core_fxt;
|
||||
public Scrib_core Core() {return core;}
|
||||
public Scrib_invoke_func_fxt Init_module(String ttl, String text) {
|
||||
fxt.Init_page_create("Module:" + ttl, text);
|
||||
return this;
|
||||
}
|
||||
public Scrib_invoke_func_fxt Init_cbk(String lib_name, Scrib_lib lib, String... proc_names) {
|
||||
int len = proc_names.length;
|
||||
@@ -50,7 +47,6 @@ public class Scrib_invoke_func_fxt {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Scrib_invoke_func_fxt Init_lua_module() {this.Init_lua_rcvd_executeModule(); return this;}
|
||||
public Scrib_invoke_func_fxt Init_tmpl(String v) {init_tmpl = v; return this;} private String init_tmpl;
|
||||
public Scrib_invoke_func_fxt Init_page(String v) {init_page = v; return this;} private String init_page;
|
||||
public Scrib_invoke_func_fxt Init_server_print_key_y_() {server.Print_key_(true); return this;}
|
||||
@@ -60,18 +56,14 @@ public class Scrib_invoke_func_fxt {
|
||||
server.Prep_add(rsp_bldr.Bld_mw_cbk(cbk_name, ary));
|
||||
return this;
|
||||
}
|
||||
public Scrib_invoke_func_fxt Init_lua_rcvd_loadModule() {
|
||||
public Scrib_invoke_func_fxt Init_lua_module() {
|
||||
server.Prep_add("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:2:{i:1;b:1;i:2;O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:14;}}}");
|
||||
return this;
|
||||
}
|
||||
private Scrib_invoke_func_fxt Init_lua_rcvd_loadModule() {
|
||||
server.Prep_add("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;i:1;}}");
|
||||
return this;
|
||||
}
|
||||
public Scrib_invoke_func_fxt Init_lua_rcvd_executeModule() {
|
||||
server.Prep_add("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;a:1:{s:5:\"Prc_0\";O:42:\"Scribunto_LuaStandaloneInterpreterFunction\":1:{s:2:\"id\";i:14;}}}}");
|
||||
return this;
|
||||
}
|
||||
public Scrib_invoke_func_fxt Init_lua_rcvd_executeFunctionChunk() {
|
||||
server.Prep_add("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:11:\"arg_0,arg_1\";}}");
|
||||
return this;
|
||||
}
|
||||
public Scrib_invoke_func_fxt Init_lua_rcvd_preprocess(String frame, String cmd) {
|
||||
server.Prep_add(String_.Concat_any("a:4:{s:2:\"id\";s:23:\"mw_interface-preprocess\";s:2:\"op\";s:4:\"call\";s:5:\"nargs\";i:2;s:4:\"args\";a:2:{i:1;s:", String_.Len(frame), ":\"", frame, "\";i:2;s:", String_.Len(cmd), ":\"", cmd, "\";}}"));
|
||||
this.Init_lua_rcvd_rv();
|
||||
@@ -87,10 +79,6 @@ public class Scrib_invoke_func_fxt {
|
||||
server.Prep_add_dynamic_val();
|
||||
return this;
|
||||
}
|
||||
public Scrib_invoke_func_fxt Expd_lua_send(String v) {
|
||||
expd_lua_send = v;
|
||||
return this;
|
||||
} String expd_lua_send;
|
||||
public void Test_invoke(String expd) {
|
||||
if (init_tmpl != null) fxt.Init_defn_add("test", init_tmpl);
|
||||
fxt.Test_parse_tmpl_str(init_page, expd);
|
||||
@@ -100,23 +88,11 @@ public class Scrib_invoke_func_fxt {
|
||||
byte[] expd_err = tmp_bfr.XtoAryAndClear();
|
||||
fxt.Test_parse_page_tmpl_str(raw, String_.new_utf8_(expd_err));
|
||||
}
|
||||
public Object Test_lib_proc_direct(Scrib_lib lib, String proc_key, Object[] args_ary) {
|
||||
int proc_id = lib.Procs().Get_by_key(proc_key).Proc_id();
|
||||
Scrib_proc_args args = new Scrib_proc_args(Scrib_kv_utl_.base1_many_(args_ary));
|
||||
Scrib_proc_rslt rslt = new Scrib_proc_rslt();
|
||||
lib.Procs_exec(proc_id, args, rslt);
|
||||
return rslt.Ary()[0].Val();
|
||||
}
|
||||
public void Test_lib_proc(Scrib_lib lib, String func_name, Object[] args, String expd) {Test_lib_proc_kv(lib, func_name, Scrib_kv_utl_.base1_many_(args), expd);}
|
||||
public void Test_lib_proc_kv(Scrib_lib lib, String func_name, KeyVal[] args, String expd) {
|
||||
Test_lib_proc_internal(lib, func_name, args);
|
||||
this.Test_invoke(expd);
|
||||
}
|
||||
public byte[] Test_lib_proc_rv(Scrib_lib lib, String func_name, Object[] args) {
|
||||
Test_lib_proc_internal(lib, func_name, Scrib_kv_utl_.base1_many_(args));
|
||||
if (init_tmpl != null) fxt.Init_defn_add("test", init_tmpl);
|
||||
return fxt.Test_parse_tmpl_str_rv(init_page);
|
||||
}
|
||||
private void Test_lib_proc_internal(Scrib_lib lib, String func_name, KeyVal[] args) {
|
||||
Init_lua_module();
|
||||
this.Init_cbk(Scrib_core.Key_mw_interface, lib, func_name);
|
||||
@@ -126,20 +102,27 @@ public class Scrib_invoke_func_fxt {
|
||||
public void Test_log_rcvd(int i, String expd) {
|
||||
Tfds.Eq(expd, (String)server.Log_rcvd().FetchAt(i));
|
||||
}
|
||||
public void Init_scrib_proc() {
|
||||
public void Init_frame_parent(String ttl, KeyVal... ary) {
|
||||
core.Frame_parent_(Xot_invk_mock.test_(ary));
|
||||
core.Frame_parent().Frame_ttl_(Bry_.new_utf8_(ttl));
|
||||
}
|
||||
public void Init_frame_current(KeyVal... ary) {
|
||||
core.Frame_current_(Xot_invk_mock.test_(ary));
|
||||
core.Frame_current().Frame_ttl_(Bry_.new_ascii_("Module:Mod_0"));
|
||||
}
|
||||
public void Clear_for_lib() {
|
||||
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();
|
||||
core.Frame_parent_(Xot_invk_mock.new_());
|
||||
core.Frame_current_(Xot_invk_mock.new_());
|
||||
Io_mgr._.InitEngine_mem();
|
||||
fxt.Reset();
|
||||
Xot_invk parent_frame = new Xot_invk_temp(true); parent_frame.Scrib_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());
|
||||
}
|
||||
public void Test_scrib_proc_str(Scrib_lib lib, String proc_name, Object[] args, String expd) {Test_scrib_proc_str(lib, proc_name, Scrib_kv_utl_.base1_many_(args), expd);}
|
||||
public void Test_scrib_proc_str(Scrib_lib lib, String proc_name, KeyVal[] args, String expd) {
|
||||
KeyVal[] actl = Test_scrib_proc_rv(lib, proc_name, args);
|
||||
Tfds.Eq(Object_.XtoStr_OrNullStr(expd), Object_.XtoStr_OrNullStr(actl[0].Val()));
|
||||
Tfds.Eq(Object_.Xto_str_strict_or_null_mark(expd), Object_.Xto_str_strict_or_null_mark(actl[0].Val()));
|
||||
}
|
||||
public void Test_scrib_proc_kv_vals(Scrib_lib lib, String proc_name, Object[] args, String expd) {Test_scrib_proc_kv_vals(lib, proc_name, Scrib_kv_utl_.base1_many_(args), expd);}
|
||||
public void Test_scrib_proc_kv_vals(Scrib_lib lib, String proc_name, KeyVal[] args, String expd) {
|
||||
@@ -152,7 +135,7 @@ public class Scrib_invoke_func_fxt {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (i != 0) bfr.Add_byte(Byte_ascii.Semic);
|
||||
KeyVal kv = ary[i];
|
||||
bfr.Add_str(Object_.XtoStr_OrNullStr(kv.Val()));
|
||||
bfr.Add_str(Object_.Xto_str_strict_or_null_mark(kv.Val()));
|
||||
}
|
||||
return bfr.XtoStrAndClear();
|
||||
}
|
||||
|
||||
@@ -1,64 +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.scribunto; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.xtns.scribunto.lib.*;
|
||||
// public class Scrib_invoke_func_tst {
|
||||
// @Before public void init() {fxt.Clear();} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt();
|
||||
// @Test public void Err_mod_blank() {fxt.Test_parse_err("{{#invoke:}}", Scrib_invoke_func.Err_mod_missing);}
|
||||
// @Test public void Err_mod_missing() {fxt.Test_parse_err("{{#invoke:Missing}}", Scrib_invoke_func.Err_mod_missing);}
|
||||
// @Test public void Preprocess() {
|
||||
// this.Init_preprocess();
|
||||
// this.Exec_preprocess(Scrib_core.Frame_key_module , "1", "c");
|
||||
// this.Exec_preprocess(Scrib_core.Frame_key_module , "2", "d");
|
||||
// this.Exec_preprocess(Scrib_core.Frame_key_template , "1", "a");
|
||||
// this.Exec_preprocess(Scrib_core.Frame_key_template , "2", "b");
|
||||
// }
|
||||
// @Test public void ExpandTemplate() {
|
||||
// this.Init_expandTemplate();
|
||||
// fxt.Parser_fxt().Init_page_create("Template:Format", "{{{1}}}");
|
||||
// fxt.Init_lua_module();
|
||||
// fxt.Init_lua_rcvd_expandTemplate(Scrib_core.Frame_key_module , "Format", KeyVal_.int_(1, "a"));
|
||||
// fxt.Test_invoke("a");
|
||||
// }
|
||||
// @Test public void ExpandTemplate_ns_name() {
|
||||
// this.Init_expandTemplate();
|
||||
// fxt.Parser_fxt().Init_page_create("Template:Format", "{{{1}}}");
|
||||
// fxt.Init_lua_module();
|
||||
// fxt.Init_lua_rcvd_expandTemplate(Scrib_core.Frame_key_module , "Template:Format", KeyVal_.int_(1, "a"));
|
||||
// fxt.Test_invoke("a");
|
||||
// }
|
||||
// private void Init_preprocess() {
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Func_0|1|c|d}}"); // current
|
||||
// fxt.Init_page("{{test|1|a|b|c}}"); // parent
|
||||
// fxt.Core().Lib_mw().Init();
|
||||
// fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_mw(), Scrib_lib_mw.Invk_preprocess);
|
||||
// }
|
||||
// private void Exec_preprocess(String frame, String arg_idx, String expd) {
|
||||
// fxt.Parser_fxt().Wiki().Cache_mgr().Tmpl_result_cache().Clear();
|
||||
// fxt.Init_lua_module();
|
||||
// fxt.Init_lua_rcvd_preprocess(frame, "{{#ifeq:" + arg_idx + "|{{{1}}}|{{{2}}}|{{{3}}}}}");
|
||||
// fxt.Test_invoke(expd);
|
||||
// }
|
||||
// private void Init_expandTemplate() {
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Func_0|1|c|d}}"); // current
|
||||
// fxt.Init_page("{{test|null|1|a|b}}"); // parent
|
||||
// fxt.Core().Lib_mw().Init();
|
||||
// fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_mw(), Scrib_lib_mw.Invk_expandTemplate);
|
||||
// }
|
||||
// }
|
||||
@@ -51,8 +51,8 @@ public class Scrib_proc_args {
|
||||
public boolean Cast_bool_or_y(int i) {Object rv = Get_or_null(i); return rv == null ? Bool_.Y : Bool_.cast_(rv);}
|
||||
public boolean Cast_bool_or_n(int i) {Object rv = Get_or_null(i); return rv == null ? Bool_.N : Bool_.cast_(rv);}
|
||||
public int Cast_int_or(int i, int or) {Object rv = Get_or_null(i); return rv == null ? or : Int_.coerce_(rv);} // coerce to handle "1" and 1;
|
||||
public String Form_str_or_null(int i) {Object rv = Get_or_null(i); return rv == null ? null : Object_.XtoStr_OrNull(rv);} // NOTE: Modules can throw exceptions in which return value is nothing; do not fail; return ""; EX: -logy; DATE:2013-10-14
|
||||
public byte[] Form_bry_or_null(int i) {Object rv = Get_or_null(i); return rv == null ? null : Bry_.new_utf8_(Object_.XtoStr_OrNull(rv));}
|
||||
public String Xstr_str_or_null(int i) {Object rv = Get_or_null(i); return rv == null ? null : Object_.Xto_str_loose_or(rv, null);} // NOTE: Modules can throw exceptions in which return value is nothing; do not fail; return ""; EX: -logy; DATE:2013-10-14
|
||||
public byte[] Xstr_bry_or_null(int i) {Object rv = Get_or_null(i); return rv == null ? null : Bry_.new_utf8_(Object_.Xto_str_loose_or(rv, null));}
|
||||
public KeyVal[] Cast_kv_ary_or_null(int i) {Object rv = Get_or_null(i); return rv == null ? null : (KeyVal[])rv;}
|
||||
public KeyVal[] Pull_kv_ary(int i) {
|
||||
Object rv = Get_or_fail(i);
|
||||
|
||||
@@ -40,20 +40,20 @@ public class Scrib_xtn_mgr extends Xox_mgr_base {
|
||||
}
|
||||
public Xop_log_invoke_wkr Invoke_wkr() {return invoke_wkr;} private Xop_log_invoke_wkr invoke_wkr;
|
||||
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Invk_engine_type)) return Scrib_engine_type.X_to_str(engine_type);
|
||||
else if (ctx.Match(k, Invk_engine_type_)) Engine_type_(Scrib_engine_type.X_to_byte(m.ReadStr("v")));
|
||||
if (ctx.Match(k, Invk_engine_type)) return Scrib_engine_type.Xto_str(engine_type);
|
||||
else if (ctx.Match(k, Invk_engine_type_)) Engine_type_(Scrib_engine_type.Xto_byte(m.ReadStr("v")));
|
||||
else if (ctx.Match(k, Invk_engine_type_list)) return Scrib_engine_type.Options__list;
|
||||
else if (ctx.Match(k, Invk_lua_timeout)) return lua_timeout;
|
||||
else if (ctx.Match(k, Invk_lua_timeout_)) lua_timeout = m.ReadInt("v");
|
||||
else if (ctx.Match(k, Invk_lua_timeout_polling)) return lua_timeout_polling;
|
||||
else if (ctx.Match(k, Invk_lua_timeout_polling_)) lua_timeout_polling = m.ReadInt("v");
|
||||
else if (ctx.Match(k, Invk_lua_log_enabled)) return Yn.X_to_str(lua_log_enabled);
|
||||
else if (ctx.Match(k, Invk_lua_log_enabled)) return Yn.Xto_str(lua_log_enabled);
|
||||
else if (ctx.Match(k, Invk_lua_log_enabled_)) lua_log_enabled = m.ReadBool("v");
|
||||
else if (ctx.Match(k, Invk_lua_timeout_busy_wait)) return lua_timeout_busy_wait;
|
||||
else if (ctx.Match(k, Invk_lua_timeout_busy_wait_)) lua_timeout_busy_wait = m.ReadInt("v");
|
||||
else if (ctx.Match(k, Invk_lua_timeout_loop)) return lua_timeout_loop;
|
||||
else if (ctx.Match(k, Invk_lua_timeout_loop_)) lua_timeout_loop = m.ReadInt("v");
|
||||
else if (ctx.Match(k, Invk_luaj_debug_enabled)) return Yn.X_to_str(luaj_debug_enabled);
|
||||
else if (ctx.Match(k, Invk_luaj_debug_enabled)) return Yn.Xto_str(luaj_debug_enabled);
|
||||
else if (ctx.Match(k, Invk_luaj_debug_enabled_)) Luaj_debug_enabled_(m.ReadBool("v"));
|
||||
else if (ctx.Match(k, Invk_invoke_wkr)) return m.ReadYnOrY("v") ? Invoke_wkr_or_new() : GfoInvkAble_.Null;
|
||||
else return super.Invk(ctx, ikey, k, m);
|
||||
|
||||
@@ -17,14 +17,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.scribunto.engines; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
public class Scrib_engine_type {
|
||||
public static String X_to_str(byte v) {
|
||||
public static String Xto_str(byte v) {
|
||||
switch (v) {
|
||||
case Type_lua: return "lua";
|
||||
case Type_luaj: return "luaj";
|
||||
default: throw Err_.not_implemented_();
|
||||
}
|
||||
}
|
||||
public static byte X_to_byte(String s) {
|
||||
public static byte Xto_byte(String s) {
|
||||
if (String_.Eq(s, "lua")) return Type_lua;
|
||||
else if (String_.Eq(s, "luaj")) return Type_luaj;
|
||||
else throw Err_.not_implemented_();
|
||||
|
||||
@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.scribunto.engines.process; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.engines.*;
|
||||
public class Process_server_mock implements Scrib_server {
|
||||
ListAdp rsps = ListAdp_.new_(); int rsps_idx = 0;
|
||||
private ListAdp rsps = ListAdp_.new_(); private int rsps_idx = 0;
|
||||
public void Init(String... process_args) {}
|
||||
public int Server_timeout() {return server_timeout;} public Scrib_server Server_timeout_(int v) {server_timeout = v; return this;} private int server_timeout = 8000;
|
||||
public int Server_timeout_polling() {return server_timeout_polling;} public Scrib_server Server_timeout_polling_(int v) {server_timeout_polling = v; return this;} private int server_timeout_polling = 1;
|
||||
@@ -41,8 +41,8 @@ public class Process_server_mock implements Scrib_server {
|
||||
public boolean Print_key() {return print_key;} public Process_server_mock Print_key_(boolean v) {print_key = v; return this;} private boolean print_key;
|
||||
public void Prep_add(String v) {rsps.Add(new Process_server_mock_rcvd_str(v));}
|
||||
public void Prep_add_dynamic_val() {rsps.Add(new Process_server_mock_rcvd_val(print_key));}
|
||||
public ListAdp Log_rcvd() {return log_rcvd;} ListAdp log_rcvd = ListAdp_.new_();
|
||||
public ListAdp Log_sent() {return log_sent;} ListAdp log_sent = ListAdp_.new_();
|
||||
public ListAdp Log_rcvd() {return log_rcvd;} private ListAdp log_rcvd = ListAdp_.new_();
|
||||
public ListAdp Log_sent() {return log_sent;} private ListAdp log_sent = ListAdp_.new_();
|
||||
}
|
||||
interface Process_server_mock_rcvd {
|
||||
String Bld(Object[] cmd_obs);
|
||||
|
||||
@@ -162,7 +162,7 @@ public class Scrib_lib_language implements Scrib_lib {
|
||||
public boolean CaseFold(Scrib_proc_args args, Scrib_proc_rslt rslt) {return Uc(args, rslt);} // REF.MW:Language.php!caseFold; http://www.w3.org/International/wiki/Case_folding
|
||||
public boolean FormatNum(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
Xol_lang lang = lang_(args);
|
||||
byte[] num = args.Form_bry_or_null(1);
|
||||
byte[] num = args.Xstr_bry_or_null(1);
|
||||
boolean skip_commafy = false;
|
||||
if (num != null) { // MW: if num present, check options table for noCommafy arg;
|
||||
KeyVal[] kv_ary = args.Cast_kv_ary_or_null(2);
|
||||
@@ -194,7 +194,7 @@ public class Scrib_lib_language implements Scrib_lib {
|
||||
}
|
||||
public boolean ParseFormattedNumber(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
Xol_lang lang = lang_(args);
|
||||
byte[] num = args.Form_bry_or_null(1);
|
||||
byte[] num = args.Xstr_bry_or_null(1);
|
||||
if (num == null) return rslt.Init_null(); // ParseFormattedNumber can sometimes take 1 arg ({'en'}), or null arg ({'en', null}); return null (not ""); DATE:2014-01-07
|
||||
byte[] rv = lang.Num_mgr().Raw(num);
|
||||
return rslt.Init_obj(rv);
|
||||
@@ -203,7 +203,7 @@ public class Scrib_lib_language implements Scrib_lib {
|
||||
Xol_lang lang = lang_(args);
|
||||
long seconds = args.Pull_long(1);
|
||||
KeyVal[] intervals_kv_ary = args.Cast_kv_ary_or_null(2);
|
||||
Xol_duration_itm[] intervals = Xol_duration_itm_.X_to_itm_ary(intervals_kv_ary);
|
||||
Xol_duration_itm[] intervals = Xol_duration_itm_.Xto_itm_ary(intervals_kv_ary);
|
||||
byte[] rv = lang.Duration_mgr().Format_durations(core.Ctx(), seconds, intervals);
|
||||
return rslt.Init_obj(rv);
|
||||
}
|
||||
@@ -211,9 +211,9 @@ public class Scrib_lib_language implements Scrib_lib {
|
||||
Xol_lang lang = lang_(args);
|
||||
long seconds = args.Pull_long(1);
|
||||
KeyVal[] intervals_kv_ary = args.Cast_kv_ary_or_null(2);
|
||||
Xol_duration_itm[] intervals = Xol_duration_itm_.X_to_itm_ary(intervals_kv_ary);
|
||||
Xol_duration_itm[] intervals = Xol_duration_itm_.Xto_itm_ary(intervals_kv_ary);
|
||||
Xol_interval_itm[] rv = lang.Duration_mgr().Get_duration_intervals(seconds, intervals);
|
||||
return rslt.Init_obj(Xol_interval_itm.X_to_kv_ary(rv));
|
||||
return rslt.Init_obj(Xol_interval_itm.Xto_kv_ary(rv));
|
||||
}
|
||||
public boolean ConvertPlural(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
Xol_lang lang = lang_(args);
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.junit.*;
|
||||
import gplx.xowa.langs.numbers.*;
|
||||
public class Scrib_lib_language_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_language().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void GetContLangCode() {
|
||||
|
||||
@@ -19,7 +19,7 @@ package gplx.xowa.xtns.scribunto.lib; import gplx.*; import gplx.xowa.*; import
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_message_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_message().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void Plain() {
|
||||
|
||||
@@ -136,12 +136,12 @@ public class Scrib_lib_mw implements Scrib_lib {
|
||||
int key_int = Bry_.NotFound;
|
||||
byte[] key_dat_ary = nde.Key_tkn().Dat_ary();
|
||||
if (Env_.Mode_testing() && src == null) // some tests will always pass a null src;
|
||||
key_int = Bry_.X_to_int_or(key_dat_ary, 0, key_dat_ary.length, Bry_.NotFound);
|
||||
key_int = Bry_.Xto_int_or(key_dat_ary, 0, key_dat_ary.length, Bry_.NotFound);
|
||||
else {
|
||||
if (Bry_.Len_eq_0(key_dat_ary)) // should be called by current context;
|
||||
key_int = Bry_.X_to_int_or(src, nde.Key_tkn().Src_bgn(), nde.Key_tkn().Src_end(), Bry_.NotFound);
|
||||
key_int = Bry_.Xto_int_or(src, nde.Key_tkn().Src_bgn(), nde.Key_tkn().Src_end(), Bry_.NotFound);
|
||||
else // will be called by parent context; note that this calls Xot_defn_tmpl_.Make_itm which sets a key_dat_ary; DATE:2013-09-23
|
||||
key_int = Bry_.X_to_int_or(key_dat_ary, 0, key_dat_ary.length, Bry_.NotFound);
|
||||
key_int = Bry_.Xto_int_or(key_dat_ary, 0, key_dat_ary.length, Bry_.NotFound);
|
||||
}
|
||||
if (key_int == Bry_.NotFound) // key is not-numeric
|
||||
return false;
|
||||
@@ -155,8 +155,8 @@ public class Scrib_lib_mw implements Scrib_lib {
|
||||
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;
|
||||
if (args_len < 1) return rslt.Init_obj(KeyVal_.Ary_empty); // occurs when "frame:getParent().args" but no parent frame
|
||||
Bry_bfr tmp_bfr = ctx.Wiki().Utl_bry_bfr_mkr().Get_b128(); // NOTE: do not make modular level variable, else random failures; DATE:2013-10-14
|
||||
if (args_len < 1) return rslt.Init_obj(KeyVal_.Ary_empty); // occurs when "frame:getParent().args" but no parent frame
|
||||
Bry_bfr tmp_bfr = ctx.Wiki().Utl_bry_bfr_mkr().Get_b128(); // NOTE: do not make modular level variable, else random failures; DATE:2013-10-14
|
||||
ListAdp rv = ListAdp_.new_();
|
||||
int arg_idx = 0;
|
||||
for (int i = 0; i < args_len; i++) {
|
||||
@@ -180,7 +180,7 @@ public class Scrib_lib_mw implements Scrib_lib {
|
||||
if (key_missing) // key missing; EX: {{a|val}}
|
||||
key_as_int = ++arg_idx;// NOTE: MW requires a key; if none, then default to int index; NOTE: must be int, not String; NOTE: must be indexed to keyless args; EX: in "key1=val1,val2", "val2" must be "1" (1st keyless arg) not "2" (2nd arg); DATE:2013-11-09
|
||||
else { // key exists; EX:{{a|key=val}}
|
||||
key_as_int = Bry_.X_to_int_or(tmp_bfr.Bfr(), 0, tmp_bfr.Len(), Int_.MinValue);
|
||||
key_as_int = Bry_.Xto_int_or(tmp_bfr.Bfr(), 0, tmp_bfr.Len(), Int_.MinValue);
|
||||
if (key_as_int == Int_.MinValue) { // key is not int; create str
|
||||
key_as_str = tmp_bfr.XtoStrAndClear();
|
||||
key_is_str = true;
|
||||
@@ -202,7 +202,9 @@ public class Scrib_lib_mw implements Scrib_lib {
|
||||
Xot_invk frame = Scrib_frame_.Get_frame(core, frame_id);
|
||||
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());}
|
||||
public boolean ParentFrameExists(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
return rslt.Init_obj(!core.Frame_parent().Root_frame());
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
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.scribunto.lib; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_mw__invoke_tst {
|
||||
@Before public void init() {
|
||||
fxt.Clear_for_invoke();
|
||||
lib = fxt.Core().Lib_mw().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void GetAllExpandedArguments_ws_prm_key_exists() { // PURPOSE: trim val if key exists; parameterized value ("key={{{1}}}")
|
||||
fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|key={{{1}}}}}");
|
||||
fxt.Init_page("{{test| a }}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("current"), "\n a"); // " a " -> "a"
|
||||
}
|
||||
@Test public void GetAllExpandedArguments_ws_prm_key_missing() { // PURPOSE: do not trim val if key missing; parameterized value ("{{{1}}}")
|
||||
fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|{{{1}}}}}");
|
||||
fxt.Init_page("{{test| a }}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("current"), "\n a "); // " a " -> " a "
|
||||
}
|
||||
@Test public void GetAllExpandedArguments__ignore_empty_key() {// PURPOSE: ignore arguents that have an empty key (|=8|); EX:w:Fool's_mate; DATE:2014-03-05
|
||||
fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Init_page("{{test|a1||a2|=a3|a4}}");
|
||||
fxt.Init_server_print_key_y_();
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("parent"), "\n 1:a1;2:;3:a2;4:a4"); // NOTE: || is not ignored but |=a3| is
|
||||
fxt.Init_server_print_key_n_();
|
||||
}
|
||||
@Test public void GetExpandedArgument_ws_key_exists() { // PURPOSE: trim val if key exists; literal value
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0| key1 = val1 }}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key1") , "val1"); // "key1" -> "key1"
|
||||
}
|
||||
@Test public void GetExpandedArgument_ws_key_missing() { // PURPOSE: do not trim val if key missing; literal value
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0| a }}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1") , " a "); // " a " -> " a "
|
||||
}
|
||||
@Test public void GetExpandedArgument_ws_key_prm_key_exists() { // PURPOSE: trim val if key exists; parameterized value ("key={{{1}}}")
|
||||
fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|key1={{{1}}}}}");
|
||||
fxt.Init_page("{{test| a }}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key1") , "a"); // " a " -> "a"
|
||||
}
|
||||
@Test public void GetExpandedArgument_ws_key_prm_key_missing() { // PURPOSE: do not trim val if key missing; parameterized value ("{{{1}}}")
|
||||
fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|{{{1}}}}}");
|
||||
fxt.Init_page("{{test| a }}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1") , " a "); // " a " -> " a "
|
||||
}
|
||||
@Test public void Preprocess() {
|
||||
this.Init_preprocess();
|
||||
this.Exec_preprocess(Scrib_core.Frame_key_module , "1", "c");
|
||||
this.Exec_preprocess(Scrib_core.Frame_key_module , "2", "d");
|
||||
this.Exec_preprocess(Scrib_core.Frame_key_template , "1", "a");
|
||||
this.Exec_preprocess(Scrib_core.Frame_key_template , "2", "b");
|
||||
}
|
||||
@Test public void Preprocess_duplicate_key() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0|key1=a|key2=b|key1=c}}"); // add key1 twice
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_preprocess, Object_.Ary("current", "{{#ifeq:1|1|{{{key1}}}|{{{key2}}}}}"), "c");
|
||||
}
|
||||
@Test public void CallParserFunction() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.base1_many_ary_("current", "#expr", "1") , "1"); // named: args is scalar
|
||||
fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.base1_many_ary_("current", "#if", Scrib_kv_utl_.base1_many_("", "y", "n")) , "n"); // named: args is table
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_callParserFunction, Object_.Ary("current", "#if", "", "y", "n") , "n"); // list: args is ary
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_callParserFunction, Object_.Ary("current", "#if", Scrib_kv_utl_.base1_many_("", "y", "n")) , "n"); // list: args is table
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_callParserFunction, Object_.Ary("current", "#if:", "y", "n") , "n"); // colon_in_name
|
||||
}
|
||||
@Test public void CallParserFunction_tag() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.flat_many_(1, "current", 2, "#tag", 3, Scrib_kv_utl_.flat_many_("3", "id=1", "2", "text", "1", "pre")), "<pre 3=\"id=1\">2=text</pre>");// named: sort args; NOTE: keys should probably be stripped
|
||||
}
|
||||
@Test public void CallParserFunction_displayTitle() { // PURPOSE: DISPLAYTITLE not being set when called through CallParserFunction; DATE:2013-08-05
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.base1_many_ary_("current", "DISPLAYTITLE", "''a''"), "");
|
||||
Tfds.Eq("<i>a</i>", String_.new_ascii_(fxt.Parser_fxt().Ctx().Cur_page().Display_ttl()));
|
||||
}
|
||||
@Test public void ExpandTemplate_tmpl() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Parser_fxt().Data_create("Template:A", "b{{{key1}}}c");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", "A", Scrib_kv_utl_.flat_many_("key1", "val1")) , "bval1c"); // list: args is ary
|
||||
}
|
||||
@Test public void ExpandTemplate() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Parser_fxt().Init_page_create("Template:Format", "{{{1}}}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", "Format", Scrib_kv_utl_.base1_many_("a")), "a");
|
||||
}
|
||||
@Test public void ExpandTemplate_ns_specified() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Parser_fxt().Init_page_create("Template:Format", "{{{1}}}");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", "Template:Format", Scrib_kv_utl_.base1_many_("a")), "a"); // NOTE: "Template:" specified
|
||||
}
|
||||
@Test public void ExpandTemplate_tmpl_bool() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Parser_fxt().Data_create("Template:Scribunto_bool", "bool_true={{{bool_true}}};bool_false={{{bool_false}}};");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", "Scribunto_bool", Scrib_kv_utl_.flat_many_("bool_true", true, "bool_false", false)), "bool_true=1;bool_false={{{bool_false}}};");
|
||||
}
|
||||
@Test public void ExpandTemplate_page() {
|
||||
fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
fxt.Parser_fxt().Data_create("A", "b{{{key1}}}c");
|
||||
fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", ":A", Scrib_kv_utl_.flat_many_("key1", "val1")) , "bval1c"); // list: args is ary
|
||||
}
|
||||
@Test public void Err_mod_blank() {fxt.Test_parse_err("{{#invoke:}}" , Scrib_invoke_func.Err_mod_missing);}
|
||||
@Test public void Err_mod_missing() {fxt.Test_parse_err("{{#invoke:Missing}}" , Scrib_invoke_func.Err_mod_missing);}
|
||||
private void Init_preprocess() {
|
||||
fxt.Init_tmpl("{{#invoke:Mod_0|Func_0|1|c|d}}"); // current
|
||||
fxt.Init_page("{{test|1|a|b|c}}"); // parent
|
||||
fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_mw(), Scrib_lib_mw.Invk_preprocess);
|
||||
}
|
||||
private void Exec_preprocess(String frame, String arg_idx, String expd) {
|
||||
fxt.Parser_fxt().Wiki().Cache_mgr().Tmpl_result_cache().Clear();
|
||||
fxt.Init_lua_module();
|
||||
fxt.Init_lua_rcvd_preprocess(frame, "{{#ifeq:" + arg_idx + "|{{{1}}}|{{{2}}}|{{{3}}}}}");
|
||||
fxt.Test_invoke(expd);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
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.scribunto.lib; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_mw__lib_tst {
|
||||
@Before public void init() {
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_mw().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void ParentFrameExists() {
|
||||
fxt.Init_frame_parent("test");
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_mw.Invk_parentFrameExists, Object_.Ary_empty, true);
|
||||
}
|
||||
@Test public void ParentFrameExists_false() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_mw.Invk_parentFrameExists, Object_.Ary_empty, false);
|
||||
}
|
||||
@Test public void GetAllExpandedArguments() {
|
||||
fxt.Init_frame_current(KeyVal_.new_("k1", "v1"));
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("current"), "1=\n k1=v1");
|
||||
}
|
||||
@Test public void GetAllExpandedArguments_parent() {
|
||||
fxt.Init_frame_parent("test", KeyVal_.new_("1", "a1"), KeyVal_.new_("2", "a2"));
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("parent"), "1=\n 1=a1\n 2=a2");
|
||||
}
|
||||
@Test public void GetExpandedArgument() {
|
||||
fxt.Init_frame_current(KeyVal_.int_(1, "val_1"), KeyVal_.new_("key_2", "val_2"), KeyVal_.int_(3, "val_3"));
|
||||
fxt.Test_scrib_proc_str (lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1") , "val_1"); // get 1st by idx
|
||||
fxt.Test_scrib_proc_str (lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "2") , "val_3"); // get 2nd by idx (which is "3", not "key_2)
|
||||
fxt.Test_scrib_proc_empty (lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "3")); // get 3rd by idx (which is n/a, not "val_3")
|
||||
fxt.Test_scrib_proc_str (lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key_2") , "val_2"); // get key_2
|
||||
fxt.Test_scrib_proc_empty (lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key_3")); // key_3 n/a
|
||||
}
|
||||
@Test public void GetExpandedArgument_parent() {
|
||||
fxt.Init_frame_parent ("test", KeyVal_.new_("1", "a1"), KeyVal_.new_("2", "a2"));
|
||||
fxt.Init_frame_current(KeyVal_.new_("2", "b2"));
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("parent", "1"), "a1");
|
||||
}
|
||||
@Test public void GetExpandedArgument_numeric_key() { // PURPOSE.FIX: frame.args[1] was ignoring "1=val_1" b/c it was looking for 1st unnamed arg (and 1 is the name for "1=val_1")
|
||||
fxt.Init_frame_current(KeyVal_.new_("1", "val_1"));
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1"), "val_1"); // get 1st by idx, even though idx is String
|
||||
}
|
||||
@Test public void GetExpandedArgument_numeric_key_2() { // PURPOSE.FIX: same as above, but for parent context; DATE:2013-09-23
|
||||
fxt.Init_frame_parent ("test", KeyVal_.new_("2", "a1"));
|
||||
fxt.Init_frame_current(KeyVal_.new_("2", "a2"));
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("parent", "2"), "a1"); // get 1st by idx, even though idx is String
|
||||
}
|
||||
@Test public void GetExpandedArgument_out_of_bounds() {
|
||||
fxt.Init_frame_parent ("test");
|
||||
fxt.Test_scrib_proc_empty(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("parent", "2"));
|
||||
}
|
||||
@Test public void IsSubsting() {
|
||||
fxt.Test_scrib_proc_bool(lib, Scrib_lib_mw.Invk_isSubsting, Object_.Ary_empty, false);
|
||||
}
|
||||
@Test public void GetFrameTitle_current() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_mw.Invk_getFrameTitle, Object_.Ary("current") , "Module:Mod_0");
|
||||
}
|
||||
@Test public void GetFrameTitle_parent() {
|
||||
fxt.Init_frame_parent("Template:Test");
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_mw.Invk_getFrameTitle, Object_.Ary("parent") , "Template:Test");
|
||||
}
|
||||
@Test public void GetFrameTitle_empty() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_mw.Invk_getFrameTitle, Object_.Ary("empty") , Scrib_invoke_func_fxt.Null_rslt);
|
||||
}
|
||||
@Test public void NewChildFrame() {
|
||||
fxt.Test_scrib_proc_str(lib, Scrib_lib_mw.Invk_newChildFrame, Object_.Ary("current", "Page_0", Scrib_kv_utl_.flat_many_("key1", "val1")), "frame0");
|
||||
}
|
||||
@Test public void SetTTL() {
|
||||
fxt.Test_scrib_proc_empty(lib, Scrib_lib_mw.Invk_setTTL, Object_.Ary(123));
|
||||
Tfds.Eq(123, fxt.Core().Frame_current().Frame_lifetime());
|
||||
}
|
||||
}
|
||||
@@ -1,174 +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.scribunto.lib; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_mw_tst {
|
||||
@Test public void Stub() {}
|
||||
// @Before public void init() {
|
||||
// fxt.Clear();
|
||||
// lib = fxt.Core().Lib_mw().Init();
|
||||
// } private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
// @Test public void ParentFrameExists() {
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Init_page("{{test}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_parentFrameExists, Object_.Ary_empty, "true");
|
||||
// }
|
||||
// @Test public void ParentFrameExists_false() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_parentFrameExists, Object_.Ary_empty, "false");
|
||||
// }
|
||||
// @Test public void GetAllExpandedArguments() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0|v0|k1=v1}}");
|
||||
// fxt.Init_server_print_key_y_();
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("current"), "\n 1:v0;k1:v1");
|
||||
// fxt.Init_server_print_key_n_();
|
||||
// }
|
||||
// @Test public void GetAllExpandedArguments_parent() {
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|b1}}");
|
||||
// fxt.Init_page("{{test|a1|a2}}");
|
||||
// fxt.Init_server_print_key_y_();
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("parent"), "\n 1:a1;2:a2");
|
||||
// fxt.Init_server_print_key_n_();
|
||||
// }
|
||||
// @Test public void GetAllExpandedArguments_ws_prm_key_exists() { // PURPOSE: trim val if key exists; parameterized value ("key={{{1}}}")
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|key={{{1}}}}}");
|
||||
// fxt.Init_page("{{test| a }}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("current"), "\n a"); // " a " -> "a"
|
||||
// }
|
||||
// @Test public void GetAllExpandedArguments_ws_prm_key_missing() { // PURPOSE: do not trim val if key missing; parameterized value ("{{{1}}}")
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|{{{1}}}}}");
|
||||
// fxt.Init_page("{{test| a }}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("current"), "\n a "); // " a " -> " a "
|
||||
// }
|
||||
// @Test public void GetAllExpandedArguments__ignore_empty_key() {// PURPOSE: ignore arguents that have an empty key (|=8|); EX:w:Fool's_mate; DATE:2014-03-05
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Init_page("{{test|a1||a2|=a3|a4}}");
|
||||
// fxt.Init_server_print_key_y_();
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getAllExpandedArguments, Object_.Ary("parent"), "\n 1:a1;2:;3:a2;4:a4"); // NOTE: || is not ignored but |=a3| is
|
||||
// fxt.Init_server_print_key_n_();
|
||||
// }
|
||||
// @Test public void GetExpandedArgument() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0|val_1|key_2=val_2|val_3}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1") , "val_1"); // get 1st by idx
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "2") , "val_3"); // get 2nd by idx (which is "3", not "key_2)
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "3") , ""); // get 3rd by idx (which is n/a, not "3")
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key_2") , "val_2"); // get key_2
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key_3") , ""); // key_3 n/a
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_ws_key_exists() { // PURPOSE: trim val if key exists; literal value
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0| key1 = val1 }}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key1") , "val1"); // "key1" -> "key1"
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_ws_key_missing() { // PURPOSE: do not trim val if key missing; literal value
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0| a }}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1") , " a "); // " a " -> " a "
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_ws_key_prm_key_exists() { // PURPOSE: trim val if key exists; parameterized value ("key={{{1}}}")
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|key1={{{1}}}}}");
|
||||
// fxt.Init_page("{{test| a }}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "key1") , "a"); // " a " -> "a"
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_ws_key_prm_key_missing() { // PURPOSE: do not trim val if key missing; parameterized value ("{{{1}}}")
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|{{{1}}}}}");
|
||||
// fxt.Init_page("{{test| a }}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1") , " a "); // " a " -> " a "
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_parent() {
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|b1}}");
|
||||
// fxt.Init_page("{{test|a1|a2}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("parent", "1"), "a1");
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_numeric_key() { // PURPOSE.FIX: frame.args[1] was ignoring "1=val_1" b/c it was looking for 1st unnamed arg (and 1 is the name for "1=val_1")
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0|1=val_1}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("current", "1") , "val_1"); // get 1st by idx, even though idx is String
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_numeric_key_2() { // PURPOSE.FIX: same as above, but for parent context; DATE:2013-09-23
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|b2}}"); // current
|
||||
// fxt.Init_page("{{test|2=b1}}"); // parent
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("parent", "2") , "b1"); // get 1st by idx, even though idx is String
|
||||
// }
|
||||
// @Test public void GetExpandedArgument_out_of_bounds() {
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0|b1}}");
|
||||
// fxt.Init_page("{{test}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getExpandedArgument, Object_.Ary("parent", "2") , "");
|
||||
// }
|
||||
// @Test public void Preprocess() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0|key1=a|key2=b|key1=c}}"); // add key1 twice
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_preprocess, Object_.Ary("current", "{{#ifeq:1|1|{{{key1}}}|{{{key2}}}}}"), "c");
|
||||
// }
|
||||
// @Test public void CallParserFunction() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.base1_many_ary_("current", "#expr", "1") , "1"); // named: args is scalar
|
||||
// fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.base1_many_ary_("current", "#if", Scrib_kv_utl_.base1_many_("", "y", "n")) , "n"); // named: args is table
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_callParserFunction, Object_.Ary("current", "#if", "", "y", "n") , "n"); // list: args is ary
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_callParserFunction, Object_.Ary("current", "#if", Scrib_kv_utl_.base1_many_("", "y", "n")) , "n"); // list: args is table
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_callParserFunction, Object_.Ary("current", "#if:", "y", "n") , "n"); // colon_in_name
|
||||
// }
|
||||
// @Test public void CallParserFunction_tag() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.flat_many_(1, "current", 2, "#tag", 3, Scrib_kv_utl_.flat_many_("3", "id=1", "2", "text", "1", "pre")), "<pre 3=\"id=1\">2=text</pre>");// named: sort args; NOTE: keys should probably be stripped
|
||||
// }
|
||||
// @Test public void CallParserFunction_displayTitle() { // PURPOSE: DISPLAYTITLE not being set when called through CallParserFunction; DATE:2013-08-05
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Test_lib_proc_kv(lib, Scrib_lib_mw.Invk_callParserFunction, Scrib_kv_utl_.base1_many_ary_("current", "DISPLAYTITLE", "''a''"), "");
|
||||
// Tfds.Eq("<i>a</i>", String_.new_ascii_(fxt.Parser_fxt().Ctx().Cur_page().Display_ttl()));
|
||||
// }
|
||||
// @Test public void IsSubsting() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_isSubsting, Object_.Ary_empty, "false");
|
||||
// }
|
||||
// @Test public void ExpandTemplate_tmpl() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Parser_fxt().Data_create("Template:A", "b{{{key1}}}c");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", "A", Scrib_kv_utl_.flat_many_("key1", "val1")) , "bval1c"); // list: args is ary
|
||||
// }
|
||||
// @Test public void ExpandTemplate_tmpl_bool() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Parser_fxt().Data_create("Template:Scribunto_bool", "bool_true={{{bool_true}}};bool_false={{{bool_false}}};");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", "Scribunto_bool", Scrib_kv_utl_.flat_many_("bool_true", true, "bool_false", false)), "bool_true=1;bool_false={{{bool_false}}};");
|
||||
// }
|
||||
// @Test public void ExpandTemplate_page() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Parser_fxt().Data_create("A", "b{{{key1}}}c");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_expandTemplate, Object_.Ary("current", ":A", Scrib_kv_utl_.flat_many_("key1", "val1")) , "bval1c"); // list: args is ary
|
||||
// }
|
||||
// @Test public void GetFrameTitle_current() {
|
||||
// fxt.Parser_fxt().Wiki().Cache_mgr().Free_mem_all();
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}"); // current
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getFrameTitle, Object_.Ary("current") , "Module:Mod_0");
|
||||
// }
|
||||
// @Test public void GetFrameTitle_owner() {
|
||||
// fxt.Parser_fxt().Wiki().Cache_mgr().Free_mem_all();
|
||||
// fxt.Init_tmpl("{{#invoke:Mod_0|Prc_0}}"); // current
|
||||
// fxt.Init_page("{{test}}"); // parent
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getFrameTitle, Object_.Ary("parent") , "Template:Test");
|
||||
// }
|
||||
// @Test public void GetFrameTitle_empty() {
|
||||
// fxt.Parser_fxt().Wiki().Cache_mgr().Free_mem_all();
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}"); // current
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_getFrameTitle, Object_.Ary("empty") , Scrib_invoke_func_fxt.Null_rslt);
|
||||
// }
|
||||
// @Test public void NewChildFrame() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_newChildFrame, Object_.Ary("current", "Page_0", Scrib_kv_utl_.flat_many_("key1", "val1")), "frame0");
|
||||
// }
|
||||
// @Test public void SetTTL() {
|
||||
// fxt.Init_page("{{#invoke:Mod_0|Prc_0}}");
|
||||
// fxt.Test_lib_proc(lib, Scrib_lib_mw.Invk_setTTL, Object_.Ary(123), ""); // smoke test; difficult to get member reference to current_frame since it's freed automatically in invoke; DATE:2014-07-12
|
||||
// }
|
||||
}
|
||||
@@ -19,7 +19,7 @@ package gplx.xowa.xtns.scribunto.lib; import gplx.*; import gplx.xowa.*; import
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_site_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_site().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void GetNsIndex() {
|
||||
|
||||
@@ -19,7 +19,7 @@ package gplx.xowa.xtns.scribunto.lib; import gplx.*; import gplx.xowa.*; import
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_text_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_text().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void Unstrip() {
|
||||
|
||||
@@ -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.wikis.caches.*;
|
||||
import gplx.xowa.wikis.caches.*; import gplx.xowa.xtns.pfuncs.ttls.*;
|
||||
public class Scrib_lib_title implements Scrib_lib {
|
||||
public Scrib_lib_title(Scrib_core core) {this.core = core;} private Scrib_core core;
|
||||
public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod;
|
||||
@@ -56,7 +56,7 @@ public class Scrib_lib_title implements Scrib_lib {
|
||||
Xow_wiki wiki = core.Wiki();
|
||||
byte[] ns_bry = null;
|
||||
if (ns_obj != null) {
|
||||
ns_bry = Parse_ns(wiki, ns_obj); if (ns_bry == null) throw Err_.new_fmt_("unknown ns: {0}", Object_.XtoStr_OrEmpty(ns_bry));
|
||||
ns_bry = Parse_ns(wiki, ns_obj); if (ns_bry == null) throw Err_.new_fmt_("unknown ns: {0}", Object_.Xto_str_strict_or_empty(ns_bry));
|
||||
}
|
||||
if (ns_bry != null) {
|
||||
Bry_bfr bfr = wiki.Utl_bry_bfr_mkr().Get_b512();
|
||||
@@ -78,20 +78,20 @@ public class Scrib_lib_title implements Scrib_lib {
|
||||
// byte[] proto = Scrib_kv_utl_.Val_to_bry_or(values, 3, null); // NOTE: Scribunto has more conditional logic around argument 2 and setting protocols; DATE:2014-07-07
|
||||
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry); if (ttl == null) return rslt.Init_obj(null);
|
||||
Bry_bfr bfr = wiki.App().Utl_bry_bfr_mkr().Get_b512();
|
||||
//if (url_func_tid == Pf_url_urlfunc.Tid_full) {
|
||||
//if (url_func_tid == Pfunc_urlfunc.Tid_full) {
|
||||
// if (proto == null) proto = Proto_relative;
|
||||
// Object proto_obj = proto_hash.Fetch(proto); if (proto_obj == null) throw Err_.new_fmt_("protocol is not valid: {0}", proto);
|
||||
// //qry_bry = (byte[])proto_obj;
|
||||
// byte proto_tid = ((Byte_obj_val)proto_obj).Val();
|
||||
// bfr.Add();
|
||||
//}
|
||||
Pf_url_urlfunc.UrlString(core.Ctx(), url_func_tid, false, ttl_bry, bfr, qry_bry);
|
||||
Pfunc_urlfunc.UrlString(core.Ctx(), url_func_tid, false, ttl_bry, bfr, qry_bry);
|
||||
return rslt.Init_obj(bfr.Mkr_rls().XtoStrAndClear());
|
||||
}
|
||||
private static final Hash_adp_bry url_func_hash = Hash_adp_bry.ci_ascii_()
|
||||
.Add_str_byte("fullUrl", Pf_url_urlfunc.Tid_full)
|
||||
.Add_str_byte("localUrl", Pf_url_urlfunc.Tid_local)
|
||||
.Add_str_byte("canonicalUrl", Pf_url_urlfunc.Tid_canonical);
|
||||
.Add_str_byte("fullUrl", Pfunc_urlfunc.Tid_full)
|
||||
.Add_str_byte("localUrl", Pfunc_urlfunc.Tid_local)
|
||||
.Add_str_byte("canonicalUrl", Pfunc_urlfunc.Tid_canonical);
|
||||
// private static final byte[] Proto_relative = Bry_.new_ascii_("relative");
|
||||
// private static final Hash_adp_bry proto_hash = Hash_adp_bry.ci_ascii_().Add_str_obj("http", Bry_.new_ascii_("http://")).Add_str_obj("https", Bry_.new_ascii_("https://")).Add_str_obj("relative", Bry_.new_ascii_("//")).Add_str_obj("canonical", Bry_.new_ascii_("1"));
|
||||
private byte[] Parse_ns(Xow_wiki wiki, Object ns_obj) {
|
||||
@@ -127,7 +127,7 @@ public class Scrib_lib_title implements Scrib_lib {
|
||||
|| !ttl.Ns().Id_file_or_media()
|
||||
) return rslt.Init_obj(false);
|
||||
if (ttl.Ns().Id_media()) ttl = Xoa_ttl.parse_(wiki, Xow_ns_.Id_file, ttl.Page_db()); // if [[Media:]] change to [[File:]]; theoretically, this should be changed in Get_page, but not sure if I want to put this logic that low; DATE:2014-01-07
|
||||
Xoa_page file_page = Pf_url_filepath.Load_page(wiki, ttl);
|
||||
Xoa_page file_page = Pfunc_filepath.Load_page(wiki, ttl);
|
||||
return rslt.Init_obj(!file_page.Missing());
|
||||
}
|
||||
public boolean GetContent(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
|
||||
@@ -19,7 +19,7 @@ package gplx.xowa.xtns.scribunto.lib; import gplx.*; import gplx.xowa.*; import
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_title_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_title().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void NewTitle() {
|
||||
|
||||
@@ -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.scribunto.lib; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
import gplx.xowa.xtns.pfuncs.ttls.*;
|
||||
public class Scrib_lib_uri implements Scrib_lib {
|
||||
public Scrib_lib_uri(Scrib_core core) {this.core = core;} private Scrib_core core;
|
||||
public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod;
|
||||
@@ -31,9 +32,9 @@ public class Scrib_lib_uri implements Scrib_lib {
|
||||
public boolean Procs_exec(int key, Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
switch (key) {
|
||||
case Proc_anchorEncode: return AnchorEncode(args, rslt);
|
||||
case Proc_localUrl: return Url_func(args, rslt, Pf_url_urlfunc.Tid_local);
|
||||
case Proc_fullUrl: return Url_func(args, rslt, Pf_url_urlfunc.Tid_full);
|
||||
case Proc_canonicalUrl: return Url_func(args, rslt, Pf_url_urlfunc.Tid_canonical);
|
||||
case Proc_localUrl: return Url_func(args, rslt, Pfunc_urlfunc.Tid_local);
|
||||
case Proc_fullUrl: return Url_func(args, rslt, Pfunc_urlfunc.Tid_full);
|
||||
case Proc_canonicalUrl: return Url_func(args, rslt, Pfunc_urlfunc.Tid_canonical);
|
||||
case Proc_init_uri_for_page: return Init_uri_for_page(args, rslt);
|
||||
default: throw Err_.unhandled(key);
|
||||
}
|
||||
@@ -45,8 +46,8 @@ public class Scrib_lib_uri implements Scrib_lib {
|
||||
byte[] raw_bry = args.Pull_bry(0);
|
||||
Bry_bfr bfr = core.App().Utl_bry_bfr_mkr().Get_b512();
|
||||
Bry_bfr tmp_bfr = core.App().Utl_bry_bfr_mkr().Get_b512();
|
||||
Pf_url_anchorencode.Func_init(core.Ctx());
|
||||
Pf_url_anchorencode.Anchor_encode(raw_bry, bfr, tmp_bfr);
|
||||
Pfunc_anchorencode.Func_init(core.Ctx());
|
||||
Pfunc_anchorencode.Anchor_encode(raw_bry, bfr, tmp_bfr);
|
||||
tmp_bfr.Mkr_rls().Clear();
|
||||
return rslt.Init_obj(bfr.Mkr_rls().XtoStrAndClear());
|
||||
}
|
||||
@@ -62,14 +63,14 @@ public class Scrib_lib_uri implements Scrib_lib {
|
||||
bfr.Add(ttl.Page_db());
|
||||
ttl_bry = bfr.XtoAryAndClear();
|
||||
}
|
||||
Pf_url_urlfunc.UrlString(core.Ctx(), url_tid, false, ttl_bry, bfr, qry_bry);
|
||||
Pfunc_urlfunc.UrlString(core.Ctx(), url_tid, false, ttl_bry, bfr, qry_bry);
|
||||
return rslt.Init_obj(bfr.Mkr_rls().XtoStrAndClear());
|
||||
}
|
||||
private boolean Init_uri_for_page(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
Xop_ctx ctx = core.Ctx();
|
||||
byte[] ttl_bry = ctx.Cur_page().Ttl().Raw();
|
||||
Bry_bfr tmp_bfr = ctx.Wiki().Utl_bry_bfr_mkr().Get_b512();
|
||||
Pf_url_urlfunc.UrlString(ctx, Pf_url_urlfunc.Tid_full, false, ttl_bry, tmp_bfr, Bry_.Empty);
|
||||
Pfunc_urlfunc.UrlString(ctx, Pfunc_urlfunc.Tid_full, false, ttl_bry, tmp_bfr, Bry_.Empty);
|
||||
return rslt.Init_obj(tmp_bfr.Mkr_rls().XtoAryAndClear());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package gplx.xowa.xtns.scribunto.lib; import gplx.*; import gplx.xowa.*; import
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_uri_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_uri().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void Url() {
|
||||
|
||||
@@ -110,7 +110,7 @@ public class Scrib_lib_ustring implements Scrib_lib {
|
||||
return rslt.Init_many_objs(pcre, regx_converter.Capt_ary());
|
||||
}
|
||||
public boolean Gmatch_callback(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
String text = args.Form_str_or_null(0); // NOTE: UstringLibrary.php!ustringGmatchCallback calls preg_match directly; $s can be any type, and php casts automatically;
|
||||
String text = args.Xstr_str_or_null(0); // NOTE: UstringLibrary.php!ustringGmatchCallback calls preg_match directly; $s can be any type, and php casts automatically;
|
||||
String regx = args.Pull_str(1);
|
||||
KeyVal[] capt = args.Cast_kv_ary_or_null(2);
|
||||
int pos = args.Pull_int(3);
|
||||
@@ -160,7 +160,7 @@ class Scrib_lib_ustring_gsub_mgr {
|
||||
public boolean Exec(Scrib_proc_args args, Scrib_proc_rslt rslt) {
|
||||
Object text_obj = args.Cast_obj_or_null(0);
|
||||
String text = String_.as_(text_obj);
|
||||
if (text == null) text = Object_.XtoStr_OrEmpty(text_obj);
|
||||
if (text == null) text = Object_.Xto_str_strict_or_empty(text_obj);
|
||||
String regx = args.Cast_str_or_null(1);
|
||||
if (args.Len() == 2) return rslt.Init_obj(text); // if no replace arg, return self; EX:enwikt:'orse; DATE:2013-10-13
|
||||
Object repl_obj = args.Cast_obj_or_null(2);
|
||||
|
||||
@@ -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.scribunto.lib; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.scribunto.*;
|
||||
import org.junit.*;
|
||||
public class Scrib_lib_ustring__invoke_tst {
|
||||
@Before public void init() {
|
||||
fxt.Clear_for_invoke();
|
||||
fxt.Init_page("{{#invoke:Mod_0|Func_0}}");
|
||||
fxt.Core().Lib_ustring().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt();
|
||||
@Test public void Gsub_proc() {
|
||||
fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_ustring(), Scrib_lib_ustring.Invk_gsub);
|
||||
Exec_gsub_regx_func_0("abcd", "([a])", "Abcd;1");
|
||||
}
|
||||
@Test public void Gsub_proc_w_grouped() { // PURPOSE: gsub_proc should pass matched String, not entire String; DATE:2013-12-01
|
||||
fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_ustring(), Scrib_lib_ustring.Invk_gsub);
|
||||
Exec_gsub_regx_func_1("[[a]]", "%[%[([^#|%]]-)%]%]" , "A;1");
|
||||
fxt.Test_log_rcvd(3, "000000370000006D{[\"op\"]=\"call\",[\"id\"]=1,[\"nargs\"]=1,[\"args\"]={[1]=\"a\"}}"); // should be "a", not "[[a]]"
|
||||
}
|
||||
@Test public void Gsub_proc_w_grouped_2() {// PURPOSE: gsub_proc failed when passing multiple matches; DATE:2013-12-01
|
||||
fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_ustring(), Scrib_lib_ustring.Invk_gsub);
|
||||
Exec_gsub_regx_func_2("[[a]] [[b]]", "%[%[([^#|%]]-)%]%]" , "A B;2");
|
||||
fxt.Test_log_rcvd(3, "000000370000006D{[\"op\"]=\"call\",[\"id\"]=1,[\"nargs\"]=1,[\"args\"]={[1]=\"a\"}}"); // should be "a", not "[[a]]"
|
||||
fxt.Test_log_rcvd(4, "000000370000006D{[\"op\"]=\"call\",[\"id\"]=1,[\"nargs\"]=1,[\"args\"]={[1]=\"b\"}}"); // should be "b", not "[[b]]"
|
||||
}
|
||||
@Test public void Gsub_int() { // PURPOSE: gsub with integer arg should not fail; DATE:2013-11-06
|
||||
fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_ustring(), Scrib_lib_ustring.Invk_gsub);
|
||||
fxt.Init_lua_module();
|
||||
fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(1, "[1]", "2", 1)); // NOTE: text is integer (lua / php are type-less)
|
||||
fxt.Init_lua_rcvd_rv();
|
||||
fxt.Test_invoke("2;1");
|
||||
}
|
||||
private void Exec_gsub_regx_func_0(String text, String regx, String expd) {
|
||||
fxt.Init_lua_module();
|
||||
fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)));
|
||||
fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"A\";}}");
|
||||
fxt.Init_lua_rcvd_rv();
|
||||
fxt.Test_invoke(expd);
|
||||
}
|
||||
private void Exec_gsub_regx_func_1(String text, String regx, String expd) {
|
||||
fxt.Init_lua_module();
|
||||
fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)));
|
||||
fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"A\";}}");
|
||||
fxt.Init_lua_rcvd_rv();
|
||||
fxt.Test_invoke(expd);
|
||||
}
|
||||
private void Exec_gsub_regx_func_2(String text, String regx, String expd) {
|
||||
fxt.Init_lua_module();
|
||||
fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)));
|
||||
fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"A\";}}");
|
||||
fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"B\";}}");
|
||||
fxt.Init_lua_rcvd_rv();
|
||||
fxt.Init_lua_rcvd_rv();
|
||||
fxt.Test_invoke(expd);
|
||||
}
|
||||
}
|
||||
@@ -17,10 +17,9 @@ 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 org.junit.*;
|
||||
public class Scrib_lib_ustring_tst {
|
||||
public class Scrib_lib_ustring__lib_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Init_page("{{#invoke:Mod_0|Func_0}}");
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_ustring().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void Find() {
|
||||
@@ -49,11 +48,6 @@ public class Scrib_lib_ustring_tst {
|
||||
@Test public void Match_args_out_of_order() {
|
||||
fxt.Test_scrib_proc_empty(lib, Scrib_lib_ustring.Invk_match, KeyVal_.Ary(KeyVal_.int_(2, "[a]")));
|
||||
}
|
||||
// @Test public void Match_viwiktionary() {
|
||||
// fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_ustring(), Scrib_lib_ustring.Invk_match);
|
||||
// Exec_match("tr" , "()(r)", 1, ";"); // should return all matches
|
||||
// Exec_match("tr" , "^([b]*).-([c]*)$", 1, ";"); // should return all matches
|
||||
// }
|
||||
@Test public void Gsub() {
|
||||
Exec_gsub_regx("abcd", "[a]" , -1, "A" , "Abcd;1");
|
||||
Exec_gsub_regx("aaaa", "[a]" , 2, "A" , "AAaa;2");
|
||||
@@ -70,26 +64,6 @@ public class Scrib_lib_ustring_tst {
|
||||
Exec_gsub_regx("aa" , "(a)%1" , 1, "%1z", "az;1"); // capture
|
||||
Exec_gsub_regx("a\"b'c\"d" , "([\"'])(.-)%1" , 1, "%1z", "a\"zd;1"); // capture; http://www.lua.org/pil/20.3.html; {{#invoke:test|gsub_string|a"b'c"d|(["'])(.-)%1|%1z}}
|
||||
}
|
||||
// @Test public void Gsub_proc() {
|
||||
// Exec_gsub_regx_func_0("abcd", "([a])", "Abcd;1");
|
||||
// }
|
||||
// @Test public void Gsub_proc_w_grouped() { // PURPOSE: gsub_proc should pass matched String, not entire String; DATE:2013-12-01
|
||||
// Exec_gsub_regx_func_1("[[a]]", "%[%[([^#|%]]-)%]%]" , "A;1");
|
||||
// fxt.Test_log_rcvd(3, "000000370000006D{[\"op\"]=\"call\",[\"id\"]=1,[\"nargs\"]=1,[\"args\"]={[1]=\"a\"}}"); // should be "a", not "[[a]]"
|
||||
// }
|
||||
// @Test public void Gsub_proc_w_grouped_2() {// PURPOSE: gsub_proc failed when passing multiple matches; DATE:2013-12-01
|
||||
// Exec_gsub_regx_func_2("[[a]] [[b]]", "%[%[([^#|%]]-)%]%]" , "A B;2");
|
||||
// fxt.Test_log_rcvd(3, "000000370000006D{[\"op\"]=\"call\",[\"id\"]=1,[\"nargs\"]=1,[\"args\"]={[1]=\"a\"}}"); // should be "a", not "[[a]]"
|
||||
// fxt.Test_log_rcvd(4, "000000370000006D{[\"op\"]=\"call\",[\"id\"]=1,[\"nargs\"]=1,[\"args\"]={[1]=\"b\"}}"); // should be "b", not "[[b]]"
|
||||
// }
|
||||
// @Test public void Gsub_int() { // PURPOSE: gsub with integer arg should not fail; DATE:2013-11-06
|
||||
//// fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_ustring(), Scrib_lib_ustring.Invk_gsub);
|
||||
//// fxt.Init_lua_module();
|
||||
//// fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(1, "[1]", "2", 1)); // NOTE: text is integer (lua / php are type-less)
|
||||
//// fxt.Init_lua_rcvd_rv();
|
||||
//// fxt.Test_invoke("2;1");
|
||||
// fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_ustring.Invk_gsub, Object_.Ary("[1]", 1) , "2;1");
|
||||
// }
|
||||
@Test public void Gsub_no_replace() {// PURPOSE: gsub with no replace argument should not fail; EX:d:'orse; DATE:2013-10-14
|
||||
fxt.Test_scrib_proc_str_ary(lib, Scrib_lib_ustring.Invk_gsub, Object_.Ary("text", "regx") , "1=text"); // NOTE: repl, limit deliberately omitted
|
||||
}
|
||||
@@ -124,6 +98,11 @@ public class Scrib_lib_ustring_tst {
|
||||
, " 1=2"
|
||||
));
|
||||
}
|
||||
// @Test public void Match_viwiktionary() {
|
||||
// fxt.Init_cbk(Scrib_core.Key_mw_interface, fxt.Core().Lib_ustring(), Scrib_lib_ustring.Invk_match);
|
||||
// Exec_match("tr" , "()(r)", 1, ";"); // should return all matches
|
||||
// Exec_match("tr" , "^([b]*).-([c]*)$", 1, ";"); // should return all matches
|
||||
// }
|
||||
private void Exec_find(String text, String regx, int bgn, boolean plain, String expd) {
|
||||
fxt.Test_scrib_proc_kv_vals(lib, Scrib_lib_ustring.Invk_find, Scrib_kv_utl_.base1_many_(text, regx, bgn, plain), expd);
|
||||
}
|
||||
@@ -134,29 +113,4 @@ public class Scrib_lib_ustring_tst {
|
||||
private void Exec_gsub(String text, String regx, int limit, Object repl, String expd) {
|
||||
fxt.Test_scrib_proc_kv_vals(lib, Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, repl, limit), expd);
|
||||
}
|
||||
// private void Exec_gsub_regx_func_0(String text, String regx, String expd) {
|
||||
// fxt.Test_scrib_proc_kv_vals(lib, Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)), expd);
|
||||
//// fxt.Init_lua_module();
|
||||
//// fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)));
|
||||
//// fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"A\";}}");
|
||||
//// fxt.Init_lua_rcvd_rv();
|
||||
//// fxt.Test_invoke(expd);
|
||||
// }
|
||||
// private void Exec_gsub_regx_func_1(String text, String regx, String expd) {
|
||||
// fxt.Test_scrib_proc_kv_vals(lib, Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)), expd);
|
||||
//// fxt.Init_lua_module();
|
||||
//// fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)));
|
||||
//// fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"A\";}}");
|
||||
//// fxt.Init_lua_rcvd_rv();
|
||||
//// fxt.Test_invoke(expd);
|
||||
// }
|
||||
// private void Exec_gsub_regx_func_2(String text, String regx, String expd) {
|
||||
// fxt.Init_lua_module();
|
||||
// fxt.Init_lua_rcvd(Scrib_lib_ustring.Invk_gsub, Scrib_kv_utl_.base1_many_(text, regx, new Scrib_lua_proc("ignore_key", 1)));
|
||||
// fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"A\";}}");
|
||||
// fxt.Init_lua_rcvd_raw("a:3:{s:2:\"op\";s:6:\"return\";s:7:\"nvalues\";i:1;s:6:\"values\";a:1:{i:1;s:1:\"B\";}}");
|
||||
// fxt.Init_lua_rcvd_rv();
|
||||
// fxt.Init_lua_rcvd_rv();
|
||||
// fxt.Test_invoke(expd);
|
||||
// }
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import org.junit.*;
|
||||
import gplx.xowa.xtns.wdatas.*;
|
||||
public class Scrib_lib_wikibase_entity_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_wikibase().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void GetGlobalSiteId() {
|
||||
|
||||
@@ -341,6 +341,6 @@ class Scrib_lib_wikibase_srl_fxt {
|
||||
Class<?> kv_val_cls = kv_val.getClass();
|
||||
if (ClassAdp_.Eq(kv_val_cls, KeyVal[].class)) {bfr.Add_byte_nl(); Xto_str(bfr, (KeyVal[])kv_val, depth + 1);}
|
||||
else if (ClassAdp_.Eq(kv_val_cls, KeyVal[].class)) {bfr.Add_byte_nl(); Xto_str(bfr, (KeyVal)kv_val, depth + 1);}
|
||||
else bfr.Add_byte(Byte_ascii.Apos).Add_str(Object_.XtoStr_OrEmpty(kv_val)).Add_byte(Byte_ascii.Apos).Add_byte_nl();
|
||||
else bfr.Add_byte(Byte_ascii.Apos).Add_str(Object_.Xto_str_strict_or_empty(kv_val)).Add_byte(Byte_ascii.Apos).Add_byte_nl();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.junit.*;
|
||||
import gplx.xowa.xtns.wdatas.*;
|
||||
public class Scrib_lib_wikibase_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = fxt.Core().Lib_wikibase().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void GetGlobalSiteId() {
|
||||
|
||||
@@ -59,14 +59,14 @@ class Int_rng_mgr_base implements Int_rng_mgr {
|
||||
if (pos == -1) pos = i;
|
||||
break;
|
||||
case Byte_ascii.Dash:
|
||||
val_bgn = Bry_.X_to_int_or(src, pos, i, -1); if (val_bgn == -1) return false;
|
||||
val_bgn = Bry_.Xto_int_or(src, pos, i, -1); if (val_bgn == -1) return false;
|
||||
pos = -1;
|
||||
break;
|
||||
default: // invalid char;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int val_end = Bry_.X_to_int_or(src, pos, src_len, -1); if (val_end == -1) return false;
|
||||
int val_end = Bry_.Xto_int_or(src, pos, src_len, -1); if (val_end == -1) return false;
|
||||
if (val_bgn == -1)
|
||||
itms.Add(new Int_where_val(val_end));
|
||||
else
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.junit.*;
|
||||
import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.lib.*;
|
||||
public class Blacklist_scrib_lib_tst {
|
||||
@Before public void init() {
|
||||
fxt.Init_scrib_proc();
|
||||
fxt.Clear_for_lib();
|
||||
lib = new Blacklist_scrib_lib().Init();
|
||||
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Scrib_lib lib;
|
||||
@Test public void Exec_test() {
|
||||
|
||||
@@ -135,7 +135,7 @@ public class Wdata_doc_bldr {
|
||||
wtr.Comma();
|
||||
wtr.Nde_bgn();
|
||||
wtr.Kv(Bool_.N, Wdata_doc_consts.Key_ent_entity_type_bry, Wdata_doc_consts.Val_ent_entity_type_item_bry);
|
||||
wtr.Kv(Bool_.Y, Wdata_doc_consts.Key_ent_numeric_id_bry, Bry_.X_to_int(prop.Val()));
|
||||
wtr.Kv(Bool_.Y, Wdata_doc_consts.Key_ent_numeric_id_bry, Bry_.Xto_int(prop.Val()));
|
||||
wtr.Nde_end();
|
||||
break;
|
||||
case Wdata_prop_itm_base_.Val_tid_time:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user