mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
Section_edit: Show section when section_key is passed
This commit is contained in:
@@ -21,7 +21,7 @@ import gplx.xowa.wikis.*; import gplx.core.envs.*;
|
||||
import gplx.xowa.files.*;
|
||||
import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.wbases.hwtrs.*; import gplx.xowa.xtns.pfuncs.ifs.*; import gplx.xowa.xtns.pfuncs.times.*; import gplx.xowa.xtns.pfuncs.ttls.*;
|
||||
import gplx.xowa.parsers.uniqs.*; import gplx.xowa.parsers.hdrs.sections.*;
|
||||
public class Xow_parser_mgr implements Gfo_invk {
|
||||
public class Xow_parser_mgr {
|
||||
private final Xowe_wiki wiki; private final Xop_tkn_mkr tkn_mkr;
|
||||
public Xow_parser_mgr(Xowe_wiki wiki) {
|
||||
this.wiki = wiki; this.tkn_mkr = wiki.Appe().Parser_mgr().Tkn_mkr();
|
||||
@@ -42,8 +42,6 @@ public class Xow_parser_mgr implements Gfo_invk {
|
||||
public boolean Lst__recursing() {return lst_recursing;} private boolean lst_recursing; public void Lst__recursing_(boolean v) {lst_recursing = v;}
|
||||
public Bry_bfr Wbase__time__bfr() {return wbase__time__bfr;} private final Bry_bfr wbase__time__bfr = Bry_bfr_.New();
|
||||
public Bry_fmtr Wbase__time__fmtr() {return wbase__time__fmtr;} private final Bry_fmtr wbase__time__fmtr = Bry_fmtr.new_();
|
||||
public boolean Hdr__section_editable__enabled() {return hdr__section_editable__enabled;} private boolean hdr__section_editable__enabled;
|
||||
public Bry_fmt Hdr__section_editable__imt_fmt() {return hdr__section_editable__imt_fmt;} private final Bry_fmt hdr__section_editable__imt_fmt = Bry_fmt.New("<!--xo_meta|section_edit|~{page}|~{section}-->");
|
||||
public Xop_section_mgr Hdr__section_editable__mgr() {return hdr__section_editable__mgr;} private final Xop_section_mgr hdr__section_editable__mgr = new Xop_section_mgr();
|
||||
public Wdata_hwtr_msgs Wbase__time__msgs() {
|
||||
if (wbase__time__msgs == null)
|
||||
@@ -65,7 +63,6 @@ public class Xow_parser_mgr implements Gfo_invk {
|
||||
tmpl_stack_ary_len = new_len;
|
||||
return true;
|
||||
} private byte[][] tmpl_stack_ary = Bry_.Ary_empty; private int tmpl_stack_ary_len = 0, tmpl_stack_ary_max = 0;
|
||||
|
||||
public Pfunc_anchorencode_mgr Anchor_encoder_mgr__dflt_or_new(Xop_ctx calling_ctx) {
|
||||
// lazy-instantiate anchor_encoder_mgr
|
||||
if (anchor_encoder_mgr == null) anchor_encoder_mgr = new Pfunc_anchorencode_mgr(wiki);
|
||||
@@ -77,16 +74,16 @@ public class Xow_parser_mgr implements Gfo_invk {
|
||||
rv.Used_(Bool_.Y);
|
||||
return rv;
|
||||
} private Pfunc_anchorencode_mgr anchor_encoder_mgr;
|
||||
public void Init_by_wiki() {
|
||||
hdr__section_editable__mgr.Init_by_wiki(wiki);
|
||||
}
|
||||
public void Parse(Xoae_page page, boolean clear) { // main parse method; should never be called nested
|
||||
if (!Env_.Mode_testing()) wiki.Init_assert();
|
||||
|
||||
// init
|
||||
if (!Env_.Mode_testing()) wiki.Init_assert(); // needed for html_server?
|
||||
tmpl_stack_ary = Bry_.Ary_empty;
|
||||
tmpl_stack_ary_len = tmpl_stack_ary_max = 0;
|
||||
uniq_mgr.Clear();
|
||||
|
||||
// hdr__section_editable__enabled = page.Wiki().App().Cfg().Bind_bool(wiki, gplx.xowa.htmls.core.wkrs.hdrs.Xoh_section_editable_.Cfg__section_editing__enabled, this); // COMMENT:section_edit DATE:2016-12-04
|
||||
|
||||
scrib.When_page_changed(page); // notify scribunto about page changed
|
||||
ctx.Page_(page);
|
||||
Xop_root_tkn root = ctx.Tkn_mkr().Root(page.Db().Text().Text_bry());
|
||||
@@ -99,9 +96,4 @@ public class Xow_parser_mgr implements Gfo_invk {
|
||||
page.Root_(root);
|
||||
root.Data_htm_(root.Root_src());
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, gplx.xowa.htmls.core.wkrs.hdrs.Xoh_section_editable_.Cfg__section_editing__enabled)) hdr__section_editable__enabled = m.ReadBool("v");
|
||||
else return Gfo_invk_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,10 +78,10 @@ public class Xop_hdr_wkr implements Xop_ctx_wkr {
|
||||
hdr.Init_by_parse(hdr_len, bgn_manual, end_manual);
|
||||
|
||||
// section-editable
|
||||
if ( ctx.Wiki().Parser_mgr().Hdr__section_editable__enabled()
|
||||
&& Bry_.Eq(src, cur_pos, cur_pos + Xop_section_mgr.Len__meta, Xop_section_mgr.Bry__meta)) {
|
||||
ctx.Wiki().Parser_mgr().Hdr__section_editable__mgr().Parse(hdr, ctx.Page().Ttl().Full_db(), src, cur_pos, src_len);
|
||||
}
|
||||
// if ( ctx.Wiki().Parser_mgr().Hdr__section_editable__enabled()
|
||||
// && Bry_.Eq(src, cur_pos, cur_pos + Xop_section_mgr.Len__meta, Xop_section_mgr.Bry__meta)) {
|
||||
// ctx.Wiki().Parser_mgr().Hdr__section_editable__mgr().Parse(hdr, ctx.Page().Ttl().Full_db(), src, cur_pos, src_len); // SECTION_EDIT
|
||||
// }
|
||||
|
||||
// gobble ws; hdr gobbles up trailing ws; EX: "==a== \n\t \n \nb" gobbles up all 3 "\n"s; otherwise para_wkr will process <br/>
|
||||
cur_pos = Find_fwd_while_ws_hdr_version(src, cur_pos, src_len);
|
||||
|
||||
@@ -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.hdrs.sections; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.hdrs.*;
|
||||
class Xop_section_itm {
|
||||
public Xop_section_itm(int idx, byte[] key, int src_bgn, int src_end) {
|
||||
this.idx = idx;
|
||||
this.key = key;
|
||||
this.src_bgn = src_bgn;
|
||||
this.src_end = src_end;
|
||||
}
|
||||
public int Idx() {return idx;} private final int idx;
|
||||
public byte[] Key() {return key;} private final byte[] key;
|
||||
public int Src_bgn() {return src_bgn;} private final int src_bgn;
|
||||
public int Src_end() {return src_end;} private final int src_end;
|
||||
}
|
||||
@@ -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.hdrs.sections; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.hdrs.*;
|
||||
import gplx.xowa.parsers.mws.*; import gplx.xowa.parsers.mws.wkrs.*;
|
||||
class Xop_section_list implements Xomw_hdr_cbk {
|
||||
private final Xomw_hdr_wkr hdr_wkr = new Xomw_hdr_wkr();
|
||||
private final Ordered_hash hash = Ordered_hash_.New_bry();
|
||||
private byte[] src;
|
||||
|
||||
public Xop_section_list Parse(byte[] ttl_full_db, byte[] src) {
|
||||
this.src = src;
|
||||
Xomw_parser_ctx pctx = new Xomw_parser_ctx();
|
||||
hdr_wkr.Parse(pctx, src, 0, src.length, this);
|
||||
return this;
|
||||
}
|
||||
public byte[] Extract_bry_or_null(byte[] key) {
|
||||
// find section matching key
|
||||
Xop_section_itm itm = (Xop_section_itm)hash.Get_by(key);
|
||||
if (itm == null) return null;
|
||||
|
||||
int src_bgn = itm.Src_bgn();
|
||||
if (src[src_bgn] == Byte_ascii.Nl) src_bgn++;
|
||||
|
||||
int src_end = src.length;
|
||||
if (itm.Idx() != hash.Len() - 1) { // if not last, get next
|
||||
Xop_section_itm nxt = (Xop_section_itm)hash.Get_at(itm.Idx() + 1);
|
||||
src_end = nxt.Src_bgn();
|
||||
}
|
||||
src_end = Bry_find_.Find_bwd__skip_ws(src, src_end, src_bgn);
|
||||
|
||||
return Bry_.Mid(src, src_bgn, src_end);
|
||||
}
|
||||
public void On_hdr_seen(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {
|
||||
byte[] src = wkr.Src();
|
||||
int hdr_txt_bgn = wkr.Hdr_lhs_end();
|
||||
int hdr_txt_end = wkr.Hdr_rhs_bgn();
|
||||
hdr_txt_bgn = Bry_find_.Find_fwd_while_ws(src, hdr_txt_bgn, hdr_txt_end);
|
||||
hdr_txt_end = Bry_find_.Find_bwd__skip_ws(src, hdr_txt_end, hdr_txt_bgn);
|
||||
|
||||
byte[] key = Bry_.Mid(wkr.Src(), hdr_txt_bgn, hdr_txt_end);
|
||||
Xop_section_itm itm = new Xop_section_itm(hash.Count(), key, wkr.Hdr_bgn(), wkr.Hdr_end());
|
||||
hash.Add(key, itm);
|
||||
}
|
||||
public void On_src_done(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.hdrs.sections; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.hdrs.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
public class Xop_section_list__tst {
|
||||
private final Xop_section_list__fxt fxt = new Xop_section_list__fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Exec__parse
|
||||
( "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
, ""
|
||||
, "== Hdr 2 =="
|
||||
, "Para 2"
|
||||
, ""
|
||||
, "== Hdr 3 =="
|
||||
, "Para 3"
|
||||
);
|
||||
fxt.Test__extract_bry_or_null("Hdr 1"
|
||||
, "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
);
|
||||
fxt.Test__extract_bry_or_null("Hdr 2"
|
||||
, "== Hdr 2 =="
|
||||
, "Para 2"
|
||||
);
|
||||
fxt.Test__extract_bry_or_null("Hdr 3"
|
||||
, "== Hdr 3 =="
|
||||
, "Para 3"
|
||||
);
|
||||
}
|
||||
}
|
||||
class Xop_section_list__fxt {
|
||||
private final Xop_section_list list = new Xop_section_list();
|
||||
public void Exec__parse(String... lines) {
|
||||
list.Parse(Bry_.Empty, Bry_.new_u8(String_.Concat_lines_nl_skip_last(lines)));
|
||||
}
|
||||
public void Test__extract_bry_or_null(String key, String... lines) {
|
||||
String expd = String_.Concat_lines_nl_skip_last(lines);
|
||||
byte[] actl = list.Extract_bry_or_null(Bry_.new_u8(key));
|
||||
Gftest.Eq__ary__lines(expd, actl, key);
|
||||
}
|
||||
}
|
||||
@@ -17,16 +17,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.hdrs.sections; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.hdrs.*;
|
||||
import gplx.langs.htmls.*;
|
||||
import gplx.xowa.parsers.mws.*; import gplx.xowa.parsers.mws.wkrs.*;
|
||||
public class Xop_section_mgr implements Xomw_hdr_cbk {
|
||||
private final Bry_bfr bfr = Bry_bfr_.New();
|
||||
private final Xomw_hdr_wkr hdr_wkr = new Xomw_hdr_wkr();
|
||||
private int section_idx;
|
||||
public byte[] Insert(Xoa_ttl ttl, byte[] src) {
|
||||
section_idx = 0;
|
||||
Xomw_parser_ctx pctx = new Xomw_parser_ctx(ttl);
|
||||
hdr_wkr.Parse(bfr, pctx, src, 0, src.length, this);
|
||||
return bfr.To_bry_and_clear();
|
||||
import gplx.xowa.parsers.mws.*; import gplx.xowa.parsers.mws.wkrs.*; import gplx.xowa.parsers.hdrs.*;
|
||||
public class Xop_section_mgr implements Gfo_invk {
|
||||
public boolean Enabled() {return enabled;} private boolean enabled;
|
||||
private final Bry_fmt section_editable_fmt = Bry_fmt.Auto_nl_apos
|
||||
( "<span class='mw-editsection'><span class='mw-editsection-bracket'>[</span><a href='/wiki/~{page_ttl}?action=edit§ion_key=~{section_key}' title='Edit section: ~{section_name}' class='xowa-hover-off'>edit</a><span class='mw-editsection-bracket'>]</span></span>"
|
||||
);
|
||||
private static final byte[] Qarg__section_key = Bry_.new_u8("section_key");
|
||||
|
||||
public void Init_by_wiki(Xowe_wiki wiki) {
|
||||
enabled = wiki.App().Cfg().Bind_bool(wiki, gplx.xowa.htmls.core.wkrs.hdrs.Xoh_section_editable_.Cfg__section_editing__enabled, this); // SECTION_EDIT
|
||||
}
|
||||
public byte[] Extract_section(Xoa_url url, Xoa_ttl ttl, byte[] src) {
|
||||
// return orig if section_editing not enabled
|
||||
if (!enabled) return src;
|
||||
|
||||
// return orig if section_key not in qargs
|
||||
byte[] section_key = url.Qargs_mgr().Get_val_bry_or(Qarg__section_key, null);
|
||||
if (section_key == null) return src;
|
||||
|
||||
// parse wikitext into list of headers
|
||||
Xop_section_list section_list = new Xop_section_list().Parse(ttl.Full_db(), src);
|
||||
byte[] rv = section_list.Extract_bry_or_null(section_key);
|
||||
if (rv == null)
|
||||
throw Err_.new_wo_type("section_key not found", "page", ttl.Full_db(), "section_key", section_key);
|
||||
return rv;
|
||||
}
|
||||
public void Parse(Xop_hdr_tkn hdr, byte[] page_ttl, byte[] src, int cur_pos, int src_len) {
|
||||
// get page ttl
|
||||
@@ -49,14 +64,22 @@ public class Xop_section_mgr implements Xomw_hdr_cbk {
|
||||
|
||||
hdr.Section_editable_(section_page, section_idx);
|
||||
}
|
||||
public void Write(Bry_bfr bfr, Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {
|
||||
bfr.Add_mid(wkr.Src(), wkr.Hdr_lhs_bgn(), wkr.Hdr_rhs_end());
|
||||
bfr.Add(Bry__meta); // <!--xo_meta|section_edit|
|
||||
bfr.Add(pctx.Page_ttl().Full_db()); // Page_1
|
||||
bfr.Add_byte_pipe(); // |
|
||||
bfr.Add_int_variable(++section_idx); // 123
|
||||
bfr.Add(Gfh_tag_.Comm_end); // -->
|
||||
public void Write_html(Bry_bfr bfr, byte[] src, byte[] page_ttl, Xop_hdr_tkn hdr, byte[] name) {
|
||||
Xop_tkn_itm[] subs = hdr.Subs();
|
||||
if (subs.length == 0) return; // GUARD:should not happen, but avoid array-index error
|
||||
int key_bgn = subs[0].Src_bgn();
|
||||
int key_end = subs[hdr.Subs_len() - 1].Src_end();
|
||||
key_bgn = Bry_find_.Find_fwd_while_ws(src, key_bgn, key_end);
|
||||
key_end = Bry_find_.Find_bwd__skip_ws(src, key_end, key_bgn);
|
||||
byte[] key = Bry_.Mid(src, key_bgn, key_end);
|
||||
section_editable_fmt.Bld_many(bfr, page_ttl, key, name);
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, gplx.xowa.htmls.core.wkrs.hdrs.Xoh_section_editable_.Cfg__section_editing__enabled)) enabled = m.ReadBool("v");
|
||||
else return Gfo_invk_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static final byte[] Bry__meta = Bry_.new_a7("<!--xo_meta|section_edit|");
|
||||
public static final int Len__meta = Bry__meta.length;
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.hdrs.sections; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.hdrs.*;
|
||||
import org.junit.*; import gplx.core.tests.*;
|
||||
public class Xop_section_mgr__tst {
|
||||
private final Xop_section_mgr__fxt fxt = new Xop_section_mgr__fxt();
|
||||
@Test public void Basic() {
|
||||
fxt.Test__insert("Page_1", String_.Concat_lines_nl_skip_last
|
||||
( "A"
|
||||
, "== Hdr_1 =="
|
||||
, "B"
|
||||
, "== Hdr_2 =="
|
||||
, "C"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "A"
|
||||
, "== Hdr_1 ==<!--xo_meta|section_edit|Page_1|1-->"
|
||||
, "B"
|
||||
, "== Hdr_2 ==<!--xo_meta|section_edit|Page_1|2-->"
|
||||
, "C"
|
||||
));
|
||||
}
|
||||
}
|
||||
class Xop_section_mgr__fxt {
|
||||
private final Xowe_wiki wiki;
|
||||
private final Xop_section_mgr mgr = new Xop_section_mgr();
|
||||
public Xop_section_mgr__fxt() {
|
||||
Xoae_app app = Xoa_app_fxt.Make__app__edit();
|
||||
this.wiki = Xoa_app_fxt.Make__wiki__edit(app);
|
||||
}
|
||||
public void Test__insert(String page, String raw, String expd) {
|
||||
Xoa_ttl ttl = wiki.Ttl_parse(Bry_.new_u8(page));
|
||||
byte[] actl = mgr.Insert(ttl, Bry_.new_u8(raw));
|
||||
Gftest.Eq__ary__lines(expd, actl, "section_edit:insert");
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,12 @@ public class Xop_eq_lxr implements Xop_lxr {
|
||||
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==="
|
||||
if (prv_pos > -1 && src[prv_pos] == Byte_ascii.Nl) // is prv char \n; EX: "\n==="
|
||||
hdr_like = true;
|
||||
else {
|
||||
int eol_pos = Bry_find_.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"
|
||||
|| src[eol_pos] == Byte_ascii.Nl // cur_pos is \n; EX: "===\n"
|
||||
) {
|
||||
hdr_like = true;
|
||||
cur_pos = eol_pos;
|
||||
@@ -58,15 +58,15 @@ public class Xop_eq_lxr implements Xop_lxr {
|
||||
return cur_pos;
|
||||
}
|
||||
int ws_end = Bry_find_.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
|
||||
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_find_.Not_found) { // [[Category: found
|
||||
if ( ctg_end != Bry_find_.Not_found) { // [[Category: found
|
||||
ctg_end = Bry_find_.Find_fwd(src, Xop_tkn_.Lnki_end, ctg_end, src_len);
|
||||
if (ctg_end != Bry_find_.Not_found) { // ]] found; note that this should do more validation; EX: [[Category:]] should not be valid; DATE:2014-04-17
|
||||
if (ctg_end != Bry_find_.Not_found) { // ]] 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_find_.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]]
|
||||
if (ctg_end == src_len || src[ctg_end] == Byte_ascii.Nl) // hdr_like if ]]\n after [[Category:A]]
|
||||
hdr_like = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.mws; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
|
||||
public class Xomw_parser_ctx {
|
||||
public Xomw_parser_ctx(Xoa_ttl page_ttl) {
|
||||
this.page_ttl = page_ttl;
|
||||
public Xomw_parser_ctx() {
|
||||
}
|
||||
public Xoa_ttl Page_ttl() {return page_ttl;} private Xoa_ttl page_ttl;
|
||||
public static final int Pos__bos = -1;
|
||||
}
|
||||
|
||||
@@ -17,5 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.mws.wkrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.mws.*;
|
||||
public interface Xomw_hdr_cbk {
|
||||
void Write(Bry_bfr bfr, Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr);
|
||||
void On_hdr_seen(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr);
|
||||
void On_src_done(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr);
|
||||
}
|
||||
|
||||
@@ -17,11 +17,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.parsers.mws.wkrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.mws.*;
|
||||
public class Xomw_hdr_cbk__html implements Xomw_hdr_cbk {
|
||||
public void Write(Bry_bfr bfr, Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {
|
||||
int hdr_len = wkr.Hdr_len();
|
||||
bfr.Add(Tag__lhs).Add_int_digits(1, hdr_len).Add(Byte_ascii.Angle_end_bry); // <h2>
|
||||
public Bry_bfr Bfr() {return bfr;} private final Bry_bfr bfr = Bry_bfr_.New();
|
||||
public void On_hdr_seen(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {
|
||||
// add from txt_bgn to hdr_bgn; EX: "abc\n==A==\n"; "\n==" seen -> add "abc"
|
||||
byte[] src = wkr.Src();
|
||||
int hdr_bgn = wkr.Hdr_bgn(), txt_bgn = wkr.Txt_bgn();
|
||||
if (hdr_bgn > txt_bgn)
|
||||
bfr.Add_mid(src, txt_bgn, hdr_bgn);
|
||||
|
||||
// add "\n" unless BOS
|
||||
if (hdr_bgn != Xomw_parser_ctx.Pos__bos) bfr.Add_byte_nl();
|
||||
|
||||
// add <h2>...</h2>
|
||||
int hdr_num = wkr.Hdr_num();
|
||||
bfr.Add(Tag__lhs).Add_int_digits(1, hdr_num).Add(Byte_ascii.Angle_end_bry); // <h2>
|
||||
bfr.Add_mid(wkr.Src(), wkr.Hdr_lhs_end(), wkr.Hdr_rhs_bgn());
|
||||
bfr.Add(Tag__rhs).Add_int_digits(1, hdr_len).Add(Byte_ascii.Angle_end_bry); // </h2>
|
||||
bfr.Add(Tag__rhs).Add_int_digits(1, hdr_num).Add(Byte_ascii.Angle_end_bry); // </h2>
|
||||
}
|
||||
public void On_src_done(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {
|
||||
// add from txt_bgn to EOS;
|
||||
byte[] src = wkr.Src();
|
||||
int txt_bgn = wkr.Txt_bgn(), src_end = wkr.Src_end();
|
||||
if (txt_bgn != src_end) // PERF: don't call Add_mid() if hdr is at end of EOS
|
||||
bfr.Add_mid(src, txt_bgn, src_end);
|
||||
}
|
||||
private static final byte[]
|
||||
Tag__lhs = Bry_.new_a7("<h")
|
||||
|
||||
@@ -18,19 +18,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa.parsers.mws.wkrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.mws.*;
|
||||
import gplx.core.btries.*; import gplx.xowa.langs.*;
|
||||
public class Xomw_hdr_wkr {
|
||||
private Bry_bfr bfr;
|
||||
private Xomw_parser_ctx pctx;
|
||||
private int src_end;
|
||||
private Xomw_hdr_cbk cbk;
|
||||
public byte[] Src() {return src;} private byte[] src;
|
||||
public int Hdr_len() {return hdr_len;} private int hdr_len;
|
||||
public int Src_end() {return src_end;} private int src_end;
|
||||
public int Txt_bgn() {return txt_bgn;} private int txt_bgn;
|
||||
public int Hdr_bgn() {return hdr_bgn;} private int hdr_bgn;
|
||||
public int Hdr_end() {return hdr_end;} private int hdr_end;
|
||||
public int Hdr_num() {return hdr_num;} private int hdr_num;
|
||||
public int Hdr_lhs_bgn() {return hdr_lhs_bgn;} private int hdr_lhs_bgn;
|
||||
public int Hdr_lhs_end() {return hdr_lhs_end;} private int hdr_lhs_end;
|
||||
public int Hdr_rhs_bgn() {return hdr_rhs_bgn;} private int hdr_rhs_bgn;
|
||||
public int Hdr_rhs_end() {return hdr_rhs_end;} private int hdr_rhs_end;
|
||||
public void Parse(Bry_bfr bfr, Xomw_parser_ctx pctx, byte[] src, int src_bgn, int src_end, Xomw_hdr_cbk cbk) { // REF.MW: /includes/parser/Parser.php|doHeadings
|
||||
public void Parse(Xomw_parser_ctx pctx, byte[] src, int src_bgn, int src_end, Xomw_hdr_cbk cbk) { // REF.MW: /includes/parser/Parser.php|doHeadings
|
||||
// init members
|
||||
this.bfr = bfr;
|
||||
this.pctx = pctx;
|
||||
this.src = src;
|
||||
this.src_end = src_end;
|
||||
@@ -38,41 +39,46 @@ public class Xomw_hdr_wkr {
|
||||
|
||||
// do loop
|
||||
int pos = src_bgn;
|
||||
int txt_bgn = pos == Xomw_parser_ctx.Pos__bos ? 0 : pos;
|
||||
this.txt_bgn = pos == Xomw_parser_ctx.Pos__bos ? 0 : pos;
|
||||
byte b = Byte_ascii.Nl;
|
||||
while (true) {
|
||||
int nxt = pos + 1;
|
||||
// check if (a) cur is \n; (b) nxt is '='
|
||||
if ( b == Byte_ascii.Nl
|
||||
&& nxt < src_end
|
||||
&& src[nxt] == Byte_ascii.Eq
|
||||
) { // if \n, check if "="
|
||||
int rv = Parse_hdr_nl(txt_bgn, pos, nxt + 1);
|
||||
if (rv < 0) {
|
||||
pos = rv * -1;
|
||||
}
|
||||
else
|
||||
pos = txt_bgn = rv;
|
||||
) {
|
||||
pos = Parse_hdr_nl(txt_bgn, pos, nxt + 1);
|
||||
this.txt_bgn = pos;
|
||||
}
|
||||
else
|
||||
++pos;
|
||||
|
||||
// EOS; add all text after last "==\n"
|
||||
if (pos == src_end) {
|
||||
if (txt_bgn != src_end) // PERF: don't call Add_mid() if hdr is at end of EOS
|
||||
bfr.Add_mid(src, txt_bgn, src_end);
|
||||
cbk.On_src_done(pctx, this);
|
||||
break;
|
||||
}
|
||||
b = src[pos];
|
||||
}
|
||||
}
|
||||
private int Parse_hdr_nl(int txt_bgn, int nl_lhs, int pos) {
|
||||
// calc pos and len
|
||||
this.hdr_lhs_bgn = nl_lhs + 1;
|
||||
this.hdr_lhs_end = Bry_find_.Find_fwd_while(src, pos, src_end, Byte_ascii.Eq);
|
||||
int nl_rhs = Bry_find_.Find_fwd_or(src, Byte_ascii.Nl, hdr_lhs_end + 1, src_end, src_end); // no "\n"; src_end is rest of text; EX: "\n==<text>EOS
|
||||
// calc lhs vars
|
||||
this.hdr_bgn = nl_lhs;
|
||||
this.hdr_lhs_bgn = nl_lhs == 0 ? 0 : nl_lhs + 1; // set pos of 1st "="; note that "==" can be at BOS;
|
||||
this.hdr_lhs_end = Bry_find_.Find_fwd_while(src, pos, src_end, Byte_ascii.Eq);
|
||||
|
||||
// calc rhs vars
|
||||
int nl_rhs = Bry_find_.Find_fwd_or(src, Byte_ascii.Nl, hdr_lhs_end + 1, src_end, src_end); // if no "\n", src_end is rest of text; EX: "\n==<text>EOS
|
||||
this.hdr_end = nl_rhs;
|
||||
this.hdr_rhs_end = Bry_find_.Find_bwd__skip_ws(src, nl_rhs, hdr_lhs_end);
|
||||
this.hdr_rhs_bgn = Bry_find_.Find_bwd__skip(src, hdr_rhs_end - 1, hdr_lhs_end, Byte_ascii.Eq);
|
||||
|
||||
int hdr_lhs_len = hdr_lhs_end - hdr_lhs_bgn;
|
||||
int hdr_rhs_len = hdr_rhs_end - hdr_rhs_bgn;
|
||||
if (hdr_rhs_len == 0) { // handle rare situations like "\n====\n"
|
||||
|
||||
// handle rare situations like "\n====\n"
|
||||
if (hdr_rhs_len == 0) {
|
||||
int hdr_lhs_len_half = hdr_lhs_len / 2;
|
||||
hdr_rhs_len = hdr_lhs_len - hdr_lhs_len_half;
|
||||
hdr_lhs_len = hdr_lhs_len_half;
|
||||
@@ -80,13 +86,9 @@ public class Xomw_hdr_wkr {
|
||||
this.hdr_rhs_bgn = hdr_lhs_end;
|
||||
}
|
||||
|
||||
// bld bry
|
||||
this.hdr_len = hdr_lhs_len < hdr_rhs_len ? hdr_lhs_len : hdr_rhs_len;
|
||||
if (nl_lhs > txt_bgn)
|
||||
bfr.Add_mid(src, txt_bgn, nl_lhs); // add all txt up to nl_lhs
|
||||
this.hdr_num = hdr_lhs_len < hdr_rhs_len ? hdr_lhs_len : hdr_rhs_len;
|
||||
|
||||
if (nl_lhs != Xomw_parser_ctx.Pos__bos) bfr.Add_byte_nl();
|
||||
cbk.Write(bfr, pctx, this);
|
||||
cbk.On_hdr_seen(pctx, this);
|
||||
return nl_rhs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,10 +30,11 @@ public class Xomw_hdr_wkr_tst {
|
||||
}
|
||||
class Xomw_hdr_wkr_fxt {
|
||||
private final Xomw_hdr_wkr wkr = new Xomw_hdr_wkr();
|
||||
private final Bry_bfr bfr = Bry_bfr_.New(); private final Xomw_parser_ctx pctx = new Xomw_parser_ctx(null);
|
||||
private final Xomw_hdr_cbk__html cbk = new Xomw_hdr_cbk__html();
|
||||
private final Xomw_parser_ctx pctx = new Xomw_parser_ctx();
|
||||
public void Test__parse(String src_str, String expd) {
|
||||
byte[] src_bry = Bry_.new_u8(src_str);
|
||||
wkr.Parse(bfr, pctx, src_bry, -1, src_bry.length, new Xomw_hdr_cbk__html());
|
||||
Tfds.Eq_str_lines(expd, bfr.To_str_and_clear(), src_str);
|
||||
wkr.Parse(pctx, src_bry, -1, src_bry.length, cbk);
|
||||
Tfds.Eq_str_lines(expd, cbk.Bfr().To_str_and_clear(), src_str);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user