diff --git a/100_core/src/gplx/core/tests/Gftest.java b/100_core/src/gplx/core/tests/Gftest.java index 280b178bb..d050cfd41 100644 --- a/100_core/src/gplx/core/tests/Gftest.java +++ b/100_core/src/gplx/core/tests/Gftest.java @@ -24,7 +24,7 @@ public class Gftest { public static void Eq__ary(long[] expd, long[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__long, expd, actl, msg_fmt, msg_args);} public static void Eq__ary__lines(String expd, byte[] actl) {Eq__ary__lines(expd, String_.new_u8(actl), "no_msg");} public static void Eq__ary__lines(String expd, byte[] actl, String msg_fmt, Object... msg_args) {Eq__ary__lines(expd, String_.new_u8(actl), msg_fmt, msg_args);} - public static void Eq__ary__lines(String expd, String actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_split_.Split_lines(Bry_.new_u8(expd)), Bry_split_.Split_lines(Bry_.new_u8(actl)), msg_fmt, msg_args);} + public static void Eq__ary__lines(String expd, String actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_split_.Split_lines(Bry_.new_u8_safe(expd)), Bry_split_.Split_lines(Bry_.new_u8_safe(actl)), msg_fmt, msg_args);} public static void Eq__ary(String[] expd, String[] actl) {Eq__array(Type_adp_.Tid__bry, Bry_.Ary(expd), Bry_.Ary(actl), "no_msg");} public static void Eq__ary(String[] expd, String[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_.Ary(expd), Bry_.Ary(actl), msg_fmt, msg_args);} public static void Eq__ary(String[] expd, byte[][] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_adp_.Tid__bry, Bry_.Ary(expd), actl, msg_fmt, msg_args);} diff --git a/400_xowa/src/gplx/xowa/Xowe_wiki.java b/400_xowa/src/gplx/xowa/Xowe_wiki.java index 352a4d5cf..e4693e1ed 100644 --- a/400_xowa/src/gplx/xowa/Xowe_wiki.java +++ b/400_xowa/src/gplx/xowa/Xowe_wiki.java @@ -205,6 +205,8 @@ public class Xowe_wiki implements Xow_wiki, Gfo_invk, Gfo_evt_itm { db_mgr.Load_mgr().Load_init(this); app.Gfs_mgr().Run_url_for(this, tdb_fsys_mgr.Cfg_wiki_core_fil()); gplx.xowa.bldrs.setups.upgrades.Xoa_upgrade_mgr.Check(this); + parser_mgr.Init_by_wiki(); + // init ns_mgr if (lang.Init_by_load()) { if (domain_tid == Xow_domain_tid_.Tid__wikipedia) // NOTE: if type is wikipedia, add "Wikipedia" as an alias; PAGE:en.w:pt.wikipedia.org/wiki/Página principal which redirects to Wikipedia:Página principal @@ -214,10 +216,12 @@ public class Xowe_wiki implements Xow_wiki, Gfo_invk, Gfo_evt_itm { app.Gfs_mgr().Run_url_for(this, app.Fsys_mgr().Cfg_wiki_core_dir().GenSubFil(domain_str + ".gfs")); // NOTE: must be run after lang.Init_by_load b/c lang will reload ns_mgr; DATE:2015-04-17run cfg for wiki by user ; EX: /xowa/user/anonymous/wiki/en.wikipedia.org/cfg/user_wiki.gfs cfg_parser.Xtns().Itm_pages().Init(ns_mgr); // init ns_mgr for Page / Index ns just before rebuild; usually set by #cfg file Xow_ns_mgr_.rebuild_(lang, ns_mgr); // always rebuild; may be changed by user_wiki.gfs; different lang will change namespaces; EX: de.wikisource.org will have Seite for File and none of {{#lst}} will work + // push lang changes fragment_mgr.Evt_lang_changed(lang); parser_mgr.Main().Init_by_lang(lang); html_mgr.Init_by_lang(lang); + // other init Bry_fmtr.Null.Eval_mgr().Enabled_(false); app.Wiki_mgr().Scripts().Exec(this); Bry_fmtr.Null.Eval_mgr().Enabled_(true); app.Html__css_installer().Install(this, Xowd_css_core_mgr.Key_default); diff --git a/400_xowa/src/gplx/xowa/addons/apps/cfgs/Xocfg_mgr.java b/400_xowa/src/gplx/xowa/addons/apps/cfgs/Xocfg_mgr.java index 94bd3f2df..0fa75f9db 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/cfgs/Xocfg_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/apps/cfgs/Xocfg_mgr.java @@ -20,12 +20,12 @@ import gplx.dbs.*; import gplx.xowa.addons.apps.cfgs.mgrs.*; public class Xocfg_mgr { private final Xocfg_cache_mgr cache_mgr = new Xocfg_cache_mgr(); public void Init_by_app(Db_conn conn) { - // cache_mgr.Init_by_app(conn); // COMMENT:section_edit DATE:2016-12-04 + cache_mgr.Init_by_app(conn); // SECTION_EDIT } public void Clear() { cache_mgr.Clear(); } - public boolean Bind_bool(Xow_wiki wiki, String key, Gfo_invk sub) {return Bool_.Parse_or(Bind_str(wiki, key, sub), false);} + public boolean Bind_bool(Xow_wiki wiki, String key, Gfo_invk sub) {return Yn.parse_or(Bind_str(wiki, key, sub), false);} public String Bind_str(Xow_wiki wiki, String key, Gfo_invk sub) { String ctx = wiki.Domain_itm().Abrv_xo_str(); cache_mgr.Sub(sub, ctx, key, key); diff --git a/400_xowa/src/gplx/xowa/addons/apps/cfgs/gui/Xogui_itm_html.java b/400_xowa/src/gplx/xowa/addons/apps/cfgs/gui/Xogui_itm_html.java index efe971285..da0d46c38 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/cfgs/gui/Xogui_itm_html.java +++ b/400_xowa/src/gplx/xowa/addons/apps/cfgs/gui/Xogui_itm_html.java @@ -21,7 +21,7 @@ public class Xogui_itm_html { public void Build_html(Bry_bfr bfr, String key, String name, int gui_type, String gui_args, String data) { switch (gui_type) { case Xoitm_gui_tid.Tid__checkbox: - bfr.Add_str_u8_fmt("", key, String_.Eq(data, "true") ? " checked='checked'" : ""); + bfr.Add_str_u8_fmt("", key, String_.Eq(data, "y") ? " checked='checked'" : ""); break; case Xoitm_gui_tid.Tid__numeric: bfr.Add_str_u8_fmt("", key, data); diff --git a/400_xowa/src/gplx/xowa/addons/apps/cfgs/mgrs/Xocfg_cache_mgr.java b/400_xowa/src/gplx/xowa/addons/apps/cfgs/mgrs/Xocfg_cache_mgr.java index 19956cff8..b5742784f 100644 --- a/400_xowa/src/gplx/xowa/addons/apps/cfgs/mgrs/Xocfg_cache_mgr.java +++ b/400_xowa/src/gplx/xowa/addons/apps/cfgs/mgrs/Xocfg_cache_mgr.java @@ -34,6 +34,7 @@ public class Xocfg_cache_mgr { public void Set(String ctx, String key, String val) { Xocfg_cache_grp grp = Grps__get_or_load(key); grp.Set(ctx, val); + db_mgr.Set_str(ctx, key, val); grp.Pub(ctx, val); } public void Sub(Gfo_invk sub, String ctx, String key, String evt) { diff --git a/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java b/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java index 954cd6e05..d1ee31c54 100644 --- a/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java +++ b/400_xowa/src/gplx/xowa/guis/views/Xog_tab_itm_edit_mgr.java @@ -123,6 +123,7 @@ public class Xog_tab_itm_edit_mgr { } private static byte[] Get_new_text(Xog_tab_itm tab) { byte[] rv = tab.Html_itm().Get_elem_value_for_edit_box_as_bry(); + // tab.Wiki().Parser_mgr().Hdr__section_editable__mgr().Merge(rv); rv = Bry_.Trim(rv, 0, rv.length, false, true, Bry_.Trim_ary_ws); // MW: trim all trailing ws; REF:EditPage.php!safeUnicodeInput; DATE:2014-04-25 return rv; } diff --git a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java index 76a8de880..9c1647546 100644 --- a/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java +++ b/400_xowa/src/gplx/xowa/htmls/Xoh_page_wtr_wkr.java @@ -225,8 +225,11 @@ public class Xoh_page_wtr_wkr { ) data_raw = Gfs_php_converter.Xto_php(tmp_bfr, Bool_.N, data_raw); int data_raw_len = data_raw.length; - if (mgr.Html_capable()) + if (mgr.Html_capable()) { + data_raw = wiki.Parser_mgr().Hdr__section_editable__mgr().Extract_section(page.Url(), page.Ttl(), data_raw); + data_raw_len = data_raw.length; Xoh_html_wtr_escaper.Escape(page.Wikie().Appe().Parser_amp_mgr(), bfr, data_raw, 0, data_raw_len, false, false); // NOTE: must escape; assume that browser will automatically escape (<) (which Mozilla does) + } else bfr.Add(data_raw); if (data_raw_len > 0) // do not add nl if empty String diff --git a/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr.java b/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr.java index cdd04f6b0..c2c71efac 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr.java +++ b/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr.java @@ -41,8 +41,6 @@ public class Xoh_html_wtr { public void Init_by_wiki(Xowe_wiki wiki) { cfg.Toc__show_(Bool_.Y).Lnki__title_(true).Lnki__visited_y_().Lnki__id_(Bool_.Y); // NOTE: set during Init_by_wiki, b/c all tests assume these are false - - // cfg.Section_editable_(wiki.App().Cfg().Bind_bool(wiki, gplx.xowa.htmls.core.wkrs.hdrs.Xoh_section_editable_.Cfg__section_editing__enabled, cfg)); // COMMENT:section_edit DATE:2016-12-04 ref_wtr.Init_by_wiki(wiki); } public void Init_by_page(Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xoae_page page) { diff --git a/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr_cfg.java b/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr_cfg.java index ff8d19c8c..c043791c0 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr_cfg.java +++ b/400_xowa/src/gplx/xowa/htmls/core/htmls/Xoh_html_wtr_cfg.java @@ -16,16 +16,9 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.xowa.htmls.core.htmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.*; -public class Xoh_html_wtr_cfg implements Gfo_invk { +public class Xoh_html_wtr_cfg { public boolean Toc__show() {return toc__show;} public Xoh_html_wtr_cfg Toc__show_(boolean v) {toc__show = v; return this;} private boolean toc__show; public boolean Lnki__id() {return lnki__id;} public Xoh_html_wtr_cfg Lnki__id_(boolean v) {lnki__id = v; return this;} private boolean lnki__id; public boolean Lnki__title() {return lnki__title;} public Xoh_html_wtr_cfg Lnki__title_(boolean v) {lnki__title = v; return this;} private boolean lnki__title; public boolean Lnki__visited() {return lnki__visited;} public Xoh_html_wtr_cfg Lnki__visited_y_() {lnki__visited = true; return this;} private boolean lnki__visited; - public boolean Section_editable() {return section_editable;} public Xoh_html_wtr_cfg Section_editable_(boolean v) {section_editable = v; return this;} private boolean section_editable; - - 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)) section_editable = m.ReadBool("v"); - else return Gfo_invk_.Rv_unhandled; - return this; - } } diff --git a/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_hdr_html.java b/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_hdr_html.java index f9378b949..44b19fc22 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_hdr_html.java +++ b/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_hdr_html.java @@ -23,9 +23,6 @@ import gplx.xowa.htmls.core.htmls.*; import gplx.xowa.addons.htmls.tocs.*; public class Xoh_hdr_html { private final Bry_bfr hdr_text_bfr = Bry_bfr_.New(); private final Xoh_toc_itm invalid_toc_itm = new Xoh_toc_itm().Set__txt(Bry_.Empty, Bry_.Empty); - private final Bry_fmt section_editable_fmt = Bry_fmt.Auto_nl_apos - ( "[edit]" - ); public void Write_html(Bry_bfr bfr, Xoh_html_wtr wtr, Xowe_wiki wiki, Xoae_page page, Xop_ctx ctx, Xoh_wtr_ctx hctx, Xoh_html_wtr_cfg cfg, Xop_tkn_grp grp, int sub_idx, byte[] src, Xop_hdr_tkn hdr) { // init @@ -68,8 +65,8 @@ public class Xoh_hdr_html { bfr.Add(Gfh_tag_.Span_rhs); // '' // write section editable - if (cfg.Section_editable()) - section_editable_fmt.Bld_many(bfr, hdr.Section_editable_page(), hdr.Section_editable_idx(), toc_itm.Anch()); + if (wiki.Parser_mgr().Hdr__section_editable__mgr().Enabled()) + wiki.Parser_mgr().Hdr__section_editable__mgr().Write_html(bfr, src, page.Ttl().Full_db(), hdr, toc_itm.Anch()); bfr.Add(Bry__hdr_rhs_bgn).Add_int(hdr_num, 1, 1); // '\n' diff --git a/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_section_editable_.java b/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_section_editable_.java index 6d0753b97..d32519586 100644 --- a/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_section_editable_.java +++ b/400_xowa/src/gplx/xowa/htmls/core/wkrs/hdrs/Xoh_section_editable_.java @@ -18,9 +18,5 @@ along with this program. If not, see . package gplx.xowa.htmls.core.wkrs.hdrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.htmls.*; import gplx.xowa.htmls.core.*; import gplx.xowa.htmls.core.wkrs.*; import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.parsers.hdrs.*; public class Xoh_section_editable_ { - public static void Write_imt(Bry_bfr bfr, Xop_ctx ctx, Xop_tkn_itm tkn) { - Xop_hdr_tkn hdr_tkn = (Xop_hdr_tkn)tkn; - ctx.Wiki().Parser_mgr().Hdr__section_editable__imt_fmt().Bld_many_to_bry(bfr, hdr_tkn.Section_editable_page(), hdr_tkn.Section_editable_idx()); - } public static final String Cfg__section_editing__enabled = "section_editing.enabled"; } diff --git a/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java b/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java index 5aac35b35..3d1d747c5 100644 --- a/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java +++ b/400_xowa/src/gplx/xowa/parsers/Xow_parser_mgr.java @@ -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(""); 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; - } } diff --git a/400_xowa/src/gplx/xowa/parsers/hdrs/Xop_hdr_wkr.java b/400_xowa/src/gplx/xowa/parsers/hdrs/Xop_hdr_wkr.java index 65ac84460..f307d6518 100644 --- a/400_xowa/src/gplx/xowa/parsers/hdrs/Xop_hdr_wkr.java +++ b/400_xowa/src/gplx/xowa/parsers/hdrs/Xop_hdr_wkr.java @@ -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
cur_pos = Find_fwd_while_ws_hdr_version(src, cur_pos, src_len); diff --git a/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_itm.java b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_itm.java new file mode 100644 index 000000000..7dce7a639 --- /dev/null +++ b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_itm.java @@ -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 . +*/ +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; +} diff --git a/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_list.java b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_list.java new file mode 100644 index 000000000..331a729e1 --- /dev/null +++ b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_list.java @@ -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 . +*/ +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) {} +} diff --git a/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_list__tst.java b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_list__tst.java new file mode 100644 index 000000000..048ab0dc5 --- /dev/null +++ b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_list__tst.java @@ -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 . +*/ +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); + } +} diff --git a/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_mgr.java b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_mgr.java index 06266e328..63ede945e 100644 --- a/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_mgr.java +++ b/400_xowa/src/gplx/xowa/parsers/hdrs/sections/Xop_section_mgr.java @@ -17,16 +17,31 @@ along with this program. If not, see . */ 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 + ( "[edit]" + ); + 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); // + 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("" - , "B" - , "== Hdr_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"); - } -} diff --git a/400_xowa/src/gplx/xowa/parsers/miscs/Xop_eq_lxr.java b/400_xowa/src/gplx/xowa/parsers/miscs/Xop_eq_lxr.java index d0be9f182..84760f5ef 100644 --- a/400_xowa/src/gplx/xowa/parsers/miscs/Xop_eq_lxr.java +++ b/400_xowa/src/gplx/xowa/parsers/miscs/Xop_eq_lxr.java @@ -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; } } diff --git a/400_xowa/src/gplx/xowa/parsers/mws/Xomw_parser_ctx.java b/400_xowa/src/gplx/xowa/parsers/mws/Xomw_parser_ctx.java index fac38cbd6..d0636f8b9 100644 --- a/400_xowa/src/gplx/xowa/parsers/mws/Xomw_parser_ctx.java +++ b/400_xowa/src/gplx/xowa/parsers/mws/Xomw_parser_ctx.java @@ -17,9 +17,7 @@ along with this program. If not, see . */ 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; } diff --git a/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk.java b/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk.java index 83b6555ea..f8b0397aa 100644 --- a/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk.java +++ b/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk.java @@ -17,5 +17,6 @@ along with this program. If not, see . */ 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); } diff --git a/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk__html.java b/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk__html.java index 6a9fb8451..12029bd30 100644 --- a/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk__html.java +++ b/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_cbk__html.java @@ -17,11 +17,29 @@ along with this program. If not, see . */ 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); //

