1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-09-13 21:54:44 -04:00
parent 2145f6382c
commit 5fe27b5b3b
649 changed files with 4726 additions and 3432 deletions

View File

@@ -0,0 +1,324 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.core.btries.*; import gplx.xowa.gui.*; import gplx.xowa.xtns.lst.*;
import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.wdatas.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.hdrs.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.tmpls.*;
import gplx.xowa.parsers.logs.*; import gplx.xowa.html.modules.popups.keeplists.*;
public class Xop_ctx {
private Xop_ctx_wkr[] wkrs = new Xop_ctx_wkr[] {};
Xop_ctx(Xowe_wiki wiki, Xoae_page page) {
this.app = wiki.Appe(); this.msg_log = app.Msg_log();
this.wiki = wiki; this.cur_page = page;
this.wkrs = new Xop_ctx_wkr[] {para, apos, xnde, list, lnki, hdr, amp, lnke, tblw, invk};
for (Xop_ctx_wkr wkr : wkrs) wkr.Ctor_ctx(this);
this.xnde_tag_regy = wiki.Mw_parser_mgr().Xnde_tag_regy();
}
public Xoae_app App() {return app;} private Xoae_app app;
public Xowe_wiki Wiki() {return wiki;} private Xowe_wiki wiki;
public Xol_lang Lang() {return wiki.Lang();}
public Xop_tkn_mkr Tkn_mkr() {return app.Tkn_mkr();}
public Xoae_page Cur_page() {return cur_page;} public void Cur_page_(Xoae_page v) {cur_page = v;} private Xoae_page cur_page;
public byte Parse_tid() {return parse_tid;} public Xop_ctx Parse_tid_(byte v) {parse_tid = v; xnde_names_tid = v; return this;} private byte parse_tid = Xop_parser_.Parse_tid_null;
public byte Xnde_names_tid() {return xnde_names_tid;} public Xop_ctx Xnde_names_tid_(byte v) {xnde_names_tid = v; return this;} private byte xnde_names_tid = Xop_parser_.Parse_tid_null;
public Xop_amp_wkr Amp() {return amp;} private Xop_amp_wkr amp = new Xop_amp_wkr();
public Xop_apos_wkr Apos() {return apos;} private Xop_apos_wkr apos = new Xop_apos_wkr();
public Xop_lnke_wkr Lnke() {return lnke;} private Xop_lnke_wkr lnke = new Xop_lnke_wkr();
public Xop_lnki_wkr Lnki() {return lnki;} private Xop_lnki_wkr lnki = new Xop_lnki_wkr();
public Xop_hdr_wkr Hdr() {return hdr;} private Xop_hdr_wkr hdr = new Xop_hdr_wkr();
public Xop_para_wkr Para() {return para;} private Xop_para_wkr para = new Xop_para_wkr();
public Xop_list_wkr List() {return list;} private Xop_list_wkr list = new Xop_list_wkr();
public Xop_tblw_wkr Tblw() {return tblw;} private Xop_tblw_wkr tblw = new Xop_tblw_wkr();
public Xop_xnde_wkr Xnde() {return xnde;} private Xop_xnde_wkr xnde = new Xop_xnde_wkr();
public Xot_invk_wkr Invk() {return invk;} private Xot_invk_wkr invk = new Xot_invk_wkr();
public Xop_curly_wkr Curly() {return curly;} private Xop_curly_wkr curly = new Xop_curly_wkr();
public Xop_xnde_tag_regy Xnde_tag_regy() {return xnde_tag_regy;} private final Xop_xnde_tag_regy xnde_tag_regy; // PERF:demeter
public boolean Tmpl_load_enabled() {return tmpl_load_enabled;} public void Tmpl_load_enabled_(boolean v) {tmpl_load_enabled = v;} private boolean tmpl_load_enabled = true;
public int Tmpl_tkn_max() {return tmpl_tkn_max;} public void Tmpl_tkn_max_(int v) {tmpl_tkn_max = v;} private int tmpl_tkn_max = Int_.Max_value;
public Xop_keeplist_wiki Tmpl_keeplist() {return tmpl_keeplist;} public void Tmpl_keeplist_(Xop_keeplist_wiki v) {this.tmpl_keeplist = v;} private Xop_keeplist_wiki tmpl_keeplist;
public boolean Tmpl_args_parsing() {return tmpl_args_parsing;} public Xop_ctx Tmpl_args_parsing_(boolean v) {tmpl_args_parsing = v; return this;} private boolean tmpl_args_parsing;
public Bry_bfr Tmpl_output() {return tmpl_output;} public Xop_ctx Tmpl_output_(Bry_bfr v) {tmpl_output = v; return this;} private Bry_bfr tmpl_output; // OBSOLETE: after tmpl_prepend_nl rewrite; DATE:2014-08-21
public Xot_defn_trace Defn_trace() {return defn_trace;} public Xop_ctx Defn_trace_(Xot_defn_trace v) {defn_trace = v; return this;} private Xot_defn_trace defn_trace = Xot_defn_trace_null._;
public boolean Only_include_evaluate() {return only_include_evaluate;} public Xop_ctx Only_include_evaluate_(boolean v) {only_include_evaluate = v; return this;} private boolean only_include_evaluate;
public Lst_section_nde_mgr Lst_section_mgr() {if (lst_section_mgr == null) lst_section_mgr = new Lst_section_nde_mgr(); return lst_section_mgr;} private Lst_section_nde_mgr lst_section_mgr;
public Hash_adp_bry Lst_page_regy() {return lst_page_regy;} private Hash_adp_bry lst_page_regy;
public boolean Ref_ignore() {return ref_ignore;} public Xop_ctx Ref_ignore_(boolean v) {ref_ignore = v; return this;} private boolean ref_ignore; // NOTE: only applies to sub_ctx's created by <pages> and {{#lst}}; if true, does not add <ref> to page.Ref_mgr; DATE:2014-04-24
public byte[] References_group() {return references_group;} public Xop_ctx References_group_(byte[] v) {references_group = v; return this;} private byte[] references_group;
public boolean Tid_is_popup() {return tid_is_popup;} public void Tid_is_popup_(boolean v) {tid_is_popup = v;} private boolean tid_is_popup = false;
public boolean Tid_is_image_map() {return tid_is_image_map;} public Xop_ctx Tid_is_image_map_(boolean v) {tid_is_image_map = v; return this;} private boolean tid_is_image_map;
public Xop_log_invoke_wkr Xtn__scribunto__invoke_wkr() {
if (scrib_invoke_wkr == null)
scrib_invoke_wkr = ((Scrib_xtn_mgr)(app.Xtn_mgr().Get_or_fail(Scrib_xtn_mgr.XTN_KEY))).Invoke_wkr();
return scrib_invoke_wkr;
} private Xop_log_invoke_wkr scrib_invoke_wkr;
public Xop_log_property_wkr Xtn__wikidata__property_wkr() {return app.Wiki_mgr().Wdata_mgr().Property_wkr();}
public Gfo_msg_log Msg_log() {return msg_log;} private Gfo_msg_log msg_log;
public Xop_ctx Clear() {
cur_page.Clear();
stack = Xop_tkn_itm_.Ary_empty;
stack_len = stack_max = 0;
app.Wiki_mgr().Wdata_mgr().Clear();
if (lst_section_mgr != null) lst_section_mgr.Clear();
if (lst_page_regy != null) lst_page_regy.Clear();
tmpl_output = null;
tmpl_args_parsing = false;
return this;
}
public String Page_url_str() {
try {return cur_page.Url().To_str();}
catch (Exception e) {Err_.Noop(e); return "page_url shouldn't fail";}
}
public void Page_bgn(Xop_root_tkn root, byte[] src) {
this.Msg_log().Clear(); cur_tkn_tid = Xop_tkn_itm_.Tid_null;
empty_ignored = false;
for (Xop_ctx_wkr wkr : wkrs) wkr.Page_bgn(this, root);
}
public void Page_end(Xop_root_tkn root, byte[] src, int src_len) {
Stack_pop_til(root, src, 0, true, src_len, src_len, Xop_tkn_itm_.Tid_txt);
for (Xop_ctx_wkr wkr : wkrs) wkr.Page_end(this, root, src, src_len);
}
public boolean Lxr_make() {return lxr_make;} public Xop_ctx Lxr_make_(boolean v) {lxr_make = v; return this;} private boolean lxr_make = false;
public int Lxr_make_txt_(int pos) {lxr_make = false; return pos;}
public int Lxr_make_log_(Gfo_msg_itm itm, byte[] src, int bgn_pos, int cur_pos) {lxr_make = false; msg_log.Add_itm_none(itm, src, bgn_pos, cur_pos); return cur_pos;}
public boolean Empty_ignored() {return empty_ignored;}
public void Empty_ignored_y_() {empty_ignored = true;} private boolean empty_ignored = false;
public void Empty_ignored_n_() {empty_ignored = false;}
public void Empty_ignore(Xop_root_tkn root, int empty_bgn) {
int empty_end = root.Subs_len();
for (int i = empty_bgn; i < empty_end; i++) {
Xop_tkn_itm sub_tkn = root.Subs_get(i);
sub_tkn.Ignore_y_grp_(this, root, i);
}
empty_ignored = false;
}
public byte Cur_tkn_tid() {return cur_tkn_tid;} private byte cur_tkn_tid = Xop_tkn_itm_.Tid_null;
public void Subs_add_and_stack_tblw(Xop_root_tkn root, Xop_tblw_tkn owner_tkn, Xop_tkn_itm sub) {
if (owner_tkn != null) owner_tkn.Tblw_subs_len_add_(); // owner_tkn can be null;EX: "{|" -> prv_tkn is null
Subs_add_and_stack(root, sub);
}
public void Subs_add_and_stack(Xop_root_tkn root, Xop_tkn_itm sub) {this.Subs_add(root, sub); this.Stack_add(sub);}
public void Subs_add(Xop_root_tkn root, Xop_tkn_itm sub) {
switch (sub.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:
break;
default:
empty_ignored = false;
break;
}
root.Subs_add(sub);
}
public void StackTkn_add(Xop_root_tkn root, Xop_tkn_itm sub) {
root.Subs_add(sub);
this.Stack_add(sub);
}
public void Stack_add(Xop_tkn_itm tkn) {
int newLen = stack_len + 1;
if (newLen > stack_max) {
stack_max = newLen * 2;
stack = (Xop_tkn_itm[])Array_.Resize(stack, stack_max);
}
stack[stack_len] = tkn;
cur_tkn_tid = tkn.Tkn_tid();
stack_len = newLen;
} private Xop_tkn_itm[] stack = Xop_tkn_itm_.Ary_empty; int stack_len = 0, stack_max = 0;
public int Stack_len() {return stack_len;}
public Xop_tkn_itm Stack_get_last() {return stack_len == 0 ? null : stack[stack_len - 1];}
public Xop_tkn_itm Stack_get(int i) {return i < 0 || i >= stack_len ? null : stack[i];}
public Xop_tblw_tkn Stack_get_tblw_tb() {// find any {| (exclude <table)
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
if (tkn.Tkn_tid() == Xop_tkn_itm_.Tid_tblw_tb) {
Xop_tblw_tkn tkn_as_tbl = (Xop_tblw_tkn)tkn;
if (!tkn_as_tbl.Tblw_xml()) return tkn_as_tbl;
}
}
return null;
}
public Xop_tblw_tkn Stack_get_tbl_tb() {
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_tblw_tb:
return (Xop_tblw_tkn)tkn;
case Xop_tkn_itm_.Tid_xnde:
Xop_xnde_tkn xnde_tkn = (Xop_xnde_tkn)tkn;
switch (xnde_tkn.Tag().Id()) {
case Xop_xnde_tag_.Tid_table:
return (Xop_tblw_tkn)tkn;
}
break;
}
}
return null;
}
public Xop_tblw_tkn Stack_get_tbl() {
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_tblw_tb:
case Xop_tkn_itm_.Tid_tblw_tr:
case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_th:
case Xop_tkn_itm_.Tid_tblw_tc:
return (Xop_tblw_tkn)tkn;
case Xop_tkn_itm_.Tid_xnde:
Xop_xnde_tkn xnde_tkn = (Xop_xnde_tkn)tkn;
switch (xnde_tkn.Tag().Id()) {
case Xop_xnde_tag_.Tid_table:
case Xop_xnde_tag_.Tid_tr:
case Xop_xnde_tag_.Tid_td:
case Xop_xnde_tag_.Tid_th:
case Xop_xnde_tag_.Tid_caption:
return (Xop_tblw_tkn)tkn;
}
break;
}
}
return null;
}
public static final int Stack_not_found = -1;
public boolean Stack_has(int typeId) {return Stack_idx_typ(typeId) != Stack_not_found;}
public int Stack_idx_typ(int typeId) {
for (int i = stack_len - 1; i > -1; i--)
if (stack[i].Tkn_tid() == typeId)
return i;
return Stack_not_found;
}
public int Stack_idx_find_but_stop_at_tbl(int tid) {
for (int i = stack_len - 1; i > -1 ; i--) {
Xop_tkn_itm tkn_itm = stack[i];
int tkn_itm_tid = tkn_itm.Tkn_tid();
switch (tkn_itm_tid) {
case Xop_tkn_itm_.Tid_tblw_tb: // NOTE: added DATE:2014-06-26
case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_th:
case Xop_tkn_itm_.Tid_tblw_tc:
return -1;
}
if (tkn_itm_tid == tid)
return i;
}
return -1;
}
public Xop_tkn_itm Stack_get_typ(int tid) {
for (int i = stack_len - 1; i > -1 ; i--) {
Xop_tkn_itm tkn = stack[i];
if (tkn.Tkn_tid() == tid) return tkn;
}
return null;
}
public void Stack_del(Xop_tkn_itm del) {
if (stack_len == 0) return;
for (int i = stack_len - 1; i > -1; i--) {
Xop_tkn_itm tkn = stack[i];
if (tkn == del) {
for (int j = i + 1; j < stack_len; j++) {
stack[j - 1] = stack[j];
}
--stack_len;
break;
}
}
}
public Xop_tkn_itm Stack_pop_til(Xop_root_tkn root, byte[] src, int til_idx, boolean include, int bgn_pos, int cur_pos, int closing_tkn_tid) { // NOTE: closing_tkn_tid is a book-keeping variable to indicate who started auto-close; only used by xnde.AutoClose
if (stack_len == 0) return null; // nothing to pop; return;
int min_idx = include ? til_idx - 1 : til_idx; // if "include", auto-close tkn at til_idx; if not, auto-close to one before
if (min_idx < -1) min_idx = -1; // bounds-check; make sure til_idx was not -1, resulting in -2; NOTE: does not seem to be needed; DATE:2015-03-31
Xop_tkn_itm rv = null;
for (int i = stack_len - 1; i > min_idx; i--) { // pop tkns going backwards
rv = stack[i];
Stack_auto_close(root, src, rv, bgn_pos, cur_pos, closing_tkn_tid);
}
Stack_pop_idx(til_idx);
return include ? rv : stack[stack_len]; // if include, return popped_tkn; if not, return tkn before popped_tkn
}
public Xop_tkn_itm Stack_pop_before(Xop_root_tkn root, byte[] src, int til_idx, boolean include, int bgn_pos, int cur_pos, int closing_tkn_tid) { // used by Xop_tblw_lxr to detect \n| in lnki; seems useful as well
if (stack_len == 0) return null;
int min_idx = include ? til_idx - 1 : til_idx;
if (min_idx < -1) min_idx = -1;
Xop_tkn_itm rv = null;
for (int i = stack_len - 1; i > min_idx; i--) {
rv = stack[i];
Stack_auto_close(root, src, rv, bgn_pos, cur_pos, closing_tkn_tid);
}
return include ? rv : stack[stack_len]; // if include, return poppedTkn; if not, return tkn before poppedTkn
}
public void Stack_auto_close(Xop_root_tkn root, byte[] src, Xop_tkn_itm tkn, int bgn_pos, int cur_pos, int closing_tkn_tid) {
int src_len = src.length;
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_newLine: break; // NOOP: just a marker
case Xop_tkn_itm_.Tid_list: list.AutoClose(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_xnde: xnde.AutoClose(this, root, src, src_len, bgn_pos, cur_pos, tkn, closing_tkn_tid); break;
case Xop_tkn_itm_.Tid_apos: apos.AutoClose(this, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_lnke: lnke.AutoClose(this, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_hdr: hdr.AutoClose(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_tblw_tb:
case Xop_tkn_itm_.Tid_tblw_tr:
case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_th:
case Xop_tkn_itm_.Tid_tblw_tc: tblw.AutoClose(this, root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_lnki: lnki.Auto_close(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
case Xop_tkn_itm_.Tid_pre: para.AutoClose(this, app.Tkn_mkr(), root, src, src_len, bgn_pos, cur_pos, tkn); break;
}
}
public void Stack_pop_idx(int tilIdx) {
stack_len = tilIdx < 0 ? 0 : tilIdx;
cur_tkn_tid = stack_len == 0 ? Xop_tkn_itm_.Tid_null : stack[stack_len - 1].Tkn_tid();
}
public void Stack_pop_last() { // used primarily by lnke to remove lnke from stack
--stack_len;
cur_tkn_tid = stack_len == 0 ? Xop_tkn_itm_.Tid_null : stack[stack_len - 1].Tkn_tid();
}
public void CloseOpenItms(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
int stack_pos = -1, stack_len = ctx.Stack_len(); boolean stop = false;
for (int i = 0; i < stack_len; i++) { // loop over stack
Xop_tkn_itm prv_tkn = ctx.Stack_get(i);
switch (prv_tkn.Tkn_tid()) { // find first list/hdr; close everything until this
case Xop_tkn_itm_.Tid_list:
case Xop_tkn_itm_.Tid_hdr:
stack_pos = i; stop = true; break;
}
if (stop) break;
}
if (stack_pos == -1) return;
ctx.Stack_pop_til(root, src, stack_pos, true, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_txt);
}
public static Xop_ctx new_(Xowe_wiki wiki) {
Xop_ctx rv = new Xop_ctx(wiki, Xoae_page.new_(wiki, Xoa_ttl.parse(wiki, Xoa_page_.Main_page_bry))); // HACK: use "Main_Page" to put in valid page title
return rv;
}
public static Xop_ctx new_sub_(Xowe_wiki wiki) {return new_sub_(wiki, wiki.Ctx().cur_page);}
public static Xop_ctx new_sub_(Xowe_wiki wiki, Xoae_page page) { // TODO: new_sub_ should reuse ctx's page; callers who want new_page should call new_sub_page_; DATE:2014-04-10
Xop_ctx ctx = wiki.Ctx();
Xop_ctx rv = new Xop_ctx(wiki, page);
new_copy(ctx, rv);
return rv;
}
public static Xop_ctx new_sub_page_(Xowe_wiki wiki, Xop_ctx ctx, Hash_adp_bry lst_page_regy) {
Xop_ctx rv = new Xop_ctx(wiki, ctx.cur_page);
new_copy(ctx, rv);
rv.lst_page_regy = lst_page_regy; // NOTE: must share ref for lst only (do not share for sub_(), else stack overflow)
return rv;
}
private static void new_copy(Xop_ctx src, Xop_ctx trg) {
trg.Lnki().File_wkr_(src.Lnki().File_wkr()); // always share file_wkr between sub contexts
trg.tmpl_output = src.tmpl_output; // share bfr for optimization purposes
}
}

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
public class Xop_ctx_ {
public static String Page_as_str(Xop_ctx ctx) {return String_.new_u8(ctx.Cur_page().Ttl().Full_db());}
public static String Src_limit_and_escape_nl(byte[] src, int bgn, int limit) {
int end = bgn + limit;
int src_len = src.length;
if (end > src_len) end = src_len;
byte[] rv = Bry_.Mid(src, bgn, end);
rv = Bry_.Replace(rv, Byte_ascii.Nl, Byte_ascii.Tab); // change nl to tab so text editor will show one warning per line
return String_.new_u8(rv);
}
}

View File

@@ -0,0 +1,33 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
import org.junit.*;
public class Xop_ctx__tst {
@Before public void init() {fxt.Clear();} private Xop_ctx__fxt fxt = new Xop_ctx__fxt();
@Test public void Src_limit_and_escape_nl() {
fxt.Test_Src_limit_and_escape_nl("abcdefg", 4, 3, "efg"); // PURPOSE: bug fix; outOfBounds thrown; DATE:2014-03-31
}
}
class Xop_ctx__fxt {
public void Clear() {
}
public void Test_Src_limit_and_escape_nl(String src, int bgn, int limit, String expd) {
String actl = Xop_ctx_.Src_limit_and_escape_nl(Bry_.new_u8(src), bgn, limit);
Tfds.Eq(expd, actl);
}
}

View File

@@ -0,0 +1,23 @@
/*
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; import gplx.*; import gplx.xowa.*;
public interface Xop_ctx_wkr {
void Ctor_ctx(Xop_ctx ctx);
void Page_bgn(Xop_ctx ctx, Xop_root_tkn root);
void Page_end(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int src_len);
}

View File

@@ -0,0 +1,25 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
import gplx.core.btries.*;
public interface Xop_lxr {
byte Lxr_tid();
void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie);
void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie);
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);
}

View 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; import gplx.*; import gplx.xowa.*;
public class Xop_lxr_ {
public static final byte
Tid_pipe = 0, Tid_space = 1, Tid_nbsp = 2, Tid_tab = 3, Tid_nl = 4, Tid_amp = 5, Tid_apos = 6, Tid_colon = 7, Tid_lnki_bgn = 8, Tid_lnki_end = 9
, Tid_list = 10, Tid_hdr = 11, Tid_hr = 12, Tid_xnde = 13, Tid_lnke_bgn = 14, Tid_lnke_end = 15, Tid_tblw = 16, Tid_pre = 17, Tid_under = 18, Tid_comment = 19
, Tid_eq = 20, Tid_curly_bgn = 21, Tid_curly_end = 22, Tid_brack_bgn = 23, Tid_brack_end = 24, Tid_poem = 25
, Tid_tvar = 26, Tid_vnt_bgn = 27, Tid_vnt_end = 28, Tid_vnt_eqgt = 29, Tid_vnt_tmpl_bgn = 30, Tid_word = 31, Tid_nl_poem = 32, Tid_cr = 33
, Tid_brack_end_lnki = 34, Tid_nl_tab = 35
;
}

View File

@@ -0,0 +1,79 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.core.btries.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.hdrs.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.miscs.*;
public class Xop_lxr_mgr {
private Xop_lxr[] ary;
public Xop_lxr_mgr(Xop_lxr[] ary) {this.ary = ary;}
public Btrie_fast_mgr Trie() {return trie;} private Btrie_fast_mgr trie = Btrie_fast_mgr.cs();
public void Init_by_wiki(Xowe_wiki wiki) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
Xop_lxr lxr = ary[i];
lxr.Init_by_wiki(wiki, trie);
}
}
public void Init_by_lang(Xol_lang lang) {
int ary_len = ary.length;
for (int i = 0; i < ary_len; i++) {
Xop_lxr lxr = ary[i];
lxr.Init_by_lang(lang, trie);
}
}
public static Xop_lxr_mgr new_tmpl_() {
return new Xop_lxr_mgr(new Xop_lxr[]
{ Xop_pipe_lxr._, new Xop_eq_lxr(true), Xop_colon_lxr._, Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._
, Xop_curly_bgn_lxr._, Xop_curly_end_lxr._
, Xop_brack_bgn_lxr._, Xop_brack_end_lxr._
, Xop_comm_lxr._
, Xop_xnde_lxr._ // needed for xtn, noinclude, etc.
, Xop_under_lxr._
, gplx.xowa.xtns.translates.Xop_tvar_lxr._
, Xop_cr_lxr._ // always ignore \r; DATE:2014-03-02
});
}
public static Xop_lxr_mgr new_wiki_() {
return new Xop_lxr_mgr(new Xop_lxr[]
{ Xop_pipe_lxr._, new Xop_eq_lxr(false), Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._
, Xop_amp_lxr._, Xop_apos_lxr._, Xop_colon_lxr._
, Xop_lnki_lxr_bgn._, Xop_lnki_lxr_end._
, Xop_list_lxr._
, Xop_hdr_lxr._
, Xop_hr_lxr._
, Xop_xnde_lxr._
, Xop_lnke_lxr._, Xop_lnke_end_lxr._
, Xop_tblw_lxr._
, Xop_pre_lxr._, Xop_nl_tab_lxr._
, Xop_comm_lxr._
, Xop_under_lxr._
});
}
public static final Xop_lxr_mgr Popup_lxr_mgr // same as orig_page, except apos_lxr added
= new Xop_lxr_mgr(new Xop_lxr[]
{ Xop_pipe_lxr._, new Xop_eq_lxr(true), Xop_colon_lxr._, Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._
, Xop_curly_bgn_lxr._, Xop_curly_end_lxr._
, Xop_brack_bgn_lxr._, Xop_brack_end_lxr._
, Xop_comm_lxr._
, Xop_xnde_lxr._ // needed for xtn, noinclude, etc.
, Xop_under_lxr._
, gplx.xowa.xtns.translates.Xop_tvar_lxr._
, Xop_cr_lxr._ // always ignore \r; DATE:2014-03-02
, gplx.xowa.parsers.apos.Xop_apos_lxr._ // needed else multiple apos may be split across blocks;
});
}

View File

@@ -0,0 +1,215 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.core.btries.*;
import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.tmpls.*;
public class Xop_parser { // NOTE: parsers are reused; do not keep any read-write state
private Xowe_wiki wiki;
public Xop_parser(Xowe_wiki wiki, Xop_lxr_mgr tmpl_lxr_mgr, Xop_lxr_mgr wtxt_lxr_mgr) {
this.wiki = wiki;
this.tmpl_lxr_mgr = tmpl_lxr_mgr; this.tmpl_trie = tmpl_lxr_mgr.Trie();
this.wtxt_lxr_mgr = wtxt_lxr_mgr; this.wtxt_trie = wtxt_lxr_mgr.Trie();
}
public Xop_lxr_mgr Tmpl_lxr_mgr() {return tmpl_lxr_mgr;} private Xop_lxr_mgr tmpl_lxr_mgr;
public Xop_lxr_mgr Wtxt_lxr_mgr() {return wtxt_lxr_mgr;} private Xop_lxr_mgr wtxt_lxr_mgr;
public Btrie_fast_mgr Tmpl_trie() {return tmpl_trie;} private Btrie_fast_mgr tmpl_trie;
public Btrie_fast_mgr Wtxt_trie() {return wtxt_trie;} private Btrie_fast_mgr wtxt_trie;
public void Init_by_wiki(Xowe_wiki wiki) {
tmpl_lxr_mgr.Init_by_wiki(wiki);
wtxt_lxr_mgr.Init_by_wiki(wiki);
}
public void Init_by_lang(Xol_lang lang) {
tmpl_lxr_mgr.Init_by_lang(lang);
wtxt_lxr_mgr.Init_by_lang(lang);
}
public byte[] Parse_text_to_html(Xop_ctx ctx, byte[] src) {
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512();
Parse_text_to_html(bfr, ctx.Cur_page(), false, src);
return bfr.To_bry_and_rls();
}
public void Parse_text_to_html(Bry_bfr trg, Xoae_page page, boolean para_enabled, byte[] src) {
Xop_ctx ctx = Xop_ctx.new_sub_(wiki, page);
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
Xop_parser parser = wiki.Parser();
byte[] wtxt = parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
root.Reset();
ctx.Para().Enabled_(para_enabled);
parser.Parse_wtxt_to_wdom(root, ctx, ctx.Tkn_mkr(), wtxt, Xop_parser_.Doc_bgn_bos);
wiki.Html_mgr().Html_wtr().Write_all(trg, ctx, wtxt, root);
}
public Xot_defn_tmpl Parse_text_to_defn_obj(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xow_ns ns, byte[] name, byte[] src) {
Xot_defn_tmpl rv = new Xot_defn_tmpl();
Parse_text_to_defn(rv, ctx, tkn_mkr, ns, name, src);
return rv;
}
public void Parse_text_to_defn(Xot_defn_tmpl tmpl, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xow_ns ns, byte[] name, byte[] src) {
Xop_root_tkn root = tkn_mkr.Root(src);
Parse(root, ctx, tkn_mkr, src, Xop_parser_.Parse_tid_tmpl, tmpl_trie, Xop_parser_.Doc_bgn_bos);
tmpl_props.OnlyInclude_exists = false; int subs_len = root.Subs_len();
for (int i = 0; i < subs_len; i++)
root.Subs_get(i).Tmpl_compile(ctx, src, tmpl_props);
boolean only_include_chk = Bry_finder.Find_fwd(src, Xop_xnde_tag_.Name_onlyinclude, 0, src.length) != Bry_.NotFound;
if (only_include_chk) tmpl_props.OnlyInclude_exists = true;
tmpl.Init_by_new(ns, name, src, root, tmpl_props.OnlyInclude_exists);
} private Xot_compile_data tmpl_props = new Xot_compile_data();
public void Parse_page_all_clear(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src) {
ctx.Cur_page().Clear(); ctx.App().Msg_log().Clear();
Parse_text_to_wdom(root, ctx, tkn_mkr, src, Xop_parser_.Doc_bgn_bos);
}
public Xop_root_tkn Parse_text_to_wdom_old_ctx(Xop_ctx old_ctx, byte[] src, boolean doc_bgn_pos) {return Parse_text_to_wdom(Xop_ctx.new_sub_(old_ctx.Wiki()), src, doc_bgn_pos);}
public Xop_root_tkn Parse_text_to_wdom(Xop_ctx new_ctx, byte[] src, boolean doc_bgn_pos) {
new_ctx.Para().Enabled_n_();
Xop_tkn_mkr tkn_mkr = new_ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
Parse_text_to_wdom(root, new_ctx, tkn_mkr, src, doc_bgn_pos ? Xop_parser_.Doc_bgn_bos : Xop_parser_.Doc_bgn_char_0);
return root;
}
public void Parse_text_to_wdom(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, int doc_bgn_pos) {
byte parse_tid_old = ctx.Parse_tid();// NOTE: must store parse_tid b/c ctx can be reused by other classes
ctx.Parse_tid_(Xop_parser_.Parse_tid_page_tmpl);
root.Reset();
byte[] mid_bry = Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
root.Data_mid_(mid_bry);
root.Reset();
Parse_wtxt_to_wdom(root, ctx, tkn_mkr, mid_bry, doc_bgn_pos);
ctx.Parse_tid_(parse_tid_old);
}
public byte[] Parse_text_to_wtxt(byte[] src) {
Xop_ctx ctx = Xop_ctx.new_sub_(wiki);
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
return wiki.Parser().Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
}
public byte[] Parse_text_to_wtxt(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src) {
Parse(root, ctx, tkn_mkr, src, Xop_parser_.Parse_tid_page_tmpl, tmpl_trie, Xop_parser_.Doc_bgn_bos);
int subs_len = root.Subs_len();
for (int i = 0; i < subs_len; i++)
root.Subs_get(i).Tmpl_compile(ctx, src, tmpl_props);
return Xot_tmpl_wtr._.Write_all(ctx, root, src); // NOTE: generate new src since most callers will use it;
}
public void Parse_wtxt_to_wdom(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] wtxt, int doc_bgn_pos) {
root.Root_src_(wtxt); // always set latest src; needed for Parse_all wherein src will first be raw and then parsed tmpl
Parse(root, ctx, tkn_mkr, wtxt, Xop_parser_.Parse_tid_page_wiki, wtxt_trie, doc_bgn_pos);
}
private void Parse(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, byte parse_type, Btrie_fast_mgr trie, int doc_bgn_pos) {
int len = src.length; if (len == 0) return; // nothing to parse;
byte parse_tid_old = ctx.Parse_tid(); // NOTE: must store parse_tid b/c ctx can be reused by other classes
ctx.Parse_tid_(parse_type);
ctx.Page_bgn(root, src);
Parse_to_src_end(root, ctx, tkn_mkr, src, trie, doc_bgn_pos, len);
ctx.Page_end(root, src, len);
ctx.Parse_tid_(parse_tid_old);
}
public int Parse_to_src_end(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, Btrie_fast_mgr trie, int pos, int len) {
byte b = pos == -1 ? Byte_ascii.Nl : src[pos]; // simulate newLine at bgn of src; needed for lxrs which rely on \n (EX: "=a=")
int txt_bgn = pos == -1 ? 0 : pos; Xop_tkn_itm txt_tkn = null;
while (true) {
Object o = trie.Match_bgn_w_byte(b, src, pos, len);
if (o == null) // no lxr found; char is txt; increment pos
pos++;
else { // lxr found
Xop_lxr lxr = (Xop_lxr)o;
if (txt_bgn != pos) // chars exist between pos and txt_bgn; make txt_tkn; see NOTE_1
txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
ctx.Lxr_make_(true);
pos = lxr.Make_tkn(ctx, tkn_mkr, root, src, len, pos, trie.Match_pos());
if (ctx.Lxr_make()) {txt_bgn = pos; txt_tkn = null;} // reset txt_tkn
}
if (pos == len) break;
b = src[pos];
}
if (txt_bgn != pos) txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
return pos;
}
public int Parse_to_stack_end(Xop_root_tkn root, Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, byte[] src, int src_len, Btrie_fast_mgr trie, int pos, int end) {
byte b = pos == -1 ? Byte_ascii.Nl : src[pos]; // simulate newLine at bgn of src; needed for lxrs which rely on \n (EX: "=a=")
int txt_bgn = pos == -1 ? 0 : pos; Xop_tkn_itm txt_tkn = null;
Xop_lxr lxr = null;
while (true) {
lxr = null;
Object o = trie.Match_bgn_w_byte(b, src, pos, src_len);
if (o == null) // no lxr found; char is txt; increment pos
pos++;
else { // lxr found
lxr = (Xop_lxr)o;
if (txt_bgn != pos) // chars exist between pos and txt_bgn; make txt_tkn; see NOTE_1
txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
ctx.Lxr_make_(true);
pos = lxr.Make_tkn(ctx, tkn_mkr, root, src, src_len, pos, trie.Match_pos());
if (ctx.Lxr_make()) {txt_bgn = pos; txt_tkn = null;} // reset txt_tkn
}
if ( pos >= end
&& ctx.Stack_len() == 0 // check stack is 0 to avoid dangling templates
) {
if (o == null) {} // last sequence is not text; avoids splitting words across blocks; EX: 4 block and word of "abcde" will split to "abcd" and "e"
else {
if (lxr != null) {
boolean stop = true;
switch (lxr.Lxr_tid()) {
case Xop_lxr_.Tid_eq:
case Xop_lxr_.Tid_nl:
stop = false;
break;
}
if (stop)
break;
}
else {
break;
}
}
}
if (pos >= src_len) break;
b = src[pos];
}
if (txt_bgn != pos) txt_tkn = Txt_add(ctx, tkn_mkr, root, txt_tkn, txt_bgn, pos);
return pos;
}
private static Xop_tkn_itm Txt_add(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, Xop_tkn_itm tkn, int txt_bgn, int pos) {
if (pos == Xop_parser_.Doc_bgn_bos) return null; // don't make txt_tkn for Bos_pos
if (tkn == null) { // no existing txt_tkn; create new one
tkn = tkn_mkr.Txt(txt_bgn, pos);
ctx.Subs_add(root, tkn);
}
else // existing txt_tkn; happens for false matches; EX: abc[[\nef[[a]]; see NOTE_1
tkn.Src_end_(pos);
return tkn;
}
public static Xop_parser new_wiki_(Xowe_wiki wiki) {
Xop_parser rv = new Xop_parser(wiki, Xop_lxr_mgr.new_tmpl_(), Xop_lxr_mgr.new_wiki_());
rv.Init_by_wiki(wiki);
rv.Init_by_lang(wiki.Lang());
return rv;
}
}
/*
NOTE_1
abc[[\nef[[a]]
<BOS> : txt_bgn = 0; txt_tkn = null;
abc : increment pos
[[\n : lnki lxr
: (1): txt_tkn == null, so create txt_tkn with (0, 3)
: (2): lxr.Make_tkn() entered for lnki; however \n exits lnki
: (3): note that ctx.Lxr_make == false, so txt_bgn/txt_tkn is not reset
ef : still just text; increment pos
[[a]] : lnki entered
: (1): txt_tkn != null; set end to 8
: (2): lxr.Make_tkn() entered and lnki made
: (3): note that ctx.Lxr_make == true, so txt_bgn = 13 and txt_tkn = null
*/

View File

@@ -0,0 +1,36 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.langs.vnts.*;
public class Xop_parser_ {
public static final byte Parse_tid_null = 0, Parse_tid_tmpl = 1, Parse_tid_page_tmpl = 2, Parse_tid_page_wiki = 3;
public static final int Doc_bgn_bos = -1, Doc_bgn_char_0 = 0;
public static byte[] Parse_text_to_html(Xowe_wiki wiki, Xoae_page page, Xoa_ttl ttl, byte[] src, boolean para_enabled) { // NOTE: must pass in same page instance; do not do Xoa_page_.new_(), else img_idx will get reset to 0; DATE:2015-02-08
Bry_bfr bfr = wiki.Utl__bfr_mkr().Get_b512();
Xop_ctx ctx = Xop_ctx.new_sub_(wiki, page);
Xop_tkn_mkr tkn_mkr = ctx.Tkn_mkr();
Xop_root_tkn root = tkn_mkr.Root(src);
Xop_parser parser = wiki.Parser();
byte[] wtxt = parser.Parse_text_to_wtxt(root, ctx, tkn_mkr, src);
root.Reset();
ctx.Para().Enabled_(para_enabled);
parser.Parse_wtxt_to_wdom(root, ctx, ctx.Tkn_mkr(), wtxt, Xop_parser_.Doc_bgn_bos);
wiki.Html_mgr().Html_wtr().Write_all(bfr, ctx, wtxt, root);
return bfr.To_bry_and_rls();
}
}

View File

@@ -0,0 +1,58 @@
/*
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; import gplx.*; import gplx.xowa.*;
import org.junit.*;
public class Xop_parser__tst {
@Before public void init() {fxt.Clear();} private Xop_parser__fxt fxt = new Xop_parser__fxt();
@Test public void Para_y() {
fxt.Test_parse_to_html(String_.Concat_lines_nl_skip_last
( "a"
, ""
, "b"
), true, String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, ""
, "<p>b"
, "</p>"
, ""
));
}
@Test public void Para_n() {
fxt.Test_parse_to_html(String_.Concat_lines_nl_skip_last
( "a"
, ""
, "b"
), false, String_.Concat_lines_nl_skip_last
( "a"
, "b"
));
}
}
class Xop_parser__fxt {
private Xop_fxt fxt = new Xop_fxt();
private Bry_bfr bfr = Bry_bfr.reset_(255);
public void Clear() {
fxt.Reset();
}
public void Test_parse_to_html(String raw, boolean para_enabled, String expd) {
byte[] raw_bry = Bry_.new_u8(raw);
fxt.Wiki().Parser().Parse_text_to_html(bfr, fxt.Page(), para_enabled, raw_bry);
Tfds.Eq(expd, bfr.Xto_str_and_clear());
}
}

View File

@@ -0,0 +1,28 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xop_root_tkn extends Xop_tkn_itm_base {
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_root;}
public byte[] Root_src() {return root_src;} public Xop_root_tkn Root_src_(byte[] v) {root_src = v; return this;} private byte[] root_src = Bry_.Empty;
public byte[] Data_mid() {return data_mid;} public Xop_root_tkn Data_mid_(byte[] v) {data_mid = v; return this;} private byte[] data_mid = Bry_.Empty;
public byte[] Data_htm() {return data_htm;} public Xop_root_tkn Data_htm_(byte[] v) {data_htm = v; return this;} private byte[] data_htm = Bry_.Empty;
@Override public void Reset() {
super.Reset();
root_src = Bry_.Empty;
}
}

View File

@@ -0,0 +1,64 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
public class Xop_tkn_chkr_base implements Tst_chkr {
@gplx.Virtual public Class<?> TypeOf() {return Xop_tkn_itm.class;}
@gplx.Virtual public byte Tkn_tid() {return Byte_.Max_value_127;}
public Xop_tkn_chkr_base TypeId_dynamic(int v) {typeId = Xop_tkn_itm_.Tid__names[v]; return this;} private String typeId = null;
public int Src_bgn() {return src_bgn;} private int src_bgn = -1;
public int Src_end() {return src_end;} private int src_end = -1;
public byte Ignore() {return ignore;} private Xop_tkn_chkr_base Ignore_(byte v) {ignore = v; return this;} private byte ignore = Bool_.__byte;
public Xop_tkn_chkr_base Ignore_y_() {return Ignore_(Bool_.Y_byte);}
public Xop_tkn_chkr_base Src_rng_(int bgn, int end) {src_bgn = bgn; src_end = end; return this;}
public String Raw() {return raw;} public Xop_tkn_chkr_base Raw_(String v) {raw = v; return this;} private String raw;
public String Raw_src() {return raw_src;} public Xop_tkn_chkr_base Raw_src_(String v) {raw_src = v; return this;} private String raw_src;
public Xop_tkn_chkr_base[] Subs() {return subs;} public Xop_tkn_chkr_base Subs_(Xop_tkn_chkr_base... v) {subs = v; return this;} private Xop_tkn_chkr_base[] subs = null;
@gplx.Virtual public int Chk(Tst_mgr mgr, String path, Object actl_obj) {
Xop_tkn_itm actl = (Xop_tkn_itm)actl_obj;
int rv = 0;
rv += Chk_basic(mgr, path, actl, rv);
rv += Chk_hook(mgr, path, actl, rv);
rv += Chk_subs(mgr, path, actl, rv);
return rv;
}
@gplx.Virtual public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {return 0;}
int Chk_basic(Tst_mgr mgr, String path, Xop_tkn_itm actl, int err) {
if (typeId == null) typeId = Xop_tkn_itm_.Tid__names[this.Tkn_tid()];
err += mgr.Tst_val(typeId == null, path, "typeId", typeId, Xop_tkn_itm_.Tid__names[actl.Tkn_tid()]);
if (ignore != Bool_.__byte) err += mgr.Tst_val(ignore == Bool_.__byte, path, "ignore", ignore == Bool_.Y_byte, actl.Ignore()); // "ignore !=" to skip comparison unless explicitly toggled
err += mgr.Tst_val(src_bgn == -1, path, "src_bgn", src_bgn, actl.Src_bgn());
err += mgr.Tst_val(src_end == -1, path, "src_end", src_end, actl.Src_end());
if (raw != null) {
String raw_actl = raw_src == null ? mgr.Vars_get_bry_as_str("raw_bry", actl.Src_bgn(), actl.Src_end()) : String_.Mid(raw_src, actl.Src_bgn(), actl.Src_end());
err += mgr.Tst_val(raw == null, path, "raw", raw, raw_actl);
}
return err;
}
int Chk_subs(Tst_mgr mgr, String path, Xop_tkn_itm actl, int err) {
if (subs != null) {
int actl_subs_len = actl.Subs_len();
Xop_tkn_itm[] actl_subs = new Xop_tkn_itm[actl_subs_len];
for (int i = 0; i < actl_subs_len; i++)
actl_subs[i] = actl.Subs_get(i);
return mgr.Tst_sub_ary(subs, actl_subs, path, err);
}
return err;
}
public static final Tst_chkr Null = Tst_mgr.Null_chkr;
public static final Xop_tkn_chkr_base[] Ary_empty = new Xop_tkn_chkr_base[0];
}

View 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; import gplx.*; import gplx.xowa.*;
public interface Xop_tkn_grp {
int Subs_len();
Xop_tkn_itm Subs_get(int i);
void Subs_add(Xop_tkn_itm sub);
void Subs_add_grp(Xop_tkn_itm sub, Xop_tkn_grp old_grp, int old_sub_idx);
void Subs_del_after(int pos_bgn);
void Subs_clear();
void Subs_move(Xop_tkn_itm tkn);
int Subs_src_bgn(int sub_idx);
int Subs_src_end(int sub_idx);
void Subs_src_pos_(int sub_idx, int bgn, int end);
Xop_tkn_itm Immutable_clone(Xop_ctx ctx, Xop_tkn_itm tkn, int sub_idx);
}
class Xop_tkn_grp_ {
public static final Xop_tkn_grp Null = null;
}

View File

@@ -0,0 +1,49 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
import gplx.xowa.parsers.tmpls.*;
public interface Xop_tkn_itm extends Xop_tkn_grp {
byte Tkn_tid();
Xop_tkn_itm Tkn_ini_pos(boolean immutable, int bgn, int end);
Xop_tkn_itm Tkn_clone(Xop_ctx ctx, int bgn, int end);
boolean Tkn_immutable();
Xop_tkn_grp Tkn_grp();
int Src_bgn();
int Src_end();
int Src_bgn_grp(Xop_tkn_grp grp, int sub_idx);
int Src_end_grp(Xop_tkn_grp grp, int sub_idx);
int Tkn_sub_idx();
boolean Ignore();
Xop_tkn_itm Tkn_grp_(Xop_tkn_grp grp, int sub_idx);
void Src_end_(int v);
void Src_end_grp_(Xop_ctx ctx, Xop_tkn_grp grp, int sub_idx, int src_end);
Xop_tkn_itm Ignore_y_();
void Ignore_y_grp_(Xop_ctx ctx, Xop_tkn_grp grp, int sub_idx);
void Clear();
void Tmpl_fmt(Xop_ctx ctx, byte[] src, Xot_fmtr fmtr);
void Tmpl_compile(Xop_ctx ctx, byte[] src, Xot_compile_data prep_data); // SEE:NOTE_1:Tmpl_compile
boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr);
}
/*
NOTE_1: Tmpl_compile
- called for tmpl_defn
- identifies tkn as static or dynamic; important for evaluate later; if static, evaluate will simply extract src
- if static, parses prm; EX: {{{1|a}}} will produce member variables of idx=1 and dflt=a
- if static, parses tmpl_name; EX: {{concat|a|b}} will generate name of concat
- if <onlyinclude> mark tmpl accordingly
*/

View File

@@ -0,0 +1,128 @@
/*
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; import gplx.*; import gplx.xowa.*;
public class Xop_tkn_itm_ {
public static final Xop_tkn_itm[] Ary_empty = new Xop_tkn_itm[0];
public static final byte
Tid_null = 0
, Tid_root = 1
, Tid_txt = 2
, Tid_ignore = 3
, Tid_newLine = 4
, Tid_space = 5
, Tid_tab = 6
, Tid_pipe = 7
, Tid_eq = 8
, Tid_colon = 9
, Tid_amp = 10
, Tid_lt = 11
, Tid_gt = 12
, Tid_quot = 13
, Tid_apos = 14
, Tid_html_ref = 15
, Tid_html_ncr = 16
, Tid_lnki_bgn = 17
, Tid_lnki_end = 18
, Tid_lnki = 19
, Tid_lnke = 20
, Tid_hr = 21
, Tid_hdr = 22
, Tid_tblw_tb = 23
, Tid_tblw_te = 24
, Tid_tblw_tr = 25
, Tid_tblw_th = 26
, Tid_tblw_td = 27
, Tid_tblw_tc = 28
, Tid_list = 29
, Tid_xnde = 30
, Tid_xatr = 31
, Tid_tmpl_prm_bgn = 32
, Tid_tmpl_prm_end = 33
, Tid_tmpl_prm = 34
, Tid_tmpl_invk_dat = 35
, Tid_arg_nde = 36
, Tid_arg_itm = 37
, Tid_tmpl_invk = 38
, Tid_tmpl_curly_bgn = 39
, Tid_brack_bgn = 40
, Tid_brack_end = 41
, Tid_para = 42
, Tid_pre = 43
, Tid_bry = 44
, Tid_under = 45
, Tid_tvar = 46
, Tid_vnt = 47
, Tid_vnt_rule = 48
, Tid_vnt_eqgt = 49
, Tid_cr = 50
;
public static final String[] Tid__names
= new String[]
{ "null"
, "root"
, "text"
, "ignore"
, "newLine"
, "space"
, "tab"
, "pipe"
, "eq"
, "colon"
, "amp"
, "lt"
, "gt"
, "quot"
, "apos"
, "htmlRef"
, "htmlNcr"
, "lnki_bgn"
, "lnki_end"
, "lnki"
, "lnke"
, "hr"
, "hdr"
, "tblw_tb"
, "tblw_te"
, "tblw_tr"
, "tblw_th"
, "tblw_td"
, "tblw_tc"
, "list"
, "xnde"
, "xatr"
, "tmpl_prm_bgn"
, "tmpl_prm_end"
, "tmpl_prm"
, "tmpl_invk_dat"
, "arg"
, "arg_itm"
, "tmpl_invk"
, "tmpl_curly_bgn"
, "brack_bgn"
, "brack_end"
, "para"
, "para_pre"
, "bry"
, "under"
, "tvar"
, "vnt"
, "vnt_rule"
, "vnt_eqgt"
, "cr"
};
}

View File

@@ -0,0 +1,167 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.parsers.tmpls.*;
public abstract class Xop_tkn_itm_base implements Xop_tkn_itm {
public abstract byte Tkn_tid();
public Xop_tkn_grp Tkn_grp() {return grp == null ? this : grp;} private Xop_tkn_grp grp; // NOTE: not sure about this; need to handle null refs when tkns are manipulated but not yet added to a group
public Xop_tkn_itm Tkn_ini_pos(boolean immutable, int bgn, int end) {this.immutable = immutable; this.src_bgn = bgn; this.src_end = end; return this;}
public Xop_tkn_itm Tkn_grp_(Xop_tkn_grp grp, int sub_idx) {this.grp = grp; this.tkn_sub_idx = sub_idx; return this;}
@gplx.Virtual public Xop_tkn_itm Tkn_clone(Xop_ctx ctx, int bgn, int end) {throw Err_.new_wo_type("tkn_clone not implemented", "name", Xop_tkn_itm_.Tid__names[this.Tkn_tid()]);}
public boolean Tkn_immutable() {return immutable;} private boolean immutable;
public int Tkn_sub_idx() {return tkn_sub_idx;} private int tkn_sub_idx = -1;
public int Src_bgn() {return src_bgn;} private int src_bgn = -1;
public int Src_end() {return src_end;} private int src_end = -1;
public void Src_end_(int v) {src_end = v;}
public int Src_bgn_grp(Xop_tkn_grp grp, int sub_idx) {return immutable ? grp.Subs_src_bgn(sub_idx) : src_bgn;}
public int Src_end_grp(Xop_tkn_grp grp, int sub_idx) {return immutable ? grp.Subs_src_end(sub_idx) : src_end;}
public int Subs_src_bgn(int sub_idx) {if (subs_len == 0) throw Err_.new_wo_type("no subs available", "idx", sub_idx); return subs_pos_ary[ sub_idx * 2];}
public int Subs_src_end(int sub_idx) {if (subs_len == 0) throw Err_.new_wo_type("no subs available", "idx", sub_idx); return subs_pos_ary[(sub_idx * 2) + 1];}
public void Subs_src_pos_(int sub_idx, int bgn, int end) {
int pos_idx = sub_idx * 2;
int subs_pos_ary_len = subs_pos_ary.length;
if (pos_idx + 1 > subs_pos_ary_len) {
int[] new_subs_pos_ary = new int[(pos_idx + 1) * 2];
Array_.Copy_to(subs_pos_ary, 0, new_subs_pos_ary, 0, subs_pos_ary.length);
subs_pos_ary = new_subs_pos_ary;
}
subs_pos_ary[pos_idx] = bgn;
subs_pos_ary[pos_idx + 1] = end;
}
public boolean Ignore() {return ignore;} private boolean ignore;
public Xop_tkn_itm Ignore_y_() {
ignore = true;
return this;
}
public int Subs_len() {return subs_len;} private int subs_len;
public Xop_tkn_itm[] Subs() {return subs;}
public Xop_tkn_itm Subs_get(int i) {return subs[i];}
public Xop_tkn_itm Subs_get_or_null(int i) {return i < subs_len ? subs[i] : null;}
public void Subs_add(Xop_tkn_itm sub) {
int new_len = subs_len + 1;
if (new_len > subs_max) { // ary too small >>> expand
subs_max = new_len * 2;
Xop_tkn_itm[] new_subs = new Xop_tkn_itm[subs_max];
Array_.Copy_to(subs, 0, new_subs, 0, subs_len);
subs = new_subs;
}
subs[subs_len] = sub;
sub.Tkn_grp_(this, subs_len);
subs_len = new_len;
} private Xop_tkn_itm[] subs = Xop_tkn_itm_.Ary_empty; int subs_max; int[] subs_pos_ary = Int_.Ary_empty;
public void Subs_add_grp(Xop_tkn_itm sub, Xop_tkn_grp old_grp, int old_sub_idx) {
this.Subs_add(sub);
if (sub.Tkn_immutable())
this.Subs_src_pos_(subs_len - 1, sub.Src_bgn_grp(old_grp, old_sub_idx), sub.Src_end_grp(old_grp, old_sub_idx));
}
public void Subs_del_after(int tkn_sub_idx) {
if (tkn_sub_idx >= subs_len) return; // ignore delete after len; PRUNE: breaks 3 tests;
for (int i = tkn_sub_idx; i < subs_len; i++)
subs[i] = null;
subs_len = tkn_sub_idx;
}
public void Subs_del_between(Xop_ctx ctx, int idx_bgn, int idx_end) {
if (idx_bgn >= subs_len || idx_bgn >= idx_end) return; // ignore invalid bounds; PRUNE: breaks 2 tests
int idx_dif = idx_end - idx_bgn;
for (int trg_idx = idx_bgn; trg_idx < subs_len; trg_idx++) {
int src_idx = trg_idx + idx_dif;
if (src_idx < subs_len) { // trg exists >>> move tkn from src to trg
Xop_tkn_itm src_tkn = subs[src_idx];
subs[trg_idx] = src_tkn;
src_tkn.Tkn_grp_(this, trg_idx);
subs[src_idx] = null;
}
else
subs[trg_idx] = null;
}
subs_len -= idx_dif;
}
public void Subs_clear() {
subs_len = subs_max = 0;
subs = Xop_tkn_itm_.Ary_empty;
subs_pos_ary = Int_.Ary_empty;
}
public void Subs_move(Xop_tkn_itm tkn) {
int nxt_idx = tkn_sub_idx + 1, len = tkn.Subs_len();
for (int i = nxt_idx; i < len; i++) {
Xop_tkn_itm sub = tkn.Subs_get(i);
Subs_add_grp(sub, tkn, i);
}
tkn.Subs_del_after(nxt_idx);
}
public void Subs_move(Xop_tkn_itm owner, int sub_idx, int subs_len) {
for (int i = sub_idx; i < subs_len; i++) {
Xop_tkn_itm sub = owner.Subs_get(i);
this.Subs_add(sub);
}
owner.Subs_del_after(sub_idx);
}
public Xop_tkn_itm Immutable_clone(Xop_ctx ctx, Xop_tkn_itm tkn, int sub_idx) {
int pos_idx = sub_idx * 2;
Xop_tkn_itm rv = tkn.Tkn_clone(ctx, subs_pos_ary[pos_idx], subs_pos_ary[pos_idx + 1]);
subs[sub_idx] = rv;
rv.Tkn_grp_(this, sub_idx);
return rv;
}
public void Src_end_grp_(Xop_ctx ctx, Xop_tkn_grp grp, int sub_idx, int src_end) {
Xop_tkn_itm tkn = this;
if (immutable) tkn = grp.Immutable_clone(ctx, this, sub_idx);
tkn.Src_end_(src_end);
subs_pos_ary[(sub_idx * 2) + 1] = src_end;
}
public void Ignore_y_grp_(Xop_ctx ctx, Xop_tkn_grp grp, int sub_idx) {
Xop_tkn_itm tkn = this;
if (immutable) tkn = grp.Immutable_clone(ctx, this, sub_idx);
tkn.Ignore_y_();
}
public void Subs_grp_(Xop_ctx ctx, Xop_tkn_itm tkn, Xop_tkn_grp grp, int sub_idx) {
// if (tkn.Tkn_immutable()) tkn = Subs_immutable_clone(ctx, tkn);
// tkn.Tkn_grp_(grp, sub_idx);
}
@gplx.Virtual public void Reset() {
src_bgn = src_end = tkn_sub_idx = -1; ignore = false; tmpl_static = false;
if (subs.length > Tkn_subs_max) {
subs = new Xop_tkn_itm[Tkn_subs_max];
subs_max = Tkn_subs_max;
subs_pos_ary = new int[(Tkn_subs_max + 1) * 2];
}
else {
for (int i = 0; i < subs_len; i++)
subs[i] = null;
}
subs_len = 0;
}
public void Clear() {
src_bgn = src_end = tkn_sub_idx = -1; ignore = false; tmpl_static = false;
Subs_clear();
}
@gplx.Virtual public void Tmpl_fmt(Xop_ctx ctx, byte[] src, Xot_fmtr fmtr) {fmtr.Reg_ary(ctx, src, tmpl_static, src_bgn, src_end, subs_len, subs);}
@gplx.Virtual public void Tmpl_compile(Xop_ctx ctx, byte[] src, Xot_compile_data prep_data) {
if (!ignore) tmpl_static = true;
for (int i = 0; i < subs_len; i++)
subs[i].Tmpl_compile(ctx, src, prep_data);
} boolean tmpl_static = false;
@gplx.Virtual public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) {
if (tmpl_static) bfr.Add_mid(src, src_bgn, src_end);
for (int i = 0; i < subs_len; i++)
subs[i].Tmpl_evaluate(ctx, src, caller, bfr);
return true;
}
static final String GRP_KEY = "xowa.tkn_base";
public static final int Tkn_subs_max = 16;
}

View File

@@ -0,0 +1,172 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.hdrs.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.xtns.cite.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.miscs.*;
public class Xop_tkn_mkr {
Xop_space_tkn space_tkn_immutable = new Xop_space_tkn(true, -1, -1);
public Xop_root_tkn Root(byte[] raw) {return new Xop_root_tkn().Root_src_(raw);}
public Xop_txt_tkn Txt(int bgn, int end) {return new Xop_txt_tkn(bgn, end);}
// public Xop_space_tkn Space(Xop_tkn_grp grp, int bgn, int end) {grp.Subs_src_pos_(grp.Subs_len(), bgn, end); return space_tkn_immutable;}
public Xop_space_tkn Space(Xop_tkn_grp grp, int bgn, int end) {Xop_space_tkn rv = new Xop_space_tkn(false, bgn, end); grp.Subs_src_pos_(grp.Subs_len(), bgn, end); return rv;}
public Xop_space_tkn Space_mutable(int bgn, int end) {return new Xop_space_tkn(false, bgn, end);}
public Xop_apos_tkn Apos(int bgn, int end
, int aposLen, int typ, int cmd, int lit_apos) {return new Xop_apos_tkn(bgn, end, aposLen, typ, cmd, lit_apos);}
public Xop_tkn_itm Amp_txt(int bgn, int end, Xop_amp_trie_itm itm) {return new Xop_amp_tkn_txt(bgn, end, itm);}
public Xop_tkn_itm Amp_num(int bgn, int end, int val_int, byte[] val_bry) {return new Xop_amp_tkn_num(bgn, end, val_int, val_bry);}
public Xop_tkn_itm Amp_num(int bgn, int end, int val_int) {return new Xop_amp_tkn_num(bgn, end, val_int, gplx.intl.Utf16_.Encode_int_to_bry(val_int));}
public Xop_nl_tkn NewLine(int bgn, int end, byte nl_typ, int nl_len) {return new Xop_nl_tkn(bgn, end, nl_typ, nl_len);}
public Xop_lnki_tkn Lnki(int bgn, int end) {return (Xop_lnki_tkn)new Xop_lnki_tkn().Tkn_ini_pos(false, bgn, end);}
public Xop_list_tkn List_bgn(int bgn, int end, byte listType, int symLen) {return Xop_list_tkn.bgn_(bgn, end, listType, symLen);}
public Xop_list_tkn List_end(int pos, byte listType) {return Xop_list_tkn.end_(pos, listType);}
public Xop_tkn_itm Pipe(int bgn, int end) {return new Xop_pipe_tkn(bgn, end);}
public Xop_tkn_itm Colon(int bgn, int end) {return new Xop_colon_tkn(bgn, end);}
public Xop_eq_tkn Eq(int bgn, int end) {return new Xop_eq_tkn(bgn, end, end - bgn);}
public Xop_eq_tkn Eq(int bgn, int end, int eq_len) {return new Xop_eq_tkn(bgn, end, eq_len);}
public Xot_invk_tkn Tmpl_invk(int bgn, int end) {return new Xot_invk_tkn(bgn, end);}
public Arg_nde_tkn ArgNde(int arg_idx, int bgn) {return new Arg_nde_tkn(arg_idx, bgn);}
public Arg_itm_tkn ArgItm(int bgn, int end) {return new Arg_itm_tkn_base(bgn, end);}
public Xop_xnde_tkn Xnde(int bgn, int end) {return (Xop_xnde_tkn)Xop_xnde_tkn.new_().Tkn_ini_pos(false, bgn, end);}
public Xop_hdr_tkn Hdr(int bgn, int end, int hdr_len) {return new Xop_hdr_tkn(bgn, end, hdr_len);}
public Xop_hr_tkn Hr(int bgn, int end, int hr_len) {return new Xop_hr_tkn(bgn, end, hr_len);}
public Xop_tab_tkn Tab(int bgn, int end) {return new Xop_tab_tkn(bgn, end);}
public Xop_curly_bgn_tkn Tmpl_curly_bgn(int bgn, int end) {return new Xop_curly_bgn_tkn(bgn, end);}
public Xop_tkn_itm Brack_bgn(int bgn, int end) {return new Xop_brack_bgn_tkn(bgn, end);}
public Xop_tkn_itm Brack_end(int bgn, int end) {return new Xop_brack_end_tkn(bgn, end);}
public Xop_lnke_tkn Lnke(int bgn, int end, byte[] protocol, byte proto_tid, byte lnke_typ, int lnk_bgn, int lnk_end) {
return new Xop_lnke_tkn(bgn, end, protocol, proto_tid, lnke_typ, lnk_bgn, lnk_end);
}
public Xop_tblw_tb_tkn Tblw_tb(int bgn, int end, boolean tblw_xml, boolean auto_created) {return new Xop_tblw_tb_tkn(bgn, end, tblw_xml, auto_created);}
public Xop_tblw_tr_tkn Tblw_tr(int bgn, int end, boolean tblw_xml, boolean auto_created) {return new Xop_tblw_tr_tkn(bgn, end, tblw_xml, auto_created);}
public Xop_tblw_td_tkn Tblw_td(int bgn, int end, boolean tblw_xml) {return new Xop_tblw_td_tkn(bgn, end, tblw_xml);}
public Xop_tblw_th_tkn Tblw_th(int bgn, int end, boolean tblw_xml) {return new Xop_tblw_th_tkn(bgn, end, tblw_xml);}
public Xop_tblw_tc_tkn Tblw_tc(int bgn, int end, boolean tblw_xml) {return new Xop_tblw_tc_tkn(bgn, end, tblw_xml);}
public Xot_prm_tkn Tmpl_prm(int bgn, int end) {return new Xot_prm_tkn(bgn, end);}
public Xop_para_tkn Para(int pos) {return new Xop_para_tkn(pos);}
public Xop_pre_tkn Para_pre_bgn(int pos) {return new Xop_pre_tkn(pos, pos, Xop_pre_tkn.Pre_tid_bgn, null);}
public Xop_pre_tkn Para_pre_end(int pos, Xop_tkn_itm bgn) {return new Xop_pre_tkn(pos, pos, Xop_pre_tkn.Pre_tid_end, bgn);}
public Xop_ignore_tkn Ignore(int bgn, int end, byte ignore_type) {return new Xop_ignore_tkn(bgn, end, ignore_type);}
public Xop_bry_tkn Bry_raw(int bgn, int end, byte[] bry) {return new Xop_bry_tkn(bgn, end, bry);}
public Xop_bry_tkn Bry_mid(byte[] src, int bgn, int end) {return new Xop_bry_tkn(bgn, end, Bry_.Mid(src, bgn, end));}
public Xop_under_tkn Under(int bgn, int end, int v) {return new Xop_under_tkn(bgn, end, v);}
public gplx.xowa.xtns.xowa_cmds.Xop_xowa_cmd Xnde_xowa_cmd() {return new gplx.xowa.xtns.xowa_cmds.Xop_xowa_cmd();}
public gplx.xowa.xtns.poems.Poem_nde Xnde_poem() {return new gplx.xowa.xtns.poems.Poem_nde();}
public Ref_nde Xnde_ref() {return new Ref_nde();}
public References_nde Xnde_references() {return new References_nde();}
public gplx.xowa.xtns.math.Math_nde Xnde_math() {return new gplx.xowa.xtns.math.Math_nde();}
public gplx.xowa.xtns.gallery.Gallery_xnde Xnde_gallery() {return new gplx.xowa.xtns.gallery.Gallery_xnde();}
public gplx.xowa.xtns.imaps.Imap_xnde Xnde_imageMap() {return new gplx.xowa.xtns.imaps.Imap_xnde();}
public gplx.xowa.xtns.hieros.Hiero_xnde Xnde_hiero() {return new gplx.xowa.xtns.hieros.Hiero_xnde();}
public gplx.xowa.xtns.graphs.Graph_xnde Xnde_graph() {return new gplx.xowa.xtns.graphs.Graph_xnde();}
public gplx.xowa.xtns.proofreadPage.Pp_pages_nde Xnde_pages() {return new gplx.xowa.xtns.proofreadPage.Pp_pages_nde();}
public gplx.xowa.xtns.proofreadPage.Pp_pagelist_nde Xnde_pagelist() {return new gplx.xowa.xtns.proofreadPage.Pp_pagelist_nde();}
public gplx.xowa.xtns.proofreadPage.Pp_pagequality_nde Xnde_pagequality() {return new gplx.xowa.xtns.proofreadPage.Pp_pagequality_nde();}
public gplx.xowa.xtns.lst.Lst_section_nde Xnde_section() {return new gplx.xowa.xtns.lst.Lst_section_nde();}
public gplx.xowa.xtns.categoryList.Xtn_categorylist_nde Xnde_categoryList() {return new gplx.xowa.xtns.categoryList.Xtn_categorylist_nde();}
public gplx.xowa.xtns.dynamicPageList.Dpl_xnde Xnde_dynamicPageList() {return new gplx.xowa.xtns.dynamicPageList.Dpl_xnde();}
public gplx.xowa.xtns.syntaxHighlight.Xtn_syntaxHighlight_nde Xnde_syntaxHighlight() {return new gplx.xowa.xtns.syntaxHighlight.Xtn_syntaxHighlight_nde();}
public gplx.xowa.xtns.templateData.Xtn_templateData_nde Xnde_templateData() {return new gplx.xowa.xtns.templateData.Xtn_templateData_nde();}
public gplx.xowa.xtns.rss.Rss_xnde Xnde_rss() {return new gplx.xowa.xtns.rss.Rss_xnde();}
public gplx.xowa.xtns.quiz.Quiz_xnde Xnde_quiz() {return new gplx.xowa.xtns.quiz.Quiz_xnde();}
public gplx.xowa.xtns.indicators.Indicator_xnde Xnde_indicator() {return new gplx.xowa.xtns.indicators.Indicator_xnde();}
public gplx.xowa.xtns.xowa_cmds.Xox_xowa_html_cmd Xnde_xowa_html() {return new gplx.xowa.xtns.xowa_cmds.Xox_xowa_html_cmd();}
public gplx.xowa.xtns.listings.Listing_xnde Xnde_listing(int tag_id) {return new gplx.xowa.xtns.listings.Listing_xnde(tag_id);}
public gplx.xowa.xtns.scores.Score_xnde Xnde_score() {return new gplx.xowa.xtns.scores.Score_xnde();}
public gplx.xowa.xtns.inputBox.Xtn_inputbox_nde Xnde_inputbox() {return new gplx.xowa.xtns.inputBox.Xtn_inputbox_nde();}
public gplx.xowa.xtns.translates.Xop_translate_xnde Xnde_translate() {return new gplx.xowa.xtns.translates.Xop_translate_xnde();}
public gplx.xowa.xtns.translates.Xop_languages_xnde Xnde_languages() {return new gplx.xowa.xtns.translates.Xop_languages_xnde();}
public gplx.xowa.xtns.translates.Xop_tvar_tkn Tvar(int tkn_bgn, int tkn_end, int key_bgn, int key_end, int txt_bgn, int txt_end, byte[] wikitext)
{return new gplx.xowa.xtns.translates.Xop_tvar_tkn(tkn_bgn, tkn_end, key_bgn, key_end, txt_bgn, txt_end, wikitext);}
public gplx.xowa.langs.vnts.Xop_vnt_tkn Vnt(int bgn_lhs, int bgn_rhs) {return new gplx.xowa.langs.vnts.Xop_vnt_tkn(bgn_lhs, bgn_rhs);}
public gplx.xowa.langs.vnts.Xop_vnt_eqgt_tkn Vnt_eqgt(int bgn, int end) {return new gplx.xowa.langs.vnts.Xop_vnt_eqgt_tkn(bgn, end);}
// public void Clear() {
// space_tkns_len = txt_tkns_len = 0;
// }
// public Xop_txt_tkn Txt(int bgn, int end) {
// Xop_txt_tkn rv = null;
// if (txt_tkns_len < txt_tkns_max) {
// rv = txt_tkns[txt_tkns_len];
// if (rv == null) {
// rv = new Xop_txt_tkn(bgn, end);
// txt_tkns[txt_tkns_len] = rv;
// }
// else {
// rv.Reset();
// rv.Src_rng_(bgn, end);
// }
// txt_tkns_len++;
// }
// else {
// rv = new Xop_txt_tkn(bgn, end);
// Txt_tkns_add(rv);
// }
// return rv;
//// return new Xop_txt_tkn(bgn, end);
// }
// public Xop_space_tkn Space(int bgn, int end) {
// Xop_space_tkn rv = null;
// if (space_tkns_len < space_tkns_max) {
// rv = space_tkns[space_tkns_len];
// if (rv == null) {
// rv = new Xop_space_tkn(bgn, end);
// space_tkns[space_tkns_len] = rv;
// }
// else {
// rv.Reset();
// rv.Src_rng_(bgn, end);
// }
// space_tkns_len++;
// }
// else {
// rv = new Xop_space_tkn(bgn, end);
// Space_tkns_add(rv);
// }
// return rv;
//// return new Xop_space_tkn(bgn, end);
// }
// private void Txt_tkns_add(Xop_txt_tkn sub) {
// int new_len = txt_tkns_len + 1;
// if (new_len > txt_tkns_max) {
// txt_tkns_max = new_len * 2;
// txt_tkns = Resize(txt_tkns, txt_tkns_len, txt_tkns_max);
// }
// txt_tkns[txt_tkns_len] = sub;
// txt_tkns_len = new_len;
// } private Xop_txt_tkn[] txt_tkns = new Xop_txt_tkn[0]; int txt_tkns_len, txt_tkns_max;
// Xop_txt_tkn[] Resize(Xop_txt_tkn[] src, int cur_len, int new_len) {
// Xop_txt_tkn[] rv = new Xop_txt_tkn[new_len];
// for (int i = 0; i < cur_len; i++)
// rv[i] = src[i];
// return rv;
// }
// private void Space_tkns_add(Xop_space_tkn sub) {
// int new_len = space_tkns_len + 1;
// if (new_len > space_tkns_max) {
// space_tkns_max = new_len * 2;
// space_tkns = Resize(space_tkns, space_tkns_len, space_tkns_max);
// }
// space_tkns[space_tkns_len] = sub;
// space_tkns_len = new_len;
// } private Xop_space_tkn[] space_tkns = new Xop_space_tkn[0]; int space_tkns_len, space_tkns_max;
// Xop_space_tkn[] Resize(Xop_space_tkn[] src, int cur_len, int new_len) {
// Xop_space_tkn[] rv = new Xop_space_tkn[new_len];
// for (int i = 0; i < cur_len; i++)
// rv[i] = src[i];
// return rv;
// }
}

View File

@@ -0,0 +1,53 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.parsers.tmpls.*;
public class Xop_tkn_null implements Xop_tkn_itm {
public byte Tkn_tid() {return Xop_tkn_itm_.Tid_null;}
public boolean Tkn_immutable() {return true;}
public Xop_tkn_grp Tkn_grp() {return Xop_tkn_grp_.Null;}
public Xop_tkn_itm Tkn_ini_pos(boolean immutable, int bgn, int end) {return this;}
public Xop_tkn_itm Tkn_grp_(Xop_tkn_grp grp, int sub_idx) {return this;}
public Xop_tkn_itm Tkn_clone(Xop_ctx ctx, int bgn, int end) {return this;}
public int Tkn_sub_idx() {return -1;}
public int Src_bgn() {return -1;}
public int Src_end() {return -1;}
public int Src_bgn_grp(Xop_tkn_grp grp, int sub_idx) {return -1;}
public int Src_end_grp(Xop_tkn_grp grp, int sub_idx) {return -1;}
public int Subs_src_bgn(int sub_idx) {return -1;}
public int Subs_src_end(int sub_idx) {return -1;}
public void Src_end_(int v) {}
public void Src_end_grp_(Xop_ctx ctx, Xop_tkn_grp grp, int sub_idx, int src_end) {}
public boolean Ignore() {return false;} public Xop_tkn_itm Ignore_y_() {return this;}
public int Subs_len() {return 0;}
public Xop_tkn_itm Subs_get(int i) {return null;}
public void Subs_add(Xop_tkn_itm sub) {}
public void Subs_add_grp(Xop_tkn_itm sub, Xop_tkn_grp old_grp, int old_sub_idx) {}
public void Subs_del_after(int pos_bgn) {}
public void Subs_clear() {}
public void Subs_move(Xop_tkn_itm tkn) {}
public Xop_tkn_itm Immutable_clone(Xop_ctx ctx, Xop_tkn_itm tkn, int sub_idx) {return this;}
public void Ignore_y_grp_(Xop_ctx ctx, Xop_tkn_grp grp, int sub_idx) {}
public void Subs_grp_(Xop_ctx ctx, Xop_tkn_itm tkn, Xop_tkn_grp grp, int sub_idx) {}
public void Subs_src_pos_(int sub_idx, int bgn, int end) {}
public void Clear() {}
public void Tmpl_fmt(Xop_ctx ctx, byte[] src, Xot_fmtr fmtr) {}
public void Tmpl_compile(Xop_ctx ctx, byte[] src, Xot_compile_data prep_data) {}
public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) {return true;}
public static final Xop_tkn_null Null_tkn = new Xop_tkn_null();
}

View 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; import gplx.*; import gplx.xowa.*;
public class Xop_txt_tkn extends Xop_tkn_itm_base {
public Xop_txt_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_txt;}
}
class Xop_colon_tkn extends Xop_tkn_itm_base {
public Xop_colon_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_colon;}
}
class Xop_brack_bgn_tkn extends Xop_tkn_itm_base {
public Xop_brack_bgn_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_brack_bgn;}
}
class Xop_brack_end_tkn extends Xop_tkn_itm_base {
public Xop_brack_end_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_brack_end;}
}

View File

@@ -0,0 +1,22 @@
/*
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; import gplx.*; import gplx.xowa.*;
import gplx.xowa.parsers.xndes.*;
public class Xow_mw_parser_mgr {
public Xop_xnde_tag_regy Xnde_tag_regy() {return xnde_tag_regy;} private final Xop_xnde_tag_regy xnde_tag_regy = new Xop_xnde_tag_regy();
}

View File

@@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers; import gplx.*; import gplx.xowa.*;
import gplx.xowa.parsers.apos.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.lnkes.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.miscs.*;
public class Xow_utl_mgr {
public Xow_utl_mgr(Xowe_wiki wiki) {this.wiki = wiki;} private Xowe_wiki wiki;
public Xop_parser Anchor_encode_parser() {
if (anchor_encode_parser == null) {
anchor_encode_parser = new Xop_parser(wiki, wiki.Parser().Tmpl_lxr_mgr(), Anchor_encode_lxr_mgr);
anchor_encode_parser.Init_by_wiki(wiki);
anchor_encode_parser.Init_by_lang(wiki.Lang());
}
return anchor_encode_parser;
} private Xop_parser anchor_encode_parser;
private static final Xop_lxr_mgr Anchor_encode_lxr_mgr
= new Xop_lxr_mgr(new Xop_lxr[]
{ Xop_pipe_lxr._, new Xop_eq_lxr(false), Xop_space_lxr._, Xop_tab_lxr._, Xop_nl_lxr._
, Xop_curly_bgn_lxr._, Xop_curly_end_lxr._
, Xop_amp_lxr._, Xop_colon_lxr._
, Xop_apos_lxr._
, Xop_lnki_lxr_bgn._, Xop_lnki_lxr_end._
, Xop_lnke_lxr._, Xop_lnke_end_lxr._
, Xop_xnde_lxr._
});
}

View File

@@ -0,0 +1,28 @@
/*
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.amps; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_html_num_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_amp_tkn_num.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_html_ncr;}
public int Html_ncr_val() {return html_ncr_val;} public Xop_html_num_tkn_chkr Html_ncr_val_(int v) {html_ncr_val = v; return this;} private int html_ncr_val = -1;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_amp_tkn_num actl = (Xop_amp_tkn_num)actl_obj;
err += mgr.Tst_val(html_ncr_val == -1, path, "html_ncr_val", html_ncr_val, actl.Val());
return err;
}
}

View File

@@ -0,0 +1,28 @@
/*
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.amps; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_html_txt_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_amp_tkn_txt.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_html_ref;}
public String Html_ref_key() {return html_ref_key;} public Xop_html_txt_tkn_chkr Html_ref_key_(String v) {html_ref_key = v; return this;} private String html_ref_key;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_amp_tkn_txt actl = (Xop_amp_tkn_txt)actl_obj;
err += mgr.Tst_val(html_ref_key == null, path, "html_ref_key", html_ref_key, String_.new_u8(actl.Xml_name_bry()));
return err;
}
}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.hdrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.parsers.xndes.*;
public class Xop_hdr_wkr implements Xop_ctx_wkr {
public void Ctor_ctx(Xop_ctx ctx) {}
public void Page_bgn(Xop_ctx ctx, Xop_root_tkn root) {}

View File

@@ -0,0 +1,40 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lists; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
public class Xop_colon_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_colon;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Byte_ascii.Colon, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
Xop_list_wkr listCtx = ctx.List();
if (listCtx.Dd_chk()) { // handle ";a:b" construct; REF.MW: Parser.php|doBlockLevels|; title : definition text
int prv_pos = cur_pos -1 ;
if ( ctx.Cur_tkn_tid() != Xop_tkn_itm_.Tid_lnki // ignore if inside link
&& prv_pos > 0
&& src[prv_pos] != Byte_ascii.Nl // only consider ":" which are not preceded by \n; DATE:2014-07-11 TODO: emulate Parser.php|findColonNoLinks which does much more logic to see if ";a:b" construct should apply
) {
listCtx.Dd_chk_(false);
return listCtx.MakeTkn_bgn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);
}
}
ctx.Subs_add(root, tkn_mkr.Colon(bgn_pos, cur_pos));
return cur_pos;
}
public static final Xop_colon_lxr _ = new Xop_colon_lxr();
}

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lists; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.parsers.tblws.*;
import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.xndes.*;
public class Xop_list_wkr implements Xop_ctx_wkr {
private int listId = 0; byte[] curSymAry = new byte[Max_list_depth]; int curSymLen = 0; byte[] prvSymAry = Bry_.Empty;
private HierPosAryBldr posBldr = new HierPosAryBldr(Max_list_depth);

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkes; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import org.junit.*; import gplx.xowa.parsers.xndes.*;
public class Xop_lnke_wkr_brack_tst {
@Before public void init() {fxt.Reset();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Brace_noText() {

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkes; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tkn_chkr_lnke extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_lnke_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_lnke;}
public Xop_tkn_chkr_lnke(int bgn, int end) {super.Src_rng_(bgn, end);}
public byte Lnke_typ() {return lnke_typ;} public Xop_tkn_chkr_lnke Lnke_typ_(byte v) {lnke_typ = v; return this;} private byte lnke_typ = Xop_lnke_tkn.Lnke_typ_null;
public Xop_tkn_chkr_lnke Lnke_rng_(int bgn, int end) {lnke_bgn = bgn; lnke_end = end; return this;} private int lnke_bgn = -1; int lnke_end = -1;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_lnke_tkn actl = (Xop_lnke_tkn)actl_obj;
err += mgr.Tst_val(lnke_typ == Xop_lnke_tkn.Lnke_typ_null, path, "lnke_typ", lnke_typ, actl.Lnke_typ());
err += mgr.Tst_val(lnke_bgn == -1, path, "lnke_bgn", lnke_bgn, actl.Lnke_bgn());
err += mgr.Tst_val(lnke_end == -1, path, "lnke_end", lnke_end, actl.Lnke_end());
return err;
}
}

View File

@@ -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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.net.*; import gplx.xowa.wikis.xwikis.*;
import gplx.xowa.html.*; import gplx.xowa.html.lnkis.*; import gplx.xowa.html.hrefs.*;
public class Xop_link_parser {
public byte[] Html_xowa_ttl() {return html_xowa_ttl;} private byte[] html_xowa_ttl;
public byte Html_anchor_cls() {return html_anchor_cls;} private byte html_anchor_cls;
public byte Html_anchor_rel() {return html_anchor_rel;} private byte html_anchor_rel;
public byte[] Parse(Bry_bfr tmp_bfr, Xoa_url tmp_url, Xowe_wiki wiki, byte[] raw, byte[] or) {
html_xowa_ttl = null; html_anchor_cls = Xoh_lnki_consts.Tid_a_cls_image; html_anchor_rel = Xoh_lnki_consts.Tid_a_rel_none; // default member variables for html
Xoae_app app = wiki.Appe(); int raw_len = raw.length;
wiki.Utl__url_parser().Parse(tmp_url, raw);
switch (tmp_url.Protocol_tid()) {
case Gfo_protocol_itm.Tid_http: case Gfo_protocol_itm.Tid_https: // "http:" or "https:"; check if to offline wiki and redirect
byte[] wiki_bry = tmp_url.Wiki_bry(), page_bry = tmp_url.Page_bry();
if ( !tmp_url.Wiki_is_missing() // https://www.a.org and others will be marked "missing" by Xoa_url_parser
&&( Bry_.Eq(wiki_bry, wiki.Domain_bry()) // link is to this wiki; check if alias
|| app.Xwiki_mgr__exists(wiki_bry) // link is to an xwiki
)
) {
page_bry = tmp_url.Page_for_lnki();
Parse__ttl(tmp_bfr, wiki, wiki_bry, page_bry);
}
else { // http is to an unknown site
if (tmp_url.Protocol_is_relative()) { // relative protocol; EX:"//www.a.org";
Gfo_protocol_itm protocol_itm = Gfo_protocol_itm.Get_or(wiki.Props().Protocol_tid(), Gfo_protocol_itm.Itm_https);
tmp_bfr.Add(protocol_itm.Key_w_colon_bry()); // prepend protocol b/c mozilla cannot launch "//www.a.org", but can launch "https://www.a.org"; DATE:2015-07-27
}
tmp_bfr.Add(raw); // dump everything
}
raw = tmp_bfr.Xto_bry_and_clear();
html_anchor_cls = Xoh_lnki_consts.Tid_a_cls_none;
html_anchor_rel = Xoh_lnki_consts.Tid_a_rel_nofollow;
break;
case Gfo_protocol_itm.Tid_file: // "file:///" or "File:A.png"
int proto_len = tmp_url.Protocol_bry().length;
if (proto_len + 1 < raw_len && raw[proto_len + 1] == Byte_ascii.Slash) { // next char is slash, assume xfer_itm refers to protocol; EX: file:///C/A.png
int slash_pos = Bry_finder.Find_bwd(raw, Byte_ascii.Slash);
if (slash_pos != Bry_.NotFound) // set xowa_title to file_name; TODO: call Xoa_url.build; note that this will fail sometimes when (a) xfer_itm is very long (File:ReallyLongName will be shortened to 128 chars) or (b) xfer_itm has invalid windows characters (EX:File:a"b"c.jpg)
html_xowa_ttl = Bry_.Mid(raw, slash_pos + Int_.Const_dlm_len, raw.length);
}
else // next char is not slash; assume xfer_itm refers to ns; EX:File:A.png
raw = tmp_bfr.Add(Xoh_href_.Bry__wiki).Add(raw).Xto_bry_and_clear();
break;
default: // is page only; EX: Abc
if (Bry_.Len_eq_0(raw)) // NOTE: handle blank link; EX: [[File:Loudspeaker.svg|11px|link=|alt=play]]
raw = or;
else {
if (raw[0] == Byte_ascii.Colon) raw = Bry_.Mid(raw, 1, raw.length); // ignore initial colon; EX: [[:commons:A.png]]
if (!Parse__ttl(tmp_bfr, wiki, wiki.Domain_bry(), raw)) {
tmp_bfr.Clear();
return null;
}
raw = tmp_bfr.Xto_bry_and_clear();
}
break;
}
return raw;
}
private static boolean Parse__ttl(Bry_bfr tmp_bfr, Xowe_wiki wiki, byte[] wiki_bry, byte[] page_bry) {
Xoa_ttl page_ttl = Xoa_ttl.parse(wiki, page_bry);
boolean page_ttl_is_valid = page_ttl != null;
if (page_ttl_is_valid) {
Xow_xwiki_itm xwiki_itm = page_ttl.Wik_itm();
if (xwiki_itm != null) { // is alias; set wiki, page
wiki_bry = xwiki_itm.Domain_bry();
page_bry = Bry_.Mid(page_bry, xwiki_itm.Key_bry().length + 1, page_bry.length); // +1 for ":"
}
else // is regular page; use ttl.Full_db() to normalize; EX: &nbsp; -> _
page_bry = page_ttl.Full_db();
}
if (Bry_.Eq(wiki_bry, wiki.Domain_bry())) // NOTE: check against wiki.Key_bry() again; EX: in en_wiki, and http://commons.wikimedia.org/wiki/w:A
tmp_bfr.Add(Xoh_href_.Bry__wiki).Add(page_bry);
else
tmp_bfr.Add(Xoh_href_.Bry__site).Add(wiki_bry).Add(Xoh_href_.Bry__wiki).Add(page_bry);
return page_ttl_is_valid;
}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_lnki_align_h {
public static final byte Null = 0, None = 1, Left = 2, Center = 3, Right = 4;
public static final byte[][] Html_names = new byte[][]
{ Object_.Bry__null
, Bry_.new_a7("none")
, Bry_.new_a7("left")
, Bry_.new_a7("center")
, Bry_.new_a7("right")
};
}
class Xop_lnki_align_v {
public static final byte None = 0, Top = 1, Middle = 2, Bottom = 4, Super = 8, Sub = 16, TextTop = 32, TextBottom = 64, Baseline = 127;
}

View File

@@ -0,0 +1,190 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.primitives.*; import gplx.core.btries.*;
import gplx.xowa.langs.numbers.*;
public class Xop_lnki_arg_parser {
private final Btrie_fast_mgr key_trie = Btrie_fast_mgr.cs();
private final Bry_bfr int_bfr = Bry_bfr.reset_(16);
private final Btrie_bwd_mgr px_trie = Btrie_bwd_mgr.cs_(); private final Btrie_fast_mgr size_trie = Btrie_fast_mgr.cs();
private int lnki_w, lnki_h;
public void Evt_lang_changed(Xol_lang lang) {
Bry_bfr tmp_bfr = int_bfr;
Byte_obj_ref rslt = Byte_obj_ref.zero_();
Xol_kwd_mgr mgr = lang.Kwd_mgr();
key_trie.Clear();
Xol_kwd_grp list = null;
int len = Keys_ids.length;
for (int i = 0; i < len; i++) {
int[] val = Keys_ids[i];
list = mgr.Get_at(val[0]); // NOTE: val[0] is magic_word id
if (list == null) {
if (Env_.Mode_testing())
continue; // TEST: allows partial parsing of $magicWords
else
list = lang.Lang_mgr().Lang_en().Kwd_mgr().Get_at(val[0]);
}
Xol_kwd_itm[] words = list.Itms();
int words_len = words.length;
for (int j = 0; j < words_len; j++) {
Xol_kwd_itm word = words[j];
byte[] word_bry = Xol_kwd_parse_data.Strip(tmp_bfr, word.Val(), rslt);
Init_key_trie(word_bry, (byte)val[1]); // NOTE: val[1] is lnki_key tid; ASSUME: case_sensitive for all "img_" words; note that all Messages**.php seem to be case_sensitive ("array(1, ..."); resisting change b/c of complexity/perf (need a cs trie and a ci trie)
}
}
list = mgr.Get_at(Xol_kwd_grp_.Id_img_width);
if (list == null)
list = lang.Lang_mgr().Lang_en().Kwd_mgr().Get_at(Xol_kwd_grp_.Id_img_width);
Init_size_trie(tmp_bfr, lang.Num_mgr().Digits_mgr(), list);
}
public byte Identify_tid(byte[] src, int bgn, int end, Xop_lnki_tkn lnki) {
lnki_w = Xop_lnki_tkn.Width_null;
lnki_h = Xop_lnki_tkn.Height_null;
byte rv = Identify_tid(src, bgn, end);
if (lnki_w != Xop_lnki_tkn.Width_null) lnki.W_(lnki_w);
if (lnki_h != Xop_lnki_tkn.Height_null)lnki.H_(lnki_h);
return rv;
}
public byte Identify_tid(byte[] src, int bgn, int end) {
int len = end - bgn;
Byte_obj_val val = (Byte_obj_val)key_trie.Match_bgn(src, bgn, end);
if (val != null && len == key_trie.Match_pos() - bgn) // check for false matches; EX: alternate= should not match alt=
return val.Val(); // match; return val;
Object bwd_obj = px_trie.Match_bgn(src, end - 1, bgn - 1);
if (bwd_obj != null && ((Byte_obj_val)bwd_obj).Val() == Tid_dim) { // ends with "px"; try to parse size
int_bfr.Clear();
int match_len = end -1 - px_trie.Match_pos();
boolean mode_width = true;
int itm_end = bgn + (len - match_len); // remove trailing px
for (int i = bgn; i < itm_end; i++) {
byte b = src[i];
Object o = size_trie.Match_bgn_w_byte(b, src, i, itm_end);
if (o == null) {
this.lnki_w = Xop_lnki_tkn.Width_null; // NOTE: must null out width; EX: "123xTextpx"; PAGE:es.b:Alimentación_infantil; DATE:2015-07-10; NOTE: must be -1, not 0; DATE:2015-08-05
return Tid_caption; // letter or other invalid character; return caption
}
Byte_obj_val v = (Byte_obj_val)o;
switch (v.Val()) { // NOTE: d0 - d9 handle non-english numbers; EX:fa.w and ۲۰۰px; DATE:2015-07-18
case Key_dim_d0: int_bfr.Add_byte(Byte_ascii.Num_0); i += (size_trie.Match_pos() - i) - 1; break; // -1 b/c loop will ++i
case Key_dim_d1: int_bfr.Add_byte(Byte_ascii.Num_1); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d2: int_bfr.Add_byte(Byte_ascii.Num_2); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d3: int_bfr.Add_byte(Byte_ascii.Num_3); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d4: int_bfr.Add_byte(Byte_ascii.Num_4); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d5: int_bfr.Add_byte(Byte_ascii.Num_5); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d6: int_bfr.Add_byte(Byte_ascii.Num_6); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d7: int_bfr.Add_byte(Byte_ascii.Num_7); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d8: int_bfr.Add_byte(Byte_ascii.Num_8); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_d9: int_bfr.Add_byte(Byte_ascii.Num_9); i += (size_trie.Match_pos() - i) - 1; break;
case Key_dim_num: int_bfr.Add_byte(b); break;
case Key_space: break; // ignore space; EX: "100 px"
case Key_dim_px: { // 2nd px found; EX: "40pxpx"; "40px px"
int tmp_pos = size_trie.Match_pos();
tmp_pos = Bry_finder.Find_fwd_while_space_or_tab(src, tmp_pos, itm_end); // look for next ws pos;
if (tmp_pos == itm_end) // no non-ws found; tmp_pos == itm_end; allow itm; EX: "40pxpx"; "40px px"; DATE:2014-03-01
i = itm_end;
else // non-ws found; consider as caption; EX: "20px20px"; "20pxpxpx"
return Tid_caption;
break;
}
case Key_dim_x: {
if (mode_width) {
this.lnki_w = int_bfr.XtoIntAndClear(-1);
mode_width = false;
break;
}
else return Tid_caption;
}
}
}
int dim = int_bfr.XtoIntAndClear(-1);
if (mode_width) this.lnki_w = dim;
else this.lnki_h = dim;
return Tid_dim;
}
return Tid_caption;
}
private void Init_key_trie(byte[] key, byte v) {
Byte_obj_val val = Byte_obj_val.new_(v);
key_trie.Add(key, val);
}
private void Init_size_trie(Bry_bfr tmp_bfr, Xol_transform_mgr digit_mgr, Xol_kwd_grp list) {
if (list == null && Env_.Mode_testing()) return; // TEST: allows partial parsing of $magicWords
size_trie.Clear(); px_trie.Clear();
for (int i = 0; i < 10; i++)
size_trie.Add((byte)(i + Char_.AsciiZero), Byte_obj_val.new_(Key_dim_num));
int len = digit_mgr.Len(); // NOTE: add non-english numbers; EX: ۲۰۰px; DATE:2015-07-18
for (int i = 0; i < len; ++i) {
KeyVal kv = digit_mgr.Get_at(i);
int num = (byte)Int_.parse_or(kv.Key(), -1); if (num == -1) continue; // ignore separators; EX: "," "."
size_trie.Add((byte[])kv.Val(), Byte_obj_val.new_((byte)num)); // NOTE: num corresponds to dim_d0 -> d9 below
}
size_trie.Add(Byte_ascii.Space, Byte_obj_val.new_(Key_space));
size_trie.Add(X_bry, Byte_obj_val.new_(Key_dim_x));
Xol_kwd_itm[] words = list.Itms();
int words_len = words.length;
Byte_obj_ref rslt = Byte_obj_ref.zero_();
for (int i = 0; i < words_len; i++) {
byte[] word_bry = Xol_kwd_parse_data.Strip(tmp_bfr, words[i].Val(), rslt);
size_trie.Add(word_bry, Byte_obj_val.new_(Key_dim_px));
px_trie.Add(word_bry, Byte_obj_val.new_(Tid_dim));
}
}
public static final byte[] Bry_upright = Bry_.new_a7("upright"), Bry_thumbtime = Bry_.new_a7("thumbtime");
public static final byte
Tid_unknown = 0, Tid_thumb = 1, Tid_left = 2, Tid_right = 3, Tid_none = 4, Tid_center = 5, Tid_frame = 6, Tid_frameless = 7, Tid_upright = 8, Tid_border = 9
, Tid_alt = 10, Tid_link = 11, Tid_baseline = 12, Tid_sub = 13, Tid_super = 14, Tid_top = 15, Tid_text_top = 16, Tid_middle = 17, Tid_bottom = 18, Tid_text_bottom = 19
, Tid_dim = 20
, Tid_trg = 21, Tid_caption = 22
, Tid_page = 23
, Tid_noplayer = 24, Tid_noicon = 25, Tid_thumbtime = 26
, Tid_class = 27
;
private static final byte[] X_bry = Bry_.new_a7("x");
private static final byte // NOTE: d0 - d9 must match 0 - 9; DATE:2015-07-18
Key_dim_d0 = 0, Key_dim_d1 = 1, Key_dim_d2 = 2, Key_dim_d3 = 3, Key_dim_d4 = 4
, Key_dim_d5 = 5, Key_dim_d6 = 6, Key_dim_d7 = 7, Key_dim_d8 = 8, Key_dim_d9 = 9
, Key_dim_num = 10, Key_dim_x = 11, Key_dim_px = 12, Key_space = 13
;
private static final int[][] Keys_ids = new int[][]
{ new int[] {Xol_kwd_grp_.Id_img_thumbnail , Tid_thumb}
, new int[] {Xol_kwd_grp_.Id_img_manualthumb , Tid_thumb} // RESEARCH: what is manualthumb? 'thumb=$1' vs 'thumb'
, new int[] {Xol_kwd_grp_.Id_img_right , Tid_right}
, new int[] {Xol_kwd_grp_.Id_img_left , Tid_left}
, new int[] {Xol_kwd_grp_.Id_img_none , Tid_none}
, new int[] {Xol_kwd_grp_.Id_img_center , Tid_center}
, new int[] {Xol_kwd_grp_.Id_img_framed , Tid_frame}
, new int[] {Xol_kwd_grp_.Id_img_frameless , Tid_frameless}
, new int[] {Xol_kwd_grp_.Id_img_page , Tid_page} // for pdf
, new int[] {Xol_kwd_grp_.Id_img_upright , Tid_upright}
, new int[] {Xol_kwd_grp_.Id_img_border , Tid_border}
, new int[] {Xol_kwd_grp_.Id_img_baseline , Tid_baseline}
, new int[] {Xol_kwd_grp_.Id_img_sub , Tid_sub}
, new int[] {Xol_kwd_grp_.Id_img_super , Tid_super}
, new int[] {Xol_kwd_grp_.Id_img_top , Tid_top}
, new int[] {Xol_kwd_grp_.Id_img_text_top , Tid_text_top}
, new int[] {Xol_kwd_grp_.Id_img_middle , Tid_middle}
, new int[] {Xol_kwd_grp_.Id_img_bottom , Tid_bottom}
, new int[] {Xol_kwd_grp_.Id_img_text_bottom , Tid_text_bottom}
, new int[] {Xol_kwd_grp_.Id_img_link , Tid_link}
, new int[] {Xol_kwd_grp_.Id_img_alt , Tid_alt}
, new int[] {Xol_kwd_grp_.Id_img_class , Tid_class}
, new int[] {Xol_kwd_grp_.Id_ogg_noplayer , Tid_noplayer} // RESEARCH: what does noplayer do?; find example
, new int[] {Xol_kwd_grp_.Id_ogg_noicon , Tid_noicon}
, new int[] {Xol_kwd_grp_.Id_ogg_thumbtime , Tid_thumbtime}
};
}

View File

@@ -0,0 +1,28 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_lnki_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "lnki");
public static final Gfo_msg_itm
Upright_val_is_invalid = Gfo_msg_itm_.new_warn_(owner, "upright_val_is_invalid")
, Escaped_lnki = Gfo_msg_itm_.new_warn_(owner, "escaped_lnki")
, Key_is_empty = Gfo_msg_itm_.new_warn_(owner, "key_is_empty")
, Ext_is_missing = Gfo_msg_itm_.new_warn_(owner, "ext_is_missing")
, Invalid_ttl = Gfo_msg_itm_.new_warn_(owner, "invalid_ttl")
;
}

View File

@@ -0,0 +1,56 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.tmpls.*;
public class Xop_lnki_lxr_bgn implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_lnki_bgn;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_bgn, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
Xop_tkn_itm prv_tkn = ctx.Stack_get_last();
if (prv_tkn != null
&& prv_tkn.Tkn_tid() == Xop_tkn_itm_.Tid_lnki) {
Xop_lnki_tkn prv_lnki = (Xop_lnki_tkn)prv_tkn;
if (prv_lnki.Pipe_count() == 0) {
ctx.Stack_pop_last();
return Xop_lnki_wkr_.Invalidate_lnki(ctx, src, root, prv_lnki, bgn_pos);
}
}
Xop_lnki_tkn lnki = tkn_mkr.Lnki(bgn_pos, cur_pos);
ctx.Subs_add_and_stack(root, lnki);
return cur_pos;
}
public static final Xop_lnki_lxr_bgn _ = new Xop_lnki_lxr_bgn();
}
class Xop_lnki_size {public static final int None = 0, Width = 1, Height = 2, WidthHeight = 4, Upright = 8;}
/*
Spaces + NewLines
. ignored near posts: '[[ '; ' ]]'; ' | '
. not ignored in: ' ='; basically breaks key
. not ignored in: '= '; will add to value; EX: alt= a -> ' a'
NewLines
. will break lnk if in trg area (before | or ]]); EX:[[Image:The\nFabs -> [[Image:The Fabs
. will break alt (which apparently does not like new lines)
. will be converted to space for caption
http://en.wikipedia.org/wiki/Wikipedia:Extended_image_syntax
The image syntax begins with "[[", contains components separated by "|", and ends with "]]". The "[[" and the first "|" (or, if there is no "|", the terminating "]]")
must be on the same line; other spaces and line breaks are ignored if they are next to "|" characters or just inside the brackets.
Spaces or line breaks are not allowed just before the "=" in the following options, and may have undesirable side effects if they appear just after the "=".
*/

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.tmpls.*;
public class Xop_lnki_lxr_end implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_lnki_end;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Xop_tkn_.Lnki_end, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {return ctx.Lnki().Make_tkn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos);}
public static final Xop_lnki_lxr_end _ = new Xop_lnki_lxr_end();
}

View File

@@ -0,0 +1,65 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.files.*; import gplx.xowa.html.*; import gplx.xowa.html.lnkis.*; import gplx.xowa.xtns.pfuncs.ttls.*;
import gplx.xowa.parsers.tmpls.*;
public class Xop_lnki_tkn extends Xop_tkn_itm_base {
@Override public byte Tkn_tid() {return tkn_tid;} private byte tkn_tid = Xop_tkn_itm_.Tid_lnki;
public void Tkn_tid_to_txt() {tkn_tid = Xop_tkn_itm_.Tid_txt;}
public int Ns_id() {return ns_id;} public Xop_lnki_tkn Ns_id_(int v) {ns_id = v; return this;} private int ns_id;
public Xoa_ttl Ttl() {return ttl;} public Xop_lnki_tkn Ttl_(Xoa_ttl v) {ttl = v; return this;} private Xoa_ttl ttl;
public byte Lnki_type() {return lnki_type;} public Xop_lnki_tkn Lnki_type_(byte v) {lnki_type = (byte)Enm_.Add_int(lnki_type, v); return this;} private byte lnki_type = Xop_lnki_type.Id_null;
public int Tail_bgn() {return tail_bgn;} public Xop_lnki_tkn Tail_bgn_(int v) {tail_bgn = v; return this;} private int tail_bgn = -1;
public int Tail_end() {return tail_end;} public Xop_lnki_tkn Tail_end_(int v) {tail_end = v; return this;} private int tail_end = -1;
public byte Border() {return border;} public Xop_lnki_tkn Border_(byte v) {border = v; return this;} private byte border = Bool_.__byte;
public byte Align_h() {return align_h;} public Xop_lnki_tkn Align_h_(byte v) {if (align_h == Xop_lnki_align_h.Null) align_h = v; return this;} private byte align_h = Xop_lnki_align_h.Null;
public byte Align_v() {return align_v;} public Xop_lnki_tkn Align_v_(byte v) {align_v = v; return this;} private byte align_v = Byte_.Max_value_127;
public int W() {return w;} public Xop_lnki_tkn W_(int v) {w = v; return this;} private int w = Width_null;
public int H() {return h;} public Xop_lnki_tkn H_(int v) {h = v; return this;} private int h = Height_null;
public byte[] Lnki_cls() {return lnki_cls;} public void Lnki_cls_(byte[] v) {lnki_cls = v;} private byte[] lnki_cls;
public boolean Media_icon() {return media_icon;} public Xop_lnki_tkn Media_icon_n_() {media_icon = false; return this;} private boolean media_icon = true;
public double Upright() {return upright;} public Xop_lnki_tkn Upright_(double v) {upright = v; return this;} private double upright = Upright_null;
public double Time() {return time;} public Xop_lnki_tkn Time_(double v) {time = v; return this;} private double time = Xof_lnki_time.Null;
public int Page() {return page;} public Xop_lnki_tkn Page_(int v) {page = v; return this;} private int page = Xof_lnki_page.Null;
public Xop_tkn_itm Trg_tkn() {return trg_tkn;} public Xop_lnki_tkn Trg_tkn_(Xop_tkn_itm v) {trg_tkn = v; return this;} private Xop_tkn_itm trg_tkn = Xop_tkn_null.Null_tkn;
public Xop_tkn_itm Caption_tkn() {return caption_tkn;} public Xop_lnki_tkn Caption_tkn_(Xop_tkn_itm v) {caption_tkn = v; return this;} private Xop_tkn_itm caption_tkn = Xop_tkn_null.Null_tkn;
public boolean Caption_tkn_pipe_trick() {return caption_tkn_pipe_trick;} public Xop_lnki_tkn Caption_tkn_pipe_trick_(boolean v) {caption_tkn_pipe_trick = v; return this;} private boolean caption_tkn_pipe_trick;
public Xop_tkn_itm Caption_val_tkn() {return caption_tkn == Xop_tkn_null.Null_tkn ? Arg_itm_tkn_null.Null_arg_itm : ((Arg_nde_tkn)caption_tkn).Val_tkn();}
public Arg_nde_tkn Link_tkn() {return link_tkn;} public Xop_lnki_tkn Link_tkn_(Arg_nde_tkn v) {link_tkn = v; return this;} Arg_nde_tkn link_tkn = Arg_nde_tkn.Null;
public Arg_nde_tkn Alt_tkn() {return alt_tkn;} public Xop_lnki_tkn Alt_tkn_(Arg_nde_tkn v) {alt_tkn = v; return this;} Arg_nde_tkn alt_tkn = Arg_nde_tkn.Null;
public boolean Alt_exists() {return alt_tkn != Arg_nde_tkn.Null;}
public int Subpage_tid() {return subpage_tid;} public Xop_lnki_tkn Subpage_tid_(int v) {subpage_tid = v; return this;} private int subpage_tid = Pfunc_rel2abs.Id_null;
public boolean Subpage_slash_at_end() {return subpage_slash_at_end;} public Xop_lnki_tkn Subpage_slash_at_end_(boolean v) {subpage_slash_at_end = v; return this;} private boolean subpage_slash_at_end;
public int Html_uid() {return html_uid;} public Xop_lnki_tkn Html_uid_(int v) {html_uid = v; return this;} private int html_uid;
public int Pipe_count() {return pipe_count;} private int pipe_count;
public boolean Pipe_count_is_zero() {return pipe_count++ == 0;}
public boolean Xtn_sites_link() {return xtn_sites_link;} public void Xtn_sites_link_(boolean v) {xtn_sites_link = v;} private boolean xtn_sites_link;
public Xoh_file_img_wkr Lnki_file_wkr() {return lnki_file_wkr;} public void Lnki_file_wkr_(Xoh_file_img_wkr v) {lnki_file_wkr = v;} private Xoh_file_img_wkr lnki_file_wkr;
public byte[] Ttl_ary() {
return ttl.ForceLiteralLink() || ns_id != Xow_ns_.Id_main // if [[:]] or non-main (Category, Template)
? ttl.Full_txt() // use full_txt (no initial colon; capitalize first)
: ttl.Raw(); // use raw (preserve case, white-spaces)
}
public boolean Caption_exists() {
return !((caption_tkn == Xop_tkn_null.Null_tkn) // trg only; no caption: EX: [[a]] vs. [[a|b]] which has a trg of a and a caption of b
|| (ns_id == Xow_ns_.Id_category // a Category only has a target; any caption is ignored; EX: [[Category:a|b], b is ignored
&& !ttl.ForceLiteralLink()));
}
public static final double Upright_null = -1;
public static final int Width_null = -1, Height_null = -1;
}

View File

@@ -0,0 +1,59 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.files.*;
public class Xop_lnki_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_lnki_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_lnki;}
public int Ns_id() {return nsId;} public Xop_lnki_tkn_chkr Ns_id_(int v) {nsId = v; return this;} private int nsId = Int_.Min_value;
public byte ImgType() {return imgType;} public Xop_lnki_tkn_chkr ImgType_(byte v) {imgType = v; return this;} private byte imgType = Byte_.Max_value_127;
public int Width() {return width;} public Xop_lnki_tkn_chkr Width_(int v) {width = v; return this;} private int width = Int_.Min_value;
public int Height() {return height;} public Xop_lnki_tkn_chkr Height_(int v) {height = v; return this;} private int height = Int_.Min_value;
public byte HAlign() {return hAlign;} public Xop_lnki_tkn_chkr HAlign_(byte v) {hAlign = v; return this;} private byte hAlign = Byte_.Max_value_127;
public byte VAlign() {return vAlign;} public Xop_lnki_tkn_chkr VAlign_(byte v) {vAlign = v; return this;} private byte vAlign = Byte_.Max_value_127;
public byte Border() {return border;} public Xop_lnki_tkn_chkr Border_(byte v) {border = v; return this;} private byte border = Bool_.__byte;
public double Upright() {return upright;} public Xop_lnki_tkn_chkr Upright_(double v) {upright = v; return this;} double upright = Xop_lnki_tkn.Upright_null;
public int Thumbtime() {return thumbtime;} public Xop_lnki_tkn_chkr Thumbtime_(int v) {thumbtime = v; return this;} int thumbtime = Xof_lnki_time.Null_as_int;
public int Page() {return page;} public Xop_lnki_tkn_chkr Page_(int v) {page = v; return this;} int page = Xof_lnki_page.Null;
public int Tail_bgn() {return tail_bgn;} public Xop_lnki_tkn_chkr Tail_bgn_(int v) {tail_bgn = v; return this;} private int tail_bgn = String_.Pos_neg1;
public int Tail_end() {return tail_end;} public Xop_lnki_tkn_chkr Tail_end_(int v) {tail_end = v; return this;} private int tail_end = String_.Pos_neg1;
public Xop_tkn_chkr_base Trg_tkn() {return trg_tkn;} public Xop_lnki_tkn_chkr Trg_tkn_(Xop_tkn_chkr_base v) {trg_tkn = v; return this;} private Xop_tkn_chkr_base trg_tkn;
public Xop_tkn_chkr_base Caption_tkn() {return caption_tkn;} public Xop_lnki_tkn_chkr Caption_tkn_(Xop_tkn_chkr_base v) {caption_tkn = v; return this;} private Xop_tkn_chkr_base caption_tkn;
public Xop_tkn_chkr_base Alt_tkn() {return alt_tkn;} public Xop_lnki_tkn_chkr Alt_tkn_(Xop_tkn_chkr_base v) {alt_tkn = v; return this;} private Xop_tkn_chkr_base alt_tkn;
public Xop_tkn_chkr_base Link_tkn() {return link_tkn;} public Xop_lnki_tkn_chkr Link_tkn_(Xop_tkn_chkr_base v) {link_tkn = v; return this;} private Xop_tkn_chkr_base link_tkn;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_lnki_tkn actl = (Xop_lnki_tkn)actl_obj;
err += mgr.Tst_val(nsId == Int_.Min_value, path, "nsId", nsId, actl.Ns_id());
err += mgr.Tst_val(imgType == Byte_.Max_value_127, path, "imgType", imgType, actl.Lnki_type());
err += mgr.Tst_val(width == Int_.Min_value, path, "width", width, actl.W());
err += mgr.Tst_val(height == Int_.Min_value, path, "height", height, actl.H());
err += mgr.Tst_val(hAlign == Byte_.Max_value_127, path, "halign", hAlign, actl.Align_h());
err += mgr.Tst_val(vAlign == Byte_.Max_value_127, path, "valign", vAlign, actl.Align_v());
err += mgr.Tst_val(border == Bool_.__byte, path, "border", border, actl.Border());
err += mgr.Tst_val(tail_bgn == String_.Pos_neg1, path, "tail_bgn", tail_bgn, actl.Tail_bgn());
err += mgr.Tst_val(tail_end == String_.Pos_neg1, path, "tail_end", tail_end, actl.Tail_end());
err += mgr.Tst_val(upright == Xop_lnki_tkn.Upright_null, path, "upright", upright, actl.Upright());
err += mgr.Tst_val(thumbtime == Xof_lnki_time.Null, path, "thumbtime", thumbtime, Xof_lnki_time.X_int(actl.Time()));
err += mgr.Tst_val(page == Xof_lnki_page.Null, path, "page", page, actl.Page());
if (trg_tkn != null) err += mgr.Tst_sub_obj(trg_tkn, actl.Trg_tkn(), path + "." + "trg", err);
if (caption_tkn != null) err += mgr.Tst_sub_obj(caption_tkn, actl.Caption_tkn(), path + "." + "caption", err);
if (alt_tkn != null) err += mgr.Tst_sub_obj(alt_tkn, actl.Alt_tkn(), path + "." + "alt", err);
if (link_tkn != null) err += mgr.Tst_sub_obj(link_tkn, actl.Link_tkn(), path + "." + "link", err);
return err;
}
}

