1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2024-10-27 20:34:16 +00:00

Section_edit: Add initial groundwork for generating html

This commit is contained in:
gnosygnu 2016-12-02 11:32:23 -05:00
parent 1e28aa6e79
commit 26ad5db8e9
14 changed files with 90 additions and 31 deletions

View File

@ -25,6 +25,7 @@ public class Xoapi_addon implements Gfo_invk {
public boolean App__scripting__enabled() {return app__scripting__enabled;} private boolean app__scripting__enabled = false;
public String App__update__restart_cmd() {return app__update__restart_cmd;} private String app__update__restart_cmd = "";
public String App__update__update_db_src() {return app__update__update_db_src;} private String app__update__update_db_src = "http://xowa.org";
public boolean Parser__hdr__section_editable() {return parser__hdr__section_editable;} private boolean parser__hdr__section_editable = false;
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk__search)) return search;
else if (ctx.Match(k, Invk__bldr)) return bldr;
@ -38,6 +39,8 @@ public class Xoapi_addon implements Gfo_invk {
else if (ctx.Match(k, Invk__app__update__restart_cmd_)) app__update__restart_cmd = m.ReadStr("v");
else if (ctx.Match(k, Invk__app__update__update_db_src)) return app__update__update_db_src;
else if (ctx.Match(k, Invk__app__update__update_db_src_)) app__update__update_db_src = m.ReadStr("v");
else if (ctx.Match(k, Invk__parser__hdr__section_editable)) return Yn.To_str(parser__hdr__section_editable);
else if (ctx.Match(k, Invk__parser__hdr__section_editable_)) parser__hdr__section_editable = m.ReadBool("v");
else return Gfo_invk_.Rv_unhandled;
return this;
}
@ -52,6 +55,8 @@ public class Xoapi_addon implements Gfo_invk {
, Invk__app__update__restart_cmd_ = "app__update__restart_cmd_"
, Invk__app__update__update_db_src = "app__update__update_db_src"
, Invk__app__update__update_db_src_ = "app__update__update_db_src_"
, Invk__parser__hdr__section_editable = "parser__hdr__section_editable"
, Invk__parser__hdr__section_editable_ = "parser__hdr__section_editable_"
;
public static boolean app__page_history__log_all;
}

View File

@ -40,7 +40,8 @@ public class Xoh_html_wtr {
public Ref_html_wtr Ref_wtr() {return ref_wtr;} private final Ref_html_wtr ref_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.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.Appe().Api_root().Addon().Parser__hdr__section_editable());
ref_wtr.Init_by_wiki(wiki);
}
public void Init_by_page(Xop_ctx ctx, Xoh_wtr_ctx hctx, byte[] src, Xoae_page page) {

View File

@ -20,5 +20,6 @@ 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 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;
}

View File

@ -16,12 +16,16 @@ 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.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.core.brys.*;
import gplx.langs.htmls.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.hdrs.*;
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
( "<span class='mw-editsection'><span class='mw-editsection-bracket'>[</span><a href='/wiki/~{page_ttl}&action=edit&section=~{section_idx}' title='Edit section: ~{section_name}'>edit</a><span class='mw-editsection-bracket'>]</span></span>"
);
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
@ -48,7 +52,7 @@ public class Xoh_hdr_html {
bfr.Add_byte(Byte_ascii.Angle_end); // '>'
if (cfg.Toc__show()) {
bfr.Add(Bry__span_lhs_bgn); // "<span class='mw-headline' id='"
bfr.Add(toc_itm.Anch()); // '1'
bfr.Add(toc_itm.Anch()); // 'Name_and_Etymology'
bfr.Add(Bry__span_lhs_end); // "'>"
}
}
@ -64,6 +68,11 @@ public class Xoh_hdr_html {
bfr.Add(Gfh_tag_.Span_rhs); // '</span>'
bfr.Add(Bry__hdr_rhs_bgn).Add_int(hdr_num, 1, 1); // '</h', '2'
bfr.Add(Bry__hdr_rhs_end); // '>\n'
// write section editable
if (cfg.Section_editable()) {
section_editable_fmt.Bld_many(bfr, hdr.Section_editable_page(), hdr.Section_editable_idx(), toc_itm.Anch());
}
}
}

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.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_imt1(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());
}
}

View File

