mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v1.6.5.1
This commit is contained in:
127
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_lxr.java
Normal file
127
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_lxr.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
class Xop_tblw_lxr implements Xop_lxr {
|
||||
public byte Lxr_tid() {return Xop_lxr_.Tid_tblw;}
|
||||
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) {
|
||||
int rv = Handle_bang(wlxr_type, ctx, ctx.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos);
|
||||
if (rv != Continue) return rv;
|
||||
rv = Handle_lnki(wlxr_type, ctx, ctx.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos);
|
||||
if (rv != Continue) return rv;
|
||||
return ctx.Tblw().Make_tkn_bgn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, false, wlxr_type, Xop_tblw_wkr.Called_from_general, -1, -1);
|
||||
}
|
||||
public static final int Continue = -2; // -2 b/c -1 used by Called_from_pre
|
||||
public static int Handle_bang(int wlxr_type, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
|
||||
// standalone "!" should be ignored if no tblw present; EX: "a b! c" should not trigger ! for header
|
||||
switch (wlxr_type) {
|
||||
case Xop_tblw_wkr.Tblw_type_th: // \n!
|
||||
case Xop_tblw_wkr.Tblw_type_th2: // !!
|
||||
case Xop_tblw_wkr.Tblw_type_td: // \n|
|
||||
Xop_tkn_itm owner_tblw_tb = ctx.Stack_get_typ(Xop_tkn_itm_.Tid_tblw_tb); // check entire stack for tblw; DATE:2014-03-11
|
||||
if ( owner_tblw_tb == null // no tblw in stack; highly probably that current sequence is not tblw tkn
|
||||
|| ctx.Cur_tkn_tid() == Xop_tkn_itm_.Tid_lnki // cur tid is lnki; PAGE:en.w:Pink_(singer); DATE:2014-06-25
|
||||
) {
|
||||
int lnki_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_lnki);
|
||||
if (lnki_pos != Xop_ctx.Stack_not_found && wlxr_type == Xop_tblw_wkr.Tblw_type_td) {// lnki present;// NOTE: added Xop_tblw_wkr.Tblw_type_td b/c th should not apply when tkn_mkr.Pipe() is called below; DATE:2013-04-24
|
||||
Xop_tkn_itm lnki_tkn = ctx.Stack_pop_til(root, src, lnki_pos, false, bgn_pos, cur_pos); // pop any intervening nodes until lnki
|
||||
ctx.Stack_add(lnki_tkn); // push lnki back onto stack; TODO: combine these 2 lines into 1
|
||||
// NOTE: this is a "\n|" inside a [[ ]]; must create two tokens for lnki to build correctly;
|
||||
ctx.Subs_add(root, tkn_mkr.NewLine(bgn_pos, bgn_pos + 1, Xop_nl_tkn.Tid_char, 1));
|
||||
return Xop_pipe_lxr._.Make_tkn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos); // NOTE: need to call pipe_lxr in order to invalidate if lnki; DATE:2014-06-06
|
||||
}
|
||||
else { // \n| or \n! but no tbl
|
||||
if ( bgn_pos != Xop_parser_.Doc_bgn_bos // avoid ! at BOS
|
||||
&& src[bgn_pos] == Byte_ascii.NewLine) // handle "!" etc.
|
||||
return Xop_tblw_wkr.Handle_false_tblw_match(ctx, root, src, bgn_pos, cur_pos, tkn_mkr.Txt(bgn_pos + 1, cur_pos), true); // +1 to ignore \n of "\n!", "\n!!", "\n|"; DATE:2014-02-19
|
||||
else // handle "!!" only
|
||||
return ctx.Lxr_make_txt_(cur_pos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return Continue;
|
||||
}
|
||||
public static int Handle_lnki(int wlxr_type, 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 last_tkn = ctx.Stack_get_last();
|
||||
if ( last_tkn != null
|
||||
&& last_tkn.Tkn_tid() == Xop_tkn_itm_.Tid_lnki) {
|
||||
Xop_lnki_tkn lnki = (Xop_lnki_tkn)last_tkn;
|
||||
if ( lnki.Pipe_count_is_zero()) { // 1st pipe; EX: [[A\n|+B]]
|
||||
boolean invalidate = false;
|
||||
switch (wlxr_type) { // tblw found; check if in lnki and validate ttl; DATE:2014-03-29
|
||||
case Xop_tblw_wkr.Tblw_type_tb: // \n{|
|
||||
case Xop_tblw_wkr.Tblw_type_tc: // \n|+
|
||||
case Xop_tblw_wkr.Tblw_type_tr: // \n|-
|
||||
case Xop_tblw_wkr.Tblw_type_te: // \n|}
|
||||
invalidate = true; // always invalidate
|
||||
break;
|
||||
case Xop_tblw_wkr.Tblw_type_td2: // ||; EX: [[A||B]]
|
||||
if (ctx.Tid_is_image_map()) { // if in ImageMap, then treat "||" as "pipe" (not "pipe_text"); note that outer tbl is ignored; EX:w:United_States_presidential_election,_1992
|
||||
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
|
||||
return cur_pos;
|
||||
}
|
||||
invalidate = !Xop_lnki_wkr_.Parse_ttl(ctx, src, lnki, bgn_pos); // check if invalid; EX: "[[A<||]]" would be invalid b/c of <
|
||||
if (!invalidate) { // "valid" title, but "||" must be converted to pipe inside lnki; EX:cs.w:Main_Page; DATE:2014-05-09
|
||||
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos)); // NOTE: technically need to check if pipe or pipe_text; for now, do pipe as pipe_text could break [[File:A.png||20px]]; DATE:2014-05-06
|
||||
return cur_pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (invalidate) {
|
||||
ctx.Stack_pop_last();
|
||||
return Xop_lnki_wkr_.Invalidate_lnki(ctx, src, root, lnki, bgn_pos);
|
||||
}
|
||||
}
|
||||
else { // nth pipe; no need to check for invalidate
|
||||
switch (wlxr_type) {
|
||||
case Xop_tblw_wkr.Tblw_type_tc: // \n|+
|
||||
case Xop_tblw_wkr.Tblw_type_tr: // \n|-
|
||||
case Xop_tblw_wkr.Tblw_type_td: // \n|
|
||||
//case Xop_tblw_wkr.Tblw_type_te: // |} // NOTE: ignore "|}"; needed for incomplete lnkis; EX: |[[a\n|}; EX:w:Wikipedia:Changing_attribution_for_an_edit; DATE:2014-03-16
|
||||
ctx.Subs_add(root, tkn_mkr.NewLine(bgn_pos, bgn_pos + 1, Xop_nl_tkn.Tid_char, 1));
|
||||
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos + 1, bgn_pos + 2));
|
||||
return bgn_pos + 2; // +2 to skip "\n|", but still look at 3rd char; ("+", "-", or "}")
|
||||
case Xop_tblw_wkr.Tblw_type_td2: // ||
|
||||
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
|
||||
return cur_pos;
|
||||
case Xop_tblw_wkr.Tblw_type_th2: // !!
|
||||
case Xop_tblw_wkr.Tblw_type_th: // !
|
||||
ctx.Subs_add(root, tkn_mkr.Txt(bgn_pos, cur_pos)); // NOTE: cur_pos should handle ! and !!
|
||||
return cur_pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Continue;
|
||||
}
|
||||
public Xop_tblw_lxr(byte wlxr_type) {this.wlxr_type = wlxr_type;} private byte wlxr_type;
|
||||
public static final Xop_tblw_lxr _ = new Xop_tblw_lxr(); Xop_tblw_lxr() {}
|
||||
public void Init_by_wiki(Xow_wiki wiki, ByteTrieMgr_fast core_trie) {
|
||||
core_trie.Add(Hook_tb, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_tb));
|
||||
core_trie.Add(Hook_te, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_te));
|
||||
core_trie.Add(Hook_tr, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_tr));
|
||||
core_trie.Add(Hook_td, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_td));
|
||||
core_trie.Add(Hook_th, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_th));
|
||||
core_trie.Add(Hook_tc, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_tc));
|
||||
core_trie.Add(Hook_td2, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_td2));
|
||||
core_trie.Add(Hook_th2, new Xop_tblw_lxr(Xop_tblw_wkr.Tblw_type_th2));
|
||||
}
|
||||
public void Init_by_lang(Xol_lang lang, ByteTrieMgr_fast core_trie) {}
|
||||
public static final byte[] Hook_tb = Bry_.new_ascii_("\n{|"), Hook_te = Bry_.new_ascii_("\n|}"), Hook_tr = Bry_.new_ascii_("\n|-")
|
||||
, Hook_td = Bry_.new_ascii_("\n|"), Hook_th = Bry_.new_ascii_("\n!"), Hook_tc = Bry_.new_ascii_("\n|+")
|
||||
, Hook_td2 = Bry_.new_ascii_("||"), Hook_th2 = Bry_.new_ascii_("!!");
|
||||
}
|
||||
110
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_lxr_ws.java
Normal file
110
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_lxr_ws.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
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_tblw_lxr_ws {
|
||||
public static int Make(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, byte wlxr_type, boolean called_from_pre) {
|
||||
int rv = Xop_tblw_lxr.Handle_bang(wlxr_type, ctx, ctx.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos);
|
||||
if (rv != Xop_tblw_lxr.Continue) return rv;
|
||||
rv = Xop_tblw_lxr.Handle_lnki(wlxr_type, ctx, ctx.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos);
|
||||
if (rv != Xop_tblw_lxr.Continue) return rv;
|
||||
if (!called_from_pre) { // skip if called from pre, else will return text, since pre_lxr has not created \n tkn yet; EX: "\n ! a"; DATE:2014-02-14
|
||||
// find first non-ws tkn; check if nl or para
|
||||
int root_subs_len = root.Subs_len();
|
||||
int tkn_idx = root_subs_len - 1;
|
||||
boolean loop = true, nl_found = false;
|
||||
while (loop) {
|
||||
if (tkn_idx < 0) break;
|
||||
Xop_tkn_itm tkn = root.Subs_get(tkn_idx);
|
||||
switch (tkn.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_space: case Xop_tkn_itm_.Tid_tab: // ws: keep moving backwards
|
||||
tkn_idx--;
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_newLine:
|
||||
case Xop_tkn_itm_.Tid_para:
|
||||
loop = false;
|
||||
nl_found = true;
|
||||
break;
|
||||
default:
|
||||
loop = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tkn_idx == -1) { // bos reached; all tkns are ws;
|
||||
if (wlxr_type == Xop_tblw_wkr.Tblw_type_tb) { // wlxr_type is {|;
|
||||
root.Subs_del_after(0); // trim
|
||||
return ctx.Tblw().Make_tkn_bgn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, false, wlxr_type, Xop_tblw_wkr.Called_from_general, -1, -1); // process {|
|
||||
}
|
||||
else // wlxr_type is something else, but invalid since no containing {|
|
||||
return ctx.Lxr_make_txt_(cur_pos);
|
||||
}
|
||||
|
||||
if (!nl_found && wlxr_type == Xop_tblw_wkr.Tblw_type_td) // | but no nl; return control to pipe_lxr for further processing
|
||||
return Tblw_ws_cell_pipe;
|
||||
if (nl_found)
|
||||
root.Subs_del_after(tkn_idx);
|
||||
}
|
||||
return ctx.Tblw().Make_tkn_bgn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, false, wlxr_type, Xop_tblw_wkr.Called_from_general, -1, -1);
|
||||
}
|
||||
public static final byte[] Hook_tb = Bry_.new_ascii_("{|"), Hook_te = Bry_.new_ascii_("|}"), Hook_tr = Bry_.new_ascii_("|-")
|
||||
, Hook_th = Bry_.new_ascii_("!"), Hook_tc = Bry_.new_ascii_("|+");
|
||||
public static final int Tblw_ws_cell_pipe = -1;
|
||||
}
|
||||
class Xop_tblw_ws_itm {
|
||||
public byte Tblw_type() {return tblw_type;} private byte tblw_type;
|
||||
public int Hook_len() {return hook_len;} private int hook_len;
|
||||
public Xop_tblw_ws_itm(byte tblw_type, int hook_len) {this.tblw_type = tblw_type; this.hook_len = hook_len;}
|
||||
|
||||
public static final byte Type_tb = Xop_tblw_wkr.Tblw_type_tb, Type_te = Xop_tblw_wkr.Tblw_type_te, Type_tr = Xop_tblw_wkr.Tblw_type_tr, Type_tc = Xop_tblw_wkr.Tblw_type_tc
|
||||
, Type_th = Xop_tblw_wkr.Tblw_type_th, Type_td = Xop_tblw_wkr.Tblw_type_td, Type_nl = 16, Type_xnde = 17;
|
||||
public static ByteTrieMgr_slim trie_() {// MW.REF:Parser.php|doBlockLevels
|
||||
ByteTrieMgr_slim rv = ByteTrieMgr_slim.cs_();
|
||||
trie_itm(rv, Type_tb, Xop_tblw_lxr_ws.Hook_tb);
|
||||
trie_itm(rv, Type_te, Xop_tblw_lxr_ws.Hook_te);
|
||||
trie_itm(rv, Type_tr, Xop_tblw_lxr_ws.Hook_tr);
|
||||
trie_itm(rv, Type_th, Xop_tblw_lxr_ws.Hook_th);
|
||||
trie_itm(rv, Type_tc, Xop_tblw_lxr_ws.Hook_tc);
|
||||
trie_itm(rv, Type_td, Bry_.bytes_(Byte_ascii.Pipe));
|
||||
trie_itm(rv, Type_nl, Bry_.bytes_(Byte_ascii.NewLine));
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_table);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_tr);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_td);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_th);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_blockquote);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_h1);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_h2);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_h3);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_h4);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_h5);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_h6);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_pre);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_p);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_div);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_hr);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_li);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_ul);
|
||||
trie_itm_xnde(rv, Xop_xnde_tag_.Tag_ol);
|
||||
return rv;
|
||||
}
|
||||
private static void trie_itm(ByteTrieMgr_slim trie, byte type, byte[] bry) {trie.Add(bry, new Xop_tblw_ws_itm(type, bry.length));}
|
||||
private static void trie_itm_xnde(ByteTrieMgr_slim trie, Xop_xnde_tag tag) {
|
||||
byte[] tag_name = tag.Name_bry();
|
||||
int tag_name_len = tag_name.length;
|
||||
trie.Add(Bry_.Add(Bry_xnde_bgn, tag_name), new Xop_tblw_ws_itm(Type_xnde, tag_name_len));
|
||||
trie.Add(Bry_.Add(Bry_xnde_end, tag_name), new Xop_tblw_ws_itm(Type_xnde, tag_name_len + 1));
|
||||
} static byte[] Bry_xnde_bgn = new byte[] {Byte_ascii.Lt, Byte_ascii.Slash}, Bry_xnde_end = new byte[] {Byte_ascii.Lt};
|
||||
}
|
||||
37
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tb_tkn.java
Normal file
37
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tb_tkn.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public class Xop_tblw_tb_tkn extends Xop_tkn_itm_base implements Xop_tblw_tkn {
|
||||
public Xop_tblw_tb_tkn(int bgn, int end, boolean tblw_xml, boolean auto_created) {
|
||||
this.tblw_xml = tblw_xml; this.Tkn_ini_pos(false, bgn, end);
|
||||
if (auto_created) // auto-created should be marked as having no attributes, else text may get gobbled up incorrectly; EX:Paris#Demographics DATE:2014-03-18
|
||||
atrs_bgn = atrs_end = bgn;
|
||||
}
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tb;}
|
||||
public int Tblw_tid() {return Xop_xnde_tag_.Tid_table;}
|
||||
public int Atrs_bgn() {return atrs_bgn;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null;
|
||||
public int Atrs_end() {return atrs_end;} private int atrs_end = -1;
|
||||
public void Atrs_rng_set(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end;}
|
||||
public Xop_xatr_itm[] Atrs_ary() {return atrs_ary;} public Xop_tblw_tkn Atrs_ary_as_tblw_(Xop_xatr_itm[] v) {atrs_ary = v; return this;} private Xop_xatr_itm[] atrs_ary;
|
||||
public boolean Tblw_xml() {return tblw_xml;} private boolean tblw_xml;
|
||||
public void Tblw_xml_(boolean v) {tblw_xml = v;}
|
||||
public int Tblw_subs_len() {return tblw_subs_len;} public void Tblw_subs_len_add_() {++tblw_subs_len;} private int tblw_subs_len;
|
||||
public int Caption_count() {return caption_count;} public Xop_tblw_tb_tkn Caption_count_(int v) {caption_count = v; return this;} private int caption_count = 0;
|
||||
public Xop_tblw_tb_tkn Caption_count_add_1() {++caption_count; return this;}
|
||||
public Xop_tblw_tb_tkn Subs_add_ary(Xop_tkn_itm... ary) {for (Xop_tkn_itm itm : ary) super.Subs_add(itm); return this;}
|
||||
}
|
||||
30
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tc_tkn.java
Normal file
30
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tc_tkn.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public class Xop_tblw_tc_tkn extends Xop_tkn_itm_base implements Xop_tblw_tkn {
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tc;}
|
||||
public int Tblw_tid() {return Xop_xnde_tag_.Tid_caption;}
|
||||
public int Atrs_bgn() {return atrs_bgn;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null;
|
||||
public int Atrs_end() {return atrs_end;} private int atrs_end = -1;
|
||||
public void Atrs_rng_set(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end;}
|
||||
public Xop_xatr_itm[] Atrs_ary() {return atrs_ary;} public Xop_tblw_tkn Atrs_ary_as_tblw_(Xop_xatr_itm[] v) {atrs_ary = v; return this;} private Xop_xatr_itm[] atrs_ary;
|
||||
public boolean Tblw_xml() {return tblw_xml;} private boolean tblw_xml;
|
||||
public int Tblw_subs_len() {return tblw_subs_len;} public void Tblw_subs_len_add_() {++tblw_subs_len;} private int tblw_subs_len;
|
||||
public Xop_tblw_tc_tkn Subs_add_ary(Xop_tkn_itm... ary) {for (Xop_tkn_itm itm : ary) super.Subs_add(itm); return this;}
|
||||
public Xop_tblw_tc_tkn(int bgn, int end, boolean tblw_xml) {this.tblw_xml = tblw_xml; this.Tkn_ini_pos(false, bgn, end);}
|
||||
}
|
||||
30
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_td_tkn.java
Normal file
30
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_td_tkn.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public class Xop_tblw_td_tkn extends Xop_tkn_itm_base implements Xop_tblw_tkn {
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_td;}
|
||||
public int Tblw_tid() {return Xop_xnde_tag_.Tid_td;}
|
||||
public int Atrs_bgn() {return atrs_bgn;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null;
|
||||
public int Atrs_end() {return atrs_end;} private int atrs_end = -1;
|
||||
public void Atrs_rng_set(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end;}
|
||||
public Xop_xatr_itm[] Atrs_ary() {return atrs_ary;} public Xop_tblw_tkn Atrs_ary_as_tblw_(Xop_xatr_itm[] v) {atrs_ary = v; return this;} private Xop_xatr_itm[] atrs_ary;
|
||||
public boolean Tblw_xml() {return tblw_xml;} private boolean tblw_xml;
|
||||
public int Tblw_subs_len() {return tblw_subs_len;} public void Tblw_subs_len_add_() {++tblw_subs_len;} private int tblw_subs_len;
|
||||
public Xop_tblw_td_tkn Subs_add_ary(Xop_tkn_itm... ary) {for (Xop_tkn_itm itm : ary) super.Subs_add(itm); return this;}
|
||||
public Xop_tblw_td_tkn(int bgn, int end, boolean tblw_xml) {this.tblw_xml = tblw_xml; this.Tkn_ini_pos(false, bgn, end);}
|
||||
}
|
||||
30
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_th_tkn.java
Normal file
30
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_th_tkn.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public class Xop_tblw_th_tkn extends Xop_tkn_itm_base implements Xop_tblw_tkn {
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_th;}
|
||||
public int Tblw_tid() {return Xop_xnde_tag_.Tid_th;}
|
||||
public int Atrs_bgn() {return atrs_bgn;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null;
|
||||
public int Atrs_end() {return atrs_end;} private int atrs_end = -1;
|
||||
public void Atrs_rng_set(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end;}
|
||||
public Xop_xatr_itm[] Atrs_ary() {return atrs_ary;} public Xop_tblw_tkn Atrs_ary_as_tblw_(Xop_xatr_itm[] v) {atrs_ary = v; return this;} private Xop_xatr_itm[] atrs_ary;
|
||||
public boolean Tblw_xml() {return tblw_xml;} private boolean tblw_xml;
|
||||
public int Tblw_subs_len() {return tblw_subs_len;} public void Tblw_subs_len_add_() {++tblw_subs_len;} private int tblw_subs_len;
|
||||
public Xop_tblw_th_tkn Subs_add_ary(Xop_tkn_itm... ary) {for (Xop_tkn_itm itm : ary) super.Subs_add(itm); return this;}
|
||||
public Xop_tblw_th_tkn(int bgn, int end, boolean tblw_xml) {this.tblw_xml = tblw_xml; this.Tkn_ini_pos(false, bgn, end);}
|
||||
}
|
||||
27
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tkn.java
Normal file
27
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tkn.java
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public interface Xop_tblw_tkn extends Xop_tkn_itm {
|
||||
int Tblw_tid();
|
||||
boolean Tblw_xml();
|
||||
int Tblw_subs_len(); void Tblw_subs_len_add_();
|
||||
int Atrs_bgn();
|
||||
int Atrs_end();
|
||||
void Atrs_rng_set(int bgn, int end);
|
||||
Xop_xatr_itm[] Atrs_ary(); Xop_tblw_tkn Atrs_ary_as_tblw_(Xop_xatr_itm[] v);
|
||||
}
|
||||
34
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tr_tkn.java
Normal file
34
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_tr_tkn.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
public class Xop_tblw_tr_tkn extends Xop_tkn_itm_base implements Xop_tblw_tkn {
|
||||
public Xop_tblw_tr_tkn(int bgn, int end, boolean tblw_xml, boolean auto_created) {
|
||||
this.tblw_xml = tblw_xml; this.Tkn_ini_pos(false, bgn, end);
|
||||
if (auto_created) // auto-created should be marked as having no attributes, else text may get gobbled up incorrectly; EX:Paris#Demographics DATE:2014-03-18
|
||||
atrs_bgn = atrs_end = bgn;
|
||||
}
|
||||
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tr;}
|
||||
public int Tblw_tid() {return Xop_xnde_tag_.Tid_tr;}
|
||||
public int Atrs_bgn() {return atrs_bgn;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null;
|
||||
public int Atrs_end() {return atrs_end;} private int atrs_end = -1;
|
||||
public void Atrs_rng_set(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end;}
|
||||
public Xop_xatr_itm[] Atrs_ary() {return atrs_ary;} public Xop_tblw_tkn Atrs_ary_as_tblw_(Xop_xatr_itm[] v) {atrs_ary = v; return this;} private Xop_xatr_itm[] atrs_ary;
|
||||
public boolean Tblw_xml() {return tblw_xml;} private boolean tblw_xml;
|
||||
public int Tblw_subs_len() {return tblw_subs_len;} public void Tblw_subs_len_add_() {++tblw_subs_len;} private int tblw_subs_len;
|
||||
public Xop_tblw_tr_tkn Subs_add_ary(Xop_tkn_itm... ary) {for (Xop_tkn_itm itm : ary) super.Subs_add(itm); return this;}
|
||||
}
|
||||
531
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr.java
Normal file
531
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr.java
Normal file
@@ -0,0 +1,531 @@
|
||||
/*
|
||||
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_tblw_wkr implements Xop_ctx_wkr {
|
||||
private int tblw_te_ignore_count = 0;
|
||||
public boolean Cell_pipe_seen() {return cell_pipe_seen;} public Xop_tblw_wkr Cell_pipe_seen_(boolean v) {cell_pipe_seen = v; return this;} private boolean cell_pipe_seen; // status of 1st cell pipe; EX: \n| a | b | c || -> flag pipe between a and b but ignore b and c
|
||||
public void Ctor_ctx(Xop_ctx ctx) {}
|
||||
public void Page_bgn(Xop_ctx ctx, Xop_root_tkn root) {cell_pipe_seen = false; tblw_te_ignore_count = 0;}
|
||||
public void Page_end(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int src_len) {}
|
||||
public void AutoClose(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, Xop_tkn_itm tkn) {
|
||||
tkn.Subs_move(root);
|
||||
tkn.Src_end_(cur_pos);
|
||||
}
|
||||
public static final byte Called_from_general = 0, Called_from_list = 1, Called_from_pre = 2;
|
||||
public int Make_tkn_bgn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, boolean tbl_is_xml, byte wlxr_type, byte called_from, int atrs_bgn, int atrs_end) {// REF.MW: Parser|doTableStuff
|
||||
if (bgn_pos == Xop_parser_.Doc_bgn_bos) {
|
||||
bgn_pos = 0; // do not allow -1 pos
|
||||
}
|
||||
|
||||
int list_tkn_idx = ctx.Stack_idx_find_but_stop_at_tbl(Xop_tkn_itm_.Tid_list);
|
||||
if ( list_tkn_idx != -1 // list is in effect; DATE:2014-05-05
|
||||
&& !tbl_is_xml // tbl is wiki-syntax; ie: auto-close if "{|" but do not close if "<table>"; DATE:2014-02-05
|
||||
&& called_from != Called_from_list // do not close if called from list; EX: consider "{|"; "* a {|" is called from list_wkr, and should not close; "* a\n{|" is called from tblw_lxr and should close; DATE:2014-02-14
|
||||
) {
|
||||
if (wlxr_type == Tblw_type_td2) { // if in list, treat "||" as lnki, not tblw; EX: es.d:casa; es.d:tres; DATE:2014-02-15
|
||||
ctx.Subs_add(root, ctx.Tkn_mkr().Pipe(bgn_pos, cur_pos)); // NOTE: technically need to check if pipe or pipe_text; for now, do pipe as pipe_text could break [[File:A.png||20px]]; DATE:2014-05-06
|
||||
return cur_pos;
|
||||
}
|
||||
else {
|
||||
Xop_list_wkr_.Close_list_if_present(ctx, root, src, bgn_pos, cur_pos);
|
||||
}
|
||||
}
|
||||
if (ctx.Apos().Stack_len() > 0) // open apos; note that apos keeps its own stack, as they are not "structural" (not sure about this)
|
||||
ctx.Apos().EndFrame(ctx, root, src, cur_pos, true); // close it
|
||||
|
||||
Xop_tblw_tkn prv_tkn = ctx.Stack_get_tbl();
|
||||
if ( prv_tkn == null // prv_tkn not found; i.e.: no earlier "{|" or "<table>"
|
||||
|| ( ctx.Stack_get_tblw_tb() == null // no {| on stack; DATE:2014-05-05
|
||||
&& !tbl_is_xml // and cur is tblw (i.e.: not xnde); DATE:2014-05-05
|
||||
)
|
||||
) {
|
||||
switch (wlxr_type) {
|
||||
case Tblw_type_tb: // "{|";
|
||||
break; // noop; by definition "{|" does not need to have a previous "{|"
|
||||
case Tblw_type_td: // "|"
|
||||
case Tblw_type_td2: // "||"
|
||||
if (tbl_is_xml) { // <td> should automatically add <table><tr>
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, tkn_mkr.Tblw_tb(bgn_pos, bgn_pos, tbl_is_xml, true));
|
||||
prv_tkn = tkn_mkr.Tblw_tr(bgn_pos, bgn_pos, tbl_is_xml, true);
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, prv_tkn);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (called_from == Called_from_pre)
|
||||
return -1;
|
||||
else { // DATE:2014-02-19; NOTE: do not add nl if ||; DATE:2014-04-14
|
||||
if (wlxr_type == Tblw_type_td) { // "\n|"
|
||||
ctx.Subs_add(root, ctx.Tkn_mkr().NewLine(bgn_pos, bgn_pos + 1, Xop_nl_tkn.Tid_char, 1));
|
||||
ctx.Subs_add(root, ctx.Tkn_mkr().Pipe(bgn_pos + 1, cur_pos));
|
||||
}
|
||||
else // "||"
|
||||
ctx.Subs_add(root, ctx.Tkn_mkr().Pipe(bgn_pos, cur_pos));
|
||||
return cur_pos;
|
||||
}
|
||||
}
|
||||
case Tblw_type_th: // "!"
|
||||
case Tblw_type_th2: // "!!"
|
||||
case Tblw_type_tc: // "|+"
|
||||
case Tblw_type_tr: // "|-"
|
||||
if (tbl_is_xml) { // <tr> should automatically add <table>; DATE:2014-02-13
|
||||
prv_tkn = tkn_mkr.Tblw_tb(bgn_pos, bgn_pos, tbl_is_xml, true);
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, prv_tkn);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (called_from == Called_from_pre)
|
||||
return -1;
|
||||
else
|
||||
return Xop_tblw_wkr.Handle_false_tblw_match(ctx, root, src, bgn_pos, cur_pos, ctx.Tkn_mkr().Txt(bgn_pos + 1, cur_pos), true); // DATE:2014-02-19
|
||||
}
|
||||
case Tblw_type_te: // "|}"
|
||||
if (tblw_te_ignore_count > 0) {
|
||||
--tblw_te_ignore_count;
|
||||
return cur_pos;
|
||||
}
|
||||
else {
|
||||
if (called_from == Called_from_pre)
|
||||
return -1;
|
||||
else
|
||||
return Xop_tblw_wkr.Handle_false_tblw_match(ctx, root, src, bgn_pos, cur_pos, tkn_mkr.Txt(bgn_pos + 1, cur_pos), true); // +1 to skip "\n" in "\n|}" (don't convert \n to text); DATE:2014-02-19
|
||||
}
|
||||
default: throw Err_.unhandled(wlxr_type);
|
||||
}
|
||||
}
|
||||
|
||||
int prv_tid = prv_tkn == null ? Xop_tkn_itm_.Tid_null : prv_tkn.Tkn_tid();
|
||||
if (prv_tkn != null && !prv_tkn.Tblw_xml()) { // note that this logic is same as Atrs_close; repeated here for "perf"
|
||||
switch (prv_tid) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: case Xop_tkn_itm_.Tid_tblw_tr:
|
||||
Atrs_make(ctx, src, root, this, prv_tkn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (wlxr_type == Tblw_type_te)
|
||||
return Make_tkn_end(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_tblw_te, wlxr_type, prv_tkn, prv_tid, tbl_is_xml);
|
||||
else
|
||||
return Make_tkn_bgn_tblw(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, wlxr_type, tbl_is_xml, atrs_bgn, atrs_end, prv_tkn, prv_tid);
|
||||
}
|
||||
private int Make_tkn_bgn_tblw(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, byte wlxr_type, boolean tbl_is_xml, int atrs_bgn, int atrs_end, Xop_tblw_tkn prv_tkn, int prv_tid) {
|
||||
if (wlxr_type != Tblw_type_tb) // NOTE: do not ignore ws if {|; will cause strange behavior with pre; DATE:2013-02-12
|
||||
Ignore_ws(ctx, root);
|
||||
Xop_tblw_tkn new_tkn = null;
|
||||
switch (wlxr_type) {
|
||||
case Tblw_type_tb: // <table>
|
||||
boolean ignore_prv = false, auto_create = false;
|
||||
switch (prv_tid) {
|
||||
case Xop_tkn_itm_.Tid_null: // noop; <table>
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_td: // noop; <td><table>
|
||||
case Xop_tkn_itm_.Tid_tblw_th: // noop; <th><table>
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: // fix; <table><table> -> <table>; ignore current table; DATE:2014-02-02
|
||||
if (prv_tkn.Tblw_xml()) { // fix: <table><table> -> <table>; earlier tbl is xnde; ignore; EX:en.b:Wikibooks:Featured books; DATE:2014-02-08
|
||||
((Xop_tblw_tb_tkn)prv_tkn).Tblw_xml_(false); // if <table>{|, discard <table>, but mark {| as <table>; needed to handle <table>\n{|\n| where "|" must be treated as tblw dlm; DATE:2014-02-22
|
||||
ignore_prv = true;
|
||||
}
|
||||
// else // fix: <table><table> -> <table><tr><td><table>; earlier tbl is tblw; auto-create; EX:it.w:Main_Page; DATE:2014-02-08; TIDY:depend on tidy to fix; PAGE: it.w:Portal:Animali; DATE:2014-05-31
|
||||
// auto_create = true;
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tr: // noop: <table><tr><table> -> <table><tr><td><table>; should probably auto-create td, but MW does not; DATE:2014-03-18
|
||||
case Xop_tkn_itm_.Tid_tblw_tc: // noop; <caption><table>; TIDY:was <caption></caption><tr><td><table>; PAGE: es.w:Savilla DATE:2014-06-29
|
||||
break;
|
||||
}
|
||||
if (ignore_prv) {
|
||||
ctx.Subs_add(root, tkn_mkr.Ignore(bgn_pos, cur_pos, Xop_ignore_tkn.Ignore_tid_htmlTidy_tblw));
|
||||
++tblw_te_ignore_count;
|
||||
cur_pos = Bry_finder.Find_fwd_until(src, cur_pos, src_len, Byte_ascii.NewLine); // NOTE: minor hack; this tblw tkn will be ignored, so ignore any of its attributes as well; gobble up all chars till nl. see: if two consecutive tbs, ignore attributes on 2nd; en.wikibooks.org/wiki/Wikibooks:Featured books
|
||||
return cur_pos;
|
||||
}
|
||||
if (auto_create) {
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, tkn_mkr.Tblw_tr(bgn_pos, bgn_pos, tbl_is_xml, true));
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, tkn_mkr.Tblw_td(bgn_pos, bgn_pos, tbl_is_xml));
|
||||
}
|
||||
Xop_tblw_tb_tkn tb_tkn = tkn_mkr.Tblw_tb(bgn_pos, cur_pos, tbl_is_xml, false);
|
||||
new_tkn = tb_tkn;
|
||||
break;
|
||||
case Tblw_type_tr: // <tr>
|
||||
switch (prv_tid) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: break; // noop; <table><tr>
|
||||
case Xop_tkn_itm_.Tid_tblw_tc: // fix; <caption><tr> -> <caption></caption><tr>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tc), true, bgn_pos, bgn_pos);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_td: // fix; <td><tr> -> <td></td></tr><tr>
|
||||
case Xop_tkn_itm_.Tid_tblw_th: // fix; <th><tr> -> <th></th></tr><tr>
|
||||
if (!tbl_is_xml)
|
||||
ctx.Para().Process_nl(ctx, root, src, bgn_pos, bgn_pos + 1); // simulate "\n"; 2012-12-08
|
||||
int stack_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr);
|
||||
if (stack_pos != Xop_ctx.Stack_not_found) // don't pop <tr> if none found; EX:en.w:Turks_in_Denmark DATE:2014-03-02
|
||||
ctx.Stack_pop_til(root, src, stack_pos, true, bgn_pos, bgn_pos);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tr: // fix; <tr><tr> -> <tr>
|
||||
if (prv_tkn.Tblw_subs_len() == 0) { // NOTE: set prv_row to ignore, but do not pop; see Tr_dupe_xnde and [[Jupiter]]; only invoke if same type; EX: <tr><tr> but not |-<tr>; DATE:2013-12-09
|
||||
Xop_tkn_itm prv_row = ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr), false, bgn_pos, bgn_pos);
|
||||
prv_row.Ignore_y_();
|
||||
}
|
||||
else
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr), true, bgn_pos, bgn_pos);
|
||||
break;
|
||||
}
|
||||
Xop_tblw_tr_tkn tr_tkn = tkn_mkr.Tblw_tr(bgn_pos, cur_pos, tbl_is_xml, false);
|
||||
new_tkn = tr_tkn;
|
||||
break;
|
||||
case Tblw_type_td: // <td>
|
||||
case Tblw_type_td2:
|
||||
boolean create_th = false;
|
||||
switch (prv_tid) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tr: break; // noop; <tr><td>
|
||||
case Xop_tkn_itm_.Tid_tblw_td: // fix; <td><td> -> <td></td><td>
|
||||
if (!tbl_is_xml) // only for "\n|" not <td>
|
||||
ctx.Para().Process_nl(ctx, root, src, bgn_pos, bgn_pos + 1); // simulate "\n"; DATE:2014-02-20; ru.w:;[[Help:Download]]; DATE:2014-02-20
|
||||
ctx.Para().Process_block__bgn_y__end_n(Xop_xnde_tag_.Tag_td); // <td>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(prv_tid), true, bgn_pos, bgn_pos);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_th: // fix; <th><td> -> <th></th><td>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(prv_tid), true, bgn_pos, bgn_pos);
|
||||
if (wlxr_type == Tblw_type_td2) create_th = true; // !a||b -> <th><th>; but !a|b -> <th><td>
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: // fix; <table><td> -> <table><tr><td>
|
||||
if (wlxr_type == Tblw_type_td2) { // NOTE: ignore || if preceded by {|; {|a||b\n
|
||||
prv_tkn.Atrs_rng_set(-1, -1); // reset atrs_bgn; remainder of line will become part of tb atr
|
||||
return cur_pos;
|
||||
}
|
||||
else {
|
||||
new_tkn = tkn_mkr.Tblw_tr(bgn_pos, cur_pos, tbl_is_xml, true);
|
||||
new_tkn.Atrs_rng_set(bgn_pos, bgn_pos);
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, new_tkn);
|
||||
prv_tid = new_tkn.Tkn_tid();
|
||||
}
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tc: // fix; <caption><td> -> <caption></caption><tr><td>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tc), true, bgn_pos, bgn_pos);
|
||||
new_tkn = tkn_mkr.Tblw_tr(bgn_pos, cur_pos, tbl_is_xml, true);
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, new_tkn);
|
||||
prv_tid = new_tkn.Tkn_tid();
|
||||
break;
|
||||
}
|
||||
// if (prv_tid == Xop_tkn_itm_.Tid_xnde)
|
||||
// ctx.Stack_autoClose(root, src, prv_tkn, prv_tkn.Src_bgn(), prv_tkn.Src_end());
|
||||
if (create_th) new_tkn = tkn_mkr.Tblw_th(bgn_pos, cur_pos, tbl_is_xml);
|
||||
else new_tkn = tkn_mkr.Tblw_td(bgn_pos, cur_pos, tbl_is_xml);
|
||||
cell_pipe_seen = false;
|
||||
break;
|
||||
case Tblw_type_th: // <th>
|
||||
case Tblw_type_th2:
|
||||
switch (prv_tid) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tr: break; // noop; <tr><th>
|
||||
case Xop_tkn_itm_.Tid_tblw_th: // fix; <th><th> -> <th></th><th>
|
||||
if (tbl_is_xml // tbl_is_xml always closes previous token
|
||||
|| (wlxr_type == Tblw_type_th2 || wlxr_type == Tblw_type_th)) // ! always closes; EX: "! !!"; "!! !!"; REMOVE: 2012-05-07; had (&& !ws_enabled) but caused "\n !" to fail; guard is no longer necessary since tblw_ws changed...
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(prv_tid), true, bgn_pos, bgn_pos);
|
||||
else {
|
||||
ctx.Subs_add(root, tkn_mkr.Txt(bgn_pos, cur_pos));
|
||||
return cur_pos;
|
||||
}
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_td: // fix; <td><th> -> <td></td><th> NOTE: common use of using <th> after <td> for formatting
|
||||
if (tbl_is_xml // tbl_is_xml always closes previous token
|
||||
|| (wlxr_type == Tblw_type_th)) // "| !" closes; "| !!" does not;
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(prv_tid), true, bgn_pos, bgn_pos);
|
||||
else {
|
||||
ctx.Subs_add(root, tkn_mkr.Txt(bgn_pos, cur_pos));
|
||||
return cur_pos;
|
||||
}
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: // fix; <table><th> -> <table><tr><th>
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, tkn_mkr.Tblw_tr(bgn_pos, cur_pos, tbl_is_xml, true));
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tc: // fix; <caption><th> -> <caption></caption><tr><th>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tc), true, bgn_pos, bgn_pos);
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, tkn_mkr.Tblw_tr(bgn_pos, cur_pos, tbl_is_xml, true));
|
||||
break;
|
||||
}
|
||||
new_tkn = tkn_mkr.Tblw_th(bgn_pos, cur_pos, tbl_is_xml);
|
||||
cell_pipe_seen = false;
|
||||
break;
|
||||
case Tblw_type_tc: // <caption>
|
||||
switch (prv_tid) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: break; // noop; <table><caption>
|
||||
case Xop_tkn_itm_.Tid_tblw_tr: // fix; <tr><caption> -> <tr></tr><caption> TODO: caption should be ignored and placed in quarantine
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr), true, bgn_pos, bgn_pos);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_td: // fix; <td><caption> -> <td></td><caption>
|
||||
case Xop_tkn_itm_.Tid_tblw_th: // fix; <th><caption> -> <th></th><caption>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr), true, bgn_pos, bgn_pos); // NOTE: closing <tr> in order to close <td>/<th>
|
||||
ctx.Msg_log().Add_itm_none(Xop_tblw_log.Caption_after_td, src, prv_tkn.Src_bgn(), bgn_pos);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tc: // fix; <caption><caption> -> <caption></caption><caption>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tc), true, bgn_pos, bgn_pos);
|
||||
ctx.Msg_log().Add_itm_none(Xop_tblw_log.Caption_after_tc, src, prv_tkn.Src_bgn(), bgn_pos);
|
||||
break;
|
||||
}
|
||||
new_tkn = tkn_mkr.Tblw_tc(bgn_pos, cur_pos, tbl_is_xml);
|
||||
Xop_tblw_tb_tkn tblw_tb_tkn = (Xop_tblw_tb_tkn)ctx.Stack_get_typ(Xop_tkn_itm_.Tid_tblw_tb);
|
||||
tblw_tb_tkn.Caption_count_add_1(); // NOTE: null check is not necessary (impossible to have a caption without a tblw); DATE:2013-12-20
|
||||
cell_pipe_seen = false; // NOTE: always mark !seen; see Atrs_tc()
|
||||
break;
|
||||
}
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, new_tkn);
|
||||
if (atrs_bgn > Xop_tblw_wkr.Atrs_ignore_check) {
|
||||
new_tkn.Atrs_rng_set(atrs_bgn, atrs_end);
|
||||
if (ctx.Parse_tid() == Xop_parser_.Parse_tid_page_wiki) {
|
||||
Xop_xatr_itm[] atrs = ctx.App().Xatr_parser().Parse(ctx.Msg_log(), src, atrs_bgn, atrs_end);
|
||||
new_tkn.Atrs_ary_as_tblw_(atrs);
|
||||
}
|
||||
}
|
||||
switch (wlxr_type) {
|
||||
case Tblw_type_tb:
|
||||
case Tblw_type_tr:
|
||||
ctx.Para().Process_block__bgn_y__end_n(Xop_xnde_tag_.Tag_tr);
|
||||
break;
|
||||
case Tblw_type_td:
|
||||
case Tblw_type_th:
|
||||
ctx.Para().Process_block__bgn_n__end_y(Xop_xnde_tag_.Tag_td);
|
||||
break;
|
||||
}
|
||||
return cur_pos;
|
||||
}
|
||||
public int Make_tkn_end(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, int typeId, byte wlxr_type, Xop_tblw_tkn prv_tkn, int prv_tid, boolean tbl_is_xml) {
|
||||
if (!tbl_is_xml) // only for "\n|}" not </table>
|
||||
ctx.Para().Process_nl(ctx, root, src, bgn_pos, bgn_pos + 1); // simulate "\n"; process para (which will create paras for cells) 2012-12-08
|
||||
if (tbl_is_xml && typeId == Xop_tkn_itm_.Tid_tblw_tb // tblx: </table>
|
||||
&& prv_tkn != null && !prv_tkn.Tblw_xml()) { // tblw is prv_tkn
|
||||
++tblw_te_ignore_count; // suppress subsequent occurrences of "|}"; EX:ru.q:Авель; DATE:2014-02-22
|
||||
}
|
||||
Ignore_ws(ctx, root);
|
||||
if (wlxr_type == Tblw_type_te) {
|
||||
switch (prv_tid) {
|
||||
case Xop_tkn_itm_.Tid_tblw_td: // fix; <td></table> -> <td></td></tr></table>
|
||||
case Xop_tkn_itm_.Tid_tblw_th: // fix; <th></table> -> <th></th></tr></table>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr), true, bgn_pos, bgn_pos);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tc: // fix; <caption></table> -> <caption></caption></table>
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tc), true, bgn_pos, bgn_pos);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tr: // fix; <tr></table> -> </table> : tr but no tds; remove tr
|
||||
boolean blank = true;
|
||||
for (int j = prv_tkn.Tkn_sub_idx() + 1; j < root.Subs_len(); j++) {
|
||||
Xop_tkn_itm t = root.Subs_get(j);
|
||||
switch (t.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_newLine:
|
||||
case Xop_tkn_itm_.Tid_para:
|
||||
break;
|
||||
default:
|
||||
blank = false;
|
||||
j = root.Subs_len();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (blank)
|
||||
root.Subs_del_after(prv_tkn.Tkn_sub_idx());
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: // fix; <table></table> -> <table><tr><td></td></tr></table>
|
||||
boolean has_subs = false;
|
||||
for (int i = prv_tkn.Tkn_sub_idx() + 1; i < root.Subs_len(); i++) {
|
||||
int cur_id = root.Subs_get(i).Tkn_tid();
|
||||
switch (cur_id) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tc:
|
||||
case Xop_tkn_itm_.Tid_tblw_td:
|
||||
case Xop_tkn_itm_.Tid_tblw_th:
|
||||
case Xop_tkn_itm_.Tid_tblw_tr:
|
||||
has_subs = true;
|
||||
i = root.Subs_len();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_subs) {
|
||||
Xop_tkn_itm new_tkn = tkn_mkr.Tblw_tr(bgn_pos, bgn_pos, tbl_is_xml, true);
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, new_tkn);
|
||||
new_tkn = tkn_mkr.Tblw_td(bgn_pos, bgn_pos, tbl_is_xml);
|
||||
ctx.Subs_add_and_stack_tblw(root, prv_tkn, new_tkn);
|
||||
ctx.Stack_pop_til(root, src, ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tb), true, bgn_pos, bgn_pos);
|
||||
return cur_pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
int tb_idx = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tb);
|
||||
if (tb_idx == -1) return cur_pos; // NOTE: tb_idx can be -1 when called from Pipe in Tmpl mode
|
||||
Xop_tblw_tb_tkn tb = (Xop_tblw_tb_tkn)ctx.Stack_pop_til(root, src, tb_idx, false, bgn_pos, bgn_pos); // NOTE: need to pop manually in order to set all intermediate node ends to bgn_pos, but tb ent to cur_pos; EX: for stack of "tb,tr,td" tr and td get End_() of bgn_pos but tb gets End_() of cur_pos
|
||||
tb.Subs_move(root);
|
||||
tb.Src_end_(cur_pos);
|
||||
ctx.Para().Process_block__bgn_n__end_y(Xop_xnde_tag_.Tag_table); // NOTE: must clear block state that was started by <tr>; code implicitly relies on td clearing block state, but no td was created
|
||||
return cur_pos;
|
||||
}
|
||||
int acs_typeId = typeId;
|
||||
if (prv_tid != typeId // NOTE: special logic to handle auto-close of <td></th> or <th></td>
|
||||
&& ( (prv_tid == Xop_tkn_itm_.Tid_tblw_td && typeId == Xop_tkn_itm_.Tid_tblw_th)
|
||||
|| (prv_tid == Xop_tkn_itm_.Tid_tblw_th && typeId == Xop_tkn_itm_.Tid_tblw_td)
|
||||
)
|
||||
)
|
||||
acs_typeId = prv_tid;
|
||||
|
||||
int acs_pos = -1, acs_len = ctx.Stack_len();
|
||||
for (int i = acs_len - 1; i > -1; i--) { // find auto-close pos
|
||||
byte cur_acs_tid = ctx.Stack_get(i).Tkn_tid();
|
||||
switch (acs_typeId) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: // if </table>, match <table> only; note that it needs to be handled separately b/c of tb logic below
|
||||
if (acs_typeId == cur_acs_tid) {
|
||||
acs_pos = i;
|
||||
i = -1; // force break;
|
||||
}
|
||||
break;
|
||||
default: // if </t*>, match <t*> but stop at <table>; do not allow </t*> to close <t*> outside <table>
|
||||
if (cur_acs_tid == Xop_tkn_itm_.Tid_tblw_tb) // <table>; do not allow </t*> to close any <t*>'s above <table>; EX:w:Enthalpy_of_fusion; {{States of matter}}
|
||||
i = -1; // this will skip acs_pos != -1 below and discard token
|
||||
else if (cur_acs_tid == acs_typeId) { // </t*> matches <t*>
|
||||
acs_pos = i;
|
||||
i = -1; // force break
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (acs_pos != -1) {
|
||||
Xop_tblw_tkn bgn_tkn = (Xop_tblw_tkn)ctx.Stack_pop_til(root, src, acs_pos, false, bgn_pos, cur_pos);
|
||||
switch (wlxr_type) {
|
||||
case Tblw_type_tb:
|
||||
ctx.Para().Process_block__bgn_n__end_y(Xop_xnde_tag_.Tag_table);
|
||||
break;
|
||||
case Tblw_type_td:
|
||||
case Tblw_type_th:
|
||||
ctx.Para().Process_block__bgn_y__end_n(Xop_xnde_tag_.Tag_td);
|
||||
break;
|
||||
}
|
||||
bgn_tkn.Subs_move(root);
|
||||
bgn_tkn.Src_end_(cur_pos);
|
||||
}
|
||||
return cur_pos;
|
||||
}
|
||||
public static void Atrs_close(Xop_ctx ctx, byte[] src, Xop_root_tkn root) {
|
||||
Xop_tblw_tkn prv_tkn = ctx.Stack_get_tbl();
|
||||
if (prv_tkn == null || prv_tkn.Tblw_xml()) return; // no tblw or tblw_xnde (which does not have tblw atrs)
|
||||
switch (prv_tkn.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tb: case Xop_tkn_itm_.Tid_tblw_tr: // only tb and tr have tblw atrs (EX: "{|id=1\n"); td/th use pipes for atrs (EX: "|id=1|a"); tc has no atrs; te is never on stack
|
||||
Xop_tblw_wkr.Atrs_make(ctx, src, root, ctx.Tblw(), prv_tkn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public static boolean Atrs_make(Xop_ctx ctx, byte[] src, Xop_root_tkn root, Xop_tblw_wkr wkr, Xop_tblw_tkn prv_tblw) {
|
||||
if (prv_tblw.Atrs_bgn() != Xop_tblw_wkr.Atrs_null) return false; // atr_bgn/end is empty or already has explicit value; ignore;
|
||||
int subs_bgn = prv_tblw.Tkn_sub_idx() + 1, subs_end = root.Subs_len() - 1;
|
||||
int subs_pos = subs_bgn;
|
||||
Xop_tkn_itm last_atr_tkn = null;
|
||||
boolean loop = true;
|
||||
while (loop) { // loop over tkns after prv_tkn to find last_atr_tkn
|
||||
if (subs_pos > subs_end) break;
|
||||
Xop_tkn_itm tmp_tkn = root.Subs_get(subs_pos);
|
||||
switch (tmp_tkn.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_newLine: // nl stops; EX: "{| a b c \nd"; bgn at {| and pick up " a b c " as atrs
|
||||
case Xop_tkn_itm_.Tid_hdr: case Xop_tkn_itm_.Tid_hr: // hdr/hr incorporate nl into tkn so include these as well; EX: "{|a\n==b==" becomes tblw,txt,hdr (note that \n is part of hdr
|
||||
case Xop_tkn_itm_.Tid_list: // list stops; EX: "{| a b c\n* d"; "*d" ends atrs; EX: ru.d: DATE:2014-02-22
|
||||
loop = false;
|
||||
break;
|
||||
default:
|
||||
++subs_pos;
|
||||
last_atr_tkn = tmp_tkn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (last_atr_tkn == null) { // no atrs found; mark tblw_tkn as Atrs_empty
|
||||
prv_tblw.Atrs_rng_set(Xop_tblw_wkr.Atrs_empty, Xop_tblw_wkr.Atrs_empty);
|
||||
return false;
|
||||
}
|
||||
root.Subs_del_between(ctx, subs_bgn, subs_pos);
|
||||
int atrs_bgn = prv_tblw.Src_end(), atrs_end = last_atr_tkn.Src_end();
|
||||
if (prv_tblw.Tkn_tid() == Xop_tkn_itm_.Tid_tblw_tr) // NOTE: if "|-" gobble all trailing dashes; REF: Parser.php!doTableStuff; $line = preg_replace( '#^\|-+#', '', $line ); DATE:2013-06-21
|
||||
atrs_bgn = Bry_finder.Find_fwd_while(src, atrs_bgn, src.length, Byte_ascii.Dash);
|
||||
prv_tblw.Atrs_rng_set(atrs_bgn, atrs_end);
|
||||
if (ctx.Parse_tid() == Xop_parser_.Parse_tid_page_wiki && atrs_bgn != -1) {
|
||||
Xop_xatr_itm[] atrs = ctx.App().Xatr_parser().Parse(ctx.Msg_log(), src, atrs_bgn, atrs_end);
|
||||
prv_tblw.Atrs_ary_as_tblw_(atrs);
|
||||
}
|
||||
wkr.Cell_pipe_seen_(true);
|
||||
return true;
|
||||
}
|
||||
private void Ignore_ws(Xop_ctx ctx, Xop_root_tkn root) {
|
||||
int end = root.Subs_len() - 1;
|
||||
// get last tr, tc, tb; cannot use ctx.Stack_get_tblw b/c this gets last open tblw, and we want last tblw; EX: "<table><tr></tr>"; Stack_get_tblw gets <table> want </tr>
|
||||
boolean found = false;
|
||||
Xop_tkn_itm prv_tkn = null;
|
||||
for (int i = end; i > -1; i--) {
|
||||
prv_tkn = root.Subs_get(i);
|
||||
switch (prv_tkn.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_tblw_tr:
|
||||
case Xop_tkn_itm_.Tid_tblw_tc:
|
||||
case Xop_tkn_itm_.Tid_tblw_tb:
|
||||
found = true;
|
||||
i = -1;
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_tblw_td: // exclude td
|
||||
case Xop_tkn_itm_.Tid_tblw_th: // exclude th
|
||||
i = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return;
|
||||
int bgn = prv_tkn.Tkn_sub_idx() + 1;
|
||||
int rv = Ignore_ws_rng(ctx, root, bgn, end, true);
|
||||
if (rv == -1) return; // entire range is ws; don't bother trimming end
|
||||
Ignore_ws_rng(ctx, root, end, bgn, false);
|
||||
}
|
||||
private int Ignore_ws_rng(Xop_ctx ctx, Xop_root_tkn root, int bgn, int end, boolean fwd) {
|
||||
int cur = bgn, adj = fwd ? 1 : -1;
|
||||
while (true) {
|
||||
if (fwd) {
|
||||
if (cur > end) return -1;
|
||||
}
|
||||
else {
|
||||
if (cur < end) return -1;
|
||||
}
|
||||
Xop_tkn_itm ws_tkn = root.Subs_get(cur);
|
||||
switch (ws_tkn.Tkn_tid()) {
|
||||
case Xop_tkn_itm_.Tid_space: case Xop_tkn_itm_.Tid_tab: case Xop_tkn_itm_.Tid_newLine:
|
||||
case Xop_tkn_itm_.Tid_para:
|
||||
ws_tkn.Ignore_y_grp_(ctx, root, cur);
|
||||
break;
|
||||
case Xop_tkn_itm_.Tid_xnde:
|
||||
if (ws_tkn.Src_bgn() == ws_tkn.Src_end() // NOTE: para_wkr inserts <br/>. these should be disabled in Ignore_ws_rng; they are identified as having bgn == end; normal <br/>s will have bgn < end
|
||||
&& ((Xop_xnde_tkn)ws_tkn).Tag().Id() == Xop_xnde_tag_.Tid_br)
|
||||
ws_tkn.Ignore_y_grp_(ctx, root, cur);
|
||||
break;
|
||||
default:
|
||||
return cur;
|
||||
}
|
||||
cur += adj;
|
||||
}
|
||||
}
|
||||
public static int Handle_false_tblw_match(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int bgn_pos, int cur_pos, Xop_tkn_itm tkn, boolean add_nl) {
|
||||
if (add_nl)
|
||||
ctx.Para().Process_nl(ctx, root, src, bgn_pos, cur_pos);
|
||||
ctx.Subs_add(root, tkn);
|
||||
return cur_pos;
|
||||
}
|
||||
public static final int Atrs_null = -1, Atrs_empty = -2, Atrs_ignore_check = -1;
|
||||
public static final byte Tblw_type_tb = 0, Tblw_type_te = 1, Tblw_type_tr = 2, Tblw_type_td = 3, Tblw_type_th = 4, Tblw_type_tc = 5, Tblw_type_td2 = 6, Tblw_type_th2 = 7;
|
||||
}
|
||||
/*
|
||||
NOTE_1:
|
||||
Code tries to emulate HTML tidy behavior. Specifically:
|
||||
- ignore <table> when directly under <table>
|
||||
- if tblw, scan to end of line to ignore attributes
|
||||
- ignore any closing tblws
|
||||
EX:
|
||||
{|id=1
|
||||
{|id=2 <- ignore id=2
|
||||
|}
|
||||
|}
|
||||
*/
|
||||
1061
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_basic_tst.java
Normal file
1061
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_basic_tst.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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 org.junit.*;
|
||||
public class Xop_tblw_wkr_dangling_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 Dangling_tb_in_xnde() {// PURPOSE: dangling tblw incorrectly auto-closed by </xnde>; NOTE: this test is not correct; needs HTML tidy to close </div> earlier; EX:w:Atlanta_Olympics; DATE:2014-03-18
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<div align='center'>"
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "|}"
|
||||
, "</div>"
|
||||
, "b"
|
||||
)
|
||||
, String_.Concat_lines_nl
|
||||
( "<div align='center'>"
|
||||
, "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " <table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, ""
|
||||
, "<p>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, "</div>"
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -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.*;
|
||||
public class Xop_tblw_wkr_double_pipe_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 No_tblw() { // PURPOSE: if || has no tblw, treat as lnki; none; DATE:2014-05-06
|
||||
fxt.Test_parse_page_all_str("[[A||b|c]]", String_.Concat_lines_nl_skip_last
|
||||
( "<p><a href=\"/wiki/A\">b|c</a>" // NOTE: technically this should be "|b|c", but difficult to implement; DATE:2014-05-06
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Image_map() {// PURPOSE: if || is inside table and imagemap, treat as lnki; EX:w:United_States_presidential_election,_1992; DATE:2014-03-29; DATE:2014-05-06
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "| z"
|
||||
, "<imagemap>"
|
||||
, "File:A.png||123px|b" // NOTE: "||" should not be tblw; also should not be pipe + text; if it is pipe + text, then caption will be "|123px" and width will be -1; DATE:2014-05-06
|
||||
, "</imagemap>"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td> z"
|
||||
, "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" /></a>" // NOTE: width must be 123, not 0
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Tblw_lnki_nth() { // PURPOSE: if || is nth pipe, then treat as lnki; EX:en.w:Main_Page;de.w:Main_Page; DATE:2014-05-06
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|[[File:A.png|b||c]]"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td><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/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Tblw_lnki_list_1st() { // PURPOSE: if || is 1st pipe, but inside list, then treat as lnki; EX:w:Second_Boer_War; DATE:2014-05-05
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|"
|
||||
, "*[[A||b]]"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, ""
|
||||
, " <ul>"
|
||||
, " <li><a href=\"/wiki/A\">b</a>" // NOTE: technically this should be "|b", but difficult to implement; DATE:2014-05-06
|
||||
, " </li>"
|
||||
, " </ul>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Tblw_lnki_double_bang() { // PURPOSE: do not treat !! as tblw; PAGE:en.w:Pink_(singer); DATE:2014-06-25
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|"
|
||||
, "[[A!!b]]"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, ""
|
||||
, "<p><a href=\"/wiki/A!!b\">A!!b</a>"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
200
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_nested_tst.java
Normal file
200
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_nested_tst.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
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_tblw_wkr_nested_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "|}"
|
||||
, "|b"
|
||||
, "|}"
|
||||
)
|
||||
, fxt.tkn_tblw_tb_(0, 25).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 22).Subs_
|
||||
( fxt.tkn_tblw_td_(5, 19).Subs_
|
||||
( fxt.tkn_tblw_tb_(7, 19).Subs_
|
||||
( fxt.tkn_tblw_tr_(10, 16).Subs_
|
||||
( fxt.tkn_tblw_td_(13, 16).Subs_(fxt.tkn_txt_(15, 16), fxt.tkn_para_blank_(17))
|
||||
)
|
||||
)
|
||||
, fxt.tkn_para_blank_(20)
|
||||
)
|
||||
, fxt.tkn_tblw_td_(19, 22).Subs_(fxt.tkn_txt_(21, 22), fxt.tkn_para_blank_(23))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Leading_ws() {
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|id='a'"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "|-"
|
||||
, "|id='b'|"
|
||||
, " {|id='c'"
|
||||
, " |-"
|
||||
, " |d"
|
||||
, " |}"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table id='a'>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " <tr>"
|
||||
, " <td id='b'>"
|
||||
, " <table id='c'>"
|
||||
, " <tr>"
|
||||
, " <td>d"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Tblx_tblw() { // PURPOSE: if <table> followed by {|, ignore 2nd table; EX: en.b:Wikibooks:Featured_books; DATE:2014-02-08
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table cellpadding=\"0\">"
|
||||
, "{| cellspacing=\"0\""
|
||||
, "|a"
|
||||
, "|}"
|
||||
, "</table>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<table cellpadding=\"0\">"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Caption_and_tblw() { // TIDY: don't try to fix <caption><table> sequence; PAGE:es.w:Sevilla; DATE:2014-06-29
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|+"
|
||||
, "{|"
|
||||
, "|}"
|
||||
, "|}"), String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <caption>"
|
||||
, " <table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, " </caption>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Tb_tr_tb() { // PURPOSE: if <tr><table>, auto-create <tr><td>; EX:w:Paris; DATE:2014-03-18
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "{|"
|
||||
, "|}"
|
||||
, "|}"), String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Tblw_tblx_tblw_fails() { // PURPOSE: {| -> <table> -> \n| was not rendering as <td>; EX:en.w:Paris#Demographics; DATE:2014-03-18
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "</td></tr>"
|
||||
, "<tr><td><table>"
|
||||
, "<tr><td>b</td>"
|
||||
, "</tr>"
|
||||
, "|c"
|
||||
, "</td></tr></table>"
|
||||
, "|}"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " <table>"
|
||||
, " <tr>"
|
||||
, " <td>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " <tr>"
|
||||
, " <td>c"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
// @Test public void Nested_tbl_missing() { // PURPOSE: nested table not rendering properly; EX:ar.s:; DATE:2014-03-18
|
||||
// fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
// ( "{|"
|
||||
// , "|-"
|
||||
// , "{|"
|
||||
// , "|-"
|
||||
// , "|}"
|
||||
// , "| width='50%' | a"
|
||||
// , "|}"
|
||||
// ), String_.Concat_lines_nl_skip_last
|
||||
// ( "<table>"
|
||||
// , " <tr>"
|
||||
// , " <td>a"
|
||||
// , " </td>"
|
||||
// , " <td>[[b|c"
|
||||
// , " </td>"
|
||||
// , " </tr>"
|
||||
// , "</table>"
|
||||
// , ""
|
||||
// , "<p>d"
|
||||
// , "</p>"
|
||||
// ));
|
||||
// }
|
||||
}
|
||||
156
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_para_tst.java
Normal file
156
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_para_tst.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
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_tblw_wkr_para_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 Para() { // PURPOSE: para causing strange breaks; SEE:[[John F. Kennedy]] and "two Supreme Court appointments"
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "<p></p>"
|
||||
, "|a"
|
||||
, "<p></p>"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table><p></p>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, "<p></p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Nl() { // PURPOSE: para causing strange breaks; SEE:[[John F. Kennedy]] and "two Supreme Court appointments"
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "!a"
|
||||
, ""
|
||||
, "|-"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <th>a"
|
||||
, " </th>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Unnecessary_para() { // PURPOSE: tblw causes unnecessary <p>; [[Help:Download]]; DATE:2014-02-20
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, "a<br/>"
|
||||
, "b"
|
||||
, "|"
|
||||
, "c<br/>"
|
||||
, "d"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, ""
|
||||
, "<p>a<br/>"
|
||||
, "b"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " <td>"
|
||||
, ""
|
||||
, "<p>c<br/>"
|
||||
, "d"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Ws_leading() { // EX.WP: AGPLv3
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, " !a"
|
||||
, " !b"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <th>a"
|
||||
, " </th>"
|
||||
, " <th>b"
|
||||
, " </th>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Ws_th_2() { // "\n\s!" should still be interpreted as tblw; s.w:Manchester; DATE:2014-02-14
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|!style='color:red'|a"
|
||||
, " !style=\"color:blue\"|b"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " <th style=\"color:blue\">b"
|
||||
, " </th>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Ws_th_3() { // "\n\s!" and "!!" breaks tblw; ru.w:Храмы_Санкт-Петербурга (List of churches in St Petersburg); DATE:2014-02-20
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, " ! id='1' | a !! id='2' | b"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <th id='1'> a "
|
||||
, " </th>"
|
||||
, " <th id='2'> b"
|
||||
, " </th>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Tblw_td2_should_not_create_ws() { // PURPOSE: a||b -> a\n||b; EX:none;discovered during luaj test; DATE:2014-04-14
|
||||
fxt.Test_parse_page_wiki_str("a||b", "<p>a||b\n</p>");
|
||||
}
|
||||
}
|
||||
71
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_tblx_tst.java
Normal file
71
400_xowa/src_480_tblw/gplx/xowa/Xop_tblw_wkr_tblx_tst.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Xop_tblw_wkr_tblx_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 Ignore_td() { // PURPOSE: do not parse pipe as td if in <table>; EX:ru.w:Сочи; DATE:2014-02-22
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, "| b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, "| b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Ignore_tr() { // PURPOSE: do not parse "\n|-", "\n!" if in <table>; EX:s.w:Uranus; DATE:2014-05-05
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, "|-"
|
||||
, "! b"
|
||||
, "| c"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, ""
|
||||
, "<p>|-"
|
||||
, "! b"
|
||||
, "| c"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa; import gplx.*;
|
||||
import org.junit.*;
|
||||
public class Xop_tblw_wkr_uncommon_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 Tr_pops_entire_stack() { // PURPOSE: in strange cases, tr will pop entire stack; EX:en.w:Turks_in_Denmark; DATE:2014-03-02
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "<caption>a"
|
||||
, "|b"
|
||||
, "|-"
|
||||
, "|c"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <caption>a"
|
||||
, " </caption>"
|
||||
, " <tr>"
|
||||
, " <td>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " <tr>"
|
||||
, " <td>c"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Atrs_defect() { // PURPOSE: < in atrs was causing premature termination; EX:en.w:Wikipedia:List of hoaxes on Wikipedia
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|id=\"a<b\""
|
||||
, "|a"
|
||||
, "|}"), String_.Concat_lines_nl_skip_last
|
||||
( "<table id=\"a.3Cb\">"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Broken_lnki() { // PURPOSE: broken lnki was not closing table properly; EX:en.w:Wikipedia:Changing_attribution_for_an_edit; DATE:2014-03-16
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "|[[b|c"
|
||||
, "|}"
|
||||
, "d"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " <td>[[b|c"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
, "<p>d"
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user