mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v2.7.2.1
This commit is contained in:
31
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_align_h.java
Normal file
31
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_align_h.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; import gplx.*;
|
||||
public class Xop_lnki_align_h {
|
||||
public static final byte Null = 0, None = 1, Left = 2, Center = 3, Right = 4;
|
||||
public static final byte[][] Html_names = new byte[][]
|
||||
{ Bry_.new_a7("null")
|
||||
, Bry_.new_a7("none")
|
||||
, Bry_.new_a7("left")
|
||||
, Bry_.new_a7("center")
|
||||
, Bry_.new_a7("right")
|
||||
};
|
||||
}
|
||||
class Xop_lnki_align_v {
|
||||
public static final byte None = 0, Top = 1, Middle = 2, Bottom = 4, Super = 8, Sub = 16, TextTop = 32, TextBottom = 64, Baseline = 127;
|
||||
}
|
||||
168
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_arg_parser.java
Normal file
168
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_arg_parser.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import gplx.core.primitives.*; import gplx.core.btries.*;
|
||||
public class Xop_lnki_arg_parser {
|
||||
private int lnki_w, lnki_h;
|
||||
private Btrie_fast_mgr key_trie = Btrie_fast_mgr.cs_();
|
||||
private Bry_bfr int_bfr = Bry_bfr.reset_(16);
|
||||
public void Evt_lang_changed(Xol_lang lang) {
|
||||
Bry_bfr tmp_bfr = int_bfr;
|
||||
Byte_obj_ref rslt = Byte_obj_ref.zero_();
|
||||
Xol_kwd_mgr mgr = lang.Kwd_mgr();
|
||||
key_trie.Clear();
|
||||
Xol_kwd_grp list = null;
|
||||
int len = Keys_ids.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int[] val = Keys_ids[i];
|
||||
list = mgr.Get_at(val[0]); // NOTE: val[0] is magic_word id
|
||||
if (list == null) {
|
||||
if (Env_.Mode_testing())
|
||||
continue; // TEST: allows partial parsing of $magicWords
|
||||
else
|
||||
list = lang.Lang_mgr().Lang_en().Kwd_mgr().Get_at(val[0]);
|
||||
}
|
||||
Xol_kwd_itm[] words = list.Itms();
|
||||
int words_len = words.length;
|
||||
for (int j = 0; j < words_len; j++) {
|
||||
Xol_kwd_itm word = words[j];
|
||||
byte[] word_bry = Xol_kwd_parse_data.Strip(tmp_bfr, word.Val(), rslt);
|
||||
Init_key_trie(word_bry, (byte)val[1]); // NOTE: val[1] is lnki_key tid; ASSUME: case_sensitive for all "img_" words; note that all Messages**.php seem to be case_sensitive ("array(1, ..."); resisting change b/c of complexity/perf (need a cs trie and a ci trie)
|
||||
}
|
||||
}
|
||||
list = mgr.Get_at(Xol_kwd_grp_.Id_img_width);
|
||||
if (list == null)
|
||||
list = lang.Lang_mgr().Lang_en().Kwd_mgr().Get_at(Xol_kwd_grp_.Id_img_width);
|
||||
Init_size_trie(tmp_bfr, list);
|
||||
}
|
||||
public byte Identify_tid(byte[] src, int bgn, int end, Xop_lnki_tkn lnki) {
|
||||
lnki_w = Xop_lnki_tkn.Width_null;
|
||||
lnki_h = Xop_lnki_tkn.Height_null;
|
||||
byte rv = Identify_tid(src, bgn, end);
|
||||
if (lnki_w != Xop_lnki_tkn.Width_null) lnki.W_(lnki_w);
|
||||
if (lnki_h != Xop_lnki_tkn.Height_null)lnki.H_(lnki_h);
|
||||
return rv;
|
||||
}
|
||||
public byte Identify_tid(byte[] src, int bgn, int end) {
|
||||
int len = end - bgn;
|
||||
Byte_obj_val val = (Byte_obj_val)key_trie.Match_bgn(src, bgn, end);
|
||||
if (val != null && len == key_trie.Match_pos() - bgn) // check for false matches; EX: alternate= should not match alt=
|
||||
return val.Val(); // match; return val;
|
||||
Object bwd_obj = bwd_trie.Match_bgn(src, end - 1, bgn - 1);
|
||||
if (bwd_obj != null && ((Byte_obj_val)bwd_obj).Val() == Tid_dim) { // ends with "px"; try to parse size
|
||||
int_bfr.Clear();
|
||||
int match_len = end -1 - bwd_trie.Match_pos();
|
||||
boolean mode_width = true;
|
||||
int itm_end = bgn + (len - match_len); // remove trailing px
|
||||
for (int i = bgn; i < itm_end; i++) {
|
||||
byte b = src[i];
|
||||
Object o = size_trie.Match_bgn_w_byte(b, src, i, itm_end);
|
||||
if (o == null) {
|
||||
this.lnki_w = 0; // NOTE: must null out width; EX: "123xTextpx"; PAGE:es.b:Alimentaci<63>n_infantil; DATE:2015-07-10
|
||||
return Tid_caption; // letter or other invalid character; return caption
|
||||
}
|
||||
Byte_obj_val v = (Byte_obj_val)o;
|
||||
switch (v.Val()) {
|
||||
case Key_dim_num: int_bfr.Add_byte(b); break;
|
||||
case Key_space: break; // ignore space; EX: "100 px"
|
||||
case Key_dim_px: { // 2nd px found; EX: "40pxpx"; "40px px"
|
||||
int tmp_pos = size_trie.Match_pos();
|
||||
tmp_pos = Bry_finder.Find_fwd_while_space_or_tab(src, tmp_pos, itm_end); // look for next ws pos;
|
||||
if (tmp_pos == itm_end) // no non-ws found; tmp_pos == itm_end; allow itm; EX: "40pxpx"; "40px px"; DATE:2014-03-01
|
||||
i = itm_end;
|
||||
else // non-ws found; consider as caption; EX: "20px20px"; "20pxpxpx"
|
||||
return Tid_caption;
|
||||
break;
|
||||
}
|
||||
case Key_dim_x: {
|
||||
if (mode_width) {
|
||||
this.lnki_w = int_bfr.XtoIntAndClear(-1);
|
||||
mode_width = false;
|
||||
break;
|
||||
}
|
||||
else return Tid_caption;
|
||||
}
|
||||
}
|
||||
}
|
||||
int dim = int_bfr.XtoIntAndClear(-1);
|
||||
if (mode_width) this.lnki_w = dim;
|
||||
else this.lnki_h = dim;
|
||||
return Tid_dim;
|
||||
}
|
||||
return Tid_caption;
|
||||
} private Btrie_bwd_mgr bwd_trie = Btrie_bwd_mgr.cs_(); private Btrie_fast_mgr size_trie = Btrie_fast_mgr.cs_();
|
||||
private void Init_key_trie(byte[] key, byte v) {
|
||||
Byte_obj_val val = Byte_obj_val.new_(v);
|
||||
key_trie.Add(key, val);
|
||||
}
|
||||
private void Init_size_trie(Bry_bfr tmp_bfr, Xol_kwd_grp list) {
|
||||
if (list == null && Env_.Mode_testing()) return; // TEST: allows partial parsing of $magicWords
|
||||
size_trie.Clear(); bwd_trie.Clear();
|
||||
for (int i = 0; i < 10; i++)
|
||||
size_trie.Add((byte)(i + Char_.AsciiZero), Byte_obj_val.new_(Key_dim_num));
|
||||
size_trie.Add(Byte_ascii.Space, Byte_obj_val.new_(Key_space));
|
||||
size_trie.Add(X_bry, Byte_obj_val.new_(Key_dim_x));
|
||||
Xol_kwd_itm[] words = list.Itms();
|
||||
int words_len = words.length;
|
||||
Byte_obj_ref rslt = Byte_obj_ref.zero_();
|
||||
for (int i = 0; i < words_len; i++) {
|
||||
byte[] word_bry = Xol_kwd_parse_data.Strip(tmp_bfr, words[i].Val(), rslt);
|
||||
size_trie.Add(word_bry, Byte_obj_val.new_(Key_dim_px));
|
||||
bwd_trie.Add(word_bry, Byte_obj_val.new_(Tid_dim));
|
||||
}
|
||||
}
|
||||
public static final byte[] Bry_upright = Bry_.new_u8("upright"), Bry_thumbtime = Bry_.new_u8("thumbtime");
|
||||
public static final byte
|
||||
Tid_unknown = 0, Tid_thumb = 1, Tid_left = 2, Tid_right = 3, Tid_none = 4, Tid_center = 5, Tid_frame = 6, Tid_frameless = 7, Tid_upright = 8, Tid_border = 9
|
||||
, Tid_alt = 10, Tid_link = 11, Tid_baseline = 12, Tid_sub = 13, Tid_super = 14, Tid_top = 15, Tid_text_top = 16, Tid_middle = 17, Tid_bottom = 18, Tid_text_bottom = 19
|
||||
, Tid_dim = 20
|
||||
, Tid_trg = 21, Tid_caption = 22
|
||||
, Tid_page = 23
|
||||
, Tid_noplayer = 24, Tid_noicon = 25, Tid_thumbtime = 26
|
||||
, Tid_class = 27
|
||||
;
|
||||
private static final byte[] X_bry = Bry_.new_u8("x");
|
||||
private static final byte Key_dim_num = 0, Key_dim_x = 1, Key_dim_px = 2, Key_space = 3;
|
||||
private static final int[][] Keys_ids = new int[][]
|
||||
{ new int[] {Xol_kwd_grp_.Id_img_thumbnail , Tid_thumb}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_manualthumb , Tid_thumb} // RESEARCH: what is manualthumb? 'thumb=$1' vs 'thumb'
|
||||
, new int[] {Xol_kwd_grp_.Id_img_right , Tid_right}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_left , Tid_left}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_none , Tid_none}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_center , Tid_center}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_framed , Tid_frame}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_frameless , Tid_frameless}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_page , Tid_page} // for pdf
|
||||
, new int[] {Xol_kwd_grp_.Id_img_upright , Tid_upright}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_border , Tid_border}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_baseline , Tid_baseline}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_sub , Tid_sub}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_super , Tid_super}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_top , Tid_top}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_text_top , Tid_text_top}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_middle , Tid_middle}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_bottom , Tid_bottom}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_text_bottom , Tid_text_bottom}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_link , Tid_link}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_alt , Tid_alt}
|
||||
, new int[] {Xol_kwd_grp_.Id_img_class , Tid_class}
|
||||
, new int[] {Xol_kwd_grp_.Id_ogg_noplayer , Tid_noplayer} // RESEARCH: what does noplayer do?; find example
|
||||
, new int[] {Xol_kwd_grp_.Id_ogg_noicon , Tid_noicon}
|
||||
, new int[] {Xol_kwd_grp_.Id_ogg_thumbtime , Tid_thumbtime}
|
||||
};
|
||||
}
|
||||
56
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_lxr_bgn.java
Normal file
56
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_lxr_bgn.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; import gplx.*;
|
||||
import gplx.core.btries.*;
|
||||
public class Xop_lnki_lxr_bgn implements Xop_lxr {
|
||||
public byte Lxr_tid() {return Xop_lxr_.Tid_lnki_bgn;}
|
||||
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_bgn, this);}
|
||||
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
|
||||
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
|
||||
Xop_tkn_itm prv_tkn = ctx.Stack_get_last();
|
||||
if (prv_tkn != null
|
||||
&& prv_tkn.Tkn_tid() == Xop_tkn_itm_.Tid_lnki) {
|
||||
Xop_lnki_tkn prv_lnki = (Xop_lnki_tkn)prv_tkn;
|
||||
if (prv_lnki.Pipe_count() == 0) {
|
||||
ctx.Stack_pop_last();
|
||||
return Xop_lnki_wkr_.Invalidate_lnki(ctx, src, root, prv_lnki, bgn_pos);
|
||||
}
|
||||
}
|
||||
Xop_lnki_tkn lnki = tkn_mkr.Lnki(bgn_pos, cur_pos);
|
||||
ctx.Subs_add_and_stack(root, lnki);
|
||||
return cur_pos;
|
||||
}
|
||||
public static final Xop_lnki_lxr_bgn _ = new Xop_lnki_lxr_bgn();
|
||||
}
|
||||
class Xop_lnki_size {public static final int None = 0, Width = 1, Height = 2, WidthHeight = 4, Upright = 8;}
|
||||
/*
|
||||
Spaces + NewLines
|
||||
. ignored near posts: '[[ '; ' ]]'; ' | '
|
||||
. not ignored in: ' ='; basically breaks key
|
||||
. not ignored in: '= '; will add to value; EX: alt= a -> ' a'
|
||||
|
||||
NewLines
|
||||
. will break lnk if in trg area (before | or ]]); EX:[[Image:The\nFabs -> [[Image:The Fabs
|
||||
. will break alt (which apparently does not like new lines)
|
||||
. will be converted to space for caption
|
||||
|
||||
http://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax
|
||||
The image syntax begins with "[[", contains components separated by "|", and ends with "]]". The "[[" and the first "|" (or, if there is no "|", the terminating "]]")
|
||||
must be on the same line; other spaces and line breaks are ignored if they are next to "|" characters or just inside the brackets.
|
||||
Spaces or line breaks are not allowed just before the "=" in the following options, and may have undesirable side effects if they appear just after the "=".
|
||||
*/
|
||||
26
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_lxr_end.java
Normal file
26
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_lxr_end.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; import gplx.*;
|
||||
import gplx.core.btries.*;
|
||||
public class Xop_lnki_lxr_end implements Xop_lxr {
|
||||
public byte Lxr_tid() {return Xop_lxr_.Tid_lnki_end;}
|
||||
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_end, this);}
|
||||
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
|
||||
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {return ctx.Lnki().Make_tkn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);}
|
||||
public static final Xop_lnki_lxr_end _ = new Xop_lnki_lxr_end();
|
||||
}
|
||||
64
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_tkn.java
Normal file
64
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_tkn.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import gplx.xowa.files.*; import gplx.xowa.html.*; import gplx.xowa.html.lnkis.*; import gplx.xowa.xtns.pfuncs.ttls.*;
|
||||
public class Xop_lnki_tkn extends Xop_tkn_itm_base {
|
||||
@Override public byte Tkn_tid() {return tkn_tid;} private byte tkn_tid = Xop_tkn_itm_.Tid_lnki;
|
||||
public void Tkn_tid_to_txt() {tkn_tid = Xop_tkn_itm_.Tid_txt;}
|
||||
public int Ns_id() {return ns_id;} public Xop_lnki_tkn Ns_id_(int v) {ns_id = v; return this;} private int ns_id;
|
||||
public Xoa_ttl Ttl() {return ttl;} public Xop_lnki_tkn Ttl_(Xoa_ttl v) {ttl = v; return this;} private Xoa_ttl ttl;
|
||||
public byte Lnki_type() {return lnki_type;} public Xop_lnki_tkn Lnki_type_(byte v) {lnki_type = (byte)Enm_.AddInt(lnki_type, v); return this;} private byte lnki_type = Xop_lnki_type.Id_null;
|
||||
public int Tail_bgn() {return tail_bgn;} public Xop_lnki_tkn Tail_bgn_(int v) {tail_bgn = v; return this;} private int tail_bgn = -1;
|
||||
public int Tail_end() {return tail_end;} public Xop_lnki_tkn Tail_end_(int v) {tail_end = v; return this;} private int tail_end = -1;
|
||||
public byte Border() {return border;} public Xop_lnki_tkn Border_(byte v) {border = v; return this;} private byte border = Bool_.__byte;
|
||||
public byte Align_h() {return align_h;} public Xop_lnki_tkn Align_h_(byte v) {if (align_h == Xop_lnki_align_h.Null) align_h = v; return this;} private byte align_h = Xop_lnki_align_h.Null;
|
||||
public byte Align_v() {return align_v;} public Xop_lnki_tkn Align_v_(byte v) {align_v = v; return this;} private byte align_v = Byte_.Max_value_127;
|
||||
public int W() {return w;} public Xop_lnki_tkn W_(int v) {w = v; return this;} private int w = Width_null;
|
||||
public int H() {return h;} public Xop_lnki_tkn H_(int v) {h = v; return this;} private int h = Height_null;
|
||||
public byte[] Lnki_cls() {return lnki_cls;} public void Lnki_cls_(byte[] v) {lnki_cls = v;} private byte[] lnki_cls;
|
||||
public boolean Media_icon() {return media_icon;} public Xop_lnki_tkn Media_icon_n_() {media_icon = false; return this;} private boolean media_icon = true;
|
||||
public double Upright() {return upright;} public Xop_lnki_tkn Upright_(double v) {upright = v; return this;} private double upright = Upright_null;
|
||||
public double Time() {return time;} public Xop_lnki_tkn Time_(double v) {time = v; return this;} private double time = Xof_lnki_time.Null;
|
||||
public int Page() {return page;} public Xop_lnki_tkn Page_(int v) {page = v; return this;} private int page = Xof_lnki_page.Null;
|
||||
public Xop_tkn_itm Trg_tkn() {return trg_tkn;} public Xop_lnki_tkn Trg_tkn_(Xop_tkn_itm v) {trg_tkn = v; return this;} private Xop_tkn_itm trg_tkn = Xop_tkn_null.Null_tkn;
|
||||
public Xop_tkn_itm Caption_tkn() {return caption_tkn;} public Xop_lnki_tkn Caption_tkn_(Xop_tkn_itm v) {caption_tkn = v; return this;} private Xop_tkn_itm caption_tkn = Xop_tkn_null.Null_tkn;
|
||||
public boolean Caption_tkn_pipe_trick() {return caption_tkn_pipe_trick;} public Xop_lnki_tkn Caption_tkn_pipe_trick_(boolean v) {caption_tkn_pipe_trick = v; return this;} private boolean caption_tkn_pipe_trick;
|
||||
public Xop_tkn_itm Caption_val_tkn() {return caption_tkn == Xop_tkn_null.Null_tkn ? Arg_itm_tkn_null.Null_arg_itm : ((Arg_nde_tkn)caption_tkn).Val_tkn();}
|
||||
public Arg_nde_tkn Link_tkn() {return link_tkn;} public Xop_lnki_tkn Link_tkn_(Arg_nde_tkn v) {link_tkn = v; return this;} Arg_nde_tkn link_tkn = Arg_nde_tkn.Null;
|
||||
public Arg_nde_tkn Alt_tkn() {return alt_tkn;} public Xop_lnki_tkn Alt_tkn_(Arg_nde_tkn v) {alt_tkn = v; return this;} Arg_nde_tkn alt_tkn = Arg_nde_tkn.Null;
|
||||
public boolean Alt_exists() {return alt_tkn != Arg_nde_tkn.Null;}
|
||||
public int Subpage_tid() {return subpage_tid;} public Xop_lnki_tkn Subpage_tid_(int v) {subpage_tid = v; return this;} private int subpage_tid = Pfunc_rel2abs.Id_null;
|
||||
public boolean Subpage_slash_at_end() {return subpage_slash_at_end;} public Xop_lnki_tkn Subpage_slash_at_end_(boolean v) {subpage_slash_at_end = v; return this;} private boolean subpage_slash_at_end;
|
||||
public int Html_uid() {return html_uid;} public Xop_lnki_tkn Html_uid_(int v) {html_uid = v; return this;} private int html_uid;
|
||||
public int Pipe_count() {return pipe_count;} private int pipe_count;
|
||||
public boolean Pipe_count_is_zero() {return pipe_count++ == 0;}
|
||||
public boolean Xtn_sites_link() {return xtn_sites_link;} public void Xtn_sites_link_(boolean v) {xtn_sites_link = v;} private boolean xtn_sites_link;
|
||||
public Xoh_file_img_wkr Lnki_file_wkr() {return lnki_file_wkr;} public void Lnki_file_wkr_(Xoh_file_img_wkr v) {lnki_file_wkr = v;} private Xoh_file_img_wkr lnki_file_wkr;
|
||||
public byte[] Ttl_ary() {
|
||||
return ttl.ForceLiteralLink() || ns_id != Xow_ns_.Id_main // if [[:]] or non-main (Category, Template)
|
||||
? ttl.Full_txt() // use full_txt (no initial colon; capitalize first)
|
||||
: ttl.Raw(); // use raw (preserve case, white-spaces)
|
||||
}
|
||||
public boolean Caption_exists() {
|
||||
return !((caption_tkn == Xop_tkn_null.Null_tkn) // trg only; no caption: EX: [[a]] vs. [[a|b]] which has a trg of a and a caption of b
|
||||
|| (ns_id == Xow_ns_.Id_category // a Category only has a target; any caption is ignored; EX: [[Category:a|b], b is ignored
|
||||
&& !ttl.ForceLiteralLink()));
|
||||
}
|
||||
public static final double Upright_null = -1;
|
||||
public static final int Width_null = -1, Height_null = -1;
|
||||
}
|
||||
65
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_type.java
Normal file
65
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_type.java
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public class Xop_lnki_type {
|
||||
public static final byte Id_null = 0, Id_none = 1, Id_frameless = 2, Id_frame = 4, Id_thumb = 8;
|
||||
public static boolean Id_is_thumbable(byte id) {
|
||||
return ( Enm_.HasInt(id, Id_thumb) // for purposes of displaying images on page, thumb and frame both create a thumb box
|
||||
|| Enm_.HasInt(id, Id_frame)
|
||||
);
|
||||
}
|
||||
public static boolean Id_defaults_to_thumb(byte id) { // assuming original of 400,200
|
||||
if ( Enm_.HasInt(id, Id_thumb) // [[File:A.png|thumb]] -> 220,-1
|
||||
|| Enm_.HasInt(id, Id_frameless) // [[File:A.png|frameless]] -> 220,-1
|
||||
)
|
||||
return true;
|
||||
else if ( Enm_.HasInt(id, Id_frame) // [[File:A.png|frame]] -> 400,200 (frame is always default size)
|
||||
|| id == Id_null // [[File:A.png]] -> 400,200 (default to original size)
|
||||
|| Enm_.HasInt(id, Id_none) // TODO: deprecate
|
||||
)
|
||||
return false;
|
||||
else // should not happen
|
||||
throw Exc_.new_unhandled(id);
|
||||
}
|
||||
public static boolean Id_limits_large_size(byte id) {// Linker.php|makeThumbLink2|Do not present an image bigger than the source, for bitmap-style images; assuming original of 400,200
|
||||
if ( Enm_.HasInt(id, Id_thumb) // [[File:A.png|600px|thumb]] -> 400,200
|
||||
|| Enm_.HasInt(id, Id_frameless) // [[File:A.png|600px|frameless]] -> 400,200
|
||||
|| Enm_.HasInt(id, Id_frame) // [[File:A.png|600px|frame]] -> 400,200 (frame is always default size)
|
||||
)
|
||||
return true;
|
||||
else if ( id == Id_null // [[File:A.png|600px]] -> 600,400; uses orig file of 400,200, but <img> tag src_width / src_height set to 600,400
|
||||
|| Enm_.HasInt(id, Id_none) // TODO: deprecate
|
||||
)
|
||||
return false;
|
||||
else // should not happen;
|
||||
throw Exc_.new_unhandled(id);
|
||||
}
|
||||
public static boolean Id_supports_upright(byte id) {// REF:Linker.php|makeImageLink;if ( isset( $fp['thumbnail'] ) || isset( $fp['manualthumb'] ) || isset( $fp['framed'] ) || isset( $fp['frameless'] ) || !$hp['width'] ) DATE:2014-05-22
|
||||
if ( Enm_.HasInt(id, Id_thumb)
|
||||
|| Enm_.HasInt(id, Id_frameless)
|
||||
|| Enm_.HasInt(id, Id_frame)
|
||||
)
|
||||
return true;
|
||||
else if ( id == Id_null
|
||||
|| Enm_.HasInt(id, Id_none)
|
||||
)
|
||||
return false;
|
||||
else // should not happen;
|
||||
throw Exc_.new_unhandled(id);
|
||||
}
|
||||
}
|
||||
177
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr.java
Normal file
177
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr.java
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import gplx.core.btries.*;
|
||||
import gplx.xowa.wikis.*; import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.xtns.pfuncs.ttls.*; import gplx.xowa.xtns.relatedSites.*;
|
||||
public class Xop_lnki_wkr implements Xop_ctx_wkr, Xop_arg_wkr {
|
||||
private Arg_bldr arg_bldr = Arg_bldr._;
|
||||
private Number_parser number_parser = new Number_parser();
|
||||
private Sites_regy_mgr sites_regy_mgr;
|
||||
public void Ctor_ctx(Xop_ctx ctx) {}
|
||||
public void Page_bgn(Xop_ctx ctx, Xop_root_tkn root) {
|
||||
sites_regy_mgr = ctx.Wiki().Xtn_mgr().Xtn_sites().Regy_mgr(); if (!sites_regy_mgr.Xtn_mgr().Enabled()) sites_regy_mgr = null; // sets sites_xtn_mgr status for page; see below
|
||||
}
|
||||
public void Page_end(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int src_len) {}
|
||||
public Xopg_redlink_logger File_wkr() {return file_wkr;} public Xop_lnki_wkr File_wkr_(Xopg_redlink_logger v) {file_wkr = v; return this;} private Xopg_redlink_logger file_wkr;
|
||||
public void Auto_close(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, Xop_tkn_itm tkn) {
|
||||
Xop_lnki_tkn lnki = (Xop_lnki_tkn)tkn;
|
||||
lnki.Tkn_tid_to_txt();
|
||||
ctx.Msg_log().Add_itm_none(Xop_misc_log.Eos, src, lnki.Src_bgn(), lnki.Src_end());
|
||||
}
|
||||
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
|
||||
if (ctx.Cur_tkn_tid() == Xop_tkn_itm_.Tid_lnke) { // if lnke then take 1st ] in "]]" and use it close lnke
|
||||
int lnke_end_pos = bgn_pos + 1;
|
||||
ctx.Lnke().MakeTkn_end(ctx, tkn_mkr, root, src, src_len, bgn_pos, lnke_end_pos);
|
||||
return lnke_end_pos;
|
||||
}
|
||||
int stack_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_lnki);
|
||||
if (stack_pos == Xop_ctx.Stack_not_found) return ctx.Lxr_make_txt_(cur_pos); // "]]" found but no "[[" in stack; return literal "]]"
|
||||
Xop_lnki_tkn lnki = (Xop_lnki_tkn)ctx.Stack_pop_til(root, src, stack_pos, false, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_lnki_end);
|
||||
if (!arg_bldr.Bld(ctx, tkn_mkr, this, Xop_arg_wkr_.Typ_lnki, root, lnki, bgn_pos, cur_pos, lnki.Tkn_sub_idx() + 1, root.Subs_len(), src))
|
||||
return Xop_lnki_wkr_.Invalidate_lnki(ctx, src, root, lnki, bgn_pos);
|
||||
if (Xop_lnki_wkr_.Adjust_for_brack_end_len_of_3(ctx, tkn_mkr, root, src, src_len, cur_pos, lnki)) // convert "]]]" into "]" + "]]", not "]]" + "]"
|
||||
++cur_pos; // position "]]" at end of "]]]"
|
||||
cur_pos = Xop_lnki_wkr_.Chk_for_tail(ctx.Lang(), src, cur_pos, src_len, lnki);
|
||||
lnki.Src_end_(cur_pos); // NOTE: must happen after Chk_for_tail; redundant with above, but above needed b/c of returns
|
||||
root.Subs_del_after(lnki.Tkn_sub_idx() + 1); // all tkns should now be converted to args in owner; delete everything in root
|
||||
boolean lnki_is_file = false;
|
||||
switch (lnki.Ns_id()) {
|
||||
case Xow_ns_.Id_file:
|
||||
if ( Xop_lnki_type.Id_is_thumbable(lnki.Lnki_type()) // thumbs produce <div> cancels pre
|
||||
|| lnki.Align_h() != Xop_lnki_align_h.Null // halign (left, right, none) also produces <div>; DATE:2014-02-17
|
||||
)
|
||||
ctx.Para().Process_block_lnki_div();
|
||||
lnki_is_file = true;
|
||||
break;
|
||||
case Xow_ns_.Id_media:
|
||||
lnki_is_file = true;
|
||||
break;
|
||||
case Xow_ns_.Id_category:
|
||||
if (!lnki.Ttl().ForceLiteralLink()) // NOTE: do not remove ws if literal; EX:[[Category:A]]\n[[Category:B]] should stay the same; DATE:2013-07-10
|
||||
ctx.Para().Process_lnki_category(ctx, root, src,cur_pos, src_len); // removes excessive ws between categories; EX: [[Category:A]]\n\s[[Category:B]] -> [[Category:A]][[Category:B]] (note that both categories will not be rendered directly in html, but go to the bottom of the page)
|
||||
break;
|
||||
}
|
||||
if (lnki_is_file) {
|
||||
ctx.Cur_page().Lnki_list().Add(lnki);
|
||||
if (file_wkr != null) file_wkr.Wkr_exec(ctx, src, lnki, gplx.xowa.bldrs.cmds.files.Xob_lnki_src_tid.Tid_file);
|
||||
}
|
||||
Xoa_ttl lnki_ttl = lnki.Ttl();
|
||||
if ( lnki_ttl.Wik_bgn() != -1 // lnki is xwiki
|
||||
&& sites_regy_mgr != null // relatedSites xtn is enabled
|
||||
) {
|
||||
lnki.Xtn_sites_link_(sites_regy_mgr.Match(ctx.Cur_page(), lnki_ttl));
|
||||
}
|
||||
return cur_pos;
|
||||
}
|
||||
public boolean Args_add(Xop_ctx ctx, byte[] src, Xop_tkn_itm tkn, Arg_nde_tkn arg, int arg_idx) {
|
||||
Xop_lnki_tkn lnki = (Xop_lnki_tkn)tkn;
|
||||
try {
|
||||
if (arg_idx == 0) { // 1st arg; assume trg; process ns;
|
||||
if (lnki.Ttl() == null) { // ttl usually set by 1st pipe, but some lnkis have no pipe; EX: [[A]]
|
||||
Arg_itm_tkn ttl_tkn = arg.Val_tkn();
|
||||
if (!Xop_lnki_wkr_.Parse_ttl(ctx, src, lnki, ttl_tkn.Dat_bgn(), ttl_tkn.Dat_end()))
|
||||
return false;
|
||||
}
|
||||
lnki.Trg_tkn_(arg);
|
||||
}
|
||||
else { // nth arg; guess arg type
|
||||
int arg_tid = -1;
|
||||
int bgn = arg.Val_tkn().Dat_bgn(), end = arg.Val_tkn().Dat_end();
|
||||
if (arg.KeyTkn_exists()) {bgn = arg.Key_tkn().Dat_bgn(); end = arg.Key_tkn().Dat_end();}
|
||||
arg_tid = ctx.Wiki().Lang().Lnki_arg_parser().Identify_tid(src, bgn, end, lnki);
|
||||
switch (arg_tid) {
|
||||
case Xop_lnki_arg_parser.Tid_none: lnki.Align_h_(Xop_lnki_type.Id_none); break;
|
||||
case Xop_lnki_arg_parser.Tid_border: lnki.Border_(Bool_.Y_byte); break;
|
||||
case Xop_lnki_arg_parser.Tid_thumb: lnki.Lnki_type_(Xop_lnki_type.Id_thumb); break;
|
||||
case Xop_lnki_arg_parser.Tid_frame: lnki.Lnki_type_(Xop_lnki_type.Id_frame); break;
|
||||
case Xop_lnki_arg_parser.Tid_frameless: lnki.Lnki_type_(Xop_lnki_type.Id_frameless); break;
|
||||
case Xop_lnki_arg_parser.Tid_left: lnki.Align_h_(Xop_lnki_align_h.Left); break;
|
||||
case Xop_lnki_arg_parser.Tid_center: lnki.Align_h_(Xop_lnki_align_h.Center); break;
|
||||
case Xop_lnki_arg_parser.Tid_right: lnki.Align_h_(Xop_lnki_align_h.Right); break;
|
||||
case Xop_lnki_arg_parser.Tid_top: lnki.Align_v_(Xop_lnki_align_v.Top); break;
|
||||
case Xop_lnki_arg_parser.Tid_middle: lnki.Align_v_(Xop_lnki_align_v.Middle); break;
|
||||
case Xop_lnki_arg_parser.Tid_bottom: lnki.Align_v_(Xop_lnki_align_v.Bottom); break;
|
||||
case Xop_lnki_arg_parser.Tid_super: lnki.Align_v_(Xop_lnki_align_v.Super); break;
|
||||
case Xop_lnki_arg_parser.Tid_sub: lnki.Align_v_(Xop_lnki_align_v.Sub); break;
|
||||
case Xop_lnki_arg_parser.Tid_text_top: lnki.Align_v_(Xop_lnki_align_v.TextTop); break;
|
||||
case Xop_lnki_arg_parser.Tid_text_bottom: lnki.Align_v_(Xop_lnki_align_v.TextBottom); break;
|
||||
case Xop_lnki_arg_parser.Tid_baseline: lnki.Align_v_(Xop_lnki_align_v.Baseline); break;
|
||||
case Xop_lnki_arg_parser.Tid_class: lnki.Lnki_cls_(Xop_lnki_wkr_.Val_extract(src, arg)); break;
|
||||
case Xop_lnki_arg_parser.Tid_alt: lnki.Alt_tkn_(arg);
|
||||
lnki.Alt_tkn().Tkn_ini_pos(false, arg.Src_bgn(), arg.Src_end());
|
||||
break;
|
||||
case Xop_lnki_arg_parser.Tid_caption:
|
||||
Xop_tkn_itm cur_caption_tkn = lnki.Caption_tkn();
|
||||
if ( cur_caption_tkn == Xop_tkn_null.Null_tkn // lnki doesn't have caption; add arg as caption
|
||||
|| lnki.Ttl().Ns().Id_file_or_media()) { // or lnki is File; always take last
|
||||
lnki.Caption_tkn_(arg);
|
||||
if (arg.Eq_tkn() != Xop_tkn_null.Null_tkn) { // equal tkn exists; add val tkns to key and then swap key with val
|
||||
Arg_itm_tkn key_tkn = arg.Key_tkn(), val_tkn = arg.Val_tkn();
|
||||
key_tkn.Subs_add(arg.Eq_tkn());
|
||||
for (int i = 0; i < val_tkn.Subs_len(); i++) {
|
||||
Xop_tkn_itm sub = val_tkn.Subs_get(i);
|
||||
key_tkn.Subs_add(sub);
|
||||
}
|
||||
key_tkn.Dat_end_(val_tkn.Dat_end());
|
||||
val_tkn.Subs_clear();
|
||||
arg.Key_tkn_(Arg_itm_tkn_null.Null_arg_itm);
|
||||
arg.Val_tkn_(key_tkn);
|
||||
}
|
||||
else // no equal tkn
|
||||
lnki.Caption_tkn_pipe_trick_(end - bgn == 0); // NOTE: pipe_trick check must go here; checks for val_tkn.Bgn == val_tkn.End; if there is an equal token but no val, then Bgn == End which would trigger false pipe trick (EX:"[[A|B=]]")
|
||||
}
|
||||
else { // lnki does have caption; new caption should be concatenated; EX:[[A|B|C]] -> "B|C" x> "B"; NOTE: pipe-trick and eq tkn should not matter to multiple captions; DATE:2014-05-05
|
||||
Xop_tkn_itm val_tkn = arg.Val_tkn();
|
||||
int subs_len = val_tkn.Subs_len();
|
||||
Xop_tkn_itm caption_val_tkn = ((Arg_nde_tkn)cur_caption_tkn).Val_tkn();
|
||||
int pipe_bgn = caption_val_tkn.Src_bgn(); // for bookeeping purposes, assign | pos to same pos as val_tkn; note that pos really shouldn't be used; DATE:2014-05-05
|
||||
caption_val_tkn.Subs_add(ctx.Tkn_mkr().Bry_raw(pipe_bgn, pipe_bgn + 1, Const_pipe)); // NOTE: add pipe once for entire caption tkn; used to add for every val tkn; DATE:2014-06-08
|
||||
for (int i = 0 ; i < subs_len; i++) {
|
||||
Xop_tkn_itm sub_itm = val_tkn.Subs_get(i);
|
||||
caption_val_tkn.Subs_add(sub_itm);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Xop_lnki_arg_parser.Tid_link: lnki.Link_tkn_(arg); break;
|
||||
case Xop_lnki_arg_parser.Tid_dim: break;// NOOP: Identify_tid does actual setting
|
||||
case Xop_lnki_arg_parser.Tid_upright:
|
||||
if (arg.KeyTkn_exists()) {
|
||||
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
|
||||
val_tkn_bgn = Bry_finder.Find_fwd_while_space_or_tab(src, val_tkn_bgn, val_tkn_end); // trim ws at bgn; needed for next step
|
||||
if (val_tkn_end - val_tkn_bgn > 19) val_tkn_end = val_tkn_bgn + 19; // HACK: limit upright tkn to 19 digits; 20 or more will overflow long; WHEN: rewrite number_parser to handle doubles; PAGE:de.w:Feuerland DATE:2015-02-03
|
||||
number_parser.Parse(src, val_tkn_bgn, val_tkn_end);
|
||||
if (number_parser.Has_err())
|
||||
ctx.Msg_log().Add_itm_none(Xop_lnki_log.Upright_val_is_invalid, src, val_tkn_bgn, val_tkn_end);
|
||||
else
|
||||
lnki.Upright_(number_parser.Rv_as_dec().Xto_double());
|
||||
}
|
||||
else // no =; EX: [[Image:a|upright]]
|
||||
lnki.Upright_(gplx.xowa.files.Xof_img_size.Upright_default_marker);// NOTE: was incorrectly hardcoded as 1; DATE:2014-07-23
|
||||
break;
|
||||
case Xop_lnki_arg_parser.Tid_noicon: lnki.Media_icon_n_(); break;
|
||||
case Xop_lnki_arg_parser.Tid_page: Xop_lnki_wkr_.Page_parse(ctx, src, number_parser, lnki, arg); break;
|
||||
case Xop_lnki_arg_parser.Tid_thumbtime: Xop_lnki_wkr_.Thumbtime_parse(ctx, src, number_parser, lnki, arg); break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
ctx.App().Usr_dlg().Warn_many("", "", "fatal error in lnki: page=~{0} src=~{1} err=~{2}", String_.new_u8(ctx.Cur_page().Ttl().Full_db()), String_.new_u8(src, lnki.Src_bgn(), lnki.Src_end()), Err_.Message_gplx(e));
|
||||
return false;
|
||||
}
|
||||
} private static final byte[] Const_pipe = Bry_.new_a7("|");
|
||||
}
|
||||
138
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr_.java
Normal file
138
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr_.java
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import gplx.core.primitives.*; import gplx.core.btries.*;
|
||||
import gplx.xowa.wikis.*; import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.xtns.pfuncs.ttls.*; import gplx.xowa.xtns.relatedSites.*;
|
||||
public class Xop_lnki_wkr_ {
|
||||
private static final Int_obj_ref rel2abs_tid = Int_obj_ref.zero_();
|
||||
public static final int Invalidate_lnki_len = 128;
|
||||
public static int Invalidate_lnki(Xop_ctx ctx, byte[] src, Xop_root_tkn root, Xop_lnki_tkn lnki, int cur_pos) {
|
||||
lnki.Tkn_tid_to_txt(); // convert initial "[[" to text; note that this lnki has no pipes as pipe_lxr does similar check; EX: [[<invalid>]]; DATE:2014-03-26
|
||||
root.Subs_del_after(lnki.Tkn_sub_idx() + 1);// remove all tkns after [[ from root
|
||||
int reparse_bgn = lnki.Src_end(); // NOTE: reparse all text from "[["; needed to handle [[|<i>a</i>]] where "<i>a</i>" cannot be returned as text; DATE:2014-03-04
|
||||
ctx.App().Msg_log().Add_itm_none(Xop_lnki_log.Invalid_ttl, src, reparse_bgn, reparse_bgn + 128);
|
||||
// int reparse_len = cur_pos - reparse_bgn;
|
||||
// if (reparse_len > 512) ctx.App().Usr_dlg().Warn_many("", "", "lnki.reparsing large block; page=~{0} len=~{1} src=~{2}", Xop_ctx_.Page_as_str(ctx), reparse_len, Xop_ctx_.Src_limit_and_escape_nl(src, reparse_bgn, Invalidate_lnki_len));
|
||||
return reparse_bgn;
|
||||
}
|
||||
public static boolean Parse_ttl(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int pipe_pos) {
|
||||
int ttl_bgn = lnki.Src_bgn() + Xop_tkn_.Lnki_bgn_len;
|
||||
ttl_bgn = Bry_finder.Find_fwd_while(src, ttl_bgn, pipe_pos, Byte_ascii.Space); // remove \s from bgn
|
||||
int ttl_end = Bry_finder.Find_bwd_while(src, pipe_pos, ttl_bgn, Byte_ascii.Space); // remove \s from end
|
||||
++ttl_end; // +1 to place after non-ws; EX: [[ a ]]; ttl_end should go from 3 -> 4
|
||||
return Parse_ttl(ctx, src, lnki, ttl_bgn, ttl_end);
|
||||
}
|
||||
public static boolean Parse_ttl(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int ttl_bgn, int ttl_end) {
|
||||
Xoae_app app = ctx.App();
|
||||
byte[] ttl_bry = Bry_.Mid(src, ttl_bgn, ttl_end);
|
||||
ttl_bry = Xoa_app_.Utl__encoder_mgr().Http_url_ttl().Decode(ttl_bry);
|
||||
int ttl_bry_len = ttl_bry.length;
|
||||
Xoa_ttl page_ttl = ctx.Cur_page().Ttl();
|
||||
if (page_ttl.Ns().Subpages_enabled()
|
||||
&& Pfunc_rel2abs.Rel2abs_ttl(ttl_bry, 0, ttl_bry_len)) { // Linker.php|normalizeSubpageLink
|
||||
Bry_bfr tmp_bfr = app.Utl__bfr_mkr().Get_b512();
|
||||
byte[] new_bry = Pfunc_rel2abs.Rel2abs(tmp_bfr, ttl_bry, page_ttl.Raw(), rel2abs_tid.Val_zero_());
|
||||
lnki.Subpage_tid_(rel2abs_tid.Val());
|
||||
lnki.Subpage_slash_at_end_(Bry_.Get_at_end(ttl_bry) == Byte_ascii.Slash);
|
||||
ttl_bry = new_bry;
|
||||
tmp_bfr.Mkr_rls();
|
||||
}
|
||||
Xowe_wiki wiki = ctx.Wiki();
|
||||
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, ttl_bry);
|
||||
if (ttl == null) return false;
|
||||
if ( wiki.Cfg_parser_lnki_xwiki_repos_enabled() // wiki has lnki.xwiki_repos
|
||||
&& ttl.Wik_bgn() != Xoa_ttl.Null_wik_bgn // xwiki available; EX: [[en:]]
|
||||
)
|
||||
ttl = Adj_ttl_for_file(wiki, ctx, ttl, ttl_bry);
|
||||
lnki.Ttl_(ttl);
|
||||
lnki.Ns_id_(ttl.Ns().Id());
|
||||
return true;
|
||||
}
|
||||
private static Xoa_ttl Adj_ttl_for_file(Xowe_wiki wiki, Xop_ctx ctx, Xoa_ttl ttl, byte[] ttl_bry) { // NOTE: remove the xwiki part; EX: [[en:File:A.png]] -> [[File:A.png]]
|
||||
byte[] xwiki_bry = ttl.Wik_txt(); if (xwiki_bry == null) return ttl; // should not happen, but just in case
|
||||
int xwiki_bry_len = xwiki_bry.length;
|
||||
int ttl_bry_len = ttl_bry.length;
|
||||
if (xwiki_bry_len + 1 >= ttl_bry_len) return ttl; // invalid ttl; EX: [[en:]]
|
||||
byte[] ttl_in_xwiki_bry = Bry_.Mid(ttl_bry, xwiki_bry_len + 1, ttl_bry_len); // +1 to position after xwiki :; EX: [[en:File:A.png]]; +1 to put after ":" at "F"
|
||||
if (!wiki.Cfg_parser().Lnki_cfg().Xwiki_repo_mgr().Has(xwiki_bry)) return ttl; // alias not in xwikis; EX: [[en_bad:File:A.png]]
|
||||
Xoa_ttl ttl_in_xwiki = Xoa_ttl.parse_(wiki, ttl_in_xwiki_bry);
|
||||
if (ttl_in_xwiki == null) return ttl; // occurs if ttl is bad in xwiki; EX: [[en:<bad>]]
|
||||
return ttl_in_xwiki.Ns().Id_file() ? ttl_in_xwiki : ttl;
|
||||
}
|
||||
public static int Chk_for_tail(Xol_lang lang, byte[] src, int cur_pos, int src_len, Xop_lnki_tkn lnki) {
|
||||
int bgn_pos = cur_pos;
|
||||
Btrie_slim_mgr lnki_trail = lang.Lnki_trail_mgr().Trie();
|
||||
while (true) { // loop b/c there can be multiple consecutive lnki_trail_chars; EX: [[A]]bcde
|
||||
if (cur_pos == src_len) break;
|
||||
byte[] lnki_trail_bry = (byte[])lnki_trail.Match_bgn_w_byte(src[cur_pos], src, cur_pos, src_len);
|
||||
if (lnki_trail_bry == null) break; // no longer a lnki_trail char; stop
|
||||
cur_pos += lnki_trail_bry.length; // lnki_trail char; add
|
||||
}
|
||||
if (bgn_pos != cur_pos && lnki.Ns_id() == Xow_ns_.Id_main) { // only mark trail if Main ns (skip trail for Image)
|
||||
lnki.Tail_bgn_(bgn_pos).Tail_end_(cur_pos);
|
||||
return cur_pos;
|
||||
}
|
||||
else
|
||||
return bgn_pos;
|
||||
}
|
||||
public static void Page_parse(Xop_ctx ctx, byte[] src, Number_parser number_parser, Xop_lnki_tkn lnki, Arg_nde_tkn arg) {
|
||||
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
|
||||
byte[] val_bry = Bry_.Trim(src, val_tkn_bgn, val_tkn_end); // some tkns have trailing space; EX.WWI: [[File:Bombers of WW1.ogg|thumb |thumbtime=3]]
|
||||
number_parser.Parse(val_bry);
|
||||
if (number_parser.Has_err())
|
||||
ctx.Msg_log().Add_itm_none(Xop_lnki_log.Upright_val_is_invalid, src, val_tkn_bgn, val_tkn_end);
|
||||
else
|
||||
lnki.Page_(number_parser.Rv_as_int());
|
||||
}
|
||||
public static byte[] Val_extract(byte[] src, Arg_nde_tkn arg) {
|
||||
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
|
||||
return Bry_.Trim(src, val_tkn_bgn, val_tkn_end); // trim trailing space
|
||||
}
|
||||
public static void Thumbtime_parse(Xop_ctx ctx, byte[] src, Number_parser number_parser, Xop_lnki_tkn lnki, Arg_nde_tkn arg) {
|
||||
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
|
||||
long fracs = TimeSpanAdp_.parse_to_fracs(src, val_tkn_bgn, val_tkn_end, false);
|
||||
if (fracs == TimeSpanAdp_.parse_null) {
|
||||
ctx.Msg_log().Add_itm_none(Xop_lnki_log.Upright_val_is_invalid, src, val_tkn_bgn, val_tkn_end);
|
||||
}
|
||||
else
|
||||
lnki.Time_(fracs / TimeSpanAdp_.Ratio_f_to_s);
|
||||
}
|
||||
public static boolean Adjust_for_brack_end_len_of_3(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int cur_pos, Xop_lnki_tkn lnki) {
|
||||
if ( cur_pos < src_len // bounds check
|
||||
&& src[cur_pos] == Byte_ascii.Brack_end // is next char after "]]", "]"; i.e.: "]]]"; PAGE:en.w:Aubervilliers DATE:2014-06-25
|
||||
) {
|
||||
int nxt_pos = cur_pos + 1;
|
||||
if ( nxt_pos == src_len // allow "]]]EOS"
|
||||
|| ( nxt_pos < src_len // bounds check
|
||||
&& src[nxt_pos] != Byte_ascii.Brack_end // is next char after "]]]", "]"; i.e.: not "]]]]"; PAGE:ru.w:Меркатале_ин_Валь_ди_Песа; DATE:2014-02-04
|
||||
)
|
||||
) {
|
||||
if ( lnki.Caption_exists() // does a caption exist?
|
||||
&& lnki.Caption_tkn().Src_end() + 2 == cur_pos // is "]]]" at end of caption?; 2="]]".Len; handle [http://a.org [[File:A.png|123px]]] PAGE:ar.w:محمد; DATE:2014-08-20
|
||||
&& lnki.Ttl() != null // only change "]]]" to "]" + "]]" if lnki is not title; otherwise [[A]]] -> "A]" which will be invalid; PAGE:en.w:Tall_poppy_syndrome DATE:2014-07-23
|
||||
) {
|
||||
Xop_tkn_itm caption_val_tkn = lnki.Caption_val_tkn();
|
||||
caption_val_tkn.Subs_add(tkn_mkr.Bry_raw(cur_pos, cur_pos + 1, Byte_ascii.Brack_end_bry)); // add "]" as bry
|
||||
caption_val_tkn.Src_end_(caption_val_tkn.Src_end() + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
351
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__basic_tst.java
Normal file
351
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__basic_tst.java
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.langs.cases.*; import gplx.xowa.parsers.paras.*;
|
||||
public class Xop_lnki_wkr__basic_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Test_parse_page_wiki("[[a]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)));
|
||||
}
|
||||
@Test public void HtmlRef() {
|
||||
fxt.Test_parse_page_wiki("[[a&b]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 3), fxt.tkn_html_ref_("&"), fxt.tkn_txt_(8, 9)))));
|
||||
}
|
||||
@Test public void Url_encode() { // PURPOSE:title should automatically do url decoding; DATE:2013-08-26
|
||||
fxt.Test_parse_page_all_str("[[A%20b]]", "<a href=\"/wiki/A_b\">A b</a>");
|
||||
}
|
||||
@Test public void Url_encode_plus() { // PURPOSE:do not decode plus; DATE:2013-08-26
|
||||
fxt.Test_parse_page_all_str("[[A+b]]", "<a href=\"/wiki/A%2Bb\">A+b</a>");
|
||||
}
|
||||
@Test public void Caption() {
|
||||
fxt.Test_parse_page_wiki("[[a|b]]" , fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)).Caption_tkn_(fxt.tkn_arg_val_txt_(4, 5)));
|
||||
fxt.Test_parse_page_wiki("[[a|b:c]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)).Caption_tkn_(fxt.tkn_arg_val_(fxt.tkn_txt_(4, 5), fxt.tkn_colon_(5), fxt.tkn_txt_(6, 7))));
|
||||
}
|
||||
@Test public void Caption_equal() { // should ignore = if only caption arg (2 args)
|
||||
fxt.Test_parse_page_wiki("[[a|=]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)).Caption_tkn_(fxt.tkn_arg_val_(fxt.tkn_eq_(4))));
|
||||
}
|
||||
@Test public void Caption_ampersand() {fxt.Test_parse_page_wiki_str("[[A|a & b]]", "<a href=\"/wiki/A\">a & b</a>");}
|
||||
@Test public void Tail() {
|
||||
fxt.Test_parse_page_wiki("[[a|b]]c" , fxt.tkn_lnki_(0, 8).Tail_bgn_(7).Tail_end_(8));
|
||||
fxt.Test_parse_page_wiki("[[a|b]] c", fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_space_(7, 8), fxt.tkn_txt_(8, 9));
|
||||
fxt.Test_parse_page_wiki("[[a|b]]'c", fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_txt_(7, 9));
|
||||
}
|
||||
@Test public void Tail_number() {fxt.Test_parse_page_wiki("[[a|b]]1" , fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_txt_(7, 8));}
|
||||
@Test public void Tail_upper() {fxt.Test_parse_page_wiki("[[a|b]]A" , fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_txt_(7, 8));} // make sure trie is case-insensitive
|
||||
@Test public void Tail_image() {fxt.Test_parse_page_wiki("[[Image:a|b]]c", fxt.tkn_lnki_(0, 13).Tail_bgn_(-1).Tail_end_(-1), fxt.tkn_txt_(13, 14));} // NOTE: this occurs on some pages;
|
||||
@Test public void Image() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a]]" , fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file).Trg_tkn_(fxt.tkn_arg_val_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9))));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|border]]" , fxt.tkn_lnki_().Border_(Bool_.Y_byte));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|thumb]]" , fxt.tkn_lnki_().ImgType_(Xop_lnki_type.Id_thumb));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|left]]" , fxt.tkn_lnki_().HAlign_(Xop_lnki_align_h.Left));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|top]]" , fxt.tkn_lnki_().VAlign_(Xop_lnki_align_v.Top));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|10px]]" , fxt.tkn_lnki_().Width_(10).Height_(-1));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|20x30px]]" , fxt.tkn_lnki_().Width_(20).Height_(30));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|alt=b]]" , fxt.tkn_lnki_().Alt_tkn_(fxt.tkn_arg_nde_().Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13))).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(14, 15)))));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|link=a]]" , fxt.tkn_lnki_().Link_tkn_(fxt.tkn_arg_nde_().Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 14))).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(15, 16)))));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|thumb|alt=b|c d]]"
|
||||
, fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file)
|
||||
.Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9))))
|
||||
.Alt_tkn_(fxt.tkn_arg_nde_().Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(16, 19))).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(20, 21))))
|
||||
.Caption_tkn_(fxt.tkn_arg_nde_(22, 25).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(22, 23), fxt.tkn_space_(23, 24), fxt.tkn_txt_(24, 25)))))
|
||||
;
|
||||
}
|
||||
@Test public void Thumbtime() {
|
||||
fxt.Test_parse_page_wiki("[[File:A.ogv|thumbtime=123]]", fxt.tkn_lnki_().Thumbtime_(123));
|
||||
fxt.Test_parse_page_wiki("[[File:A.ogv|thumbtime=1:23]]", fxt.tkn_lnki_().Thumbtime_(83));
|
||||
fxt.Test_parse_page_wiki("[[File:A.ogv|thumbtime=1:01:01]]", fxt.tkn_lnki_().Thumbtime_(3661));
|
||||
fxt.Init_log_(Xop_lnki_log.Upright_val_is_invalid).Test_parse_page_wiki("[[File:A.ogv|thumbtime=a]]", fxt.tkn_lnki_().Thumbtime_(-1));
|
||||
}
|
||||
@Test public void Width_ws() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a| 123 px]]" , fxt.tkn_lnki_().Width_(123));
|
||||
}
|
||||
@Test public void Height() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|x40px]]" , fxt.tkn_lnki_().Height_(40).Width_(-1));
|
||||
}
|
||||
@Test public void Size_double_px_ignored() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|40pxpx]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
|
||||
}
|
||||
@Test public void Size_px_px_ignored() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|40px20px]]" , fxt.tkn_lnki_().Width_(-1).Height_(-1));
|
||||
}
|
||||
@Test public void Size_double_px_ws_allowed() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|40pxpx ]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
|
||||
}
|
||||
@Test public void Size_double_px_ws_allowed_2() { // PURPOSE: handle ws between px's; EX:sv.w:Drottningholms_slott; DATE:2014-03-01
|
||||
fxt.Test_parse_page_wiki("[[Image:a|40px px]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
|
||||
}
|
||||
@Test public void Size_large_numbers() { // PURPOSE: perf code identified large sizes as caption; DATE:2014-02-15
|
||||
fxt.Test_parse_page_wiki("[[Image:a|1234567890x1234567890px]]" , fxt.tkn_lnki_().Width_(1234567890).Height_(1234567890));
|
||||
}
|
||||
@Test public void Size_dangling_xnde() { // PURPOSE: dangling xnde should not eat rest of lnki; PAGE:sr.w:Сићевачка_клисура DATE:2014-07-03
|
||||
fxt.Init_log_(Xop_xnde_log.Dangling_xnde).Test_parse_page_wiki("[[Image:a.png|<b>c|40px]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
|
||||
}
|
||||
@Test public void Size_ws_para() { // PURPOSE: <p> in arg_bldr causes parse to fail; EX: w:Supreme_Court_of_the_United_States; DATE:2014-04-05; updated test; DATE:2015-03-31
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_all("[[File:A.png| \n 40px]]"
|
||||
, fxt.tkn_para_bgn_para_(0)
|
||||
, fxt.tkn_lnki_().Width_(40).Height_(-1)
|
||||
, fxt.tkn_para_end_para_(22));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
|
||||
@Test public void Image_upright() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|upright=.123]]" , fxt.tkn_lnki_().Upright_(.123));
|
||||
fxt.Test_parse_page_wiki("[[Image:a|upright]]" , fxt.tkn_lnki_().Upright_(gplx.xowa.files.Xof_img_size.Upright_default_marker)); // no eq tokn
|
||||
fxt.Test_parse_page_wiki("[[Image:a|upright=.42190046219457]]", fxt.tkn_lnki_().Upright_(.42190046219457)); // many decimal places breaks upright
|
||||
fxt.Init_log_(Xop_lnki_log.Upright_val_is_invalid)
|
||||
.Test_parse_page_wiki("[[Image:a|upright=y]]" , fxt.tkn_lnki_().Upright_(-1)); // invalid
|
||||
}
|
||||
@Test public void Recurse() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|b-[[c]]-d]]"
|
||||
, fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file)
|
||||
.Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9))))
|
||||
.Caption_tkn_(fxt.tkn_arg_nde_(10, 19).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 12), fxt.tkn_lnki_(12, 17), fxt.tkn_txt_(17, 19))))
|
||||
);
|
||||
}
|
||||
@Test public void Outliers() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a=b.svg|thumb|10px]]", fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file).Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9), fxt.tkn_eq_(9), fxt.tkn_txt_(10, 15)))));
|
||||
fxt.Test_parse_page_wiki("[[Category:a|b]]", fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_category));
|
||||
}
|
||||
@Test public void Exc_caption_has_eq() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a.svg|thumb|a=b]]", fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file)
|
||||
.Caption_tkn_(fxt.tkn_arg_nde_(20, 23).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(20, 21), fxt.tkn_eq_(21), fxt.tkn_txt_(22, 23)))));
|
||||
}
|
||||
@Test public void Border_with_space_should_not_be_caption() {// happens with {{flag}}; EX: [[Image:Flag of Argentina.svg|22x20px|border |alt=|link=]]
|
||||
Xop_root_tkn root = fxt.Test_parse_page_wiki_root("[[Image:a.svg|22x20px|border |alt=|link=]]");
|
||||
Xop_lnki_tkn lnki = (Xop_lnki_tkn)root.Subs_get(0);
|
||||
Tfds.Eq(Xop_tkn_itm_.Tid_null, lnki.Caption_tkn().Tkn_tid());
|
||||
}
|
||||
@Test public void Ws_key_bgn() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a| alt=b]]", fxt.tkn_lnki_()
|
||||
.Alt_tkn_(fxt.tkn_arg_nde_()
|
||||
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(10, 11).Ignore_y_(), fxt.tkn_txt_(11, 14)))
|
||||
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(15, 16)))
|
||||
));
|
||||
}
|
||||
@Test public void Ws_key_end() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|alt =b]]", fxt.tkn_lnki_()
|
||||
.Caption_tkn_(fxt.tkn_arg_nde_(10, 16)
|
||||
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13), fxt.tkn_space_(13, 14), fxt.tkn_eq_(14), fxt.tkn_txt_(15, 16)))
|
||||
));
|
||||
}
|
||||
@Test public void Ws_val_bgn() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|alt= b]]", fxt.tkn_lnki_()
|
||||
.Alt_tkn_(fxt.tkn_arg_nde_()
|
||||
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13)))
|
||||
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(14, 15), fxt.tkn_txt_(15, 16)))
|
||||
));
|
||||
}
|
||||
@Test public void Ws_val_end() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a|alt=b ]]", fxt.tkn_lnki_()
|
||||
.Alt_tkn_(fxt.tkn_arg_nde_()
|
||||
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13)))
|
||||
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(14, 15), fxt.tkn_space_(15, 16).Ignore_y_()))
|
||||
));
|
||||
}
|
||||
@Test public void Ws_val_only() { // simpler variation of Ws_val_size
|
||||
fxt.Test_parse_page_wiki("[[Image:a| b ]]", fxt.tkn_lnki_()
|
||||
.Caption_tkn_(fxt.tkn_arg_nde_()
|
||||
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(10, 11), fxt.tkn_txt_(11, 12), fxt.tkn_space_(12, 13)))
|
||||
));
|
||||
}
|
||||
@Test public void Ws_val_size() {
|
||||
fxt.Test_parse_page_wiki("[[Image:a| 20x30px ]]" , fxt.tkn_lnki_().Width_(20).Height_(30));
|
||||
}
|
||||
@Test public void Nl_pipe() { // PURPOSE: "\n|" triggers tblw; PAGE:fr.w:France; [[Fichier:Carte demographique de la France.svg
|
||||
fxt.Test_parse_page_wiki("[[Image:A.png|thumb\n|alt=test]]", fxt.tkn_lnki_()
|
||||
.Alt_tkn_(fxt.tkn_arg_nde_()
|
||||
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(21, 24)))
|
||||
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(25, 29)))
|
||||
));
|
||||
}
|
||||
@Test public void Exc_empty_caption() {
|
||||
fxt.Test_parse_page_wiki("[[a|]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)));
|
||||
}
|
||||
@Test public void Exc_empty() {
|
||||
fxt.Init_log_(Xop_ttl_log.Len_0, Xop_lnki_log.Invalid_ttl);
|
||||
fxt.Test_parse_page_wiki("[[]]", fxt.tkn_txt_(0, 2), fxt.tkn_txt_(2, 4));
|
||||
fxt.Init_log_(Xop_ttl_log.Len_0, Xop_lnki_log.Invalid_ttl);
|
||||
fxt.Test_parse_page_wiki("[[ ]]", fxt.tkn_txt_(0, 2), fxt.tkn_space_(2, 3), fxt.tkn_txt_(3, 5));
|
||||
}
|
||||
@Test public void Exc_invalid_utf8() { // PURPOSE: "%DO" is an invalid UTF-8 sequence (requires 2 bytes, not just %D0); DATE:2013-11-11
|
||||
fxt.Ctx().Lang().Case_mgr_utf8_(); // NOTE: only occurs during Universal
|
||||
fxt.Test_parse_page_all_str("[[%D0]]", "[[%D0]]"); // invalid titles render literally
|
||||
}
|
||||
@Test public void Ex_eq() { // make sure that eq is not evaluated for kv delimiter
|
||||
fxt.Test_parse_page_wiki("[[=]]", fxt.tkn_lnki_(0, 5));
|
||||
fxt.Test_parse_page_wiki("[[a|=]]", fxt.tkn_lnki_(0, 7));
|
||||
}
|
||||
@Test public void Unclosed() { // PURPOSE: unclosed lnki skips rendering of next table; PAGE:en.w:William Penn (Royal Navy officer)
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "a [[b|c]"
|
||||
, ""
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "|d"
|
||||
, "|}"
|
||||
),String_.Concat_lines_nl_skip_last
|
||||
( "a [[b|c] " // NOTE: \n is converted to \s b/c caption does not allow \n
|
||||
, "<table>"
|
||||
, " <tr>"
|
||||
, " <td>d"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Caption_nl() { // PURPOSE: \n in caption should be rendered as space; PAGE:en.w:Schwarzschild radius; and the stellar [[Velocity dispersion|velocity\ndispersion]]
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "a [[b|c"
|
||||
, ""
|
||||
, ""
|
||||
, "d]]"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a <a href=\"/wiki/B\">c d</a>" // NOTE: this depends on html viewer to collapse multiple spaces into 1
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Caption_nl_2() { // PURPOSE: unclosed lnki breaks paragraph unexpectedly; PAGE:en.w:Oldsmobile;
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "a"
|
||||
, ""
|
||||
, "b [[c"
|
||||
, "" // NOTE: this new line is needed to produce strange behavior
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a"
|
||||
, "</p>"
|
||||
, ""
|
||||
, "<p>b [[c" // NOTE: \n is converted to \s b/c caption does not allow \n; NOTE: removed \s after "c" due to new lnki invalidation;DATE:2014-04-03
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Caption_ref() { // PURPOSE: <ref> not handled in lnki; PAGE:en.w:WWI
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "[[File:A.png|thumb|b <ref>c</ref>]]"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"thumb tright\">"
|
||||
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
|
||||
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
|
||||
, " <div class=\"thumbcaption\">"
|
||||
, " <div class=\"magnify\">"
|
||||
, " <a href=\"/wiki/File:A.png\" class=\"inte" +"rnal\" title=\"Enlarge\">"
|
||||
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
|
||||
, " </a>"
|
||||
, " </div>"
|
||||
, " b <sup id=\"cite_ref-0\" class=\"reference\"><a href=\"#cite_note-0\">[1]</a></sup>"
|
||||
, " </div>"
|
||||
, " </div>"
|
||||
, "</div>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Html_ent_pound() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[A#b|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/A#b\">c</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Html_ent_ltr_a() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[Ab|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/Ab\">c</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Pipe_trick() {
|
||||
fxt.Test_parse_page_wiki_str("[[Page1|]]" , "<a href=\"/wiki/Page1\">Page1</a>");
|
||||
fxt.Test_parse_page_wiki_str("[[Help:Page1|]]" , "<a href=\"/wiki/Help:Page1\">Page1</a>");
|
||||
}
|
||||
@Test public void Thumb_first_align_trumps_all() { // PURPOSE: if there are multiple alignment instructions, take the first EX:[[File:A.png|thumb|center|left]] DATE:20121226
|
||||
fxt.Test_parse_page_wiki_str("[[File:A.png|thumb|right|center]]" // NOTE: right trumps center
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( Xop_para_wkr_basic_tst.File_html("File", "A.png", "7/0", "")
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Eq() {
|
||||
fxt.Test_parse_page_all_str("[[B|=]]", "<a href=\"/wiki/B\">=</a>");
|
||||
}
|
||||
@Test public void Href_encode_anchor() { // PURPOSE: test separate encoding for ttl (%) and anchor (.)
|
||||
fxt.Test_parse_page_all_str("[[^#^]]", "<a href=\"/wiki/%5E#.5E\">^#^</a>");
|
||||
}
|
||||
@Test public void Href_question() { // PURPOSE.fix: ttl with ? at end should not be considered qarg; DATE:2013-02-08
|
||||
fxt.Test_parse_page_all_str("[[A?]]", "<a href=\"/wiki/A%3F\">A?</a>");
|
||||
}
|
||||
@Test public void Href_question_2() { // PURPOSE: ?action=edit should be encoded; DATE:2013-02-10
|
||||
fxt.Test_parse_page_all_str("[[A?action=edit]]", "<a href=\"/wiki/A%3Faction%3Dedit\">A?action=edit</a>");
|
||||
}
|
||||
@Test public void Href_question_3() { // PURPOSE.fix: DATE:2014-01-16
|
||||
fxt.Test_parse_page_all_str("[[A?b]]", "<a href=\"/wiki/A%3Fb\">A?b</a>");
|
||||
}
|
||||
@Test public void Encoded_url() { // PURPOSE.fix: url-encoded characters broke parser when embedded in link; DATE:2013-03-01
|
||||
fxt.Init_xwiki_add_user_("commons.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str("[[File:A.png|link=//commons.wikimedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0?uselang=ru|b]]"
|
||||
, "<a href=\"/site/commons.wikimedia.org/wiki/Заглавная_страница?uselang=ru\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>");
|
||||
}
|
||||
@Test public void Link_invalid() { // PURPOSE.fix: do not render invalid text; EX: link={{{1}}}; [[Fil:Randers_-_Hadsund_railway.png|120x160px|link={{{3}}}|Randers-Hadsund Jernbane]]; DATE:2013-03-04
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link={{{1}}}|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Href_anchor_leading_space() { // PURPOSE: ?action=edit should be encoded; DATE:2013-02-10
|
||||
fxt.Test_parse_page_all_str("[[A #b]]", "<a href=\"/wiki/A#b\">A #b</a>");
|
||||
}
|
||||
@Test public void Anchor_not_shown_for_wikipedia_ns() { // PURPOSE: Help:A#b was omitting anchor; showing text of "Help:A"; DATE:2013-06-21
|
||||
fxt.Test_parse_page_all_str("[[Help:A#b]]", "<a href=\"/wiki/Help:A#b\">Help:A#b</a>");
|
||||
}
|
||||
@Test public void Anchor_shown_for_main_ns() { // PURPOSE: counterpart to Anchor_not_shown_for_wikipedia_ns; DATE:2013-06-21
|
||||
fxt.Test_parse_page_all_str("[[A#b]]", "<a href=\"/wiki/A#b\">A#b</a>");
|
||||
}
|
||||
@Test public void Trail_en() {
|
||||
fxt.Test_parse_page_all_str("[[Ab]]cd e", "<a href=\"/wiki/Ab\">Abcd</a> e");
|
||||
}
|
||||
@Test public void Trail_fr() {
|
||||
byte[] ltr_c_in_french = Bry_.new_u8("ç");
|
||||
Xol_lnki_trail_mgr lnki_trail_mgr = fxt.Wiki().Lang().Lnki_trail_mgr();
|
||||
lnki_trail_mgr.Add(ltr_c_in_french);
|
||||
fxt.Test_parse_page_all_str("[[Ab]]çd e", "<a href=\"/wiki/Ab\">Abçd</a> e");
|
||||
lnki_trail_mgr.Del(ltr_c_in_french);
|
||||
}
|
||||
@Test public void Link_html_ent() {// PURPOSE:html entities should be converted to chars; EX: -> _; DATE:2013-12-16
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|link=b c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/B_c\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Page() {
|
||||
fxt.Test_parse_page_wiki("[[File:A.pdf|page=12]]" , fxt.tkn_lnki_().Page_(12));
|
||||
}
|
||||
@Test public void Visited() { // PURPOSE: show redirected titles as visited; EX:fr.w:Alpes_Pennines; DATE:2014-02-28
|
||||
Xowe_wiki wiki = fxt.Wiki();
|
||||
Xoa_ttl ttl = Xoa_ttl.parse_(wiki, Bry_.new_a7("Src")); // simulate requrest for "Src" page
|
||||
Xoae_page previous_page = Xoae_page.test_(wiki, ttl);
|
||||
previous_page.Redirected_ttls().Add(Bry_.new_a7("Src")); // simulate redirect from "Src"
|
||||
fxt.App().Usere().History_mgr().Add(previous_page); // simulate "Src" already being clicked once; this is the key call
|
||||
fxt.Wtr_cfg().Lnki_visited_y_();
|
||||
fxt.Test_parse_page_all_str("[[Src]]" , "<a href=\"/wiki/Src\" class=\"xowa-visited\">Src</a>"); // show [[Src]] as visited since it exists in history
|
||||
fxt.Test_parse_page_all_str("[[Other]]" , "<a href=\"/wiki/Other\">Other</a>"); // show other pages as not visited
|
||||
}
|
||||
}
|
||||
132
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__ctg_tst.java
Normal file
132
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__ctg_tst.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.langs.cases.*;
|
||||
public class Xop_lnki_wkr__ctg_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_y_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@After public void term() {fxt.Init_para_n_();}
|
||||
@Test public void Pre() { // PURPOSE: Category should trim preceding nl; EX:w:Mount Kailash
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "a"
|
||||
, " [[Category:b]]"
|
||||
, "c"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a"
|
||||
, "c"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Ws() { // FUTURE: needs more para rework; conflicts with Li() test; WHEN: when issue is found
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "a"
|
||||
, "x [[Category:b]]"
|
||||
, "c"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a"
|
||||
, "x "
|
||||
, "c"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Li() { // PURPOSE: Category strips all preceding ws; PAGE:en.w:NYC (in external links)
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "*a"
|
||||
, "*b"
|
||||
, " [[Category:c]]"
|
||||
, "*d"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<ul>"
|
||||
, " <li>a"
|
||||
, " </li>"
|
||||
, " <li>b"
|
||||
, " </li>"
|
||||
, " <li>d"
|
||||
, " </li>"
|
||||
, "</ul>"
|
||||
));
|
||||
}
|
||||
@Test public void Li_w_lnke() { // PURPOSE: [[Category]] was being absorbed into lnke; PAGE:de.w:ISO/IEC/IEEE_29119_Software_Testing DATE:2014-07-11
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "* http://a.org"
|
||||
, "[[Category:B]]" // category should not show below
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<ul>"
|
||||
, " <li> <a href=\"http://a.org\" class=\"external text\" rel=\"nofollow\">http://a.org</a>"
|
||||
, " </li>"
|
||||
, "</ul>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Merge_li() { // PURPOSE: trim ws preceding [[Category:; de.d:plant; DATE:2014-03-27
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "*a"
|
||||
, ""
|
||||
, " [[Category:B]] c"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<ul>"
|
||||
, " <li>a c"
|
||||
, " </li>"
|
||||
, "</ul>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Merge_pre() { // PURPOSE: leading spaces / nls should be removed from normal Category, else false pre's or excessive line breaks
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
|
||||
( " [[Category:A]]" // removes \s
|
||||
, " [[Category:B]]" // removes \n\s
|
||||
), String_.Concat_lines_nl
|
||||
( "<p>"
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
@Test public void Literal() { // PURPOSE: do not trim ws if literal Category; EX:fr.wikiquote.org/wiki/Accueil; REF: https://sourceforge.net/p/xowa/tickets/167/; DATE:2013-07-10
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
|
||||
( "[[:Category:A]]"
|
||||
, "[[:Category:B]]"
|
||||
), String_.Concat_lines_nl
|
||||
( "<p><a href=\"/wiki/Category:A\">Category:A</a>" // NOTE: technically WP converts to "</a> <a>" not "</a>\n<a>" (via HtmlTidy?)
|
||||
, "<a href=\"/wiki/Category:B\">Category:B</a>"
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
@Test public void Hdr_w_nl() { // PURPOSE: hdr code broken by Category; DATE:2014-04-17
|
||||
fxt.Test_parse_page_all_str("==a==\n[[Category:C]]"
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<h2>a</h2>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Hdr_only() { // PURPOSE: check that == is hdr; EX:ar.d:جَبَّارَة; DATE:2014-04-17
|
||||
fxt.Test_parse_page_wiki_str("==a==[[Category:C]]"
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<h2>a</h2>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Hdr_ignore() { // PURPOSE: check that hdr is ignored if next char is not nl; DATE:2014-04-17
|
||||
fxt.Test_parse_page_wiki_str("==a==[[Category:C]]b"
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "==a==b"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.langs.cases.*;
|
||||
public class Xop_lnki_wkr__invalid_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Ignore_invalid_url_encodings() { // PURPOSE: if url encoding is invalid, still render lnki as <a>; EX: fr.w:Bordetella;
|
||||
fxt.Test_parse_page_all_str("[[%GC]]", "<a href=\"/wiki/%25GC\">%GC</a>");
|
||||
}
|
||||
@Test public void Caption_still_parsed() { // PURPOSE: failed lnki should still parse xml in caption; EX:ar.w:الصومال; DATE:2014-03-04
|
||||
fxt.Test_parse_page_all_str("[[|''a'']]" , "[[|<i>a</i>]]");
|
||||
}
|
||||
@Test public void Ttl_still_parsed() { // PURPOSE: invalid lnki should still parse ttl; BASED_ON:ar.w:الصومال; DATE:2014-03-26
|
||||
fxt.Test_parse_page_all_str("[[''[a]'']]" , "[[<i>[a]</i>]]");
|
||||
}
|
||||
@Test public void Pipe_only() {
|
||||
fxt.Init_log_(Xop_ttl_log.Len_0, Xop_lnki_log.Invalid_ttl);
|
||||
fxt.Test_parse_page_wiki("[[|]]", fxt.tkn_txt_(0, 2), fxt.tkn_pipe_(2), fxt.tkn_txt_(3, 5));
|
||||
}
|
||||
@Test public void Xnde_should_force_ttl_parse() { // PURPOSE: reparse should be forced at xnde not at pipe; EX: [[a<b>c</b>|d]] reparse should start at <b>; DATE:2014-03-30
|
||||
fxt.Test_parse_page_all_str_and_chk("[[a<b>c</b>|d]]" , "[[a<b>c</b>|d]]", Xop_lnki_log.Invalid_ttl);
|
||||
}
|
||||
@Test public void Tblw_tb() { // PURPOSE: reparse should be forced at tblw.tb; DATE:2014-04-03
|
||||
fxt.Test_parse_page_all_str_and_chk("[[a\n{||b]]", String_.Concat_lines_nl_skip_last
|
||||
( "[[a"
|
||||
, "<table>|b]]"
|
||||
, "</table>"
|
||||
, ""
|
||||
), Xop_lnki_log.Invalid_ttl);
|
||||
}
|
||||
@Test public void Tblw_tr() { // PURPOSE: reparse should be forced at tblw.tr; DATE:2014-04-03
|
||||
fxt.Test_parse_page_all_str_and_chk("[[a\n|-b]]", String_.Concat_lines_nl_skip_last
|
||||
( "[[a"
|
||||
, "|-b]]"
|
||||
), Xop_lnki_log.Invalid_ttl);
|
||||
}
|
||||
@Test public void Tblw_tr_like() { // PURPOSE: do not invalidate if pseudo-tr; DATE:2014-04-03
|
||||
fxt.Test_parse_page_all_str_and_chk("[[a|-b]]", "<a href=\"/wiki/A\">-b</a>");
|
||||
}
|
||||
@Test public void Nl() { // PURPOSE: invalidate if nl; DATE:2014-04-03
|
||||
fxt.Test_parse_page_all_str_and_chk("''[[\n]]", "<i>[[</i>\n]]", Xop_lnki_log.Invalid_ttl);
|
||||
}
|
||||
@Test public void Nl_with_apos_shouldnt_fail() { // PURPOSE: apos, lnki and nl will cause parser to fail; DATE:2013-10-31
|
||||
fxt.Test_parse_page_all_str("''[[\n]]", "<i>[[</i>\n]]");
|
||||
}
|
||||
// @Test public void Brack_end_invalid() { // PURPOSE: invalidate if ]; DATE:2014-04-03; // TODO: backout apos changes
|
||||
// fxt.Test_parse_page_all_str_and_chk("[[A] ]", "[[A] ]", Xop_lnki_log.Invalid_ttl);
|
||||
// }
|
||||
@Test public void Module() { // PURPOSE: handle lnki_wkr parsing Module text (shouldn't happen); apos, tblw, lnki, and nl will cause parser to fail; also handles scan-bwd; EX:Module:Taxobox; DATE:2013-11-10
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
|
||||
( " [[''"
|
||||
, " [["
|
||||
, " |" // NOTE: this is actually a tblw_ws_tkn ("\n |") not a pipe_tkn
|
||||
, "]]"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<pre>[[</i>" // NOTE: should be <i> but scan_bwd can't undo previous apos
|
||||
, "[["
|
||||
, " |"
|
||||
, "</pre>"
|
||||
, ""
|
||||
, "<p>]]"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Tblw_in_lnki() { // PURPOSE: handle invalid tblw tkn inside lnki; DATE:2014-06-06
|
||||
fxt.Test_parse_page_all_str("[[A[]\n|b]]", "[[A[]\n|b]]"); // NOTE: \n| is tblw code for td
|
||||
}
|
||||
// @Test public void Tmpl() { // PURPOSE: invalid lnki breaks template
|
||||
// fxt.Init_defn_clear();
|
||||
// fxt.Init_defn_add("a", "b");
|
||||
// fxt.Test_parse_page_all_str("{{a|[[}}", "b");
|
||||
// }
|
||||
}
|
||||
|
||||
144
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__link_tst.java
Normal file
144
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__link_tst.java
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.langs.cases.*;
|
||||
public class Xop_lnki_wkr__link_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Link() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_blank() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_external() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=http://www.b.org|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"http://www.b.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_file_system() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=file:///C/B.png|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"file:///C/B.png\" class=\"image\" xowa_title=\"B.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_file_ns() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_external_relative() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"http://fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_external_absolute() {
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"http://fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_external_double_http() {// PURPOSE.fix: link=http://a.org?b=http://c.org breaks lnki; DATE:2013-02-03
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=//a.org?b=http://c.org]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"http://a.org?b=http://c.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_xwiki_relative() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
|
||||
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_xwiki_relative_domain_only() { // lnki_wtr fails if link is only domain; EX: wikimediafoundation.org; [[Image:Wikispecies-logo.png|35px|link=//species.wikimedia.org]]; // NOTE: changed href to return "/wiki/" instead of ""; DATE:2013-02-18
|
||||
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=//fr.wikipedia.org]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_xwiki_absolute() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
|
||||
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_xwiki_absolute_upload() { // PURPOSE: link to upload.wikimedia.org omits /wiki/; EX: wikimediafoundation.org: [[File:Page1-250px-WMF_AR11_SHIP_spreads_15dec11_72dpi.png|right|125px|border|2010–2011 Annual Report|link=https://upload.wikimedia.org/wikipedia/commons/4/48/WMF_AR11_SHIP_spreads_15dec11_72dpi.pdf]]
|
||||
fxt.Init_xwiki_add_user_("commons.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=http://upload.wikimedia.org/wikipedia/commons/7/70/A.png|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/commons.wikimedia.org/wiki/File:A.png\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_xwiki_relative_deep() {
|
||||
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/A/b|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/fr.wikipedia.org/wiki/A/b\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
}
|
||||
@Test public void Link_xwiki_alias() { // [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
|
||||
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:B|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/commons.wikimedia.org/wiki/B\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
fxt.Init_xwiki_clear();
|
||||
}
|
||||
@Test public void Link_xwiki_alias_sub_page() { // same as above, but for sub-page; [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
|
||||
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
fxt.Init_xwiki_clear();
|
||||
}
|
||||
@Test public void Link_xwiki_alias_only() { // only alias; [[File:Commons-logo.svg|25x25px|link=commons:Special:Search/Earth]]; fictitious example; DATE:2013-02-18
|
||||
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
fxt.Init_xwiki_clear();
|
||||
}
|
||||
@Test public void Link_xwiki_alias_only_colon() { // only alias, but prepended with ":"; [[File:Wikipedia-logo.svg|40px|link=:w:|Wikipedia]]; DATE:2013-05-06
|
||||
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|12x10px|link=:commons:A/B|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/commons.wikimedia.org/wiki/A/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
fxt.Init_xwiki_clear();
|
||||
}
|
||||
@Test public void Encode() {// PURPOSE: encode invalid characters in link; PAGE:en.w:List_of_cultural_heritage_sites_in_Punjab,_Pakistan DATE:2014-07-16
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[File:A.png|link=//b?c\">|d]]"
|
||||
, "<a href=\"http://b?c%22%3E\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"d\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
|
||||
);
|
||||
}
|
||||
}
|
||||
109
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__pre_tst.java
Normal file
109
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__pre_tst.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.langs.cases.*;
|
||||
public class Xop_lnki_wkr__pre_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_y_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@After public void term() {fxt.Init_para_n_();}
|
||||
@Test public void Previous_pre() { // PURPOSE: if pre is already in effect, end it; EX: en.b:Knowing_Knoppix/Other_applications
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "a"
|
||||
, " b"
|
||||
, "[[File:A.png|thumb]]"
|
||||
, "c"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a"
|
||||
, "</p>"
|
||||
, ""
|
||||
, "<pre>b" // NOTE: pre is ended; " b\n[[" -> <pre>b</pre><div>"
|
||||
, "</pre>"
|
||||
, ""
|
||||
, Html_A_png
|
||||
, ""
|
||||
, "<p>c"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Current_pre_and_thumb() { // PURPOSE: current pre should be ended by thumb; EX: w:Roller coaster; it.w:Provincia_di_Pesaro_e_Urbino; DATE:2014-02-17
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "a"
|
||||
, " [[File:A.png|thumb]]"
|
||||
, "b"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a"
|
||||
, "</p>"
|
||||
, "" // NOTE: do not capture " "; confirmed against MW; DATE:2014-02-19
|
||||
, Html_A_png
|
||||
, ""
|
||||
, "<p>b"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Current_pre_and_halign() { // PURPOSE: current pre should be ended by halign since they also produce divs; EX: w:Trombiculidae; DATE:2014-02-17
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "a"
|
||||
, " [[File:A.png|right]]"
|
||||
, "b"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a"
|
||||
, "</p>"
|
||||
, "<div class=\"floatright\">" // NOTE: do not capture " "; confirmed against MW; DATE:2014-02-19
|
||||
, "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a></div>"
|
||||
, ""
|
||||
, "<p>b"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Current_pre() { // PURPOSE: current pre should exist if not div; DATE:2014-02-17
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "a"
|
||||
, " [[File:A.png]]"
|
||||
, "b"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<p>a"
|
||||
, "</p>"
|
||||
, ""
|
||||
, "<pre> <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>" // NOTE: capture " "; confirmed against MW; DATE:2014-04-14
|
||||
, "</pre>"
|
||||
, ""
|
||||
, "<p>b"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
private static final String Html_A_png = String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"thumb tright\">"
|
||||
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
|
||||
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
|
||||
, " <div class=\"thumbcaption\">"
|
||||
, " <div class=\"magnify\">"
|
||||
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
|
||||
, " <img src=\"file:///mem/xowa/user/test_user/app/img/file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
|
||||
, " </a>"
|
||||
, " </div>"
|
||||
, " "
|
||||
, " </div>"
|
||||
, " </div>"
|
||||
, "</div>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Xop_lnki_wkr__subpage_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Disabled() { // PURPOSE: slash being interpreted as subpage; PAGE:en.w:[[/dev/null]]
|
||||
fxt.Wiki().Ns_mgr().Ids_get_or_null(Xow_ns_.Id_main).Subpages_enabled_(false);
|
||||
fxt.Test_parse_page_all_str("[[/dev/null]]", "<a href=\"/wiki//dev/null\">/dev/null</a>");
|
||||
fxt.Wiki().Ns_mgr().Ids_get_or_null(Xow_ns_.Id_main).Subpages_enabled_(true);
|
||||
}
|
||||
@Test public void False_match() {// PAGE:en.w:en.wiktionary.org/wiki/Wiktionary:Requests for cleanup/archive/2006
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[.../compare ...]]"
|
||||
, "<a href=\"/wiki/.../compare_...\">.../compare ...</a>"
|
||||
);
|
||||
}
|
||||
@Test public void Owner() { // PURPOSE: ../c does "A/c", not "c"; DATE:2014-01-02
|
||||
fxt.Page_ttl_("A/b");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[../c]]"
|
||||
, "<a href=\"/wiki/A/c\">A/c</a>"
|
||||
);
|
||||
}
|
||||
@Test public void Owner_w_slash() { // PURPOSE: ../c/ does "c", not "A/c"; DATE:2014-01-02
|
||||
fxt.Page_ttl_("A/b");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[../c/]]"
|
||||
, "<a href=\"/wiki/A/c\">c</a>"
|
||||
);
|
||||
}
|
||||
@Test public void Slash() { // PURPOSE: /B should show /B, not A/B; DATE:2014-01-02
|
||||
fxt.Page_ttl_("A");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[/B]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/A/B\">/B</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Slash_w_slash() { // PURPOSE: /B/ should show B, not /B; DATE:2014-01-02
|
||||
fxt.Page_ttl_("A");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[/B/]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/A/B\">B</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Leaf_w_ncr() { // PURPOSE: /Bc should not encode c PAGE:en.s:The_English_Constitution_(1894) DATE:2014-09-07
|
||||
fxt.Page_ttl_("A");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[/Bc|B]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/A/Bc\">B</a>"
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -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; import gplx.*;
|
||||
import org.junit.*;
|
||||
import gplx.xowa.langs.cases.*;
|
||||
public class Xop_lnki_wkr__uncommon_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Double_bracket() { // PURPOSE: handle [[[[A]]]] constructions; PAGE:ru.w:Меркатале_ин_Валь_ди_Песа; DATE:2014-02-04
|
||||
fxt.Test_parse_page_all_str("[[[[Test_1]]]]" , "[[<a href=\"/wiki/Test_1\">Test_1</a>]]");
|
||||
}
|
||||
@Test public void Single_bracket() { // PURPOSE: handle [[A|[b]]] PAGE:en.w:Aubervilliers DATE:2014-06-25
|
||||
fxt.Test_html_full_str("[[A|[B]]]", "<a href=\"/wiki/A\">[B]</a>");
|
||||
}
|
||||
@Test public void Triple_bracket() { // PURPOSE: "]]]" shouldn't invalidate tkn; PAGE:en.w:Tall_poppy_syndrome; DATE:2014-07-23
|
||||
fxt.Test_parse_page_all_str("[[A]]]" , "<a href=\"/wiki/A\">A</a>]"); // title only
|
||||
fxt.Test_parse_page_all_str("[[A|B]]]" , "<a href=\"/wiki/A\">B]</a>"); // title + caption; note that ] should be outside </a> b/c MW has more logic that says "if caption starts with '['", but leaving as is; DATE:2014-07-23
|
||||
}
|
||||
@Test public void Triple_bracket_with_lnke_lnki() { // PURPOSE: handle [http://a.org [[File:A.png|123px]]]; PAGE:ar.w:محمد DATE:2014-08-20
|
||||
fxt.Test_parse_page_all_str("[http://a.org [[File:A.png|123px]]]"
|
||||
, "<a href=\"http://a.org\" class=\"external text\" rel=\"nofollow\"><a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" /></a></a>"
|
||||
);
|
||||
}
|
||||
@Test public void Multiple_captions() { // PURPOSE: multiple captions should be concatenated (used to only take first); EX:zh.d:维基词典:Unicode字符索引/0000–0FFF; DATE:2014-05-05
|
||||
fxt.Test_parse_page_all_str("[[A|B|C|D]]" , "<a href=\"/wiki/A\">B|C|D</a>");
|
||||
}
|
||||
@Test public void Multiple_captions_file() { // PURPOSE: multiple captions should take last; EX:none; DATE:2014-05-05
|
||||
fxt.Test_html_wiki_frag("[[File:A|B|C|D|thumb]]" , "</div>\n D\n </div>");
|
||||
}
|
||||
@Test public void Multiple_captions_pipe() { // PURPOSE.fix: multiple captions caused multiple pipes; PAGE:w:Wikipedia:Administrators'_noticeboard/IncidentArchive24; DATE:2014-06-08
|
||||
fxt.Test_parse_page_all_str("[[a|b|c d e]]", "<a href=\"/wiki/A\">b|c d e</a>"); // was b|c| |d| |e
|
||||
}
|
||||
@Test public void Toc_fails() { // PURPOSE: null ref when writing hdr with lnki inside xnde; EX:pl.d:head_sth_off;DATE:2014-05-07
|
||||
fxt.Test_parse_page_all_str("== <i>[[A]]</i> ==", "<h2> <i><a href=\"/wiki/A\">A</a></i> </h2>\n");
|
||||
}
|
||||
@Test public void Large_size() { // PURPOSE: size larger than int should be discard, not be Int_.MaxValue: PAGE:id.w:Baho; DATE:2014-06-10
|
||||
fxt.Test_html_wiki_frag("[[File:A.png|9999999999x30px]]", " width=\"0\" height=\"30\""); // width should not be Int_.MaxValue
|
||||
}
|
||||
@Test public void Upright_is_large() { // PURPOSE: handle large upright which overflows int; PAGE:de.w:Feuerland DATE:2015-02-03
|
||||
fxt.Test_html_wiki_frag("[[File:A.png|upright=1.333333333333333333333333333333333333333333333333333333333333333333333]]", " width=\"0\" height=\"0\""); // failure would print out original lnki
|
||||
}
|
||||
@Test public void Mistaken_x_px() { // PURPOSE: 1234xTextpx interpreted as size; PAGE:es.b:Alimentación_infantil; DATE:2015-07-10
|
||||
fxt.Test_html_wiki_frag("[[File:A.png|1234xSomeTextpx]]", " width=\"0\" height=\"0\""); // width should be 0
|
||||
}
|
||||
}
|
||||
|
||||
115
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__xwiki_tst.java
Normal file
115
400_xowa/src_440_lnki/gplx/xowa/Xop_lnki_wkr__xwiki_tst.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Xop_lnki_wkr__xwiki_tst {
|
||||
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Xwiki_file() { // PURPOSE: if xwiki and File, ignore xwiki (hackish); DATE:2013-12-22
|
||||
Reg_xwiki_alias("test", "test.wikimedia.org"); // must register xwiki, else ttl will not parse it
|
||||
fxt.Wiki().Cfg_parser().Lnki_cfg().Xwiki_repo_mgr().Add_or_mod(Bry_.new_a7("test")); // must add to xwiki_repo_mgr
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[test:File:A.png|12x10px]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
|
||||
));
|
||||
fxt.Wiki().Cfg_parser_lnki_xwiki_repos_enabled_(false); // disable for other tests
|
||||
}
|
||||
@Test public void Xwiki_anchor() {
|
||||
Reg_xwiki_alias("test", "test.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[test:A#b]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/test.wikimedia.org/wiki/A#b\">test:A#b</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Xwiki_empty() {
|
||||
Reg_xwiki_alias("test", "test.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[test:]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/test.wikimedia.org/wiki/\">test:</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Xwiki_empty_literal() {
|
||||
Reg_xwiki_alias("test", "test.wikimedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[:test:]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/test.wikimedia.org/wiki/\">test:</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Xwiki_not_registered() {
|
||||
fxt.App().Usere().Wiki().Xwiki_mgr().Clear();
|
||||
fxt.Wiki().Xwiki_mgr().Add_full(Bry_.new_a7("test"), Bry_.new_a7("test.wikimedia.org")); // register alias only, but not in user_wiki
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[test:A|A]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"https://test.wikimedia.org/wiki/A\">A</a>"
|
||||
));
|
||||
}
|
||||
@Test public void Literal_lang() {
|
||||
Reg_xwiki_alias("fr", "fr.wikipedia.org");
|
||||
fxt.Test_parse_page_wiki_str
|
||||
( "[[:fr:A]]", String_.Concat_lines_nl_skip_last
|
||||
( "<a href=\"/site/fr.wikipedia.org/wiki/A\">A</a>"
|
||||
));
|
||||
Tfds.Eq(0, fxt.Page().Slink_list().Count());
|
||||
}
|
||||
@Test public void Simple_and_english() { // PURPOSE: s.w xwiki links to en were not working b/c s.w and en had same super lang of English; PAGE:s.q:Anonymous DATE:2014-09-10
|
||||
Xoae_app app = Xoa_app_fxt.app_();
|
||||
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "simple.wikipedia.org");
|
||||
fxt = new Xop_fxt(app, wiki); // change fxt to simple.wikipedia.org
|
||||
Reg_xwiki_alias("en", "en.wikipedia.org"); // register "en" alias
|
||||
fxt.Test_parse_page_wiki_str // test nothing printed
|
||||
( "[[en:A]]"
|
||||
, ""
|
||||
);
|
||||
Tfds.Eq(1, fxt.Page().Slink_list().Count()); // test 1 xwiki lang
|
||||
}
|
||||
@Test public void Species_and_commons() { // PURPOSE: species xwiki links to commons should not put link in wikidata langs; PAGE:species:Scarabaeidae DATE:2014-09-10
|
||||
Xoae_app app = Xoa_app_fxt.app_();
|
||||
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "species.wikimedia.org");
|
||||
fxt = new Xop_fxt(app, wiki); // change fxt to species.wikimedia.org
|
||||
Reg_xwiki_alias("commons", "commons.wikimedia.org"); // register "en" alias
|
||||
fxt.Test_parse_page_wiki_str // test something printed
|
||||
( "[[commons:A]]"
|
||||
, "<a href=\"/site/commons.wikimedia.org/wiki/A\">commons:A</a>"
|
||||
);
|
||||
Tfds.Eq(0, fxt.Page().Slink_list().Count()); // no xwiki langs
|
||||
}
|
||||
@Test public void Wiktionary_and_wikipedia() { // PURPOSE: do not create xwiki links if same lang and differet type; PAGE:s.d:water DATE:2014-09-14
|
||||
Xoae_app app = Xoa_app_fxt.app_();
|
||||
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "simple.wiktionary.org");
|
||||
fxt = new Xop_fxt(app, wiki); // change fxt to simple.wiktionary.org
|
||||
Reg_xwiki_alias("w", "simple.wikipedia.org"); // register "w" alias
|
||||
fxt.Test_parse_page_wiki_str // test something printed
|
||||
( "[[w:A]]"
|
||||
, "<a href=\"/site/simple.wikipedia.org/wiki/A\">w:A</a>"
|
||||
);
|
||||
Tfds.Eq(0, fxt.Page().Slink_list().Count()); // test 0 xwiki lang
|
||||
}
|
||||
@Test public void Species_and_wikipedia() { // PURPOSE: species creates xwiki links to wikipedia; PAGE:species:Puccinia DATE:2014-09-14
|
||||
Xoae_app app = Xoa_app_fxt.app_();
|
||||
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "species.wikimedia.org");
|
||||
fxt = new Xop_fxt(app, wiki); // change fxt to species.wikimedia.org
|
||||
Reg_xwiki_alias("fr", "fr.wikipedia.org"); // register "fr" alias
|
||||
fxt.Test_parse_page_wiki_str // nothing printed
|
||||
( "[[fr:A]]"
|
||||
, ""
|
||||
);
|
||||
Tfds.Eq(1, fxt.Page().Slink_list().Count()); // 1 xwiki lang
|
||||
}
|
||||
private void Reg_xwiki_alias(String alias, String domain) {
|
||||
Xop_fxt.Reg_xwiki_alias(fxt.Wiki(), alias, domain);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user