View File

@@ -0,0 +1,65 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_lnki_type {
public static final byte Id_null = 0, Id_none = 1, Id_frameless = 2, Id_frame = 4, Id_thumb = 8;
public static boolean Id_is_thumbable(byte id) {
return ( Enm_.Has_int(id, Id_thumb) // for purposes of displaying images on page, thumb and frame both create a thumb box
|| Enm_.Has_int(id, Id_frame)
);
}
public static boolean Id_defaults_to_thumb(byte id) { // assuming original of 400,200
if ( Enm_.Has_int(id, Id_thumb) // [[File:A.png|thumb]] -> 220,-1
|| Enm_.Has_int(id, Id_frameless) // [[File:A.png|frameless]] -> 220,-1
)
return true;
else if ( Enm_.Has_int(id, Id_frame) // [[File:A.png|frame]] -> 400,200 (frame is always default size)
|| id == Id_null // [[File:A.png]] -> 400,200 (default to original size)
|| Enm_.Has_int(id, Id_none) // TODO: deprecate; NOTE: still used by one test; DATE:2015-08-03
)
return false;
else // should not happen
throw Err_.new_unhandled(id);
}
public static boolean Id_limits_large_size(byte id) {// Linker.php|makeThumbLink2|Do not present an image bigger than the source, for bitmap-style images; assuming original of 400,200
if ( Enm_.Has_int(id, Id_thumb) // [[File:A.png|600px|thumb]] -> 400,200
|| Enm_.Has_int(id, Id_frameless) // [[File:A.png|600px|frameless]] -> 400,200
|| Enm_.Has_int(id, Id_frame) // [[File:A.png|600px|frame]] -> 400,200 (frame is always default size)
)
return true;
else if ( id == Id_null // [[File:A.png|600px]] -> 600,400; uses orig file of 400,200, but <img> tag src_width / src_height set to 600,400
|| Enm_.Has_int(id, Id_none) // TODO: deprecate; NOTE: leaving in b/c of above failed-deprecate; DATE:2015-08-03
)
return false;
else // should not happen;
throw Err_.new_unhandled(id);
}
public static boolean Id_supports_upright(byte id) {// REF:Linker.php|makeImageLink;if ( isset( $fp['thumbnail'] ) || isset( $fp['manualthumb'] ) || isset( $fp['framed'] ) || isset( $fp['frameless'] ) || !$hp['width'] ) DATE:2014-05-22
if ( Enm_.Has_int(id, Id_thumb)
|| Enm_.Has_int(id, Id_frameless)
|| Enm_.Has_int(id, Id_frame)
)
return true;
else if ( id == Id_null
|| Enm_.Has_int(id, Id_none)
)
return false;
else // should not happen;
throw Err_.new_unhandled(id);
}
}