@ -22,6 +22,7 @@ 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 final Xowe_wiki wiki;
private final Btrie_fast_mgr tmpl_trie, wtxt_trie;
private Xot_compile_data tmpl_props = new Xot_compile_data(); // NOTE: probably should not be a member variable, but leave for now; DATE:2016-12-02
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();
@ -82,7 +83,7 @@ public class Xop_parser { // NOTE: parsers are reused; do not keep any read-writ
boolean only_include_chk = Bry_find_.Find_fwd(src, Xop_xnde_tag_.Bry__onlyinclude, 0, src.length) != Bry_find_.Not_found;
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.Page().Clear_all(); ctx.App().Msg_log().Clear();
Parse_text_to_wdom(root, ctx, tkn_mkr, src, Xop_parser_.Doc_bgn_bos);

View File

@ -42,6 +42,7 @@ public class Xow_parser_mgr {
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 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 Wdata_hwtr_msgs Wbase__time__msgs() {
if (wbase__time__msgs == null)
wbase__time__msgs = Wdata_hwtr_msgs.new_(wiki.Msg_mgr());

View File

@ -18,17 +18,24 @@ 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.*;
public class Xop_hdr_tkn extends Xop_tkn_itm_base {
public Xop_hdr_tkn(int bgn, int end, int num) {this.Tkn_ini_pos(false, bgn, end); this.num = num;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_hdr;}
public int Num() {return num;} private int num = -1; // EX: 4 for <h2>
public int Manual_bgn() {return manual_bgn;} private int manual_bgn; // unbalanced count; EX: === A == -> 1
public int Manual_end() {return manual_end;} private int manual_end; // unbalanced count; EX: == A === -> 1
public boolean First_in_doc() {return first_in_doc;} private boolean first_in_doc; // true if 1st hdr in doc
public void First_in_doc_y_() {first_in_doc = true;}
@Override public byte Tkn_tid() {return Xop_tkn_itm_.Tid_hdr;}
public int Num() {return num;} private int num = -1; // EX: 2 for <h2>
public int Manual_bgn() {return manual_bgn;} private int manual_bgn; // unbalanced count; EX: === A == -> 1
public int Manual_end() {return manual_end;} private int manual_end; // unbalanced count; EX: == A === -> 1
public boolean First_in_doc() {return first_in_doc;} private boolean first_in_doc; // true if 1st hdr in doc
public void First_in_doc_y_() {first_in_doc = true;}
public int Section_editable_idx() {return section_editable_idx;} private int section_editable_idx; // EX: 1 as in "section=1"
public byte[] Section_editable_page() {return section_editable_page;} private byte[] section_editable_page; // EX: Earth as in 'href="/wiki/Earth"'
public void Init_by_parse(int num, int manual_bgn, int manual_end) {
this.num = num;
this.manual_bgn = manual_bgn;
this.manual_end = manual_end;
}
public void Init_by_section_editable(int section_editable_idx, byte[] section_editable_page) {
this.section_editable_idx = section_editable_idx;
this.section_editable_page = section_editable_page;
}
public static final Xop_hdr_tkn[] Ary_empty = new Xop_hdr_tkn[0];
}

View File

@ -48,8 +48,12 @@ public class Xop_hdr_wkr implements Xop_ctx_wkr {
}
public int Make_tkn_end(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn root, byte[] src, int src_len, int bgn_pos, int cur_pos, int stackPos, int end_hdr_len) {// REF.MW: Parser|doHeadings
if (ctx.Cur_tkn_tid() == Xop_tkn_itm_.Tid_tmpl_curly_bgn) return ctx.Lxr_make_txt_(cur_pos);
// end frame
Xop_hdr_tkn hdr = (Xop_hdr_tkn)ctx.Stack_pop_til(root, src, stackPos, false, bgn_pos, cur_pos, Xop_tkn_itm_.Tid_hdr);
ctx.Apos().End_frame(ctx, root, src, bgn_pos, false); // end any apos; EX: ==''a==
// handle asymmetrical "="; EX: "== A ==="
int hdr_len = hdr.Num(), bgn_manual = 0, end_manual = 0;
boolean dirty = false;
if (end_hdr_len < hdr_len) { // mismatch: end has more; adjust hdr
@ -71,8 +75,12 @@ public class Xop_hdr_wkr implements Xop_ctx_wkr {
}
if (dirty)
hdr.Init_by_parse(hdr_len, bgn_manual, end_manual);
cur_pos = Find_fwd_while_ws_hdr_version(src, cur_pos, src_len); // NOTE: hdr gobbles up trailing ws; EX: "==a== \n\t \n \nb" gobbles up all 3 "\n"s; otherwise para_wkr will process <br/>
// 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);
ctx.Para().Process_block__bgn_n__end_y(Xop_xnde_tag_.Tag__h2);
// add to root tkn; other post-processing
hdr.Subs_move(root);
hdr.Src_end_(cur_pos);
if (ctx.Parse_tid() == Xop_parser_tid_.Tid__wtxt) { // do not add if defn / tmpl mode

View File

@ -310,7 +310,7 @@ public class Xop_lnki_wkr__basic_tst {
Xoae_page previous_page = Xoae_page.New_test(wiki, ttl);
previous_page.Redirect_trail().Itms__add__article(previous_page.Url(), ttl, null); // 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.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

@ -18,13 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.log_msgs.*;
public class Xop_tmpl_log {
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tmpl");
public static final Gfo_msg_itm
Escaped_tmpl = Gfo_msg_itm_.new_warn_(owner, "Escaped_tmpl")
, Escaped_end = Gfo_msg_itm_.new_warn_(owner, "Escaped_end")
, Key_is_empty = Gfo_msg_itm_.new_note_(owner, "Key_is_empty")
, Dangling = Gfo_msg_itm_.new_note_(owner, "Dangling_tmpl")
, Tmpl_end_autoCloses_something = Gfo_msg_itm_.new_note_(owner, "Tmpl_end_autoCloses_something")
, Tmpl_is_empty = Gfo_msg_itm_.new_note_(owner, "Tmpl_is_empty")
;
private static final Gfo_msg_grp owner = Gfo_msg_grp_.new_(Xoa_app_.Nde, "tmpl");
public static final Gfo_msg_itm
Escaped_tmpl = Gfo_msg_itm_.new_warn_(owner, "Escaped_tmpl")
, Escaped_end = Gfo_msg_itm_.new_warn_(owner, "Escaped_end")
, Key_is_empty = Gfo_msg_itm_.new_note_(owner, "Key_is_empty")
, Dangling = Gfo_msg_itm_.new_note_(owner, "Dangling_tmpl")
, Tmpl_end_autoCloses_something = Gfo_msg_itm_.new_note_(owner, "Tmpl_end_autoCloses_something")
, Tmpl_is_empty = Gfo_msg_itm_.new_note_(owner, "Tmpl_is_empty")
;
}

View File

@ -18,6 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
public class Xot_compile_data {
public boolean OnlyInclude_exists;
public boolean Arg_nde_has_key() {return arg_nde_has_key;} public Xot_compile_data Arg_nde_has_key_(boolean v) {arg_nde_has_key = v; return this;} private boolean arg_nde_has_key;
public boolean Arg_nde_has_key() {return arg_nde_has_key;} private boolean arg_nde_has_key;
public Xot_compile_data Arg_nde_has_key_(boolean v) {arg_nde_has_key = v; return this;}
public static final Xot_compile_data Noop = new Xot_compile_data();
}

View File

@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.brys.*; import gplx.xowa.wikis.nss.*;
public class Xot_defn_tmpl implements Xot_defn {
private boolean onlyinclude_parsed = false;
public byte Defn_tid() {return Xot_defn_.Tid_tmpl;}
public boolean Defn_require_colon_arg() {return false;}
public int Cache_size() {return data_raw.length;}
@ -60,7 +61,7 @@ public class Xot_defn_tmpl implements Xot_defn {
if (root != null) root.Clear();
root = null;
}
public void Parse_tmpl(Xop_ctx ctx) {ctx.Wiki().Parser_mgr().Main().Parse_text_to_defn(this, ctx, ctx.Tkn_mkr(), ns, name, data_raw);} boolean onlyinclude_parsed = false;
public void Parse_tmpl(Xop_ctx ctx) {ctx.Wiki().Parser_mgr().Main().Parse_text_to_defn(this, ctx, ctx.Tkn_mkr(), ns, name, data_raw);}
public boolean Tmpl_evaluate(Xop_ctx ctx, Xot_invk caller, Bry_bfr bfr) {
if (root == null) Parse_tmpl(ctx);
Xoae_page page = ctx.Page();

View File

@ -20,21 +20,19 @@ import gplx.core.envs.*;
import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.miscs.*;
public class Xot_tmpl_wtr {
public byte[] Write_all(Xop_ctx ctx, Xop_root_tkn root, byte[] src) {
// synchronized (this) { // THREAD:added synchronized after "failed to write tkn" DATE:2015-04-29
Bry_bfr rslt_bfr = ctx.Wiki().Utl__bfr_mkr().Get_m001();
rslt_bfr.Reset_if_gt(Io_mgr.Len_mb);
Write_tkn(ctx, src, src.length, rslt_bfr, root);
return rslt_bfr.To_bry_and_rls();
// }
Bry_bfr rslt_bfr = ctx.Wiki().Utl__bfr_mkr().Get_m001();
rslt_bfr.Reset_if_gt(Io_mgr.Len_mb);
Write_tkn(rslt_bfr, ctx, src, src.length, root);
return rslt_bfr.To_bry_and_rls();
}
private void Write_tkn(Xop_ctx ctx, byte[] src, int src_len, Bry_bfr rslt_bfr, Xop_tkn_itm tkn) {
private void Write_tkn(Bry_bfr rslt_bfr, Xop_ctx ctx, byte[] src, int src_len, Xop_tkn_itm tkn) {
switch (tkn.Tkn_tid()) {
case Xop_tkn_itm_.Tid_root: // write each sub
int subs_len = tkn.Subs_len();
for (int i = 0; i < subs_len; i++) {
Xop_tkn_itm sub_tkn = tkn.Subs_get(i);
if (!sub_tkn.Ignore())
Write_tkn(ctx, src, src_len, rslt_bfr, sub_tkn);
Write_tkn(rslt_bfr, ctx, src, src_len, sub_tkn);
}
break;
case Xop_tkn_itm_.Tid_bry: