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:
135
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr.java
Normal file
135
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
import gplx.core.btries.*; import gplx.xowa.parsers.paras.*;
|
||||
public 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, Xop_tkn_itm_.Tid_tblw_td); // 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.Nl) // 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);
|
||||
}
|
||||
}
|
||||
if (wlxr_type == Xop_tblw_wkr.Tblw_type_th2) { // !!; extra check to make sure \n! exists; DATE:2014-10-19
|
||||
int prv_th_pos = Bry_finder.Find_bwd(src, Byte_ascii.Nl, bgn_pos); // search for previous \n
|
||||
boolean invalid = prv_th_pos == Bry_finder.Not_found; // no \n; invalid
|
||||
if (!invalid) {
|
||||
++prv_th_pos; // skip \n
|
||||
prv_th_pos = Bry_finder.Find_fwd_while_space_or_tab(src, prv_th_pos, src_len); // skip \s; needed for "\n\s!" which is still a tblw
|
||||
if (prv_th_pos == bgn_pos) // invalid: "\n" is directly in front of "!!"
|
||||
invalid = true;
|
||||
else
|
||||
invalid = src[prv_th_pos] != Byte_ascii.Bang; // invalid if not "\n!"
|
||||
}
|
||||
if (invalid)
|
||||
return Xop_tblw_wkr.Handle_false_tblw_match(ctx, root, src, bgn_pos, cur_pos, tkn_mkr.Txt(bgn_pos, cur_pos), false);
|
||||
}
|
||||
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_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(Xowe_wiki wiki, Btrie_fast_mgr 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, Btrie_fast_mgr core_trie) {}
|
||||
public static final byte[] Hook_tb = Bry_.new_a7("\n{|"), Hook_te = Bry_.new_a7("\n|}"), Hook_tr = Bry_.new_a7("\n|-")
|
||||
, Hook_td = Bry_.new_a7("\n|"), Hook_th = Bry_.new_a7("\n!"), Hook_tc = Bry_.new_a7("\n|+")
|
||||
, Hook_td2 = Bry_.new_a7("||"), Hook_th2 = Bry_.new_a7("!!");
|
||||
}
|
||||
66
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr_ws.java
Normal file
66
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_lxr_ws.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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_a7("{|"), Hook_te = Bry_.new_a7("|}"), Hook_tr = Bry_.new_a7("|-")
|
||||
, Hook_th = Bry_.new_a7("!"), Hook_tc = Bry_.new_a7("|+");
|
||||
public static final int Tblw_ws_cell_pipe = -1;
|
||||
}
|
||||
37
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_tb_tkn.java
Normal file
37
400_xowa/src/gplx/xowa/parsers/tblws/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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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/gplx/xowa/parsers/tblws/Xop_tblw_tc_tkn.java
Normal file
30
400_xowa/src/gplx/xowa/parsers/tblws/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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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/gplx/xowa/parsers/tblws/Xop_tblw_td_tkn.java
Normal file
30
400_xowa/src/gplx/xowa/parsers/tblws/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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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/gplx/xowa/parsers/tblws/Xop_tblw_th_tkn.java
Normal file
30
400_xowa/src/gplx/xowa/parsers/tblws/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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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/gplx/xowa/parsers/tblws/Xop_tblw_tkn.java
Normal file
27
400_xowa/src/gplx/xowa/parsers/tblws/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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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/gplx/xowa/parsers/tblws/Xop_tblw_tr_tkn.java
Normal file
34
400_xowa/src/gplx/xowa/parsers/tblws/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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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;}
|
||||
}
|
||||
551
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr.java
Normal file
551
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr.java
Normal file
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.paras.*;
|
||||
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 Exc_.new_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, Bool_.N);
|
||||
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.Nl); // 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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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; PAGE:en.w:Turks_in_Denmark DATE:2014-03-02
|
||||
ctx.Stack_pop_til(root, src, stack_pos, true, bgn_pos, bgn_pos, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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_auto_close(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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td); // 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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, Xop_tkn_itm_.Tid_tblw_td); // 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, Xop_tkn_itm_.Tid_tblw_td);
|
||||
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, boolean called_from_xnde) {
|
||||
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, called_from_xnde);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public static boolean Atrs_make(Xop_ctx ctx, byte[] src, Xop_root_tkn root, Xop_tblw_wkr wkr, Xop_tblw_tkn prv_tblw, boolean called_from_xnde) {
|
||||
if (prv_tblw.Atrs_bgn() != Xop_tblw_wkr.Atrs_null) { // atr_bgn/end is empty or already has explicit value; ignore;
|
||||
if (prv_tblw.Atrs_bgn() == Atrs_invalid_by_xnde) { // atr range marked invalid; ignore all tkns between prv_tblw and end of root; EX:"|-id=1<br/>"; PAGE:en.w:A DATE:2014-07-16
|
||||
for (int j = root.Subs_len() - 1; j > -1; --j) {
|
||||
Xop_tkn_itm sub = root.Subs_get(j);
|
||||
if (sub == prv_tblw)
|
||||
return false;
|
||||
else
|
||||
sub.Ignore_y_();
|
||||
}
|
||||
ctx.App().Usr_dlg().Warn_many("", "", "xnde.invalided attributes could not find previous tkn; page=~{0}", ctx.Page_url_str()); // should never happen; DATE:2014-07-16
|
||||
}
|
||||
return false;
|
||||
}
|
||||
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
|
||||
int atr_rng_tid
|
||||
= called_from_xnde
|
||||
&& !prv_tblw.Tblw_xml()
|
||||
&& prv_tblw.Tkn_tid() == Xop_tkn_itm_.Tid_tblw_tr // called from xnde && current tid is Tblw_tr; EX:"|- <br/>" PAGE:en.w:A DATE:2014-07-16
|
||||
? Atrs_invalid_by_xnde // invalidate everything
|
||||
: Atrs_empty
|
||||
;
|
||||
prv_tblw.Atrs_rng_set(atr_rng_tid, atr_rng_tid);
|
||||
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_invalid_by_xnde = -3, 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
|
||||
|}
|
||||
|}
|
||||
*/
|
||||
212
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr__atrs_tst.java
Normal file
212
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_wkr__atrs_tst.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
import org.junit.*;
|
||||
public class Xop_tblw_wkr__atrs_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Tr() {
|
||||
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-style='a'"
|
||||
, "|b"
|
||||
, "|}"
|
||||
), fxt.tkn_tblw_tb_(0, 20).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 17).Atrs_rng_(5, 14).Subs_
|
||||
( fxt.tkn_tblw_td_(14, 17).Subs_(fxt.tkn_txt_(16, 17), fxt.tkn_para_blank_(18))
|
||||
))
|
||||
);
|
||||
}
|
||||
@Test public void Td() {
|
||||
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|style='a'|b"
|
||||
, "|}"
|
||||
), fxt.tkn_tblw_tb_(0, 21).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 18).Subs_
|
||||
( fxt.tkn_tblw_td_(5, 18).Atrs_rng_(7, 16).Subs_(fxt.tkn_txt_(17, 18), fxt.tkn_para_blank_(19))
|
||||
))
|
||||
);
|
||||
}
|
||||
@Test public void Td_mult() {
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, " {|"
|
||||
, " |-"
|
||||
, " | id='1'|"
|
||||
, " | id='2'|a"
|
||||
, " | id='3'|"
|
||||
, " |}"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " <table>"
|
||||
, " <tr>"
|
||||
, " <td id='1'>"
|
||||
, " </td>"
|
||||
, " <td id='2'>a"
|
||||
, " </td>"
|
||||
, " <td id='3'>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Tc() { // PAGE:en.w:1920_Palm_Sunday_tornado_outbreak
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|id='1'"
|
||||
, "|+id='2'|a"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table id='1'>"
|
||||
, " <caption id='2'>a"
|
||||
, " </caption>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Td_mixed() {
|
||||
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|style='a'|b||c"
|
||||
, "|}"
|
||||
), fxt.tkn_tblw_tb_(0, 24).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 21).Subs_
|
||||
( fxt.tkn_tblw_td_( 5, 18).Atrs_rng_(7, 16).Subs_(fxt.tkn_txt_(17, 18), fxt.tkn_para_blank_(19))
|
||||
, fxt.tkn_tblw_td_(18, 21).Subs_(fxt.tkn_txt_(20, 21), fxt.tkn_para_blank_(22))
|
||||
))
|
||||
);
|
||||
}
|
||||
@Test public void Th() {
|
||||
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "!style='a'|b"
|
||||
, "|}"
|
||||
), fxt.tkn_tblw_tb_(0, 21).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 18).Subs_
|
||||
( fxt.tkn_tblw_th_(5, 18).Atrs_rng_(7, 16).Subs_(fxt.tkn_txt_(17, 18), fxt.tkn_para_blank_(19))
|
||||
))
|
||||
);
|
||||
}
|
||||
@Test public void Skip_hdr() {
|
||||
fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|+b"
|
||||
, "!style='a'|b"
|
||||
, "|}"
|
||||
), fxt.tkn_tblw_tb_(0, 22).Caption_count_(1).Subs_
|
||||
( fxt.tkn_tblw_tc_(2, 6).Subs_(fxt.tkn_txt_( 5, 6))
|
||||
, fxt.tkn_tblw_tr_(6, 19).Subs_
|
||||
( fxt.tkn_tblw_th_(6, 19).Atrs_rng_(8, 17).Subs_(fxt.tkn_txt_(18, 19), fxt.tkn_para_blank_(20))
|
||||
)
|
||||
));
|
||||
}
|
||||
@Test public void Td_bg_color() { // PURPOSE: atr_parser should treat # as valid character in unquoted val; PAGE:en.w:UTF8; |bgcolor=#eeeeee|<small>Indic</small><br/><small>0800*</small><br/>'''''224'''''
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|bgcolor=#eeeeee|a"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td bgcolor=\"#eeeeee\">a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Xnde_tb() { // PURPOSE: xnde should close any open xatrs; PAGE:en.w:Western_Front_(World_War_I); stray > after == Dramatizations ==
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|id='1'<p></p>"
|
||||
, "|a"
|
||||
, "|}"), String_.Concat_lines_nl_skip_last
|
||||
( "<table id='1'><p></p>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Xnde_tr() { // PURPOSE: xnde should disable all tkns; PAGE:en.w:A DATE:2014-07-16
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-<b>c</b>id='d'<br/>" // note that id='d' should not show up since <b> invalidates entire line
|
||||
, "|a"
|
||||
, "|}"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Xnde_mix_tblw_tblx() { // PURPOSE: issue with </tr> somehow rolling up everything after <td>; PAGE:en.w:20th_century; {{Decades and years}}
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table><tr><td>a"
|
||||
, "{|id=1"
|
||||
, "|-"
|
||||
, "|b"
|
||||
, "|}</td></tr></table>"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " <table id=\"1\">"
|
||||
, " <tr>"
|
||||
, " <td>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,823 @@
|
||||
/*
|
||||
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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
import org.junit.*;
|
||||
public class Xop_tblw_wkr__basic_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Td() { // Tb_tr_td_te
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n|a\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 11).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 8).Subs_
|
||||
( fxt.tkn_tblw_td_(5, 8).Subs_(fxt.tkn_txt_(7, 8), fxt.tkn_para_blank_(9))))
|
||||
);
|
||||
}
|
||||
@Test public void Td2() { // Tb_tr_td_td2_te
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n|a||b\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 14).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 11).Subs_
|
||||
( fxt.tkn_tblw_td_(5, 8).Subs_(fxt.tkn_txt_( 7, 8), fxt.tkn_para_blank_(9))
|
||||
, fxt.tkn_tblw_td_(8, 11).Subs_(fxt.tkn_txt_(10, 11), fxt.tkn_para_blank_(12))
|
||||
)));
|
||||
}
|
||||
@Test public void Tc() { // Tb_tc_te
|
||||
fxt.Test_parse_page_wiki("{|\n|+a\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 9).Caption_count_(1).Subs_
|
||||
( fxt.tkn_tblw_tc_(2, 6).Subs_
|
||||
( fxt.tkn_txt_(5, 6)
|
||||
, fxt.tkn_para_blank_(7)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Tc_longer() { // Tb_tc_tr_td_te
|
||||
fxt.Test_parse_page_wiki("{|\n|+a\n|-\n|b\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 15).Caption_count_(1).Subs_
|
||||
( fxt.tkn_tblw_tc_(2, 6).Subs_(fxt.tkn_txt_(5, 6))
|
||||
, fxt.tkn_tblw_tr_(6, 12).Subs_
|
||||
( fxt.tkn_tblw_td_(9, 12).Subs_(fxt.tkn_txt_(11, 12), fxt.tkn_para_blank_(13))
|
||||
)
|
||||
));
|
||||
}
|
||||
@Test public void Th() { // Tb_th_te
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n!a\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 11).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 8).Subs_
|
||||
( fxt.tkn_tblw_th_(5, 8).Subs_(fxt.tkn_txt_(7, 8), fxt.tkn_para_blank_(9))
|
||||
)));
|
||||
}
|
||||
@Test public void Th2() { // Tb_th_th2_te
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n!a!!b\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 14).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 11).Subs_
|
||||
( fxt.tkn_tblw_th_(5, 8).Subs_(fxt.tkn_txt_( 7, 8))
|
||||
, fxt.tkn_tblw_th_(8, 11).Subs_(fxt.tkn_txt_(10, 11), fxt.tkn_para_blank_(12))
|
||||
)));
|
||||
}
|
||||
@Test public void Th2_td_syntax() { // Tb_th_td; || should be treated as th
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n!a||b\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 14).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 11).Subs_
|
||||
( fxt.tkn_tblw_th_(5, 8).Subs_(fxt.tkn_txt_( 7, 8))
|
||||
, fxt.tkn_tblw_th_(8, 11).Subs_(fxt.tkn_txt_(10, 11), fxt.tkn_para_blank_(12))
|
||||
)));
|
||||
}
|
||||
@Test public void Tb_td2() { // PAGE:en.w:Hectare; {| class="wikitable" || style="border: 1px solid #FFFFFF;"
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|id='1' || class='a'"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "|}")
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table id='1' class='a'>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Td_lnki() {
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n|[[a|b]]\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 17).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 14).Subs_
|
||||
( fxt.tkn_tblw_td_(5, 14).Subs_(fxt.tkn_lnki_(7, 14), fxt.tkn_para_blank_(15))))
|
||||
);
|
||||
}
|
||||
@Test public void Tr_dupe_xnde() { // PURPOSE: redundant tr should not be dropped; see [[Jupiter]]
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "<tr><td>a</td></tr>"
|
||||
, "|-"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Tr_dupe_xnde_2() { // <td></th> causes problems
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "<tr><th>a</td></tr>"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <th>a"
|
||||
, " </th>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Bang_should_not_make_cell_td_1_bang() { // PURPOSE: "| a! b" ! should not separate cell
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last("{|", "|-", "|a!b", "|}"), String_.Concat_lines_nl_skip_last("<table>", " <tr>", " <td>a!b" , " </td>", " </tr>", "</table>", ""));
|
||||
}
|
||||
@Test public void Bang_should_not_make_cell_td_2_bang() {
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last("{|", "|-", "|a!!b", "|}"), String_.Concat_lines_nl_skip_last("<table>", " <tr>", " <td>a!!b" , " </td>", " </tr>", "</table>", ""));
|
||||
}
|
||||
@Test public void Bang_should_not_make_cell_th_1_bang() {
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last("{|", "|-", "!a!b", "|}"), String_.Concat_lines_nl_skip_last("<table>", " <tr>", " <th>a!b" , " </th>", " </tr>", "</table>", ""));
|
||||
}
|
||||
@Test public void Bang_should_not_make_cell_th_2_bang() {
|
||||
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 Bang_should_not_make_cell_th_mult_line() { // FIX: make sure code does not disable subsequent bangs
|
||||
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 Fix_extra_cell() { // PURPOSE: trim should not affect td; WP:Base32
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "!id='1'|a"
|
||||
, "|"
|
||||
, "!id='2'|b"
|
||||
, "|-"
|
||||
, "|a1|| ||b1"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <th id='1'>a"
|
||||
, " </th>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " <th id='2'>b"
|
||||
, " </th>"
|
||||
, " </tr>"
|
||||
, " <tr>"
|
||||
, " <td>a1"
|
||||
, " </td>"
|
||||
, " <td> "
|
||||
, " </td>"
|
||||
, " <td>b1"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Nl_td() { // PURPOSE: <p> inside <td> does not get enclosed
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, "<tr>"
|
||||
, "<td>"
|
||||
, ""
|
||||
, ""
|
||||
, "a"
|
||||
, ""
|
||||
, ""
|
||||
, "</td>"
|
||||
, "</tr>"
|
||||
, "</table>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, ""
|
||||
, "<p><br/>"
|
||||
, "a"
|
||||
, "</p>"
|
||||
, ""
|
||||
, "<p><br/>"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Trim_ws() { // PURPOSE: trim should be done from both sides
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, "<tr>"
|
||||
, "<td>"
|
||||
, "</td>"
|
||||
, "</tr>"
|
||||
, ""
|
||||
, ""
|
||||
, "a"
|
||||
, ""
|
||||
, ""
|
||||
, "</table>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "a"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Trim_ws_tr() { // PURPOSE: trim should be done from both sides
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, "<tr>"
|
||||
, "<td>"
|
||||
, "</td>"
|
||||
, "</tr>"
|
||||
, ""
|
||||
, ""
|
||||
, ""
|
||||
, ""
|
||||
, "<tr>"
|
||||
, "<td>"
|
||||
, "</td>"
|
||||
, "</tr>"
|
||||
, "</table>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Trim_ws_td() { // PURPOSE: trim should not affect td
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, "<tr>"
|
||||
, "<td>"
|
||||
, ""
|
||||
, ""
|
||||
, "a"
|
||||
, ""
|
||||
, ""
|
||||
, "</td>"
|
||||
, "</tr>"
|
||||
, "</table>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, ""
|
||||
, "<p><br/>"
|
||||
, "a"
|
||||
, "</p>"
|
||||
, ""
|
||||
, "<p><br/>"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void No_wiki_3() {
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|style=<nowiki>'a[b]c'</nowiki>|d"
|
||||
, "|}"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td style='a[b]c'>d"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Trailing_tr_breaks_para_mode() {// PURPOSE.fix: empty trailing tr breaks para mode; EX:w:Sibelius
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|a"
|
||||
, "|-" // causes lines below not to be put in paras
|
||||
, "|}"
|
||||
, "b"
|
||||
, ""
|
||||
, "c"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
, "<p>b"
|
||||
, "</p>"
|
||||
, ""
|
||||
, "<p>c"
|
||||
, "</p>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Blank_line_should_be_own_para() {// PURPOSE.fix: caption does not begin on own line; EX:w:Old St. Peter's Basilica
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|a"
|
||||
, "b"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, ""
|
||||
, "<p>b"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Blank_line_should_be_own_para_2() {// PURPOSE.fix: caption does not begin on own line; EX:w:Old St. Peter's Basilica
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|a"
|
||||
, "b"
|
||||
, "|-"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, ""
|
||||
, "<p>b"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Bold_stops_at_table() { // PURPOSE: do not allow unclosed bold to extend over tables;
|
||||
fxt.Test_parse_page_all_str("'''<table><tr><td>a</td></tr></table>", String_.Concat_lines_nl_skip_last
|
||||
( "<b></b>"
|
||||
, "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_defn_clear();
|
||||
}
|
||||
@Test public void Orphaned_tr_breaks_nested_tables() { // PUPRPOSE: </tr> should not match <tr> outside scope; EX:w:Enthalpy_of_fusion; {{States of matter}}
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, "<tr>"
|
||||
, "<td>"
|
||||
, "<table>"
|
||||
, "</tr>"
|
||||
, "</table>"
|
||||
, "</td>"
|
||||
, "<td>a"
|
||||
, "</td>"
|
||||
, "</tr>"
|
||||
, "</table>"
|
||||
),
|
||||
String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " <table>"
|
||||
, " </table>"
|
||||
, " </td>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Space_causes_extra_p() {// PURPOSE: "\n\s</td>" should be equivalent to "\n</td>"; EX: w:Earth
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<table><tr><td>"
|
||||
, "b"
|
||||
, "<br/>c"
|
||||
, " </td></tr></table>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, ""
|
||||
, "<p>b" // used to close <p> here; <p>b</p>
|
||||
, "<br/>c"
|
||||
, "</p>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void Br_should_not_be_ignored() {// PURPOSE: document <br />'s should not be ignored between tables; 20121226
|
||||
fxt.Init_para_y_();
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "|}"
|
||||
, "<br />"
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "|b"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, "<br />" // was being ignored
|
||||
, "<table>"
|
||||
, " <tr>"
|
||||
, " <td>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
fxt.Init_para_n_();
|
||||
}
|
||||
@Test public void AutoClose_td_when_new_tr() { // retain; needed for de.w:Main_Page; DATE:2013-12-09
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "==a=="
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, ""
|
||||
, "<h2>a</h2>" // NOTE: malformed html matches MW
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
fxt.Test_parse_page_wiki("{|\n==b==\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 8).Subs_
|
||||
( fxt.tkn_hdr_(2, 8, 2).Subs_
|
||||
( fxt.tkn_txt_(5, 6)
|
||||
)
|
||||
, fxt.tkn_para_blank_(9)
|
||||
, fxt.tkn_tblw_tr_(8, 8).Subs_
|
||||
( fxt.tkn_tblw_td_( 8, 8))
|
||||
));
|
||||
}
|
||||
@Test public void Auto_create_table() {// PURPOSE: <td> should create table; EX:w:Hatfield-McCoy_feud; DATE:20121226
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<td>a"
|
||||
, "</td>"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void List_and_orphaned_td2_should_not_create_tblw() {// PURPOSE: !! was creating table; DATE:2013-04-28
|
||||
fxt.Test_parse_page_all_str("*a !! b", String_.Concat_lines_nl_skip_last
|
||||
( "<ul>"
|
||||
, " <li>a !! b"
|
||||
, " </li>"
|
||||
, "</ul>"
|
||||
));
|
||||
}
|
||||
@Test public void Tr_trailing_dashes_should_be_stripped() {// PURPOSE: trailing dashes should be stripped; |--- -> |-; EX: |--style="x" was being ignored; DATE:2013-06-21
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-----style='a'"
|
||||
, "|b"
|
||||
, "|}"
|
||||
), String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr style='a'>"
|
||||
, " <td>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Th_without_tr() { // PURPOSE: !! without preceding ! should not create table-cell; DATE:2013-12-18
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, "a!!b"
|
||||
, "|}"
|
||||
), String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, "a!!b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Td_at_eos() {// PURPOSE.fix: !! at eos fails; EX:es.s:Si_mis_manos_pudieran_deshojar; DATE:2014-02-11
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "| <poem>!!</poem>" // note that "!!" is eos inside the <poem> src
|
||||
, "|}"
|
||||
), String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td> <div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "!!"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Tr_without_tb_should_start_tb() {// PURPOSE: orphaned tr should automatically start table; EX: pl.w:Portal:Technika; DATE:2014-02-13
|
||||
fxt.Test_parse_page_all_str("<tr><td>a"
|
||||
, String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Tblx_should_not_close_tblw() {// PURPOSE: </table> should not close {|; EX:fr.w:Exp%C3%A9dition_Endurance; DATE:2014-02-13
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, "</table>"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Tblx_should_not_close_tblw_2() {// PURPOSE: </table> should close {|; ignore latter |}; EX:ru.q:Авель; DATE:2014-02-22
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|a"
|
||||
, "</table>"
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "|b"
|
||||
, "</table>"
|
||||
, "{|"
|
||||
, "|-"
|
||||
, "|c"
|
||||
, "</table>"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>a"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, "<table>"
|
||||
, " <tr>"
|
||||
, " <td>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, "<table>"
|
||||
, " <tr>"
|
||||
, " <td>c"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void Td_in_list_in_tblw_should_be_ignored() {// PURPOSE: || should be ignored if in list; EX:es.d:casa; DATE:2014-02-15
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, "* a || b"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " <ul>"
|
||||
, " <li> a || b"
|
||||
, " </li>"
|
||||
, " </ul>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
@Test public void List_in_tblw() {// PURPOSE: list should close previous cell; EX: ru.d:Викисловарь:Условные_сокращения; DATE:2014-02-22
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|"
|
||||
, "{|"
|
||||
, "*a"
|
||||
, "|}"
|
||||
, "|}"
|
||||
)
|
||||
, String_.Concat_lines_nl
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " <table>"
|
||||
, " <ul>" // NOTE: this should probably be inside <tr>, but this matches MW behavior; DATE:2014-02-22
|
||||
, " <li>a"
|
||||
, " </li>"
|
||||
, " </ul>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " </table>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
}
|
||||
// @Test public void Tb_under_tr_is_ignored() { // PURPOSE: table directly under tr is ignored; PAGE:en.w:Category:Dessert stubs; TODO: complicated, especially to handle 2nd |}
|
||||
// fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
// ( "{|"
|
||||
// , "|-id='a'"
|
||||
// , "{|style='border:1px;'"
|
||||
// , "|-id='b'"
|
||||
// , "|b"
|
||||
// , "|}"
|
||||
// , "|}"
|
||||
// ), String_.Concat_lines_nl_skip_last
|
||||
// ( "<table>"
|
||||
// , " <tr id=\"b\">"
|
||||
// , " <td>b"
|
||||
// , " </td>"
|
||||
// , " </tr>"
|
||||
// , "</table>"
|
||||
// , ""
|
||||
// ));
|
||||
// }
|
||||
// @Test public void Leading_ws() { // PAGE:en.w:Corneal dystrophy (human)
|
||||
// fxt.Test_parse_page_wiki(String_.Concat_lines_nl_skip_last
|
||||
// ( " {|"
|
||||
// , " |-"
|
||||
// , " |a"
|
||||
// , " |}"
|
||||
// )
|
||||
// , fxt.tkn_tblw_tb_(1, 15).Subs_
|
||||
// ( fxt.tkn_tblw_tr_(3, 11).Subs_
|
||||
// ( fxt.tkn_tblw_td_(7, 11).Subs_
|
||||
// ( fxt.tkn_txt_())
|
||||
// )
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
// @Test public void Atrs_tb() { // Tb_te // FUTURE: reinstate; WHEN: Template
|
||||
// fxt.Init_log_(Xop_tblw_log.Tbl_empty).Test_parse_page_wiki("{|style='a'\n|}"
|
||||
// , fxt.tkn_tblw_tb_(0, 14).Atrs_rng_(2, 11).Subs_
|
||||
// ( fxt.tkn_tblw_tr_(11, 11).Subs_
|
||||
// ( fxt.tkn_tblw_td_(11, 11)
|
||||
// )));
|
||||
// }
|
||||
// @Test public void Td_p() { // PURPOSE: <p> not being closed correctly
|
||||
// fxt.Init_para_y_();
|
||||
// fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
// ( "{|"
|
||||
// , "|-"
|
||||
// , "|"
|
||||
// , "a"
|
||||
// , "|}"), String_.Concat_lines_nl_skip_last
|
||||
// ( "<table>"
|
||||
// , " <tr>"
|
||||
// , " <td>"
|
||||
// , ""
|
||||
// , "<p>a"
|
||||
// , "</p>"
|
||||
// , " </td>"
|
||||
// , " </tr>"
|
||||
// , "</table>"
|
||||
// , ""
|
||||
// ));
|
||||
// fxt.Init_para_n_();
|
||||
// }
|
||||
// @Test public void Tb_tb() {
|
||||
// fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
// ( "{|id='1'"
|
||||
// , "{|id='2'"
|
||||
// , "|-id='3'"
|
||||
// , "|a"
|
||||
// , "|}"
|
||||
// , "|}"), String_.Concat_lines_nl_skip_last
|
||||
// ( "<table id='1'>"
|
||||
// , " <tr id='3'>"
|
||||
// , " <td>a"
|
||||
// , " </td>"
|
||||
// , " </tr>"
|
||||
// , "</table>"
|
||||
// , ""
|
||||
// ));
|
||||
// }
|
||||
// @Test public void Tb_tb_2() {
|
||||
// fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
// ( "{|id='1'"
|
||||
// , "{|id='2' <table id='3'>"
|
||||
// , "|a"
|
||||
// , "</table>"
|
||||
// , "|}"
|
||||
// , "|}"), String_.Concat_lines_nl_skip_last
|
||||
// ( "<table id='1'>"
|
||||
// , " <tr id='3'>"
|
||||
// , " <td>a"
|
||||
// , " </td>"
|
||||
// , " </tr>"
|
||||
// , "</table>"
|
||||
// , ""
|
||||
// ));
|
||||
// }
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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>; PAGE:en.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>"
|
||||
, "</div>" // TIDY.dangling: tidy will correct dangling node; DATE:2014-07-22
|
||||
, ""
|
||||
, "<p>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, "</div>"
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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 Lnki_nth() { // PURPOSE: if || is nth pipe, then treat as lnki; PAGE: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 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 Double_bang_lnki() { // 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>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Double_bang_list() { // PURPOSE: do not treat !! as tblw; PAGE:en.w:Wikipedia:Featured_picture_candidates; DATE:2014-10-19
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "* a !! b"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <ul>"
|
||||
, " <li> a !! b"
|
||||
, " </li>"
|
||||
, " </ul>"
|
||||
, " <tr>"
|
||||
, " <td>"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, "</p>" // NOTE: </p> is incorrect, but benign
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
import org.junit.*;
|
||||
public class Xop_tblw_wkr__errs_tst {
|
||||
private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Err_row_empty() {
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n|-\n|a\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 14).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 5)
|
||||
, fxt.tkn_tblw_tr_(5, 11).Subs_
|
||||
( fxt.tkn_tblw_td_(8, 11).Subs_(fxt.tkn_txt_(10, 11), fxt.tkn_para_blank_(12))
|
||||
))
|
||||
);
|
||||
}
|
||||
@Test public void Err_row_trailing() {
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n|a\n|-\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 14).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 8).Subs_
|
||||
( fxt.tkn_tblw_td_(5, 8).Subs_(fxt.tkn_txt_(7, 8), fxt.tkn_para_blank_(9))
|
||||
))
|
||||
);
|
||||
}
|
||||
@Test public void Err_caption_after_tr() {
|
||||
fxt.Test_parse_page_wiki("{|\n|-\n|+a\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 12).Caption_count_(1).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 5)
|
||||
, fxt.tkn_tblw_tc_(5, 9).Subs_(fxt.tkn_txt_(8, 9), fxt.tkn_para_blank_(10)))
|
||||
);
|
||||
}
|
||||
@Test public void Err_caption_after_td() {
|
||||
fxt.Init_log_(Xop_tblw_log.Caption_after_td).Test_parse_page_wiki("{|\n|-\n|a\n|+b\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 15).Caption_count_(1).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 8).Subs_
|
||||
( fxt.tkn_tblw_td_(5, 8).Subs_(fxt.tkn_txt_(7, 8)))
|
||||
, fxt.tkn_tblw_tc_(8, 12).Subs_(fxt.tkn_txt_(11, 12), fxt.tkn_para_blank_(13)))
|
||||
);
|
||||
}
|
||||
@Test public void Err_caption_after_tc() {
|
||||
fxt.Init_log_(Xop_tblw_log.Caption_after_tc).Test_parse_page_wiki("{|\n|+a\n|+b\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 13).Caption_count_(2).Subs_
|
||||
( fxt.tkn_tblw_tc_(2, 6).Subs_(fxt.tkn_txt_( 5, 6))
|
||||
, fxt.tkn_tblw_tc_(6, 10).Subs_(fxt.tkn_txt_( 9, 10), fxt.tkn_para_blank_(11)))
|
||||
);
|
||||
}
|
||||
@Test public void Err_row_auto_opened() {
|
||||
fxt.Test_parse_page_wiki("{|\n|a\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 8).Subs_
|
||||
( fxt.tkn_tblw_tr_(2, 5).Subs_
|
||||
( fxt.tkn_tblw_td_(2, 5).Subs_(fxt.tkn_txt_(4, 5), fxt.tkn_para_blank_(6))
|
||||
)));
|
||||
}
|
||||
@Test public void Err_caption_auto_closed() {
|
||||
fxt.Test_parse_page_wiki("{|\n|+a\n|b\n|}"
|
||||
, fxt.tkn_tblw_tb_(0, 12).Caption_count_(1).Subs_
|
||||
( fxt.tkn_tblw_tc_(2, 6).Subs_(fxt.tkn_txt_(5, 6))
|
||||
, fxt.tkn_tblw_tr_(6, 9).Subs_
|
||||
( fxt.tkn_tblw_td_(6, 9).Subs_(fxt.tkn_txt_(8, 9),fxt.tkn_para_blank_(10))
|
||||
)));
|
||||
}
|
||||
@Test public void Err_Atrs_dumped_into_text() { // PURPOSE: [[Prawn]] and {{Taxobox}} was dumping text
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "|-id='a'"
|
||||
, "|b"
|
||||
, "|}"
|
||||
) , String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr id='a'>"
|
||||
, " <td>b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
, ""
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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>; PAGE: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/gplx/xowa/parsers/tblws/Xop_tblw_wkr__para_tst.java
Normal file
156
400_xowa/src/gplx/xowa/parsers/tblws/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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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() { // PAGE:en.w: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>");
|
||||
}
|
||||
}
|
||||
@@ -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.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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,104 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
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; PAGE: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; PAGE: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; PAGE: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>"
|
||||
));
|
||||
}
|
||||
@Test public void Broken_lnki_2() { // PURPOSE: variation on above; PAGE:hr.b:Knjiga_pojmova_u_zrakoplovstvu/Kratice_u_zrakoplovstvu/S; DATE:2014-09-05
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "{|"
|
||||
, "|-"
|
||||
, "| [[A | b"
|
||||
, "|-"
|
||||
, "| B"
|
||||
, "|}"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<table>"
|
||||
, " <tr>"
|
||||
, " <td> [[A | b"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, " <tr>"
|
||||
, " <td> B"
|
||||
, " </td>"
|
||||
, " </tr>"
|
||||
, "</table>"
|
||||
));
|
||||
}
|
||||
}
|
||||
63
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_ws_itm.java
Normal file
63
400_xowa/src/gplx/xowa/parsers/tblws/Xop_tblw_ws_itm.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
import gplx.core.btries.*;
|
||||
public 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 Btrie_slim_mgr trie_() {// MW.REF:Parser.php|doBlockLevels
|
||||
Btrie_slim_mgr rv = Btrie_slim_mgr.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.Nl));
|
||||
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(Btrie_slim_mgr trie, byte type, byte[] bry) {trie.Add_obj(bry, new Xop_tblw_ws_itm(type, bry.length));}
|
||||
private static void trie_itm_xnde(Btrie_slim_mgr trie, Xop_xnde_tag tag) {
|
||||
byte[] tag_name = tag.Name_bry();
|
||||
int tag_name_len = tag_name.length;
|
||||
trie.Add_obj(Bry_.Add(Bry_xnde_bgn, tag_name), new Xop_tblw_ws_itm(Type_xnde, tag_name_len));
|
||||
trie.Add_obj(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};
|
||||
}
|
||||
Reference in New Issue
Block a user