View File

@@ -0,0 +1,178 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
import gplx.xowa.wikis.*; import gplx.xowa.parsers.lnkis.redlinks.*; import gplx.xowa.xtns.pfuncs.ttls.*; import gplx.xowa.xtns.relatedSites.*;
import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.miscs.*;
public class Xop_lnki_wkr implements Xop_ctx_wkr, Xop_arg_wkr {
private Arg_bldr arg_bldr = Arg_bldr._;
private Number_parser number_parser = new Number_parser();
private Sites_regy_mgr sites_regy_mgr;
public void Ctor_ctx(Xop_ctx ctx) {}
public void Page_bgn(Xop_ctx ctx, Xop_root_tkn root) {
sites_regy_mgr = ctx.Wiki().Xtn_mgr().Xtn_sites().Regy_mgr(); if (!sites_regy_mgr.Xtn_mgr().Enabled()) sites_regy_mgr = null; // sets sites_xtn_mgr status for page; see below
}
public void Page_end(Xop_ctx ctx, Xop_root_tkn root, byte[] src, int src_len) {}
public Xopg_redlink_logger File_wkr() {return file_wkr;} public Xop_lnki_wkr File_wkr_(Xopg_redlink_logger v) {file_wkr = v; return this;} private Xopg_redlink_logger file_wkr;
public void Auto_close(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, Xop_tkn_itm tkn) {
Xop_lnki_tkn lnki = (Xop_lnki_tkn)tkn;
lnki.Tkn_tid_to_txt();
ctx.Msg_log().Add_itm_none(Xop_misc_log.Eos, src, lnki.Src_bgn(), lnki.Src_end());
}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
if (ctx.Cur_tkn_tid() == Xop_tkn_itm_.Tid_lnke) { // if lnke then take 1st ] in "]]" and use it close lnke
int lnke_end_pos = bgn_pos + 1;
ctx.Lnke().MakeTkn_end(ctx, tkn_mkr, root, src, src_len, bgn_pos, lnke_end_pos);
return lnke_end_pos;
}
int stack_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_lnki);
if (stack_pos == Xop_ctx.Stack_not_found) return ctx.Lxr_make_txt_(cur_pos); // "]]" found but no "[[" in stack; return literal "]]"
Xop_lnki_tkn lnki = (Xop_lnki_tkn)ctx.Stack_pop_til(root, src, stack_pos, false, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_lnki_end);
if (!arg_bldr.Bld(ctx, tkn_mkr, this, Xop_arg_wkr_.Typ_lnki, root, lnki, bgn_pos, cur_pos, lnki.Tkn_sub_idx() + 1, root.Subs_len(), src))
return Xop_lnki_wkr_.Invalidate_lnki(ctx, src, root, lnki, bgn_pos);
if (Xop_lnki_wkr_.Adjust_for_brack_end_len_of_3(ctx, tkn_mkr, root, src, src_len, cur_pos, lnki)) // convert "]]]" into "]" + "]]", not "]]" + "]"
++cur_pos; // position "]]" at end of "]]]"
cur_pos = Xop_lnki_wkr_.Chk_for_tail(ctx.Lang(), src, cur_pos, src_len, lnki);
lnki.Src_end_(cur_pos); // NOTE: must happen after Chk_for_tail; redundant with above, but above needed b/c of returns
root.Subs_del_after(lnki.Tkn_sub_idx() + 1); // all tkns should now be converted to args in owner; delete everything in root
boolean lnki_is_file = false;
switch (lnki.Ns_id()) {
case Xow_ns_.Id_file:
if ( Xop_lnki_type.Id_is_thumbable(lnki.Lnki_type()) // thumbs produce <div> cancels pre
|| lnki.Align_h() != Xop_lnki_align_h.Null // halign (left, right, none) also produces <div>; DATE:2014-02-17
)
ctx.Para().Process_block_lnki_div();
lnki_is_file = true;
break;
case Xow_ns_.Id_media:
lnki_is_file = true;
break;
case Xow_ns_.Id_category:
if (!lnki.Ttl().ForceLiteralLink()) // NOTE: do not remove ws if literal; EX:[[Category:A]]\n[[Category:B]] should stay the same; DATE:2013-07-10
ctx.Para().Process_lnki_category(ctx, root, src,cur_pos, src_len); // removes excessive ws between categories; EX: [[Category:A]]\n\s[[Category:B]] -> [[Category:A]][[Category:B]] (note that both categories will not be rendered directly in html, but go to the bottom of the page)
break;
}
if (lnki_is_file) {
ctx.Cur_page().Lnki_list().Add(lnki);
if (file_wkr != null) file_wkr.Wkr_exec(ctx, src, lnki, gplx.xowa.bldrs.cmds.files.Xob_lnki_src_tid.Tid_file);
}
Xoa_ttl lnki_ttl = lnki.Ttl();
if ( lnki_ttl.Wik_bgn() != -1 // lnki is xwiki
&& sites_regy_mgr != null // relatedSites xtn is enabled
) {
lnki.Xtn_sites_link_(sites_regy_mgr.Match(ctx.Cur_page(), lnki_ttl));
}
return cur_pos;
}
public boolean Args_add(Xop_ctx ctx, byte[] src, Xop_tkn_itm tkn, Arg_nde_tkn arg, int arg_idx) {
Xop_lnki_tkn lnki = (Xop_lnki_tkn)tkn;
try {
if (arg_idx == 0) { // 1st arg; assume trg; process ns;
if (lnki.Ttl() == null) { // ttl usually set by 1st pipe, but some lnkis have no pipe; EX: [[A]]
Arg_itm_tkn ttl_tkn = arg.Val_tkn();
if (!Xop_lnki_wkr_.Parse_ttl(ctx, src, lnki, ttl_tkn.Dat_bgn(), ttl_tkn.Dat_end()))
return false;
}
lnki.Trg_tkn_(arg);
}
else { // nth arg; guess arg type
int arg_tid = -1;
int bgn = arg.Val_tkn().Dat_bgn(), end = arg.Val_tkn().Dat_end();
if (arg.KeyTkn_exists()) {bgn = arg.Key_tkn().Dat_bgn(); end = arg.Key_tkn().Dat_end();}
arg_tid = ctx.Wiki().Lang().Lnki_arg_parser().Identify_tid(src, bgn, end, lnki);
switch (arg_tid) {
case Xop_lnki_arg_parser.Tid_none: lnki.Align_h_(Xop_lnki_type.Id_none); break;
case Xop_lnki_arg_parser.Tid_border: lnki.Border_(Bool_.Y_byte); break;
case Xop_lnki_arg_parser.Tid_thumb: lnki.Lnki_type_(Xop_lnki_type.Id_thumb); break;
case Xop_lnki_arg_parser.Tid_frame: lnki.Lnki_type_(Xop_lnki_type.Id_frame); break;
case Xop_lnki_arg_parser.Tid_frameless: lnki.Lnki_type_(Xop_lnki_type.Id_frameless); break;
case Xop_lnki_arg_parser.Tid_left: lnki.Align_h_(Xop_lnki_align_h.Left); break;
case Xop_lnki_arg_parser.Tid_center: lnki.Align_h_(Xop_lnki_align_h.Center); break;
case Xop_lnki_arg_parser.Tid_right: lnki.Align_h_(Xop_lnki_align_h.Right); break;
case Xop_lnki_arg_parser.Tid_top: lnki.Align_v_(Xop_lnki_align_v.Top); break;
case Xop_lnki_arg_parser.Tid_middle: lnki.Align_v_(Xop_lnki_align_v.Middle); break;
case Xop_lnki_arg_parser.Tid_bottom: lnki.Align_v_(Xop_lnki_align_v.Bottom); break;
case Xop_lnki_arg_parser.Tid_super: lnki.Align_v_(Xop_lnki_align_v.Super); break;
case Xop_lnki_arg_parser.Tid_sub: lnki.Align_v_(Xop_lnki_align_v.Sub); break;
case Xop_lnki_arg_parser.Tid_text_top: lnki.Align_v_(Xop_lnki_align_v.TextTop); break;
case Xop_lnki_arg_parser.Tid_text_bottom: lnki.Align_v_(Xop_lnki_align_v.TextBottom); break;
case Xop_lnki_arg_parser.Tid_baseline: lnki.Align_v_(Xop_lnki_align_v.Baseline); break;
case Xop_lnki_arg_parser.Tid_class: lnki.Lnki_cls_(Xop_lnki_wkr_.Val_extract(src, arg)); break;
case Xop_lnki_arg_parser.Tid_alt: lnki.Alt_tkn_(arg);
lnki.Alt_tkn().Tkn_ini_pos(false, arg.Src_bgn(), arg.Src_end());
break;
case Xop_lnki_arg_parser.Tid_caption:
Xop_tkn_itm cur_caption_tkn = lnki.Caption_tkn();
if ( cur_caption_tkn == Xop_tkn_null.Null_tkn // lnki doesn't have caption; add arg as caption
|| lnki.Ttl().Ns().Id_file_or_media()) { // or lnki is File; always take last
lnki.Caption_tkn_(arg);
if (arg.Eq_tkn() != Xop_tkn_null.Null_tkn) { // equal tkn exists; add val tkns to key and then swap key with val
Arg_itm_tkn key_tkn = arg.Key_tkn(), val_tkn = arg.Val_tkn();
key_tkn.Subs_add(arg.Eq_tkn());
for (int i = 0; i < val_tkn.Subs_len(); i++) {
Xop_tkn_itm sub = val_tkn.Subs_get(i);
key_tkn.Subs_add(sub);
}
key_tkn.Dat_end_(val_tkn.Dat_end());
val_tkn.Subs_clear();
arg.Key_tkn_(Arg_itm_tkn_null.Null_arg_itm);
arg.Val_tkn_(key_tkn);
}
else // no equal tkn
lnki.Caption_tkn_pipe_trick_(end - bgn == 0); // NOTE: pipe_trick check must go here; checks for val_tkn.Bgn == val_tkn.End; if there is an equal token but no val, then Bgn == End which would trigger false pipe trick (EX:"[[A|B=]]")
}
else { // lnki does have caption; new caption should be concatenated; EX:[[A|B|C]] -> "B|C" x> "B"; NOTE: pipe-trick and eq tkn should not matter to multiple captions; DATE:2014-05-05
Xop_tkn_itm val_tkn = arg.Val_tkn();
int subs_len = val_tkn.Subs_len();
Xop_tkn_itm caption_val_tkn = ((Arg_nde_tkn)cur_caption_tkn).Val_tkn();
int pipe_bgn = caption_val_tkn.Src_bgn(); // for bookeeping purposes, assign | pos to same pos as val_tkn; note that pos really shouldn't be used; DATE:2014-05-05
caption_val_tkn.Subs_add(ctx.Tkn_mkr().Bry_raw(pipe_bgn, pipe_bgn + 1, Const_pipe)); // NOTE: add pipe once for entire caption tkn; used to add for every val tkn; DATE:2014-06-08
for (int i = 0 ; i < subs_len; i++) {
Xop_tkn_itm sub_itm = val_tkn.Subs_get(i);
caption_val_tkn.Subs_add(sub_itm);
}
}
break;
case Xop_lnki_arg_parser.Tid_link: lnki.Link_tkn_(arg); break;
case Xop_lnki_arg_parser.Tid_dim: break;// NOOP: Identify_tid does actual setting
case Xop_lnki_arg_parser.Tid_upright:
if (arg.KeyTkn_exists()) {
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
val_tkn_bgn = Bry_finder.Find_fwd_while_space_or_tab(src, val_tkn_bgn, val_tkn_end); // trim ws at bgn; needed for next step
if (val_tkn_end - val_tkn_bgn > 19) val_tkn_end = val_tkn_bgn + 19; // HACK: limit upright tkn to 19 digits; 20 or more will overflow long; WHEN: rewrite number_parser to handle doubles; PAGE:de.w:Feuerland DATE:2015-02-03
number_parser.Parse(src, val_tkn_bgn, val_tkn_end);
if (number_parser.Has_err())
ctx.Msg_log().Add_itm_none(Xop_lnki_log.Upright_val_is_invalid, src, val_tkn_bgn, val_tkn_end);
else
lnki.Upright_(number_parser.Rv_as_dec().To_double());
}
else // no =; EX: [[Image:a|upright]]
lnki.Upright_(gplx.xowa.files.Xof_img_size.Upright_default_marker);// NOTE: was incorrectly hardcoded as 1; DATE:2014-07-23
break;
case Xop_lnki_arg_parser.Tid_noicon: lnki.Media_icon_n_(); break;
case Xop_lnki_arg_parser.Tid_page: Xop_lnki_wkr_.Page_parse(ctx, src, number_parser, lnki, arg); break;
case Xop_lnki_arg_parser.Tid_thumbtime: Xop_lnki_wkr_.Thumbtime_parse(ctx, src, number_parser, lnki, arg); break;
}
}
return true;
} catch (Exception e) {
ctx.App().Usr_dlg().Warn_many("", "", "fatal error in lnki: page=~{0} src=~{1} err=~{2}", String_.new_u8(ctx.Cur_page().Ttl().Full_db()), String_.new_u8(src, lnki.Src_bgn(), lnki.Src_end()), Err_.Message_gplx_full(e));
return false;
}
} private static final byte[] Const_pipe = Bry_.new_a7("|");
}