+ 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

...

+ int hdr_num = wkr.Hdr_num(); + bfr.Add(Tag__lhs).Add_int_digits(1, hdr_num).Add(Byte_ascii.Angle_end_bry); //

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); //

+ bfr.Add(Tag__rhs).Add_int_digits(1, hdr_num).Add(Byte_ascii.Angle_end_bry); // + } + 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(". 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==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==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; } } diff --git a/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_wkr_tst.java b/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_wkr_tst.java index 908cb18d8..c089ba8bf 100644 --- a/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_wkr_tst.java +++ b/400_xowa/src/gplx/xowa/parsers/mws/wkrs/Xomw_hdr_wkr_tst.java @@ -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); } } diff --git a/400_xowa/src/gplx/xowa/xtns/wbases/imports/Xob_wdata_qid_base.java b/400_xowa/src/gplx/xowa/xtns/wbases/imports/Xob_wdata_qid_base.java index f0767bc0c..f1ff70e63 100644 --- a/400_xowa/src/gplx/xowa/xtns/wbases/imports/Xob_wdata_qid_base.java +++ b/400_xowa/src/gplx/xowa/xtns/wbases/imports/Xob_wdata_qid_base.java @@ -21,6 +21,7 @@ import gplx.xowa.wikis.nss.*; import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*; import gplx.xowa.bldrs.wms.sites.*; public abstract class Xob_wdata_qid_base extends Xob_itm_dump_base implements Xob_page_wkr, Gfo_invk { + private final Object thread_lock = new Object(); private Json_parser parser; private Xob_wbase_ns_parser ns_parser; private final Xob_wbase_ns_parser_rslt ns_parser_rslt = new Xob_wbase_ns_parser_rslt(); public Xob_wdata_qid_base Ctor(Xob_bldr bldr, Xowe_wiki wiki) {this.Cmd_ctor(bldr, wiki); return this;} public abstract String Page_wkr__key(); @@ -41,20 +42,22 @@ public abstract class Xob_wdata_qid_base extends Xob_itm_dump_base implements Xo } public void Page_wkr__run_cleanup() {} public void Parse_jdoc(Json_doc jdoc) { - Wdata_doc_parser wdoc_parser = app.Wiki_mgr().Wdata_mgr().Wdoc_parser(jdoc); - byte[] qid = wdoc_parser.Parse_qid(jdoc); - Bry_bfr tmp_bfr = Bry_bfr_.Reset(255); - Ordered_hash sitelinks = wdoc_parser.Parse_sitelinks(qid, jdoc); - int sitelinks_len = sitelinks.Count(); if (sitelinks_len == 0) return; // no subs; return; - for (int i = 0; i < sitelinks_len; i++) { // iterate sitelinks - Wdata_sitelink_itm sitelink = (Wdata_sitelink_itm)sitelinks.Get_at(i); - byte[] sitelink_site = sitelink.Site(), sitelink_ttl = sitelink.Name(); - ns_parser.Find(ns_parser_rslt, sitelink_site, sitelink_ttl); - int sitelink_ns = ns_parser_rslt.Ns_id(); - if (sitelink_ns != Xow_ns_.Tid__main) // ttl not in main; chop off ns portion; EX:Aide:French_title -> French_title - sitelink_ttl = Bry_.Mid(sitelink_ttl, ns_parser_rslt.Ttl_bgn(), sitelink_ttl.length); - sitelink_ttl = wiki.Lang().Case_mgr().Case_build_1st_upper(tmp_bfr, sitelink_ttl, 0, sitelink_ttl.length); - this.Qid_add(sitelink.Site(), sitelink_ns, Xoa_ttl.Replace_spaces(sitelink_ttl), qid); // NOTE: always convert spaces to underscores; EX: "A B" -> "A_B" DATE:2015-04-21 + synchronized (thread_lock) { + Wdata_doc_parser wdoc_parser = app.Wiki_mgr().Wdata_mgr().Wdoc_parser(jdoc); + byte[] qid = wdoc_parser.Parse_qid(jdoc); + Bry_bfr tmp_bfr = Bry_bfr_.Reset(255); + Ordered_hash sitelinks = wdoc_parser.Parse_sitelinks(qid, jdoc); + int sitelinks_len = sitelinks.Count(); if (sitelinks_len == 0) return; // no subs; return; + for (int i = 0; i < sitelinks_len; i++) { // iterate sitelinks + Wdata_sitelink_itm sitelink = (Wdata_sitelink_itm)sitelinks.Get_at(i); + byte[] sitelink_site = sitelink.Site(), sitelink_ttl = sitelink.Name(); + ns_parser.Find(ns_parser_rslt, sitelink_site, sitelink_ttl); + int sitelink_ns = ns_parser_rslt.Ns_id(); + if (sitelink_ns != Xow_ns_.Tid__main) // ttl not in main; chop off ns portion; EX:Aide:French_title -> French_title + sitelink_ttl = Bry_.Mid(sitelink_ttl, ns_parser_rslt.Ttl_bgn(), sitelink_ttl.length); + sitelink_ttl = wiki.Lang().Case_mgr().Case_build_1st_upper(tmp_bfr, sitelink_ttl, 0, sitelink_ttl.length); + this.Qid_add(sitelink.Site(), sitelink_ns, Xoa_ttl.Replace_spaces(sitelink_ttl), qid); // NOTE: always convert spaces to underscores; EX: "A B" -> "A_B" DATE:2015-04-21 + } } } public void Page_wkr__end() {