View File

@@ -0,0 +1,139 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.primitives.*; import gplx.core.btries.*;
import gplx.xowa.wikis.*; import gplx.xowa.xtns.pfuncs.ttls.*; import gplx.xowa.xtns.relatedSites.*;
import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.lnkis.redlinks.*;
public class Xop_lnki_wkr_ {
private static final Int_obj_ref rel2abs_tid = Int_obj_ref.zero_();
public static final int Invalidate_lnki_len = 128;
public static int Invalidate_lnki(Xop_ctx ctx, byte[] src, Xop_root_tkn root, Xop_lnki_tkn lnki, int cur_pos) {
lnki.Tkn_tid_to_txt(); // convert initial "[[" to text; note that this lnki has no pipes as pipe_lxr does similar check; EX: [[<invalid>]]; DATE:2014-03-26
root.Subs_del_after(lnki.Tkn_sub_idx() + 1);// remove all tkns after [[ from root
int reparse_bgn = lnki.Src_end(); // NOTE: reparse all text from "[["; needed to handle [[|<i>a</i>]] where "<i>a</i>" cannot be returned as text; DATE:2014-03-04
ctx.App().Msg_log().Add_itm_none(Xop_lnki_log.Invalid_ttl, src, reparse_bgn, reparse_bgn + 128);
// int reparse_len = cur_pos - reparse_bgn;
// if (reparse_len > 512) ctx.App().Usr_dlg().Warn_many("", "", "lnki.reparsing large block; page=~{0} len=~{1} src=~{2}", Xop_ctx_.Page_as_str(ctx), reparse_len, Xop_ctx_.Src_limit_and_escape_nl(src, reparse_bgn, Invalidate_lnki_len));
return reparse_bgn;
}
public static boolean Parse_ttl(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int pipe_pos) {
int ttl_bgn = lnki.Src_bgn() + Xop_tkn_.Lnki_bgn_len;
ttl_bgn = Bry_finder.Find_fwd_while(src, ttl_bgn, pipe_pos, Byte_ascii.Space); // remove \s from bgn
int ttl_end = Bry_finder.Find_bwd_while(src, pipe_pos, ttl_bgn, Byte_ascii.Space); // remove \s from end
++ttl_end; // +1 to place after non-ws; EX: [[ a ]]; ttl_end should go from 3 -> 4
return Parse_ttl(ctx, src, lnki, ttl_bgn, ttl_end);
}
public static boolean Parse_ttl(Xop_ctx ctx, byte[] src, Xop_lnki_tkn lnki, int ttl_bgn, int ttl_end) {
Xoae_app app = ctx.App();
byte[] ttl_bry = Bry_.Mid(src, ttl_bgn, ttl_end);
ttl_bry = Xoa_app_.Utl__encoder_mgr().Http_url_ttl().Decode(ttl_bry);
int ttl_bry_len = ttl_bry.length;
Xoa_ttl page_ttl = ctx.Cur_page().Ttl();
if (page_ttl.Ns().Subpages_enabled()
&& Pfunc_rel2abs.Rel2abs_ttl(ttl_bry, 0, ttl_bry_len)) { // Linker.php|normalizeSubpageLink
Bry_bfr tmp_bfr = app.Utl__bfr_mkr().Get_b512();
byte[] new_bry = Pfunc_rel2abs.Rel2abs(tmp_bfr, ttl_bry, page_ttl.Raw(), rel2abs_tid.Val_zero_());
lnki.Subpage_tid_(rel2abs_tid.Val());
lnki.Subpage_slash_at_end_(Bry_.Get_at_end(ttl_bry) == Byte_ascii.Slash);
ttl_bry = new_bry;
tmp_bfr.Mkr_rls();
}
Xowe_wiki wiki = ctx.Wiki();
Xoa_ttl ttl = Xoa_ttl.parse(wiki, ttl_bry);
if (ttl == null) return false;
if ( wiki.Cfg_parser_lnki_xwiki_repos_enabled() // wiki has lnki.xwiki_repos
&& ttl.Wik_bgn() != Xoa_ttl.Null_wik_bgn // xwiki available; EX: [[en:]]
)
ttl = Adj_ttl_for_file(wiki, ctx, ttl, ttl_bry);
lnki.Ttl_(ttl);
lnki.Ns_id_(ttl.Ns().Id());
return true;
}
private static Xoa_ttl Adj_ttl_for_file(Xowe_wiki wiki, Xop_ctx ctx, Xoa_ttl ttl, byte[] ttl_bry) { // NOTE: remove the xwiki part; EX: [[en:File:A.png]] -> [[File:A.png]]
byte[] xwiki_bry = ttl.Wik_txt(); if (xwiki_bry == null) return ttl; // should not happen, but just in case
int xwiki_bry_len = xwiki_bry.length;
int ttl_bry_len = ttl_bry.length;
if (xwiki_bry_len + 1 >= ttl_bry_len) return ttl; // invalid ttl; EX: [[en:]]
byte[] ttl_in_xwiki_bry = Bry_.Mid(ttl_bry, xwiki_bry_len + 1, ttl_bry_len); // +1 to position after xwiki :; EX: [[en:File:A.png]]; +1 to put after ":" at "F"
if (!wiki.Cfg_parser().Lnki_cfg().Xwiki_repo_mgr().Has(xwiki_bry)) return ttl; // alias not in xwikis; EX: [[en_bad:File:A.png]]
Xoa_ttl ttl_in_xwiki = Xoa_ttl.parse(wiki, ttl_in_xwiki_bry);
if (ttl_in_xwiki == null) return ttl; // occurs if ttl is bad in xwiki; EX: [[en:<bad>]]
return ttl_in_xwiki.Ns().Id_file() ? ttl_in_xwiki : ttl;
}
public static int Chk_for_tail(Xol_lang lang, byte[] src, int cur_pos, int src_len, Xop_lnki_tkn lnki) {
int bgn_pos = cur_pos;
Btrie_slim_mgr lnki_trail = lang.Lnki_trail_mgr().Trie();
while (true) { // loop b/c there can be multiple consecutive lnki_trail_chars; EX: [[A]]bcde
if (cur_pos == src_len) break;
byte[] lnki_trail_bry = (byte[])lnki_trail.Match_bgn_w_byte(src[cur_pos], src, cur_pos, src_len);
if (lnki_trail_bry == null) break; // no longer a lnki_trail char; stop
cur_pos += lnki_trail_bry.length; // lnki_trail char; add
}
if (bgn_pos != cur_pos && lnki.Ns_id() == Xow_ns_.Id_main) { // only mark trail if Main ns (skip trail for Image)
lnki.Tail_bgn_(bgn_pos).Tail_end_(cur_pos);
return cur_pos;
}
else
return bgn_pos;
}
public static void Page_parse(Xop_ctx ctx, byte[] src, Number_parser number_parser, Xop_lnki_tkn lnki, Arg_nde_tkn arg) {
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
byte[] val_bry = Bry_.Trim(src, val_tkn_bgn, val_tkn_end); // some tkns have trailing space; EX.WWI: [[File:Bombers of WW1.ogg|thumb |thumbtime=3]]
number_parser.Parse(val_bry);
if (number_parser.Has_err())
ctx.Msg_log().Add_itm_none(Xop_lnki_log.Upright_val_is_invalid, src, val_tkn_bgn, val_tkn_end);
else
lnki.Page_(number_parser.Rv_as_int());
}
public static byte[] Val_extract(byte[] src, Arg_nde_tkn arg) {
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
return Bry_.Trim(src, val_tkn_bgn, val_tkn_end); // trim trailing space
}
public static void Thumbtime_parse(Xop_ctx ctx, byte[] src, Number_parser number_parser, Xop_lnki_tkn lnki, Arg_nde_tkn arg) {
int val_tkn_bgn = arg.Val_tkn().Src_bgn(), val_tkn_end = arg.Val_tkn().Src_end();
long fracs = TimeSpanAdp_.parse_to_fracs(src, val_tkn_bgn, val_tkn_end, false);
if (fracs == TimeSpanAdp_.parse_null) {
ctx.Msg_log().Add_itm_none(Xop_lnki_log.Upright_val_is_invalid, src, val_tkn_bgn, val_tkn_end);
}
else
lnki.Time_(fracs / TimeSpanAdp_.Ratio_f_to_s);
}
public static boolean Adjust_for_brack_end_len_of_3(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int cur_pos, Xop_lnki_tkn lnki) {
if ( cur_pos < src_len // bounds check
&& src[cur_pos] == Byte_ascii.Brack_end // is next char after "]]", "]"; i.e.: "]]]"; PAGE:en.w:Aubervilliers DATE:2014-06-25
) {
int nxt_pos = cur_pos + 1;
if ( nxt_pos == src_len // allow "]]]EOS"
|| ( nxt_pos < src_len // bounds check
&& src[nxt_pos] != Byte_ascii.Brack_end // is next char after "]]]", "]"; i.e.: not "]]]]"; PAGE:ru.w:Меркатале_ин_Валь_ди_Песа; DATE:2014-02-04
)
) {
if ( lnki.Caption_exists() // does a caption exist?
&& lnki.Caption_tkn().Src_end() + 2 == cur_pos // is "]]]" at end of caption?; 2="]]".Len; handle [http://a.org [[File:A.png|123px]]] PAGE:ar.w:محمد; DATE:2014-08-20
&& lnki.Ttl() != null // only change "]]]" to "]" + "]]" if lnki is not title; otherwise [[A]]] -> "A]" which will be invalid; PAGE:en.w:Tall_poppy_syndrome DATE:2014-07-23
) {
Xop_tkn_itm caption_val_tkn = lnki.Caption_val_tkn();
caption_val_tkn.Subs_add(tkn_mkr.Bry_raw(cur_pos, cur_pos + 1, Byte_ascii.Brack_end_bry)); // add "]" as bry
caption_val_tkn.Src_end_(caption_val_tkn.Src_end() + 1);
return true;
}
}
}
return false;
}
}

View File

@@ -0,0 +1,312 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.wikis.ttls.*;
public class Xop_lnki_wkr__basic_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Basic() {
fxt.Test_parse_page_wiki("[[a]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)));
}
@Test public void HtmlRef() {
fxt.Test_parse_page_wiki("[[a&amp;b]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 3), fxt.tkn_html_ref_("&amp;"), fxt.tkn_txt_(8, 9)))));
}
@Test public void Url_encode() { // PURPOSE:title should automatically do url decoding; DATE:2013-08-26
fxt.Test_parse_page_all_str("[[A%20b]]", "<a href=\"/wiki/A_b\">A b</a>");
}
@Test public void Url_encode_plus() { // PURPOSE:do not decode plus; DATE:2013-08-26
fxt.Test_parse_page_all_str("[[A+b]]", "<a href=\"/wiki/A%2Bb\">A+b</a>");
}
@Test public void Caption() {
fxt.Test_parse_page_wiki("[[a|b]]" , fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)).Caption_tkn_(fxt.tkn_arg_val_txt_(4, 5)));
fxt.Test_parse_page_wiki("[[a|b:c]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)).Caption_tkn_(fxt.tkn_arg_val_(fxt.tkn_txt_(4, 5), fxt.tkn_colon_(5), fxt.tkn_txt_(6, 7))));
}
@Test public void Caption_equal() { // should ignore = if only caption arg (2 args)
fxt.Test_parse_page_wiki("[[a|=]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)).Caption_tkn_(fxt.tkn_arg_val_(fxt.tkn_eq_(4))));
}
@Test public void Caption_ampersand() {fxt.Test_parse_page_wiki_str("[[A|a & b]]", "<a href=\"/wiki/A\">a &amp; b</a>");}
@Test public void Tail() {
fxt.Test_parse_page_wiki("[[a|b]]c" , fxt.tkn_lnki_(0, 8).Tail_bgn_(7).Tail_end_(8));
fxt.Test_parse_page_wiki("[[a|b]] c", fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_space_(7, 8), fxt.tkn_txt_(8, 9));
fxt.Test_parse_page_wiki("[[a|b]]'c", fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_txt_(7, 9));
}
@Test public void Tail_number() {fxt.Test_parse_page_wiki("[[a|b]]1" , fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_txt_(7, 8));}
@Test public void Tail_upper() {fxt.Test_parse_page_wiki("[[a|b]]A" , fxt.tkn_lnki_(0, 7).Tail_bgn_(-1), fxt.tkn_txt_(7, 8));} // make sure trie is case-insensitive
@Test public void Tail_image() {fxt.Test_parse_page_wiki("[[Image:a|b]]c", fxt.tkn_lnki_(0, 13).Tail_bgn_(-1).Tail_end_(-1), fxt.tkn_txt_(13, 14));} // NOTE: this occurs on some pages;
@Test public void Image() {
fxt.Test_parse_page_wiki("[[Image:a]]" , fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file).Trg_tkn_(fxt.tkn_arg_val_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9))));
fxt.Test_parse_page_wiki("[[Image:a|border]]" , fxt.tkn_lnki_().Border_(Bool_.Y_byte));
fxt.Test_parse_page_wiki("[[Image:a|thumb]]" , fxt.tkn_lnki_().ImgType_(Xop_lnki_type.Id_thumb));
fxt.Test_parse_page_wiki("[[Image:a|left]]" , fxt.tkn_lnki_().HAlign_(Xop_lnki_align_h.Left));
fxt.Test_parse_page_wiki("[[Image:a|top]]" , fxt.tkn_lnki_().VAlign_(Xop_lnki_align_v.Top));
fxt.Test_parse_page_wiki("[[Image:a|10px]]" , fxt.tkn_lnki_().Width_(10).Height_(-1));
fxt.Test_parse_page_wiki("[[Image:a|20x30px]]" , fxt.tkn_lnki_().Width_(20).Height_(30));
fxt.Test_parse_page_wiki("[[Image:a|alt=b]]" , fxt.tkn_lnki_().Alt_tkn_(fxt.tkn_arg_nde_().Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13))).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(14, 15)))));
fxt.Test_parse_page_wiki("[[Image:a|link=a]]" , fxt.tkn_lnki_().Link_tkn_(fxt.tkn_arg_nde_().Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 14))).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(15, 16)))));
fxt.Test_parse_page_wiki("[[Image:a|thumb|alt=b|c d]]"
, fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file)
.Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9))))
.Alt_tkn_(fxt.tkn_arg_nde_().Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(16, 19))).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(20, 21))))
.Caption_tkn_(fxt.tkn_arg_nde_(22, 25).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(22, 23), fxt.tkn_space_(23, 24), fxt.tkn_txt_(24, 25)))))
;
}
@Test public void Image_upright() {
fxt.Test_parse_page_wiki("[[Image:a|upright=.123]]" , fxt.tkn_lnki_().Upright_(.123));
fxt.Test_parse_page_wiki("[[Image:a|upright]]" , fxt.tkn_lnki_().Upright_(gplx.xowa.files.Xof_img_size.Upright_default_marker)); // no eq tokn
fxt.Test_parse_page_wiki("[[Image:a|upright=.42190046219457]]", fxt.tkn_lnki_().Upright_(.42190046219457)); // many decimal places breaks upright
fxt.Init_log_(Xop_lnki_log.Upright_val_is_invalid)
.Test_parse_page_wiki("[[Image:a|upright=y]]" , fxt.tkn_lnki_().Upright_(-1)); // invalid
}
@Test public void Recurse() {
fxt.Test_parse_page_wiki("[[Image:a|b-[[c]]-d]]"
, fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file)
.Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9))))
.Caption_tkn_(fxt.tkn_arg_nde_(10, 19).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 12), fxt.tkn_lnki_(12, 17), fxt.tkn_txt_(17, 19))))
);
}
@Test public void Outliers() {
fxt.Test_parse_page_wiki("[[Image:a=b.svg|thumb|10px]]", fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file).Trg_tkn_(fxt.tkn_arg_nde_().Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(2, 7), fxt.tkn_colon_(7), fxt.tkn_txt_(8, 9), fxt.tkn_eq_(9), fxt.tkn_txt_(10, 15)))));
fxt.Test_parse_page_wiki("[[Category:a|b]]", fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_category));
}
@Test public void Exc_caption_has_eq() {
fxt.Test_parse_page_wiki("[[Image:a.svg|thumb|a=b]]", fxt.tkn_lnki_().Ns_id_(Xow_ns_.Id_file)
.Caption_tkn_(fxt.tkn_arg_nde_(20, 23).Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(20, 21), fxt.tkn_eq_(21), fxt.tkn_txt_(22, 23)))));
}
@Test public void Border_with_space_should_not_be_caption() {// happens with {{flag}}; EX: [[Image:Flag of Argentina.svg|22x20px|border |alt=|link=]]
Xop_root_tkn root = fxt.Test_parse_page_wiki_root("[[Image:a.svg|22x20px|border |alt=|link=]]");
Xop_lnki_tkn lnki = (Xop_lnki_tkn)root.Subs_get(0);
Tfds.Eq(Xop_tkn_itm_.Tid_null, lnki.Caption_tkn().Tkn_tid());
}
@Test public void Ws_key_bgn() {
fxt.Test_parse_page_wiki("[[Image:a| alt=b]]", fxt.tkn_lnki_()
.Alt_tkn_(fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(10, 11).Ignore_y_(), fxt.tkn_txt_(11, 14)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(15, 16)))
));
}
@Test public void Ws_key_end() {
fxt.Test_parse_page_wiki("[[Image:a|alt =b]]", fxt.tkn_lnki_()
.Caption_tkn_(fxt.tkn_arg_nde_(10, 16)
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13), fxt.tkn_space_(13, 14), fxt.tkn_eq_(14), fxt.tkn_txt_(15, 16)))
));
}
@Test public void Ws_val_bgn() {
fxt.Test_parse_page_wiki("[[Image:a|alt= b]]", fxt.tkn_lnki_()
.Alt_tkn_(fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(14, 15), fxt.tkn_txt_(15, 16)))
));
}
@Test public void Ws_val_end() {
fxt.Test_parse_page_wiki("[[Image:a|alt=b ]]", fxt.tkn_lnki_()
.Alt_tkn_(fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(10, 13)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(14, 15), fxt.tkn_space_(15, 16).Ignore_y_()))
));
}
@Test public void Ws_val_only() { // simpler variation of Ws_val_size
fxt.Test_parse_page_wiki("[[Image:a| b ]]", fxt.tkn_lnki_()
.Caption_tkn_(fxt.tkn_arg_nde_()
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_space_(10, 11), fxt.tkn_txt_(11, 12), fxt.tkn_space_(12, 13)))
));
}
@Test public void Ws_val_size() {
fxt.Test_parse_page_wiki("[[Image:a| 20x30px ]]" , fxt.tkn_lnki_().Width_(20).Height_(30));
}
@Test public void Nl_pipe() { // PURPOSE: "\n|" triggers tblw; PAGE:fr.w:France; [[Fichier:Carte demographique de la France.svg
fxt.Test_parse_page_wiki("[[Image:A.png|thumb\n|alt=test]]", fxt.tkn_lnki_()
.Alt_tkn_(fxt.tkn_arg_nde_()
. Key_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(21, 24)))
. Val_tkn_(fxt.tkn_arg_itm_(fxt.tkn_txt_(25, 29)))
));
}
@Test public void Exc_empty_caption() {
fxt.Test_parse_page_wiki("[[a|]]", fxt.tkn_lnki_().Trg_tkn_(fxt.tkn_arg_val_txt_(2, 3)));
}
@Test public void Exc_empty() {
fxt.Init_log_(Xop_ttl_log.Len_0, Xop_lnki_log.Invalid_ttl);
fxt.Test_parse_page_wiki("[[]]", fxt.tkn_txt_(0, 2), fxt.tkn_txt_(2, 4));
fxt.Init_log_(Xop_ttl_log.Len_0, Xop_lnki_log.Invalid_ttl);
fxt.Test_parse_page_wiki("[[ ]]", fxt.tkn_txt_(0, 2), fxt.tkn_space_(2, 3), fxt.tkn_txt_(3, 5));
}
@Test public void Exc_invalid_u8() { // PURPOSE: "%DO" is an invalid UTF-8 sequence (requires 2 bytes, not just %D0); DATE:2013-11-11
fxt.Ctx().Lang().Case_mgr_u8_(); // NOTE: only occurs during Universal
fxt.Test_parse_page_all_str("[[%D0]]", "[[%D0]]"); // invalid titles render literally
}
@Test public void Ex_eq() { // make sure that eq is not evaluated for kv delimiter
fxt.Test_parse_page_wiki("[[=]]", fxt.tkn_lnki_(0, 5));
fxt.Test_parse_page_wiki("[[a|=]]", fxt.tkn_lnki_(0, 7));
}
@Test public void Unclosed() { // PURPOSE: unclosed lnki skips rendering of next table; PAGE:en.w:William Penn (Royal Navy officer)
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a [[b|c]"
, ""
, "{|"
, "|-"
, "|d"
, "|}"
),String_.Concat_lines_nl_skip_last
( "a [[b|c] " // NOTE: \n is converted to \s b/c caption does not allow \n
, "<table>"
, " <tr>"
, " <td>d"
, " </td>"
, " </tr>"
, "</table>"
, ""
));
}
@Test public void Caption_nl() { // PURPOSE: \n in caption should be rendered as space; PAGE:en.w:Schwarzschild radius; and the stellar [[Velocity dispersion|velocity\ndispersion]]
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a [[b|c"
, ""
, ""
, "d]]"
), String_.Concat_lines_nl_skip_last
( "<p>a <a href=\"/wiki/B\">c d</a>" // NOTE: this depends on html viewer to collapse multiple spaces into 1
, "</p>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Caption_nl_2() { // PURPOSE: unclosed lnki breaks paragraph unexpectedly; PAGE:en.w:Oldsmobile;
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a"
, ""
, "b [[c"
, "" // NOTE: this new line is needed to produce strange behavior
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, ""
, "<p>b [[c" // NOTE: \n is converted to \s b/c caption does not allow \n; NOTE: removed \s after "c" due to new lnki invalidation;DATE:2014-04-03
, "</p>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Caption_ref() { // PURPOSE: <ref> not handled in lnki; PAGE:en.w:WWI
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "[[File:A.png|thumb|b <ref>c</ref>]]"
), String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"inte" +"rnal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/bin/any/xowa/file/mediawiki.file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " b <sup id=\"cite_ref-0\" class=\"reference\"><a href=\"#cite_note-0\">[1]</a></sup>"
, " </div>"
, " </div>"
, "</div>"
, ""
));
}
@Test public void Html_ent_pound() {
fxt.Test_parse_page_wiki_str
( "[[A&#35;b|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/A#b\">c</a>"
));
}
@Test public void Html_ent_ltr_a() {
fxt.Test_parse_page_wiki_str
( "[[A&#98;|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/Ab\">c</a>"
));
}
@Test public void Pipe_trick() {
fxt.Test_parse_page_wiki_str("[[Page1|]]" , "<a href=\"/wiki/Page1\">Page1</a>");
fxt.Test_parse_page_wiki_str("[[Help:Page1|]]" , "<a href=\"/wiki/Help:Page1\">Page1</a>");
}
@Test public void Thumb_first_align_trumps_all() { // PURPOSE: if there are multiple alignment instructions, take the first EX:[[File:A.png|thumb|center|left]] DATE:20121226
fxt.Test_parse_page_wiki_str("[[File:A.png|thumb|right|center]]" // NOTE: right trumps center
, String_.Concat_lines_nl_skip_last
( Xop_para_wkr_basic_tst.File_html("File", "A.png", "7/0", "")
, ""
));
}
@Test public void Eq() {
fxt.Test_parse_page_all_str("[[B|=]]", "<a href=\"/wiki/B\">=</a>");
}
@Test public void Href_encode_anchor() { // PURPOSE: test separate encoding for ttl (%) and anchor (.)
fxt.Test_parse_page_all_str("[[^#^]]", "<a href=\"/wiki/%5E#.5E\">^#^</a>");
}
@Test public void Href_question() { // PURPOSE.fix: ttl with ? at end should not be considered qarg; DATE:2013-02-08
fxt.Test_parse_page_all_str("[[A?]]", "<a href=\"/wiki/A%3F\">A?</a>");
}
@Test public void Href_question_2() { // PURPOSE: ?action=edit should be encoded; DATE:2013-02-10
fxt.Test_parse_page_all_str("[[A?action=edit]]", "<a href=\"/wiki/A%3Faction%3Dedit\">A?action=edit</a>");
}
@Test public void Href_question_3() { // PURPOSE.fix: DATE:2014-01-16
fxt.Test_parse_page_all_str("[[A?b]]", "<a href=\"/wiki/A%3Fb\">A?b</a>");
}
@Test public void Encoded_url() { // PURPOSE.fix: url-encoded characters broke parser when embedded in link; DATE:2013-03-01
fxt.Init_xwiki_add_user_("commons.wikimedia.org");
fxt.Test_parse_page_wiki_str("[[File:A.png|link=//commons.wikimedia.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0?uselang=ru|b]]"
, "<a href=\"/site/commons.wikimedia.org/wiki/Заглавная_страница?uselang=ru\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"b\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>");
}
@Test public void Link_invalid() { // PURPOSE.fix: do not render invalid text; EX: link={{{1}}}; [[Fil:Randers_-_Hadsund_railway.png|120x160px|link={{{3}}}|Randers-Hadsund Jernbane]]; DATE:2013-03-04
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link={{{1}}}|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Href_anchor_leading_space() { // PURPOSE: ?action=edit should be encoded; DATE:2013-02-10
fxt.Test_parse_page_all_str("[[A #b]]", "<a href=\"/wiki/A#b\">A #b</a>");
}
@Test public void Anchor_not_shown_for_wikipedia_ns() { // PURPOSE: Help:A#b was omitting anchor; showing text of "Help:A"; DATE:2013-06-21
fxt.Test_parse_page_all_str("[[Help:A#b]]", "<a href=\"/wiki/Help:A#b\">Help:A#b</a>");
}
@Test public void Anchor_shown_for_main_ns() { // PURPOSE: counterpart to Anchor_not_shown_for_wikipedia_ns; DATE:2013-06-21
fxt.Test_parse_page_all_str("[[A#b]]", "<a href=\"/wiki/A#b\">A#b</a>");
}
@Test public void Trail_en() {
fxt.Test_parse_page_all_str("[[Ab]]cd e", "<a href=\"/wiki/Ab\">Abcd</a> e");
}
@Test public void Trail_fr() {
byte[] ltr_c_in_french = Bry_.new_u8("ç");
Xol_lnki_trail_mgr lnki_trail_mgr = fxt.Wiki().Lang().Lnki_trail_mgr();
lnki_trail_mgr.Add(ltr_c_in_french);
fxt.Test_parse_page_all_str("[[Ab]]çd e", "<a href=\"/wiki/Ab\">Abçd</a> e");
lnki_trail_mgr.Del(ltr_c_in_french);
}
@Test public void Link_html_ent() {// PURPOSE:html entities should be converted to chars; EX:&nbsp; -> _; DATE:2013-12-16
fxt.Test_parse_page_wiki_str
( "[[File:A.png|link=b&nbsp;c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/B_c\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
));
}
@Test public void Page() {
fxt.Test_parse_page_wiki("[[File:A.pdf|page=12]]" , fxt.tkn_lnki_().Page_(12));
}
@Test public void Visited() { // PURPOSE: show redirected titles as visited; EX:fr.w:Alpes_Pennines; DATE:2014-02-28
Xowe_wiki wiki = fxt.Wiki();
Xoa_ttl ttl = Xoa_ttl.parse(wiki, Bry_.new_a7("Src")); // simulate requrest for "Src" page
Xoae_page previous_page = Xoae_page.test_(wiki, ttl);
previous_page.Redirected_ttls().Add(Bry_.new_a7("Src")); // simulate redirect from "Src"
fxt.App().Usere().History_mgr().Add(previous_page); // simulate "Src" already being clicked once; this is the key call
fxt.Wtr_cfg().Lnki_visited_y_();
fxt.Test_parse_page_all_str("[[Src]]" , "<a href=\"/wiki/Src\" class=\"xowa-visited\">Src</a>"); // show [[Src]] as visited since it exists in history
fxt.Test_parse_page_all_str("[[Other]]" , "<a href=\"/wiki/Other\">Other</a>"); // show other pages as not visited
}
}

View File

@@ -0,0 +1,132 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*;
public class Xop_lnki_wkr__ctg_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_y_();} private Xop_fxt fxt = new Xop_fxt();
@After public void term() {fxt.Init_para_n_();}
@Test public void Pre() { // PURPOSE: Category should trim preceding nl; EX:w:Mount Kailash
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a"
, " [[Category:b]]"
, "c"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "c"
, "</p>"
, ""
));
}
@Test public void Ws() { // FUTURE: needs more para rework; conflicts with Li() test; WHEN: when issue is found
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a"
, "x [[Category:b]]"
, "c"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "x "
, "c"
, "</p>"
, ""
));
}
@Test public void Li() { // PURPOSE: Category strips all preceding ws; PAGE:en.w:NYC (in external links)
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "*a"
, "*b"
, " [[Category:c]]"
, "*d"
), String_.Concat_lines_nl_skip_last
( "<ul>"
, " <li>a"
, " </li>"
, " <li>b"
, " </li>"
, " <li>d"
, " </li>"
, "</ul>"
));
}
@Test public void Li_w_lnke() { // PURPOSE: [[Category]] was being absorbed into lnke; PAGE:de.w:ISO/IEC/IEEE_29119_Software_Testing DATE:2014-07-11
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "* http://a.org"
, "[[Category:B]]" // category should not show below
), String_.Concat_lines_nl_skip_last
( "<ul>"
, " <li> <a href=\"http://a.org\" class=\"external text\" rel=\"nofollow\">http://a.org</a>"
, " </li>"
, "</ul>"
, ""
));
}
@Test public void Merge_li() { // PURPOSE: trim ws preceding [[Category:; de.d:plant; DATE:2014-03-27
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "*a"
, ""
, " [[Category:B]] c"
), String_.Concat_lines_nl_skip_last
( "<ul>"
, " <li>a c"
, " </li>"
, "</ul>"
, ""
));
}
@Test public void Merge_pre() { // PURPOSE: leading spaces / nls should be removed from normal Category, else false pre's or excessive line breaks
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
( " [[Category:A]]" // removes \s
, " [[Category:B]]" // removes \n\s
), String_.Concat_lines_nl
( "<p>"
, "</p>"
));
}
@Test public void Literal() { // PURPOSE: do not trim ws if literal Category; EX:fr.wikiquote.org/wiki/Accueil; REF: https://sourceforge.net/p/xowa/tickets/167/; DATE:2013-07-10
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
( "[[:Category:A]]"
, "[[:Category:B]]"
), String_.Concat_lines_nl
( "<p><a href=\"/wiki/Category:A\">Category:A</a>" // NOTE: technically WP converts to "</a> <a>" not "</a>\n<a>" (via HtmlTidy?)
, "<a href=\"/wiki/Category:B\">Category:B</a>"
, "</p>"
));
}
@Test public void Hdr_w_nl() { // PURPOSE: hdr code broken by Category; DATE:2014-04-17
fxt.Test_parse_page_all_str("==a==\n[[Category:C]]"
, String_.Concat_lines_nl_skip_last
( "<h2>a</h2>"
, ""
));
}
@Test public void Hdr_only() { // PURPOSE: check that == is hdr; EX:ar.d:جَبَّارَة; DATE:2014-04-17
fxt.Test_parse_page_wiki_str("==a==[[Category:C]]"
, String_.Concat_lines_nl_skip_last
( "<h2>a</h2>"
, ""
));
}
@Test public void Hdr_ignore() { // PURPOSE: check that hdr is ignored if next char is not nl; DATE:2014-04-17
fxt.Test_parse_page_wiki_str("==a==[[Category:C]]b"
, String_.Concat_lines_nl_skip_last
( "==a==b"
, ""
));
}
}

View File

@@ -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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*; import gplx.xowa.wikis.ttls.*;
public class Xop_lnki_wkr__invalid_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Ignore_invalid_url_encodings() { // PURPOSE: if url encoding is invalid, still render lnki as <a>; EX: fr.w:Bordetella;
fxt.Test_parse_page_all_str("[[%GC]]", "<a href=\"/wiki/%25GC\">%GC</a>");
}
@Test public void Caption_still_parsed() { // PURPOSE: failed lnki should still parse xml in caption; EX:ar.w:الصومال; DATE:2014-03-04
fxt.Test_parse_page_all_str("[[|''a'']]" , "[[|<i>a</i>]]");
}
@Test public void Ttl_still_parsed() { // PURPOSE: invalid lnki should still parse ttl; BASED_ON:ar.w:الصومال; DATE:2014-03-26
fxt.Test_parse_page_all_str("[[''[a]'']]" , "[[<i>[a]</i>]]");
}
@Test public void Pipe_only() {
fxt.Init_log_(Xop_ttl_log.Len_0, Xop_lnki_log.Invalid_ttl);
fxt.Test_parse_page_wiki("[[|]]", fxt.tkn_txt_(0, 2), fxt.tkn_pipe_(2), fxt.tkn_txt_(3, 5));
}
@Test public void Xnde_should_force_ttl_parse() { // PURPOSE: reparse should be forced at xnde not at pipe; EX: [[a<b>c</b>|d]] reparse should start at <b>; DATE:2014-03-30
fxt.Test_parse_page_all_str_and_chk("[[a<b>c</b>|d]]" , "[[a<b>c</b>|d]]", Xop_lnki_log.Invalid_ttl);
}
@Test public void Tblw_tb() { // PURPOSE: reparse should be forced at tblw.tb; DATE:2014-04-03
fxt.Test_parse_page_all_str_and_chk("[[a\n{||b]]", String_.Concat_lines_nl_skip_last
( "[[a"
, "<table>|b]]"
, "</table>"
, ""
), Xop_lnki_log.Invalid_ttl);
}
@Test public void Tblw_tr() { // PURPOSE: reparse should be forced at tblw.tr; DATE:2014-04-03
fxt.Test_parse_page_all_str_and_chk("[[a\n|-b]]", String_.Concat_lines_nl_skip_last
( "[[a"
, "|-b]]"
), Xop_lnki_log.Invalid_ttl);
}
@Test public void Tblw_tr_like() { // PURPOSE: do not invalidate if pseudo-tr; DATE:2014-04-03
fxt.Test_parse_page_all_str_and_chk("[[a|-b]]", "<a href=\"/wiki/A\">-b</a>");
}
@Test public void Nl() { // PURPOSE: invalidate if nl; DATE:2014-04-03
fxt.Test_parse_page_all_str_and_chk("''[[\n]]", "<i>[[</i>\n]]", Xop_lnki_log.Invalid_ttl);
}
@Test public void Nl_with_apos_shouldnt_fail() { // PURPOSE: apos, lnki and nl will cause parser to fail; DATE:2013-10-31
fxt.Test_parse_page_all_str("''[[\n]]", "<i>[[</i>\n]]");
}
// @Test public void Brack_end_invalid() { // PURPOSE: invalidate if ]; DATE:2014-04-03; // TODO: backout apos changes
// fxt.Test_parse_page_all_str_and_chk("[[A] ]", "[[A] ]", Xop_lnki_log.Invalid_ttl);
// }
@Test public void Module() { // PURPOSE: handle lnki_wkr parsing Module text (shouldn't happen); apos, tblw, lnki, and nl will cause parser to fail; also handles scan-bwd; EX:Module:Taxobox; DATE:2013-11-10
fxt.Init_para_y_();
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl
( " [[''"
, " [["
, " |" // NOTE: this is actually a tblw_ws_tkn ("\n |") not a pipe_tkn
, "]]"
)
, String_.Concat_lines_nl_skip_last
( "<pre>[[</i>" // NOTE: should be <i> but scan_bwd can't undo previous apos
, "[["
, " |"
, "</pre>"
, ""
, "<p>]]"
, "</p>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Tblw_in_lnki() { // PURPOSE: handle invalid tblw tkn inside lnki; DATE:2014-06-06
fxt.Test_parse_page_all_str("[[A[]\n|b]]", "[[A[]\n|b]]"); // NOTE: \n| is tblw code for td
}
// @Test public void Tmpl() { // PURPOSE: invalid lnki breaks template
// fxt.Init_defn_clear();
// fxt.Init_defn_add("a", "b");
// fxt.Test_parse_page_all_str("{{a|[[}}", "b");
// }
}

View File

@@ -0,0 +1,146 @@
/*
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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*;
public class Xop_lnki_wkr__link_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Link() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_blank() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://www.b.org|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"http://www.b.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_file_system() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=file:///C/B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"file:///C/B.png\" class=\"image\" xowa_title=\"B.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_file_ns() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=File:B.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:B.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_relative() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"https://fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_absolute() {
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"http://fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_external_double_http() {// PURPOSE.fix: link=http://a.org?b=http://c.org breaks lnki; DATE:2013-02-03
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//a.org?b=http://c.org]]", String_.Concat_lines_nl_skip_last
( "<a href=\"https://a.org?b=http://c.org\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_relative() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_relative_domain_only() { // lnki_wtr fails if link is only domain; EX: wikimediafoundation.org; [[Image:Wikispecies-logo.png|35px|link=//species.wikimedia.org]]; // NOTE: changed href to return "/wiki/" instead of ""; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_absolute() { // NOTE: changed href to return "wiki/" instead of "wiki"; DATE:2013-02-18
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://fr.wikipedia.org/wiki/|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_absolute_upload() { // PURPOSE: link to upload.wikimedia.org omits /wiki/; EX: wikimediafoundation.org: [[File:Page1-250px-WMF_AR11_SHIP_spreads_15dec11_72dpi.png|right|125px|border|20102011 Annual Report|link=https://upload.wikimedia.org/wikipedia/commons/4/48/WMF_AR11_SHIP_spreads_15dec11_72dpi.pdf]]
fxt.Init_xwiki_add_user_("commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://upload.wikimedia.org/wikipedia/commons/7/70/A.png|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/File:A.png\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_relative_deep() {
fxt.Init_xwiki_add_user_("fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=//fr.wikipedia.org/wiki/A/b|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/A/b\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
}
@Test public void Link_xwiki_alias() { // [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Init_xwiki_add_wiki_and_user_("en.wikipedia.org", "en.wikipedia.org"); // DATE:2015-07-22
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/B\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Link_xwiki_alias_sub_page() { // same as above, but for sub-page; [[File:Commons-logo.svg|25x25px|link=http://en.wikipedia.org/wiki/commons:Special:Search/Earth|alt=|Search Commons]]
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Init_xwiki_add_wiki_and_user_("en.wikipedia.org", "en.wikipedia.org"); // DATE:2015-07-22
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=http://en.wikipedia.org/wiki/commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Link_xwiki_alias_only() { // only alias; [[File:Commons-logo.svg|25x25px|link=commons:Special:Search/Earth]]; fictitious example; DATE:2013-02-18
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=commons:Special:Search/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/Special:Search/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Link_xwiki_alias_only_colon() { // only alias, but prepended with ":"; [[File:Wikipedia-logo.svg|40px|link=:w:|Wikipedia]]; DATE:2013-05-06
fxt.Init_xwiki_add_wiki_and_user_("commons", "commons.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[File:A.png|12x10px|link=:commons:A/B|c]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/commons.wikimedia.org/wiki/A/B\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"c\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Init_xwiki_clear();
}
@Test public void Encode() {// PURPOSE: encode invalid characters in link; PAGE:en.w:List_of_cultural_heritage_sites_in_Punjab,_Pakistan DATE:2014-07-16
fxt.Test_parse_page_wiki_str
( "[[File:A.png|link=//b?c\">|d]]"
, "<a href=\"https://b?c%22%3E\" rel=\"nofollow\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"d\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>"
);
}
}

View File

@@ -0,0 +1,109 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*;
public class Xop_lnki_wkr__pre_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_y_();} private Xop_fxt fxt = new Xop_fxt();
@After public void term() {fxt.Init_para_n_();}
@Test public void Previous_pre() { // PURPOSE: if pre is already in effect, end it; EX: en.b:Knowing_Knoppix/Other_applications
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " b"
, "[[File:A.png|thumb]]"
, "c"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, ""
, "<pre>b" // NOTE: pre is ended; " b\n[[" -> <pre>b</pre><div>"
, "</pre>"
, ""
, Html_A_png
, ""
, "<p>c"
, "</p>"
, ""
));
}
@Test public void Current_pre_and_thumb() { // PURPOSE: current pre should be ended by thumb; EX: w:Roller coaster; it.w:Provincia_di_Pesaro_e_Urbino; DATE:2014-02-17
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " [[File:A.png|thumb]]"
, "b"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, "" // NOTE: do not capture " "; confirmed against MW; DATE:2014-02-19
, Html_A_png
, ""
, "<p>b"
, "</p>"
, ""
));
}
@Test public void Current_pre_and_halign() { // PURPOSE: current pre should be ended by halign since they also produce divs; EX: w:Trombiculidae; DATE:2014-02-17
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " [[File:A.png|right]]"
, "b"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, "<div class=\"floatright\">" // NOTE: do not capture " "; confirmed against MW; DATE:2014-02-19
, "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a></div>"
, ""
, "<p>b"
, "</p>"
, ""
));
}
@Test public void Current_pre() { // PURPOSE: current pre should exist if not div; DATE:2014-02-17
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " [[File:A.png]]"
, "b"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, ""
, "<pre> <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/orig/7/0/A.png\" width=\"0\" height=\"0\" /></a>" // NOTE: capture " "; confirmed against MW; DATE:2014-04-14
, "</pre>"
, ""
, "<p>b"
, "</p>"
, ""
));
}
private static final String Html_A_png = String_.Concat_lines_nl_skip_last
( "<div class=\"thumb tright\">"
, " <div id=\"xowa_file_div_0\" class=\"thumbinner\" style=\"width:220px;\">"
, " <a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/220px.png\" width=\"0\" height=\"0\" /></a>"
, " <div class=\"thumbcaption\">"
, " <div class=\"magnify\">"
, " <a href=\"/wiki/File:A.png\" class=\"internal\" title=\"Enlarge\">"
, " <img src=\"file:///mem/xowa/bin/any/xowa/file/mediawiki.file/magnify-clip.png\" width=\"15\" height=\"11\" alt=\"\" />"
, " </a>"
, " </div>"
, " "
, " </div>"
, " </div>"
, "</div>"
);
}

View 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.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*; import gplx.xowa.parsers.xndes.*;
public class Xop_lnki_wkr__size_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private final Xop_fxt fxt = new Xop_fxt();
@Test public void Width__w__ws() {
fxt.Test_parse_page_wiki("[[Image:a| 123 px]]" , fxt.tkn_lnki_().Width_(123));
}
@Test public void Height() {
fxt.Test_parse_page_wiki("[[Image:a|x40px]]" , fxt.tkn_lnki_().Height_(40).Width_(-1));
}
@Test public void Invalid_px__accept_double() {
fxt.Test_parse_page_wiki("[[Image:a|40pxpx]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
}
@Test public void Invalid_px__accept_double__w_ws() {
fxt.Test_parse_page_wiki("[[Image:a|40pxpx ]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
}
@Test public void Invalid_px__accept_double__w_ws_2() {// PURPOSE: handle ws between px's; EX:sv.w:Drottningholms_slott; DATE:2014-03-01
fxt.Test_parse_page_wiki("[[Image:a|40px px]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
}
@Test public void Invalid_px__ignore_if_w() {
fxt.Test_parse_page_wiki("[[Image:a|40px20px]]" , fxt.tkn_lnki_().Width_(-1).Height_(-1)); // -1 b/c "40px"
}
@Test public void Large_number() { // PURPOSE: perf code identified large sizes as caption; DATE:2014-02-15
fxt.Test_parse_page_wiki("[[Image:a|1234567890x1234567890px]]" , fxt.tkn_lnki_().Width_(1234567890).Height_(1234567890));
}
@Test public void Large_number__discard_if_gt_int() { // PURPOSE: size larger than int should be discarded, not be Int_.Max_value: PAGE:id.w:Baho; DATE:2014-06-10
fxt.Test_html_wiki_frag("[[File:A.png|9999999999x30px]]", " width=\"0\" height=\"30\""); // width should not be Int_.Max_value
}
@Test public void Dangling_xnde() { // PURPOSE: dangling xnde should not eat rest of lnki; PAGE:sr.w:Сићевачка_клисура DATE:2014-07-03
fxt.Init_log_(Xop_xnde_log.Dangling_xnde).Test_parse_page_wiki("[[Image:a.png|<b>c|40px]]" , fxt.tkn_lnki_().Width_(40).Height_(-1));
}
@Test public void Ws_para() { // PURPOSE: <p> in arg_bldr causes parse to fail; EX: w:Supreme_Court_of_the_United_States; DATE:2014-04-05; updated test; DATE:2015-03-31
fxt.Init_para_y_();
fxt.Test_parse_page_all("[[File:A.png| \n 40px]]"
, fxt.tkn_para_bgn_para_(0)
, fxt.tkn_lnki_().Width_(40).Height_(-1)
, fxt.tkn_para_end_para_(22));
fxt.Init_para_n_();
}
@Test public void Invalid_size() { // PURPOSE: handle invalid sizes
fxt.Test_parse_page_wiki("[[File:A.png|1234xSomeTextpx]]" , fxt.tkn_lnki_().Width_(-1).Height_(-1)); // PAGE:es.b:Alimentación_infantil; DATE:2015-07-10
fxt.Test_parse_page_wiki("[[File:A.png|100 KBpx]]" , fxt.tkn_lnki_().Width_(-1).Height_(-1)); // PAGE:en.w:Bahamas; DATE:2015-08-05
fxt.Test_parse_page_wiki("[[File:A.png|size100px]]" , fxt.tkn_lnki_().Width_(-1).Height_(-1)); // PAGE:en.w:Data_compression; DATE:2015-08-05
fxt.Test_parse_page_wiki("[[File:A.png|20\n0px]]" , fxt.tkn_lnki_().Width_(-1).Height_(-1)); // PAGE:en.w:Double_bass; DATE:2015-08-05
}
}

View File

@@ -0,0 +1,68 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_lnki_wkr__subpage_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Disabled() { // PURPOSE: slash being interpreted as subpage; PAGE:en.w:[[/dev/null]]
fxt.Wiki().Ns_mgr().Ids_get_or_null(Xow_ns_.Id_main).Subpages_enabled_(false);
fxt.Test_parse_page_all_str("[[/dev/null]]", "<a href=\"/wiki//dev/null\">/dev/null</a>");
fxt.Wiki().Ns_mgr().Ids_get_or_null(Xow_ns_.Id_main).Subpages_enabled_(true);
}
@Test public void False_match() {// PAGE:en.w:en.wiktionary.org/wiki/Wiktionary:Requests for cleanup/archive/2006
fxt.Test_parse_page_wiki_str
( "[[.../compare ...]]"
, "<a href=\"/wiki/.../compare_...\">.../compare ...</a>"
);
}
@Test public void Owner() { // PURPOSE: ../c does "A/c", not "c"; DATE:2014-01-02
fxt.Page_ttl_("A/b");
fxt.Test_parse_page_wiki_str
( "[[../c]]"
, "<a href=\"/wiki/A/c\">A/c</a>"
);
}
@Test public void Owner_w_slash() { // PURPOSE: ../c/ does "c", not "A/c"; DATE:2014-01-02
fxt.Page_ttl_("A/b");
fxt.Test_parse_page_wiki_str
( "[[../c/]]"
, "<a href=\"/wiki/A/c\">c</a>"
);
}
@Test public void Slash() { // PURPOSE: /B should show /B, not A/B; DATE:2014-01-02
fxt.Page_ttl_("A");
fxt.Test_parse_page_wiki_str
( "[[/B]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/A/B\">/B</a>"
));
}
@Test public void Slash_w_slash() { // PURPOSE: /B/ should show B, not /B; DATE:2014-01-02
fxt.Page_ttl_("A");
fxt.Test_parse_page_wiki_str
( "[[/B/]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/A/B\">B</a>"
));
}
@Test public void Leaf_w_ncr() { // PURPOSE: /B&#x63; should not encode &#x63; PAGE:en.s:The_English_Constitution_(1894) DATE:2014-09-07
fxt.Page_ttl_("A");
fxt.Test_parse_page_wiki_str
( "[[/B&#x63;|B]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/A/Bc\">B</a>"
));
}
}

View File

@@ -0,0 +1,60 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
import gplx.xowa.langs.cases.*;
public class Xop_lnki_wkr__uncommon_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Double_bracket() { // PURPOSE: handle [[[[A]]]] constructions; PAGE:ru.w:Меркатале_ин_Валь_ди_Песа; DATE:2014-02-04
fxt.Test_parse_page_all_str("[[[[Test_1]]]]" , "[[<a href=\"/wiki/Test_1\">Test_1</a>]]");
}
@Test public void Single_bracket() { // PURPOSE: handle [[A|[b]]] PAGE:en.w:Aubervilliers DATE:2014-06-25
fxt.Test_html_full_str("[[A|[B]]]", "<a href=\"/wiki/A\">[B]</a>");
}
@Test public void Triple_bracket() { // PURPOSE: "]]]" shouldn't invalidate tkn; PAGE:en.w:Tall_poppy_syndrome; DATE:2014-07-23
fxt.Test_parse_page_all_str("[[A]]]" , "<a href=\"/wiki/A\">A</a>]"); // title only
fxt.Test_parse_page_all_str("[[A|B]]]" , "<a href=\"/wiki/A\">B]</a>"); // title + caption; note that ] should be outside </a> b/c MW has more logic that says "if caption starts with '['", but leaving as is; DATE:2014-07-23
}
@Test public void Triple_bracket_with_lnke_lnki() { // PURPOSE: handle [http://a.org [[File:A.png|123px]]]; PAGE:ar.w:محمد DATE:2014-08-20
fxt.Test_parse_page_all_str("[http://a.org [[File:A.png|123px]]]"
, "<a href=\"http://a.org\" class=\"external text\" rel=\"nofollow\"><a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/123px.png\" width=\"123\" height=\"0\" /></a></a>"
);
}
@Test public void Multiple_captions() { // PURPOSE: multiple captions should be concatenated (used to only take first); EX:zh.d:维基词典:Unicode字符索引/00000FFF; DATE:2014-05-05
fxt.Test_parse_page_all_str("[[A|B|C|D]]" , "<a href=\"/wiki/A\">B|C|D</a>");
}
@Test public void Multiple_captions_file() { // PURPOSE: multiple captions should take last; EX:none; DATE:2014-05-05
fxt.Test_html_wiki_frag("[[File:A|B|C|D|thumb]]" , "</div>\n D\n </div>");
}
@Test public void Multiple_captions_pipe() { // PURPOSE.fix: multiple captions caused multiple pipes; PAGE:w:Wikipedia:Administrators'_noticeboard/IncidentArchive24; DATE:2014-06-08
fxt.Test_parse_page_all_str("[[a|b|c d e]]", "<a href=\"/wiki/A\">b|c d e</a>"); // was b|c| |d| |e
}
@Test public void Toc_fails() { // PURPOSE: null ref when writing hdr with lnki inside xnde; EX:pl.d:head_sth_off;DATE:2014-05-07
fxt.Test_parse_page_all_str("== <i>[[A]]</i> ==", "<h2> <i><a href=\"/wiki/A\">A</a></i> </h2>\n");
}
@Test public void Upright_is_large() { // PURPOSE: handle large upright which overflows int; PAGE:de.w:Feuerland DATE:2015-02-03
fxt.Test_html_wiki_frag("[[File:A.png|upright=1.333333333333333333333333333333333333333333333333333333333333333333333]]", " width=\"0\" height=\"0\""); // failure would print out original lnki
}
@Test public void Persian() { // PURPOSE: handle il8n nums; EX:[[پرونده:Shahbazi 3.jpg|۲۰۰px]] -> 200px; PAGE:fa.w:فهرست_آثار_علیرضااپور_شهبازی; DATE:2015-07-18
Xol_lang lang = fxt.Wiki().Lang();
fxt.App().Gfs_mgr().Run_str_for(lang, gplx.xowa.xtns.pfuncs.numbers.Pf_formatnum_fa_tst.Persian_numbers_gfs);
lang.Evt_lang_changed(); // force rebuild of size_trie
fxt.Test_html_wiki_frag("[[File:A.png|۲۰۰px]]", " width=\"200\" height=\"0\"");
}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*; import gplx.xowa.files.*;
public class Xop_lnki_wkr__video_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Thumbtime() {
fxt.Test_parse_page_wiki("[[File:A.ogv|thumbtime=123]]" , fxt.tkn_lnki_().Thumbtime_(123));
fxt.Test_parse_page_wiki("[[File:A.ogv|thumbtime=1:23]]" , fxt.tkn_lnki_().Thumbtime_(83));
fxt.Test_parse_page_wiki("[[File:A.ogv|thumbtime=1:01:01]]" , fxt.tkn_lnki_().Thumbtime_(3661));
fxt.Init_log_(Xop_lnki_log.Upright_val_is_invalid).Test_parse_page_wiki("[[File:A.ogv|thumbtime=a]]", fxt.tkn_lnki_().Thumbtime_(-1));
}
@Test public void Size__null() { // NOTE: make sure that no size defaults to -1; needed for Xof_img_size logic of defaulting -1 to orig_w; DATE:2015-08-07
fxt.Test_parse_page_wiki("[[File:A.ogv]]" , fxt.tkn_lnki_().Width_(Xof_img_size.Size__neg1));
}
}

View File

@@ -0,0 +1,115 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_lnki_wkr__xwiki_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_n_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Xwiki_file() { // PURPOSE: if xwiki and File, ignore xwiki (hackish); DATE:2013-12-22
Reg_xwiki_alias("test", "test.wikimedia.org"); // must register xwiki, else ttl will not parse it
fxt.Wiki().Cfg_parser().Lnki_cfg().Xwiki_repo_mgr().Add_or_mod(Bry_.new_a7("test")); // must add to xwiki_repo_mgr
fxt.Test_parse_page_wiki_str
( "[[test:File:A.png|12x10px]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/wiki/File:A.png\" class=\"image\" xowa_title=\"A.png\"><img id=\"xowa_file_img_0\" alt=\"\" src=\"file:///mem/wiki/repo/trg/thumb/7/0/A.png/12px.png\" width=\"12\" height=\"10\" /></a>"
));
fxt.Wiki().Cfg_parser_lnki_xwiki_repos_enabled_(false); // disable for other tests
}
@Test public void Xwiki_anchor() {
Reg_xwiki_alias("test", "test.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[test:A#b]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/test.wikimedia.org/wiki/A#b\">test:A#b</a>"
));
}
@Test public void Xwiki_empty() {
Reg_xwiki_alias("test", "test.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[test:]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/test.wikimedia.org/wiki/\">test:</a>"
));
}
@Test public void Xwiki_empty_literal() {
Reg_xwiki_alias("test", "test.wikimedia.org");
fxt.Test_parse_page_wiki_str
( "[[:test:]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/test.wikimedia.org/wiki/\">test:</a>"
));
}
@Test public void Xwiki_not_registered() {
fxt.App().Usere().Wiki().Xwiki_mgr().Clear();
fxt.Wiki().Xwiki_mgr().Add_full(Bry_.new_a7("test"), Bry_.new_a7("test.wikimedia.org")); // register alias only, but not in user_wiki
fxt.Test_parse_page_wiki_str
( "[[test:A|A]]", String_.Concat_lines_nl_skip_last
( "<a href=\"https://test.wikimedia.org/wiki/A\">A</a>"
));
}
@Test public void Literal_lang() {
Reg_xwiki_alias("fr", "fr.wikipedia.org");
fxt.Test_parse_page_wiki_str
( "[[:fr:A]]", String_.Concat_lines_nl_skip_last
( "<a href=\"/site/fr.wikipedia.org/wiki/A\">A</a>"
));
Tfds.Eq(0, fxt.Page().Slink_list().Count());
}
@Test public void Simple_and_english() { // PURPOSE: s.w xwiki links to en were not working b/c s.w and en had same super lang of English; PAGE:s.q:Anonymous DATE:2014-09-10
Xoae_app app = Xoa_app_fxt.app_();
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "simple.wikipedia.org");
fxt = new Xop_fxt(app, wiki); // change fxt to simple.wikipedia.org
Reg_xwiki_alias("en", "en.wikipedia.org"); // register "en" alias
fxt.Test_parse_page_wiki_str // test nothing printed
( "[[en:A]]"
, ""
);
Tfds.Eq(1, fxt.Page().Slink_list().Count()); // test 1 xwiki lang
}
@Test public void Species_and_commons() { // PURPOSE: species xwiki links to commons should not put link in wikidata langs; PAGE:species:Scarabaeidae DATE:2014-09-10
Xoae_app app = Xoa_app_fxt.app_();
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "species.wikimedia.org");
fxt = new Xop_fxt(app, wiki); // change fxt to species.wikimedia.org
Reg_xwiki_alias("commons", "commons.wikimedia.org"); // register "en" alias
fxt.Test_parse_page_wiki_str // test something printed
( "[[commons:A]]"
, "<a href=\"/site/commons.wikimedia.org/wiki/A\">commons:A</a>"
);
Tfds.Eq(0, fxt.Page().Slink_list().Count()); // no xwiki langs
}
@Test public void Wiktionary_and_wikipedia() { // PURPOSE: do not create xwiki links if same lang and differet type; PAGE:s.d:water DATE:2014-09-14
Xoae_app app = Xoa_app_fxt.app_();
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "simple.wiktionary.org");
fxt = new Xop_fxt(app, wiki); // change fxt to simple.wiktionary.org
Reg_xwiki_alias("w", "simple.wikipedia.org"); // register "w" alias
fxt.Test_parse_page_wiki_str // test something printed
( "[[w:A]]"
, "<a href=\"/site/simple.wikipedia.org/wiki/A\">w:A</a>"
);
Tfds.Eq(0, fxt.Page().Slink_list().Count()); // test 0 xwiki lang
}
@Test public void Species_and_wikipedia() { // PURPOSE: species creates xwiki links to wikipedia; PAGE:species:Puccinia DATE:2014-09-14
Xoae_app app = Xoa_app_fxt.app_();
Xowe_wiki wiki = Xoa_app_fxt.wiki_(app, "species.wikimedia.org");
fxt = new Xop_fxt(app, wiki); // change fxt to species.wikimedia.org
Reg_xwiki_alias("fr", "fr.wikipedia.org"); // register "fr" alias
fxt.Test_parse_page_wiki_str // nothing printed
( "[[fr:A]]"
, ""
);
Tfds.Eq(1, fxt.Page().Slink_list().Count()); // 1 xwiki lang
}
private void Reg_xwiki_alias(String alias, String domain) {
Xop_fxt.Reg_xwiki_alias(fxt.Wiki(), alias, domain);
}
}

View File

@@ -16,8 +16,10 @@ 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.lnkis.redlinks; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.lnkis.*;
import gplx.core.primitives.*;
import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.langs.vnts.*; import gplx.xowa.gui.views.*; import gplx.xowa.pages.*; import gplx.xowa.html.hdumps.core.*;
import gplx.xowa.parsers.tmpls.*;
public class Xog_redlink_mgr implements GfoInvkAble {
private Xog_win_itm win; private Xog_html_itm html_itm; private Xowe_wiki wiki; private Xoae_page page;
private Xopg_redlink_lnki_list redlink_lnki_list; private List_adp lnki_list; private boolean log_enabled; private Gfo_usr_dlg usr_dlg; private int thread_id;

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.lnkis.redlinks; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.lnkis.*;
import gplx.core.primitives.*;
public class Xopg_redlink_idx_list {
private final Int_list list = new Int_list();
public int Len() {return list.Len();}

View File

@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.logs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.dbs.*;
import gplx.xowa.parsers.xndes.*;
public class Xop_log_basic_wkr implements GfoInvkAble {
private Xop_log_mgr log_mgr; private Xop_log_basic_tbl log_tbl;
private boolean save_page_ttl, save_log_time, save_args_len, save_args_str;

View File

@@ -0,0 +1,28 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.parsers.tmpls.*;
public class Xop_bry_tkn extends Xop_tkn_itm_base {
public Xop_bry_tkn(int bgn, int end, byte[] val) {this.val = val; this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_bry;}
public byte[] Val() {return val;} private byte[] val;
@Override public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) {
bfr.Add(val);
return true;
}
}

View File

@@ -0,0 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_comm_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "comment");
public static final Gfo_msg_itm
Eos = Gfo_msg_itm_.new_warn_(owner, "eos")
;
}

View File

@@ -0,0 +1,96 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.paras.*;
public class Xop_comm_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_comment;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Bgn_ary, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
int lhs_end = cur_pos;
int end_pos = Bry_finder.Find_fwd(src, End_ary, cur_pos, src_len); // search for "-->" // NOTE: do not reuse cur_pos, else cur_pos may become -1 and fatal error in ctx.Msg_log() below; DATE:2014-06-08
int rhs_bgn = end_pos;
if (end_pos == Bry_finder.Not_found) { // "-->" not found
ctx.Msg_log().Add_itm_none(Xop_comm_log.Eos, src, bgn_pos, cur_pos);
cur_pos = src_len; // gobble up rest of content
}
else
cur_pos = end_pos + End_len;
cur_pos = Trim_ws_if_entire_line_is_commment(ctx, tkn_mkr, root, src, src_len, cur_pos, lhs_end, rhs_bgn);
ctx.Subs_add(root, tkn_mkr.Ignore(bgn_pos, cur_pos, Xop_ignore_tkn.Ignore_tid_comment));
return cur_pos;
}
private static int Trim_ws_if_entire_line_is_commment(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int cur_pos, int lhs_end, int rhs_bgn) {// REF.MW:Preprocessor_DOM.php|preprocessToXml|handle comments; DATE:2014-02-24
if ( ctx.Tid_is_popup()
&& ctx.Parse_tid() == Xop_parser_.Parse_tid_page_wiki // note that only popup parse can generate <!-- --> that makes it to wtxt
&& Bry_.Match(src, lhs_end, rhs_bgn, Xowa_skip_text_bry) // <!--XOWA_SKIP-->
)
return cur_pos; // in popup mode only do not gobble trailing \n; PAGE:en.w:Gwynedd; DATE:2014-07-01
int nl_lhs = -1;
int subs_len = root.Subs_len();
for (int i = subs_len - 1; i > -1; i--) { // look bwd for "\n"
Xop_tkn_itm sub = root.Subs_get(i);
switch (sub.Tkn_tid()) {
case Xop_tkn_itm_.Tid_space: case Xop_tkn_itm_.Tid_tab:
break;
case Xop_tkn_itm_.Tid_ignore:
Xop_ignore_tkn sub_as_ignore = (Xop_ignore_tkn)sub;
if (sub_as_ignore.Ignore_type() != Xop_ignore_tkn.Ignore_tid_comment)
i = -1;
break;
case Xop_tkn_itm_.Tid_newLine: // new_line found; anything afterwards is a \s or a \t; SEE.WIKT:coincidence
nl_lhs = i;
break;
default:
i = -1;
break;
}
}
if (nl_lhs == -1) return cur_pos; // non ws tkns found before \n; exit now; EX: \n\sa<!--
boolean loop = true;
int nl_rhs = -1, loop_pos = cur_pos;
while (loop) { // look fwd for \n
if (loop_pos == src_len) break;
switch (src[loop_pos++]) {
case Byte_ascii.Space:
case Byte_ascii.Tab:
break;
case Byte_ascii.Nl:
loop = false;
nl_rhs = loop_pos;
break;
default:
loop = false;
break;
}
}
if (nl_rhs == -1) return cur_pos; // non ws tkns found before \n; exit now; EX: -->a\n
for (int i = nl_lhs + 1; i < subs_len; i++) { // entire line is ws; trim everything from nl_lhs + 1 to nl_rhs; do not trim nl_lhs
Xop_tkn_itm sub_tkn = root.Subs_get(i);
sub_tkn.Ignore_y_grp_(ctx, root, i);
}
ctx.Subs_add(root, tkn_mkr.NewLine(nl_rhs - 1, nl_rhs, Xop_nl_tkn.Tid_char, 1).Ignore_y_()); // add tkn for nl_rhs, but mark as ignore; needed for multiple comment nls; EX: "<!-- -->\n<!-- -->\n;"; DATE:2014-02-24
return nl_rhs;
}
public static final byte[] Bgn_ary = new byte[] {60, 33, 45, 45}, /*<!--*/ End_ary = new byte[] {45, 45, 62}; /*-->*/
private static final int End_len = End_ary.length;
public static final Xop_comm_lxr _ = new Xop_comm_lxr(); Xop_comm_lxr() {}
private static final String Xowa_skip_text_str = "XOWA_SKIP";
private static final byte[] Xowa_skip_text_bry = Bry_.new_a7(Xowa_skip_text_str);
public static final byte[] Xowa_skip_comment_bry = Bry_.new_a7("<!--" + Xowa_skip_text_str + "-->");
}

View File

@@ -0,0 +1,102 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_comm_lxr_tst {
private Xop_fxt fxt = new Xop_fxt();
@Test public void Basic() {
fxt.Test_parse_page_all_str("a<!-- b -->c", "ac");
}
@Test public void Err() {
fxt.Init_log_(Xop_comm_log.Eos).Test_parse_page_all_str("<!-- ", "");
}
@Test public void Ws_end() {
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, "<!-- b --> "
, "c"
), String_.Concat_lines_nl_skip_last
( "a"
, "c"
));
}
@Test public void Ws_bgn_end() {
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " <!-- b --> "
, "c"
), String_.Concat_lines_nl_skip_last
( "a"
, "c"
));
}
@Test public void Ws_noop() { // PURPOSE: assert that comments do not strip ws
fxt.Test_parse_page_all_str("a <!-- b -->c", "a c");
}
@Test public void Noinclude() {// PURPOSE: templates can construct comments; EX:WBK: {{Subjects/allbooks|subject=Computer programming|origin=Computer programming languages|diagnose=}}
fxt.Test_parse_page_all_str("a <!-<noinclude></noinclude>- b -->c", "a c");
}
@Test public void Comment_can_cause_pre() {// PURPOSE: assert that comment causes pre; DATE:2014-02-18
fxt.Init_para_y_();
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " <!-- b -->c"
, "d"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, ""
, "<pre>c"
, "</pre>"
, ""
, "<p>d"
, "</p>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Ws_bgn_needs_nl() { // PURPOSE: do not strip new line unles *entire* line is comment
fxt.Init_para_y_();
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " <!-- b -->"
, "c"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "c"
, "</p>"
, ""
));
fxt.Init_para_n_();
}
@Test public void Ws_strip_nl() { // PURPOSE: handle multiple "<!-- -->\n"; was only trimming 1st; DATE:2014-02-24
fxt.Init_para_y_();
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, "<!-- -->"
, "<!-- -->"
, "b"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "b"
, "</p>"
, ""
));
fxt.Init_para_n_();
}
}

View 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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
public class Xop_cr_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_cr;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {
core_trie.Add(Byte_ascii.Cr, this);
}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
return cur_pos; //ignore
}
public static final Xop_cr_lxr _ = new Xop_cr_lxr(); Xop_cr_lxr() {}
}

View File

@@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_cr_tkn extends Xop_tkn_itm_base {
public Xop_cr_tkn(int bgn, int end) {this.Tkn_ini_pos(true, -1, -1);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_cr;}
}
/*
NOTE_1:tabs
. tabs exist in wikimedia source; note that tabs (\t) are not a meaningful HTML character
. xowa uses tabs for delimiters in its xowa files
. in order to maintain some semblance of fidelity, "\t" was replaced with &#09;
. unfortunately, "\t" is generally trimmed as whitespace throughout mediawiki; "&#09;" is not
. so, as a HACK, replace "&#09;" with "\t\s\s\s\s";
.. note that all 5 chars of "&#09;" must be replaced; hence "\t\s\s\s\s"
.. note that they all need to be ws in order to be trimmed out
.. note that shrinking the src[] would be (a) memory-expensive (b) complexity-expensive (many functions assume a static src size)
.. note that "\t\t\t\t\t" was the 1st attempt, but this resulted in exponential growth of "\t"s with each save (1 -> 5 -> 25 -> 125). "\t\s\s\s\s" is less worse with its linear growth (1 -> 5 -> 10)
. TODO: swap out the "&#09;" at point of file-read;
*/

View File

@@ -0,0 +1,81 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.parsers.tmpls.*;
public class Xop_eq_lxr implements Xop_lxr {
public Xop_eq_lxr(boolean tmpl_mode) {this.tmpl_mode = tmpl_mode;} boolean tmpl_mode;
public byte Lxr_tid() {return Xop_lxr_.Tid_eq;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Byte_ascii.Eq, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
cur_pos = Bry_finder.Find_fwd_while(src, cur_pos, src_len, Byte_ascii.Eq); // gobble up eq; "==" should produce 1 eq_tkn with len of 2, not 2 eq_tkn with len of 1; DATE:2014-04-17
int eq_len = cur_pos - bgn_pos;
boolean hdr_like = false;
if (tmpl_mode) {
Xop_tkn_itm owner = ctx.Stack_get_last(); // beginning of "is == part of a hdr tkn sequence?"; DATE:2014-02-09
if ( owner != null && owner.Tkn_tid() == Xop_tkn_itm_.Tid_tmpl_curly_bgn // inside curly
&& eq_len > 1) { // only skip if at least "=="; don't want to skip "=" which could be kv delimiter; DATE:2014-04-17
int prv_pos = bgn_pos - 1;
if (prv_pos > -1 && src[prv_pos] == Byte_ascii.Nl) // is prv char \n; EX: "\n==="
hdr_like = true;
else {
int eol_pos = Bry_finder.Find_fwd_while_space_or_tab(src, cur_pos, src_len); // skip trailing ws; EX: "== \n"; PAGE:nl.q:Geert_Wilders; DATE:2014-06-05
if ( eol_pos == src_len // eos
|| src[eol_pos] == Byte_ascii.Nl // cur_pos is \n; EX: "===\n"
) {
hdr_like = true;
cur_pos = eol_pos;
}
}
if (hdr_like) // ignore hdr tkn;
return ctx.Lxr_make_txt_(cur_pos);
}
ctx.Subs_add(root, tkn_mkr.Eq(bgn_pos, cur_pos));
return cur_pos;
}
// wiki_mode; chk if hdr exists
int stack_pos = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_hdr);
if (stack_pos == Xop_ctx.Stack_not_found) { // no hdr; make eq_tkn and return;
ctx.Subs_add(root, tkn_mkr.Eq(bgn_pos, cur_pos));
return cur_pos;
}
int ws_end = Bry_finder.Find_fwd_while_space_or_tab(src, cur_pos, src_len);
hdr_like = ws_end == src_len || src[ws_end] == Byte_ascii.Nl; // hdr_like if next char \n or eos
if (!hdr_like) {
int ctg_end = Xop_nl_lxr.Scan_fwd_for_ctg(ctx, src, cur_pos, src_len); // check if ==[[Category:A]]; DATE:2014-04-17
if ( ctg_end != Bry_.NotFound) { // [[Category: found
ctg_end = Bry_finder.Find_fwd(src, Xop_tkn_.Lnki_end, ctg_end, src_len);
if (ctg_end != Bry_.NotFound) { // ]] found; note that this should do more validation; EX: [[Category:]] should not be valid; DATE:2014-04-17
ctg_end += Xop_tkn_.Lnki_end_len;
ctg_end = Bry_finder.Find_fwd_while_space_or_tab(src, ctg_end, src_len);
if (ctg_end == src_len || src[ctg_end] == Byte_ascii.Nl) // hdr_like if ]]\n after [[Category:A]]
hdr_like = true;
}
}
}
if (hdr_like) {
cur_pos = ws_end;
return ctx.Hdr().Make_tkn_end(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, stack_pos, eq_len);
}
// = is just text; create = tkn and any other ws tkns; NOTE: also create ws tkns if scanned; EX: "== a === bad"; create "===" and " "; position at "b"
ctx.Subs_add(root, tkn_mkr.Eq(bgn_pos, cur_pos, eq_len));
return cur_pos;
}
}

View File

@@ -0,0 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_eq_tkn extends Xop_tkn_itm_base {//20111222
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_eq;}
public int Eq_len() {return eq_len;} private int eq_len = -1;
public int Eq_ws_rhs_bgn() {return eq_ws_rhs_bgn;} public Xop_eq_tkn Eq_ws_rhs_bgn_(int v) {eq_ws_rhs_bgn = v; return this;} private int eq_ws_rhs_bgn = -1;
public Xop_eq_tkn(int bgn, int end, int eq_len) {this.Tkn_ini_pos(false, bgn, end); this.eq_len = eq_len;}
}

View File

@@ -0,0 +1,45 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
import gplx.xowa.parsers.xndes.*;
public class Xop_hr_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_hr;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr parse_trie) {parse_trie.Add(Hook_ary, this);} static final byte[] Hook_ary = new byte[] {Byte_ascii.Nl, Byte_ascii.Dash, Byte_ascii.Dash, Byte_ascii.Dash, Byte_ascii.Dash};
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
int nl_adj = -1; // -1 to ignore nl at bgn for hr_len
boolean bos = bgn_pos == Xop_parser_.Doc_bgn_bos;
if (bos) {
bgn_pos = 0; // do not allow -1 pos
nl_adj = 0; // no nl at bgn, so nl_adj = 0
}
ctx.Apos().EndFrame(ctx, root, src, bgn_pos, false);
ctx.CloseOpenItms(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos); // close open items
cur_pos = Bry_finder.Find_fwd_while(src, cur_pos, src_len, Hook_byt); // gobble consecutive dashes
if (!bos)
ctx.Para().Process_nl(ctx, root, src, bgn_pos, bgn_pos); // simulate \n in front of ----
ctx.Para().Process_block__bgn_y__end_n(Xop_xnde_tag_.Tag_hr); // para=n; block=y
int hr_len = cur_pos - bgn_pos + nl_adj; // TODO: syntax_check if > 4
ctx.Subs_add(root, tkn_mkr.Hr(bgn_pos, cur_pos, hr_len));
ctx.Para().Process_block__bgn_n__end_y(Xop_xnde_tag_.Tag_hr); // block=n; para=y;
return cur_pos;
} private static final byte Hook_byt = Byte_ascii.Dash;
public static final int Hr_len = 4;
public static final Xop_hr_lxr _ = new Xop_hr_lxr(); Xop_hr_lxr() {}
}

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_hr_lxr_basic_tst {
@Before public void init() {fxt.Reset();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Basic() {fxt.Test_parse_page_wiki("----" , fxt.tkn_hr_(0, 4));}
@Test public void Basic_w_nl() {fxt.Test_parse_page_wiki("\n----a" , fxt.tkn_para_blank_(0), fxt.tkn_hr_(0, 5), fxt.tkn_txt_(5, 6));}
@Test public void Many() {fxt.Test_parse_page_wiki("---------" , fxt.tkn_hr_(0, 9).Hr_len_(9));}
@Test public void Exc_short() {fxt.Test_parse_page_wiki("---" , fxt.tkn_txt_(0, 3));}
@Test public void Exc_interrupt() {fxt.Test_parse_page_wiki("\na----" , fxt.tkn_nl_char_len1_(0), fxt.tkn_txt_(1, 6));}
@Test public void Html_basic() {fxt.Test_parse_page_wiki_str("----" , "<hr/>");}
@Test public void Html_extended() {fxt.Test_parse_page_wiki_str("------" , "<hr/>");}
@Test public void Nl_bgn() {fxt.Test_parse_page_wiki_str("a\n----" , "a\n<hr/>");}
@Test public void Nl_end() {fxt.Test_parse_page_wiki_str("----\na" , "<hr/>\na");}
}

View File

@@ -0,0 +1,54 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_hr_lxr_para_tst {
@Before public void init() {fxt.Reset(); fxt.Init_para_y_();} private Xop_fxt fxt = new Xop_fxt();
@Test public void Bos() { // PURPOSE: check that bos rendered correctly; DATE:2014-04-18
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "----"
, "a"
), String_.Concat_lines_nl_skip_last
( "<hr/>"
, ""
, "<p>a"
, "</p>"
));
}
@Test public void Multiple() { // PURPOSE.fix: hr disables para for rest of page; ca.b:Xarxes; DATE:2014-04-18
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "a"
, "----"
, "b"
, ""
, ""
, "c"
), String_.Concat_lines_nl_skip_last
( "<p>a"
, "</p>"
, "<hr/>"
, ""
, "<p>b"
, "</p>"
, ""
, "<p><br/>"
, "c"
, "</p>"
));
}
}

View File

@@ -0,0 +1,23 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_hr_tkn extends Xop_tkn_itm_base {
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_hr;}
public int Hr_len() {return hr_len;} public Xop_hr_tkn Hr_len_(int v) {hr_len = v; return this;} private int hr_len;
public Xop_hr_tkn(int bgn, int end, int hr_len) {this.Tkn_ini_pos(false, bgn, end); this.hr_len = hr_len;}
}

View 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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.parsers.tmpls.*;
public class Xop_ignore_tkn extends Xop_tkn_itm_base {
public Xop_ignore_tkn(int bgn, int end, byte ignore_type) {this.Tkn_ini_pos(false, bgn, end); this.ignore_type = ignore_type;}
public byte Ignore_type() {return ignore_type;} private byte ignore_type = Ignore_tid_null;
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_ignore;}
@Override public void Tmpl_compile(Xop_ctx ctx, byte[] src, Xot_compile_data prep_data) {}
@Override public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) {return true;}
public static final byte Ignore_tid_null = 0, Ignore_tid_comment = 1, Ignore_tid_include_tmpl = 2, Ignore_tid_include_wiki = 3, Ignore_tid_htmlTidy_tblw = 3, Ignore_tid_xnde_dangling = 4, Ignore_tid_nbsp = 5, Ignore_tid_empty_li = 6, Ignore_tid_pre_at_bos = 7;
}

View File

@@ -0,0 +1,28 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_ignore_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_ignore_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_ignore;}
public byte Ignore_type() {return ignore_type;} public Xop_ignore_tkn_chkr Ignore_tid_(byte v) {ignore_type = v; return this;} private byte ignore_type = Xop_ignore_tkn.Ignore_tid_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_ignore_tkn actl = (Xop_ignore_tkn)actl_obj;
err += mgr.Tst_val(ignore_type == Xop_ignore_tkn.Ignore_tid_null, path, "ignore_type", ignore_type, actl.Ignore_type());
return err;
}
}

View File

@@ -0,0 +1,24 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_misc_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "super");
public static final Gfo_msg_itm
Eos = Gfo_msg_itm_.new_warn_(owner, "End_of_string")
;
}

View File

@@ -0,0 +1,83 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.lnkis.*;
public class Xop_pipe_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_pipe;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Byte_ascii.Pipe, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
int cur_stack_tid = ctx.Cur_tkn_tid(), rv = -1;
switch (cur_stack_tid) {
case Xop_tkn_itm_.Tid_brack_bgn: // used for tmpl mode where full lnki_wkr is too heavyweight; matches "[ |"
switch (ctx.Parse_tid()) {
case Xop_parser_.Parse_tid_tmpl:
case Xop_parser_.Parse_tid_page_tmpl:
ctx.Subs_add(root, tkn_mkr.Txt(bgn_pos, cur_pos));
break;
case Xop_parser_.Parse_tid_page_wiki: // should never happen?
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
break;
default: throw Err_.new_unhandled(ctx.Parse_tid());
}
return cur_pos;
case Xop_tkn_itm_.Tid_tblw_tb:
case Xop_tkn_itm_.Tid_tblw_tr:
rv = Xop_tblw_lxr_ws.Make(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, Xop_tblw_wkr.Tblw_type_td, false);
if (rv == Xop_tblw_lxr_ws.Tblw_ws_cell_pipe) {
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
return cur_pos;
}
else
return rv;
case Xop_tkn_itm_.Tid_tblw_td:
case Xop_tkn_itm_.Tid_tblw_th:
case Xop_tkn_itm_.Tid_tblw_tc:
rv = Xop_tblw_lxr_ws.Make(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, Xop_tblw_wkr.Tblw_type_td, false);
if (rv != Xop_tblw_lxr_ws.Tblw_ws_cell_pipe) return rv;
if (ctx.Tblw().Cell_pipe_seen()) {
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
return cur_pos;
}
else {
Xop_tblw_tkn cur_tkn = (Xop_tblw_tkn)ctx.Stack_get_typ(cur_stack_tid);
Xop_tblw_wkr.Atrs_make(ctx, src, root, ctx.Tblw(), cur_tkn, Bool_.N);
return cur_pos;
}
case Xop_tkn_itm_.Tid_vnt:
gplx.xowa.langs.vnts.Xop_vnt_tkn vnt_tkn = (gplx.xowa.langs.vnts.Xop_vnt_tkn)ctx.Stack_get_typ(Xop_tkn_itm_.Tid_vnt);
vnt_tkn.Vnt_pipe_tkn_count_add_();
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
return cur_pos;
case Xop_tkn_itm_.Tid_lnki:
Xop_lnki_tkn lnki = (Xop_lnki_tkn)ctx.Stack_get_last(); // BLOCK:invalid_ttl_check
if ( lnki.Pipe_count_is_zero()
&& !Xop_lnki_wkr_.Parse_ttl(ctx, src, lnki, bgn_pos)) {
ctx.Stack_pop_last();
return Xop_lnki_wkr_.Invalidate_lnki(ctx, src, root, lnki, bgn_pos);
}
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
return cur_pos;
default:
ctx.Subs_add(root, tkn_mkr.Pipe(bgn_pos, cur_pos));
return cur_pos;
}
}
public static final Xop_pipe_lxr _ = new Xop_pipe_lxr();
}

View File

@@ -0,0 +1,22 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_pipe_tkn extends Xop_tkn_itm_base {
public Xop_pipe_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_pipe;}
}

View 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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
public class Xop_space_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_space;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Byte_ascii.Space, this);}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
cur_pos = Bry_finder.Find_fwd_while(src, cur_pos, src_len, Byte_ascii.Space);
ctx.Subs_add(root, tkn_mkr.Space(root, bgn_pos, cur_pos));
return cur_pos;
}
public static final Xop_space_lxr _ = new Xop_space_lxr();
}

View File

@@ -0,0 +1,32 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_space_lxr_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@After public void term() {fxt.Init_para_n_();}
@Test public void Toc_basic() { // PURPOSE: make sure nbsp char is not converted to space; PAGE:en.w:MacedonianCarthaginian_Treaty; DATE:2014-06-07
fxt.Init_para_y_();
fxt.Test_parse_page_all_str("     a", String_.Concat_lines_nl_skip_last // NOTE: ws is actually nbsp;
( "<p>     a" // should be <p> not <pre>
, "</p>"
, ""
));
}
}

View File

@@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.tmpls.*;
public class Xop_space_tkn extends Xop_tkn_itm_base {
public Xop_space_tkn(boolean immutable, int bgn, int end) {this.Tkn_ini_pos(immutable, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_space;}
@Override public Xop_tkn_itm Tkn_clone(Xop_ctx ctx, int bgn, int end) {
return ctx.Tkn_mkr().Space_mutable(bgn, end);
}
@Override public boolean Tmpl_evaluate(Xop_ctx ctx, byte[] src, Xot_invk caller, Bry_bfr bfr) {
if (this.Tkn_immutable()) {
bfr.Add_byte(Byte_ascii.Space);
return true;
}
else
return super.Tmpl_evaluate(ctx, src, caller, bfr);
}
Xop_space_tkn() {}
}

View File

@@ -0,0 +1,36 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
public class Xop_tab_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_tab;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {
core_trie.Add(Byte_ascii.Tab, this);
core_trie.Add(Xop_tab_tkn.Bry_tab_ent, this);
}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
cur_pos = Bry_finder.Find_fwd_while(src, cur_pos, src_len, Byte_ascii.Tab);
src[bgn_pos] = Byte_ascii.Tab; // HACK: SEE:NOTE_1:tabs
for (int i = bgn_pos + 1; i < cur_pos; i++)
src[i] = Byte_ascii.Space;
ctx.Subs_add(root, tkn_mkr.Tab(bgn_pos, cur_pos));
return cur_pos;
}
public static final Xop_tab_lxr _ = new Xop_tab_lxr();
}

View 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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
public class Xop_tab_tkn extends Xop_tkn_itm_base {
public Xop_tab_tkn(int bgn, int end) {this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tab;}
public static final byte[] Bry_tab_ent = Bry_.new_a7("&#09;");
}
/*
NOTE_1:tabs
. tabs exist in wikimedia source; note that tabs (\t) are not a meaningful HTML character
. xowa uses tabs for delimiters in its xowa files
. in order to maintain some semblance of fidelity, "\t" was replaced with &#09;
. unfortunately, "\t" is generally trimmed as whitespace throughout mediawiki; "&#09;" is not
. so, as a HACK, replace "&#09;" with "\t\s\s\s\s";
.. note that all 5 chars of "&#09;" must be replaced; hence "\t\s\s\s\s"
.. note that they all need to be ws in order to be trimmed out
.. note that shrinking the src[] would be (a) memory-expensive (b) complexity-expensive (many functions assume a static src size)
.. note that "\t\t\t\t\t" was the 1st attempt, but this resulted in exponential growth of "\t"s with each save (1 -> 5 -> 25 -> 125). "\t\s\s\s\s" is less worse with its linear growth (1 -> 5 -> 10)
. TODO: swap out the "&#09;" at point of file-read;
*/

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tkn_chkr_hr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_hr_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_hr;}
public Xop_tkn_chkr_hr(int bgn, int end) {super.Src_rng_(bgn, end);}
public int Hr_len() {return hr_len;} public Xop_tkn_chkr_hr Hr_len_(int v) {hr_len = v; return this;} private int hr_len = -1;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_hr_tkn actl = (Xop_hr_tkn)actl_obj;
err += mgr.Tst_val(hr_len == -1, path, "hr_len", hr_len, actl.Hr_len());
return err;
}
}

View File

@@ -0,0 +1,146 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*;
import gplx.xowa.html.tocs.*;
public class Xop_under_lxr implements Xop_lxr {
private Btrie_mgr words_trie_ci, words_trie_cs;
public byte Lxr_tid() {return Xop_lxr_.Tid_under;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {
Xol_kwd_mgr kwd_mgr = lang.Kwd_mgr();
int under_kwds_len = under_kwds.length;
Xop_under_lxr lxr = new Xop_under_lxr();
lxr.words_trie_cs = Btrie_slim_mgr.cs();
lxr.words_trie_ci = Btrie_u8_mgr.new_(lang.Case_mgr());
core_trie.Add(Xop_under_hook.Key_std, lxr);
boolean hook_alt_null = true;
for (int i = 0; i < under_kwds_len; i++) {
int kwd_id = under_kwds[i];
Xol_kwd_grp kwd_grp = kwd_mgr.Get_or_new(kwd_id);
Xol_kwd_itm[] kwd_itms = kwd_grp.Itms(); if (kwd_itms == null) continue;
int kwd_itms_len = kwd_itms.length;
boolean kwd_case_match = kwd_grp.Case_match();
Btrie_mgr words_trie = kwd_grp.Case_match() ? lxr.words_trie_cs : lxr.words_trie_ci;
for (int j = 0; j < kwd_itms_len; j++) {
Xol_kwd_itm kwd_itm = kwd_itms[j];
byte[] kwd_bry = kwd_itm.Val();
int kwd_len = kwd_bry.length;
Object hook_obj = Hook_trie.Match_bgn(kwd_bry, 0, kwd_len);
if (hook_obj != null) {
Xop_under_hook hook = (Xop_under_hook)hook_obj;
byte[] word_bry = Bry_.Mid(kwd_bry, hook.Key_len(), kwd_bry.length);
words_trie.Add_obj(word_bry, new Xop_under_word(kwd_id, word_bry));
if (hook_alt_null && hook.Tid() == Xop_under_hook.Tid_alt) {
core_trie.Add(Xop_under_hook.Key_alt, lxr);
hook_alt_null = false;
}
}
else { // kwd doesn't start with __; no known examples, but just in case; EX: "NOTOC"; DATE:2014-02-14
Xop_word_lxr word_lxr = new Xop_word_lxr(kwd_id);
if (kwd_case_match) // cs; add word directly to trie
core_trie.Add(kwd_bry, word_lxr);
else { // NOTE: next part is imprecise; XOWA parser is cs, but kwd is ci; for now, just add all upper and all lower
Gfo_usr_dlg_.I.Warn_many("", "", "under keyword does not start with __; id=~{0} key=~{1} word=~{2}", kwd_id, String_.new_u8(kwd_grp.Key()), String_.new_u8(kwd_bry));
core_trie.Add(lang.Case_mgr().Case_build_lower(kwd_bry), word_lxr);
core_trie.Add(lang.Case_mgr().Case_build_upper(kwd_bry), word_lxr);
}
}
}
}
}
private static final int[] under_kwds = new int[] // REF.MW:MagicWord.php
{ Xol_kwd_grp_.Id_toc, Xol_kwd_grp_.Id_notoc, Xol_kwd_grp_.Id_forcetoc
, Xol_kwd_grp_.Id_nogallery, Xol_kwd_grp_.Id_noheader, Xol_kwd_grp_.Id_noeditsection
, Xol_kwd_grp_.Id_notitleconvert, Xol_kwd_grp_.Id_nocontentconvert, Xol_kwd_grp_.Id_newsectionlink, Xol_kwd_grp_.Id_nonewsectionlink
, Xol_kwd_grp_.Id_hiddencat, Xol_kwd_grp_.Id_index, Xol_kwd_grp_.Id_noindex, Xol_kwd_grp_.Id_staticredirect
, Xol_kwd_grp_.Id_disambig
};
private static final Btrie_fast_mgr Hook_trie = Btrie_fast_mgr.cs()
.Add(Xop_under_hook.Key_std, Xop_under_hook.Itm_std)
.Add(Xop_under_hook.Key_alt, Xop_under_hook.Itm_alt)
;
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
if (cur_pos == src_len) return ctx.Lxr_make_txt_(cur_pos); // eos
int rv = cur_pos;
Object word_obj = words_trie_cs.Match_bgn(src, cur_pos, src_len); // check cs
if (word_obj == null) {
word_obj = words_trie_ci.Match_bgn(src, cur_pos, src_len); // check ci
if (word_obj == null)
return ctx.Lxr_make_txt_(cur_pos); // kwd not found; EX: "TOCA__"
else
rv = words_trie_ci.Match_pos();
}
else
rv = words_trie_cs.Match_pos();
Xop_under_word word_itm = (Xop_under_word)word_obj;
Xop_under_lxr.Make_tkn(ctx, tkn_mkr, root, src, src_len, bgn_pos, rv, word_itm.Kwd_id());
return rv;
}
public static void 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 kwd_id) {
Xoae_page page = ctx.Cur_page();
Xow_hdr_mgr hdr_mgr = page.Hdr_mgr();
switch (kwd_id) {
case Xol_kwd_grp_.Id_toc:
hdr_mgr.Toc_manual_();
ctx.Para().Process_block_lnki_div(); // NOTE: __TOC__ will manually place <div toc> here; simulate div in order to close any pres; EX:\n\s__TOC__; PAGE:de.w: DATE:2014-07-05
ctx.Subs_add(root, tkn_mkr.Under(bgn_pos, cur_pos, kwd_id)); // NOTE: only save under_tkn for TOC (b/c its position is needed for insertion); DATE:2013-07-01
break;
case Xol_kwd_grp_.Id_forcetoc: hdr_mgr.Toc_force_(); break;
case Xol_kwd_grp_.Id_notoc: hdr_mgr.Toc_hide_(); break;
case Xol_kwd_grp_.Id_noeditsection: break; // ignore; not handling edit sections
case Xol_kwd_grp_.Id_nocontentconvert: page.Html_data().Lang_convert_content_(false); break;
case Xol_kwd_grp_.Id_notitleconvert: page.Html_data().Lang_convert_title_(false); break;
default: break; // ignore anything else
}
}
public static final Xop_under_lxr _ = new Xop_under_lxr(); Xop_under_lxr() {}
}
class Xop_word_lxr implements Xop_lxr {
private int kwd_id;
public Xop_word_lxr(int kwd_id) {this.kwd_id = kwd_id;}
public byte Lxr_tid() {return Xop_lxr_.Tid_word;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {}
public void Init_by_lang(Xol_lang lang, Btrie_fast_mgr core_trie) {}
public int Make_tkn(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos) {
Xop_under_lxr.Make_tkn(ctx, tkn_mkr, root, src, src_len, bgn_pos, cur_pos, kwd_id); // for now, all word_lxrs only call the under_lxr; DATE:2014-02-14
return cur_pos;
}
}
class Xop_under_hook {
Xop_under_hook(byte tid, byte[] key) {this.tid = tid; this.key = key; this.key_len = key.length;}
public byte Tid() {return tid;} private byte tid;
public byte[] Key() {return key;} private byte[] key;
public int Key_len() {return key_len;} private int key_len;
public static final byte Tid_std = 1, Tid_alt = 2;
public static final byte[] Key_std = new byte[] {Byte_ascii.Underline, Byte_ascii.Underline}, Key_alt = Bry_.new_u8("__"); // ja wikis
public static final Xop_under_hook
Itm_std = new Xop_under_hook(Tid_std, Key_std)
, Itm_alt = new Xop_under_hook(Tid_alt, Key_alt)
;
}
class Xop_under_word {
public Xop_under_word(int kwd_id, byte[] word_bry) {
this.kwd_id = kwd_id;
this.word_bry = word_bry;
this.word_len = word_bry.length;
}
public int Kwd_id() {return kwd_id;} private int kwd_id;
public byte[] Word_bry() {return word_bry;} private byte[] word_bry;
public int Word_len() {return word_len;} private int word_len;
}

View File

@@ -0,0 +1,187 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import org.junit.*;
public class Xop_under_lxr_tst {
private Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@After public void term() {fxt.Init_para_n_();}
@Test public void Toc_basic() {
fxt.Test_parse_page_all_str("a__TOC__b", "ab");
}
@Test public void Toc_match_failed() {
fxt.Test_parse_page_all_str("a__TOCA__b", "a__TOCA__b");
}
@Test public void Toc_match_ci() {
fxt.Test_parse_page_all_str("a__toc__b", "ab");
}
@Test public void Notoc_basic() {
fxt.Wtr_cfg().Toc__show_(Bool_.Y); // NOTE: must enable in order for TOC to show (and to make sure NOTOC suppresses)
fxt.Test_parse_page_all_str(String_.Concat_lines_nl
( "__NOTOC__"
, "==a=="
, "==b=="
, "==c=="
, "==d=="
), String_.Concat_lines_nl
( "<h2><span class='mw-headline' id='a'>a</span></h2>"
, ""
, "<h2><span class='mw-headline' id='b'>b</span></h2>"
, ""
, "<h2><span class='mw-headline' id='c'>c</span></h2>"
, ""
, "<h2><span class='mw-headline' id='d'>d</span></h2>"
));
fxt.Wtr_cfg().Toc__show_(Bool_.N);
}
@Test public void Ignore_pre() {
fxt.Init_para_y_();
fxt.Test_parse_page_all_str("a\n __NOTOC__\n", String_.Concat_lines_nl
( "<p>a"
, "</p>" // NOTE: do not capture " " in front of __NOTOC__; confirmed against MW; DATE:2014-02-19
, ""
, "<p><br/>"
, "</p>"
));
fxt.Init_para_n_();
}
@Test public void Toc_works() { // PURPOSE: make sure "suppressed" pre does not somehow suppress TOC
fxt.Init_para_y_();
fxt.Test_parse_page_all_str("a\n__TOC__\n==b==\n", String_.Concat_lines_nl
( "<p>a"
, "</p>"
, "<div id=\"toc\" class=\"toc\">"
, " <div id=\"toctitle\">"
, " <h2>Contents</h2>"
, " </div>"
, " <ul>"
, " <li class=\"toclevel-1 tocsection-1\"><a href=\"#b\"><span class=\"tocnumber\">1</span> <span class=\"toctext\">b</span></a>"
, " </li>"
, " </ul>"
, "</div>"
, ""
, "<h2>b</h2>"
));
fxt.Init_para_n_();
}
@Test public void Ignore_pre_after() { // PURPOSE: "__TOC__\s\n" must be trimmed at end, else false pre; assertion only (no code exists to handle this test); DATE:2013-07-08
fxt.Init_para_y_();
fxt.Test_parse_page_all_str(String_.Concat_lines_nl
( "a"
, "__NOTOC__ "
, "b"
), String_.Concat_lines_nl
( "<p>a"
, "</p>" // NOTE: do not capture " "; confirmed against MW; DATE:2014-02-19
, ""
, "<p>b"
, "</p>"
));
fxt.Init_para_n_();
}
@Test public void Disambig() { // PURPOSE: ignore "__DISAMBIG__"; EX:{{disambiguation}} DATE:2013-07-24
fxt.Test_parse_page_all_str("__DISAMBIG__", "");
}
@Test public void Nocontentconvert() { // simple test; test for flag only; DATE:2014-02-06
gplx.xowa.pages.Xopg_html_data html_data = fxt.Page().Html_data();
Tfds.Eq(html_data.Lang_convert_content(), true);
Tfds.Eq(html_data.Lang_convert_title(), true);
fxt.Test_parse_page_all_str("__NOCONTENTCONVERT__ __NOTITLECONVERT__", " ");
Tfds.Eq(html_data.Lang_convert_content(), false);
Tfds.Eq(html_data.Lang_convert_title(), false);
}
@Test public void Eos() { // PURPOSE: check that __ at eos doesn't fail; es.s:Luisa de Bustamante: 3; DATE:2014-02-15
fxt.Test_parse_page_all_str("__", "__");
}
@Test public void Pre_toc() { // PURPOSE: make sure that "\n\s__TOC" does not create pre; PAGE:de.w:Main_Page; DATE:2014-04-07
fxt.Init_para_y_();
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " __TOC__ " // NOTE: this should not be a pre; DATE:2014-07-05
, "b"
), String_.Concat_lines_nl
( "<p>a"
, "</p>"
, " " // NOTE: \s should not be captured, but leaving for now
, ""
, "<p>b"
, "</p>"
));
fxt.Init_para_n_();
}
@Test public void Pre_notoc() { // PURPOSE: make sure that "\n\s__NOTOC" does not create pre. note that mechanism is different from TOC; DATE:2014-07-05
fxt.Init_para_y_();
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
( "a"
, " __NOTOC__ " // NOTE: does not capture " "; confirmed against MW
, "b"
), String_.Concat_lines_nl
( "<p>a"
, "</p>"
, ""
, "<p>b"
, "</p>"
));
fxt.Init_para_n_();
}
@Test public void Hook_alt() { // PURPOSE: ja wikis use alternate __; DATE:2014-03-04
Xowe_wiki wiki = fxt.Wiki(); Xol_lang lang = wiki.Lang();
fxt.Init_lang_kwds(lang, Xol_kwd_grp_.Id_toc, true, "__TOC__");
wiki.Parser().Init_by_lang(lang);
fxt.Test_parse_page_all_str("a__TOC__b", "ab");
}
@Test public void Ascii_ci() { // PURPOSE: case-insensitive ascii; DATE:2014-07-10
Xowe_wiki wiki = fxt.Wiki(); Xol_lang lang = wiki.Lang();
fxt.Init_lang_kwds(lang, Xol_kwd_grp_.Id_toc, false, "__TOC__");
wiki.Parser().Init_by_lang(lang);
fxt.Test_parse_page_all_str("a__TOC__b", "ab");
fxt.Test_parse_page_all_str("a__toc__b", "ab");
}
@Test public void Utf8_ci() { // PURPOSE: case-insensitive UTF8; DATE:2014-07-10
Xowe_wiki wiki = fxt.Wiki(); Xol_lang lang = wiki.Lang();
lang.Case_mgr_u8_();
fxt.Init_lang_kwds(lang, Xol_kwd_grp_.Id_toc, false, "__AÉI__");
wiki.Parser().Init_by_lang(lang);
fxt.Test_parse_page_all_str("a__AÉI__b", "ab");
fxt.Test_parse_page_all_str("a__aéi__b", "ab");
}
@Test public void Utf8_ci_asymmetric() { // PURPOSE: case-insensitive UTF8; asymmetric; DATE:2014-07-10
Xowe_wiki wiki = fxt.Wiki(); Xol_lang lang = wiki.Lang();
lang.Case_mgr_u8_();
fxt.Init_lang_kwds(lang, Xol_kwd_grp_.Id_toc, false, "__İÇİNDEKİLER__"); // __TOC__ for tr.w
wiki.Parser().Init_by_lang(lang);
fxt.Test_parse_page_all_str("a__İçindekiler__b", "ab");
}
@Test public void Cs() { // PURPOSE: cs (ascii / utf8 doesn't matter); DATE:2014-07-11
Xowe_wiki wiki = fxt.Wiki(); Xol_lang lang = wiki.Lang();
fxt.Init_lang_kwds(lang, Xol_kwd_grp_.Id_toc , Bool_.Y, "__TOC__");
wiki.Parser().Init_by_lang(lang);
fxt.Test_parse_page_all_str("a__TOC__b" , "ab"); // ci.pass
fxt.Test_parse_page_all_str("a__toc__b" , "a__toc__b"); // ci.pass
}
@Test public void Ascii_cs_ci() { // PURPOSE: test simultaneous cs and ci; DATE:2014-07-11
Xowe_wiki wiki = fxt.Wiki(); Xol_lang lang = wiki.Lang();
fxt.Init_lang_kwds(lang, Xol_kwd_grp_.Id_toc , Bool_.N, "__TOC__");
fxt.Init_lang_kwds(lang, Xol_kwd_grp_.Id_notoc , Bool_.Y, "__NOTOC__");
wiki.Parser().Init_by_lang(lang);
fxt.Test_parse_page_all_str("a__TOC__b" , "ab"); // ci.pass
fxt.Test_parse_page_all_str("a__toc__b" , "ab"); // ci.pass
fxt.Test_parse_page_all_str("a__NOTOC__b" , "ab"); // cs.pass
fxt.Test_parse_page_all_str("a__notoc__b" , "a__notoc__b"); // cs.fail
}
}

View File

@@ -0,0 +1,23 @@
/*
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.miscs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_under_tkn extends Xop_tkn_itm_base {
public Xop_under_tkn(int bgn, int end, int under_tid) {this.under_tid = under_tid; this.Tkn_ini_pos(false, bgn, end);}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_under;}
public int Under_tid() {return under_tid;} private int under_tid;
}

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.paras; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*;
import gplx.core.btries.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.miscs.*;
public class Xop_nl_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_nl;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Byte_ascii.Nl, this);}

View File

@@ -0,0 +1,28 @@
/*
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.paras; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_nl_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_nl_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_newLine;}
public byte Nl_tid() {return nl_typeId;} public Xop_nl_tkn_chkr Nl_tid_(byte v) {nl_typeId = v; return this;} private byte nl_typeId = Xop_nl_tkn.Tid_unknown;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_nl_tkn actl = (Xop_nl_tkn)actl_obj;
err += mgr.Tst_val(nl_typeId == Xop_nl_tkn.Tid_unknown, path, "nl_typeId", nl_typeId, actl.Nl_tid());
return err;
}
}

View 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.paras; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_para_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_para_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_para;}
public byte Para_end() {return para_end;} public Xop_para_tkn_chkr Para_end_(byte v) {para_end = v; return this;} private byte para_end = Byte_.Max_value_127;
public byte Para_bgn() {return para_bgn;} public Xop_para_tkn_chkr Para_bgn_(byte v) {para_bgn = v; return this;} private byte para_bgn = Byte_.Max_value_127;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_para_tkn actl = (Xop_para_tkn)actl_obj;
err += mgr.Tst_val(para_end == Byte_.Max_value_127, path, "para_end", para_end, actl.Para_end());
err += mgr.Tst_val(para_bgn == Byte_.Max_value_127, path, "para_bgn", para_bgn, actl.Para_bgn());
return err;
}
}

View File

@@ -16,7 +16,8 @@ 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.paras; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.parsers.tblws.*; import gplx.core.btries.*;
import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.miscs.*;
import gplx.core.btries.*;
public class Xop_para_wkr implements Xop_ctx_wkr {
private boolean para_enabled;
private byte cur_mode;

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.paras; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*;
import gplx.core.btries.*; import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.tblws.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.miscs.*;
public class Xop_pre_lxr implements Xop_lxr {
public byte Lxr_tid() {return Xop_lxr_.Tid_pre;}
public void Init_by_wiki(Xowe_wiki wiki, Btrie_fast_mgr core_trie) {core_trie.Add(Hook_space, this);} // NOTE: do not treat \n\t as shorthand pre; EX:pl.w:Main_Page; DATE:2014-05-06

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tblw_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tblw");
public static final Gfo_msg_itm
Dangling = Gfo_msg_itm_.new_warn_(owner, "dangling_tblw")
, Elem_without_tbl = Gfo_msg_itm_.new_warn_(owner, "elem_without_tbl")
// , Row_trailing = Gfo_msg_itm_.new_warn_(owner, "Row_trailing")
, Caption_after_tr = Gfo_msg_itm_.new_warn_(owner, "caption_after_tr")
, Caption_after_td = Gfo_msg_itm_.new_warn_(owner, "caption_after_td")
, Caption_after_tc = Gfo_msg_itm_.new_warn_(owner, "caption_after_tc")
, Hdr_after_cell = Gfo_msg_itm_.new_warn_(owner, "hdr_after_cell")
, Tbl_empty = Gfo_msg_itm_.new_warn_(owner, "tbl_empty")
;
}

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.btries.*; import gplx.xowa.parsers.paras.*;
import gplx.core.btries.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.parsers.lnkis.*; import gplx.xowa.parsers.miscs.*;
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) {

View File

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

View File

@@ -0,0 +1,31 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tblw_tb_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_tb_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tb;}
public int Caption_count() {return caption_count;} public Xop_tblw_tb_tkn_chkr Caption_count_(int v) {caption_count = v; return this;} private int caption_count = Int_.Neg1_count;
public Xop_tblw_tb_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_tb_tkn actl = (Xop_tblw_tb_tkn)actl_obj;
err += mgr.Tst_val(caption_count == Int_.Neg1_count, path, "caption_count", caption_count, actl.Caption_count());
err += mgr.Tst_val(atrs_bgn == Xop_tblw_wkr.Atrs_null, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == Xop_tblw_wkr.Atrs_null, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

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

View File

@@ -0,0 +1,26 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tblw_tc_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_tc_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tc;}
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
// Xop_tblw_tc_tkn actl = (Xop_tblw_tc_tkn)actl_obj;
return err;
}
}

View File

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

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tblw_td_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_td_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_td;}
public Xop_tblw_td_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_td_tkn actl = (Xop_tblw_td_tkn)actl_obj;
err += mgr.Tst_val(atrs_bgn == Xop_tblw_wkr.Atrs_null, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == Xop_tblw_wkr.Atrs_null, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

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

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tblw_th_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_th_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_th;}
public Xop_tblw_th_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_th_tkn actl = (Xop_tblw_th_tkn)actl_obj;
err += mgr.Tst_val(atrs_bgn == -1, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == -1, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.parsers.xndes.*;
public interface Xop_tblw_tkn extends Xop_tkn_itm {
int Tblw_tid();
boolean Tblw_xml();

View File

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

View File

@@ -0,0 +1,29 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xop_tblw_tr_tkn_chkr extends Xop_tkn_chkr_base {
@Override public Class<?> TypeOf() {return Xop_tblw_tr_tkn.class;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_tblw_tr;}
public Xop_tblw_tr_tkn_chkr Atrs_rng_(int bgn, int end) {this.atrs_bgn = bgn; this.atrs_end = end; return this;} private int atrs_bgn = Xop_tblw_wkr.Atrs_null, atrs_end = Xop_tblw_wkr.Atrs_null;
@Override public int Chk_hook(Tst_mgr mgr, String path, Object actl_obj, int err) {
Xop_tblw_tr_tkn actl = (Xop_tblw_tr_tkn)actl_obj;
err += mgr.Tst_val(atrs_bgn == -1, path, "atrs_bgn", atrs_bgn, actl.Atrs_bgn());
err += mgr.Tst_val(atrs_end == -1, path, "atrs_end", atrs_end, actl.Atrs_end());
return err;
}
}

View File

@@ -16,7 +16,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.parsers.tblws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.paras.*;
import gplx.xowa.parsers.lists.*; import gplx.xowa.parsers.paras.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.miscs.*;
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
@@ -48,7 +48,6 @@ public class Xop_tblw_wkr implements Xop_ctx_wkr {
}
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
@@ -192,10 +191,25 @@ public class Xop_tblw_wkr implements Xop_ctx_wkr {
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);
if ( prv_tkn.Tblw_xml() // prv is <td>
&& !tbl_is_xml // cur is "\n|"
) { // insert <tr>; EX: "<tr><td>\n|" -> "<tr><td><tr><td>" PAGE:fi.w:Salibandyn_maailmanmestaruuskilpailut_2012 DATE:2015-09-07
int prv_tr_tkn_idx = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tr);
if (prv_tr_tkn_idx != Xop_ctx.Stack_not_found) { // <tr> exists
int prv_tb_tkn_idx = ctx.Stack_idx_typ(Xop_tkn_itm_.Tid_tblw_tb);
if (prv_tb_tkn_idx < prv_tr_tkn_idx) // don't close <tr> above current tbl
ctx.Stack_pop_til(root, src, prv_tr_tkn_idx, true, bgn_pos, bgn_pos, Xop_tkn_itm_.Tid_tblw_td); // close <tr>
}
new_tkn = tkn_mkr.Tblw_tr(bgn_pos, cur_pos, tbl_is_xml, true); // make a new <tr>
new_tkn.Atrs_rng_set(bgn_pos, bgn_pos);
ctx.Subs_add_and_stack_tblw(root, prv_tkn, new_tkn);
}
else {
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);

View File

@@ -139,41 +139,6 @@ public class Xop_tblw_wkr__nested_tst {
, ""
));
}
@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
// ( "{|"

View File

@@ -68,4 +68,65 @@ public class Xop_tblw_wkr__tblx_tst {
)
);
}
@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 Auto_tr_after_td() { // PURPOSE: "<tr><td>\n|" -> "<tr><td><tr><td>"; PAGE:fi.w:Salibandyn_maailmanmestaruuskilpailut_2012 DATE:2015-09-07
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
( "{|"
, " <tr>"
, " <td>a"
, " </td>"
, " <td>"
, "|b"
, "|}"
) , String_.Concat_lines_nl_skip_last
( "<table>"
, " <tr>"
, " <td>a"
, " </td>"
, " <td>" // NOTE: dangling <td> from above just gets auto-closed; no logic in tblw_wkr to actually remove it
, " </td>"
, " </tr>"
, " <tr>" // <tr> inserted by transition from <td> to "\n|"
, " <td>b"
, " </td>"
, " </tr>"
, "</table>"
, ""
)
);
}
}

View File

@@ -17,6 +17,7 @@ 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.xndes.*;
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;

Some files were not shown because too many files have changed in this diff Show More