mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
Section_edit: Add lead paragraph edit
This commit is contained in:
@@ -39,47 +39,58 @@ class Xop_section_list implements Xomw_hdr_cbk {
|
||||
return this;
|
||||
}
|
||||
public byte[] Slice_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[] bounds = Get_section_bounds(key);
|
||||
if (bounds == null) return null; // handle missing key
|
||||
|
||||
int src_bgn = Get_src_bgn(itm.Src_bgn());
|
||||
int src_end = Get_src_end(itm);
|
||||
|
||||
return Bry_.Mid(src, src_bgn, src_end);
|
||||
// return slice
|
||||
return Bry_.Mid(src, bounds[0], bounds[1]);
|
||||
}
|
||||
public byte[] Merge_bry_or_null(byte[] key, byte[] edit) {
|
||||
// find section matching key
|
||||
Xop_section_itm itm = (Xop_section_itm)hash.Get_by(key);
|
||||
if (itm == null) return null;
|
||||
|
||||
int src_bgn = Get_src_bgn(itm.Src_bgn());
|
||||
int src_end = Get_src_end(itm);
|
||||
int[] bounds = Get_section_bounds(key);
|
||||
if (bounds == null) return null; // handle missing key
|
||||
|
||||
// merge edit into orig
|
||||
Bry_bfr bfr = Bry_bfr_.New();
|
||||
bfr.Add_mid(src, 0, src_bgn);
|
||||
bfr.Add_mid(src, 0, bounds[0]);
|
||||
bfr.Add(edit);
|
||||
bfr.Add_mid(src, src_end, src.length);
|
||||
bfr.Add_mid(src, bounds[1], src.length);
|
||||
|
||||
return bfr.To_bry_and_clear();
|
||||
}
|
||||
private int Get_src_bgn(int src_bgn) {
|
||||
if (src[src_bgn] == Byte_ascii.Nl) src_bgn++;
|
||||
return src_bgn;
|
||||
}
|
||||
private int Get_src_end(Xop_section_itm itm) {
|
||||
int src_end = -1; // default to last
|
||||
private int[] Get_section_bounds(byte[] key) {
|
||||
int src_bgn = -1, src_end = -1;
|
||||
int hash_len = hash.Len();
|
||||
for (int i = itm.Idx() + 1; i < hash_len; i++) {
|
||||
Xop_section_itm nxt = (Xop_section_itm)hash.Get_at(i);
|
||||
if (nxt.Num() > itm.Num()) continue; // skip headers that are at lower level; EX: == H2 == should skip === H3 ===
|
||||
src_end = nxt.Src_bgn();
|
||||
break;
|
||||
|
||||
// if key == "", get lead section
|
||||
if (Bry_.Eq(key, Bry_.Empty)) {
|
||||
src_bgn = 0;
|
||||
src_end = src.length;
|
||||
if (hash_len > 0) {
|
||||
Xop_section_itm itm = (Xop_section_itm)hash.Get_at(0);
|
||||
src_end = itm.Src_bgn(); // -1 to skip "\n" in "\n=="
|
||||
}
|
||||
}
|
||||
if (src_end == -1) src_end = src.length; // no headers found; default to EOS
|
||||
src_end = Bry_find_.Find_bwd__skip_ws(src, src_end, itm.Src_bgn());
|
||||
return src_end;
|
||||
// else, get section matching key
|
||||
else {
|
||||
Xop_section_itm itm = (Xop_section_itm)hash.Get_by(key);
|
||||
if (itm == null) return null;
|
||||
|
||||
// get bgn
|
||||
src_bgn = itm.Src_bgn();
|
||||
if (src[src_bgn] == Byte_ascii.Nl) src_bgn++; // skip "\n" in "\n=="
|
||||
|
||||
// get end
|
||||
for (int i = itm.Idx() + 1; i < hash_len; i++) {
|
||||
Xop_section_itm nxt = (Xop_section_itm)hash.Get_at(i);
|
||||
if (nxt.Num() > itm.Num()) continue; // skip headers that are at lower level; EX: == H2 == should skip === H3 ===
|
||||
src_end = nxt.Src_bgn();
|
||||
break;
|
||||
}
|
||||
if (src_end == -1) src_end = src.length; // no headers found; default to EOS
|
||||
src_end = Bry_find_.Find_bwd__skip_ws(src, src_end, src_bgn); // always remove ws at end
|
||||
}
|
||||
|
||||
return new int[] {src_bgn, src_end};
|
||||
}
|
||||
public void On_hdr_seen(Xomw_parser_ctx pctx, Xomw_hdr_wkr wkr) {
|
||||
// get key by taking everything between ==; EX: "== abc ==" -> " abc "
|
||||
|
||||
@@ -141,4 +141,39 @@ public class Xop_section_list__merge__tst {
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Lead() {
|
||||
fxt.Exec__parse
|
||||
( "lead para"
|
||||
, ""
|
||||
, "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
);
|
||||
fxt.Test__merge_bry_or_null("", String_.Concat_lines_nl_skip_last
|
||||
( "lead para 1"
|
||||
, ""
|
||||
, "lead para 2"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "lead para 1"
|
||||
, ""
|
||||
, "lead para 2"
|
||||
, "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Lead__new() {
|
||||
fxt.Exec__parse
|
||||
( "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
);
|
||||
fxt.Test__merge_bry_or_null("", String_.Concat_lines_nl_skip_last
|
||||
( "lead para 1"
|
||||
, ""
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "lead para 1"
|
||||
, "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,40 @@ public class Xop_section_list__slice__tst {
|
||||
, "Para 1"
|
||||
));
|
||||
}
|
||||
@Test public void Lead() {
|
||||
fxt.Exec__parse
|
||||
( "lead text"
|
||||
, ""
|
||||
, "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
, ""
|
||||
);
|
||||
fxt.Test__slice_bry_or_null(""
|
||||
, "lead text"
|
||||
);
|
||||
}
|
||||
@Test public void Lead__none() {
|
||||
fxt.Exec__parse
|
||||
( ""
|
||||
, "== Hdr 1 =="
|
||||
, "Para 1"
|
||||
, ""
|
||||
);
|
||||
fxt.Test__slice_bry_or_null("");
|
||||
}
|
||||
@Test public void Lead__eos() {
|
||||
fxt.Exec__parse
|
||||
( "lead text"
|
||||
, ""
|
||||
, "para 1"
|
||||
, ""
|
||||
);
|
||||
fxt.Test__slice_bry_or_null(""
|
||||
, "lead text"
|
||||
, ""
|
||||
, "para 1"
|
||||
);
|
||||
}
|
||||
}
|
||||
class Xop_section_list__fxt {
|
||||
private final Xop_section_list list = new Xop_section_list();
|
||||
|
||||
@@ -67,15 +67,15 @@ public class Xop_section_mgr implements Gfo_invk {
|
||||
throw Err_.new_wo_type("could not merge section_key", "page", url.To_str(), "section_key", section_key);
|
||||
return rv;
|
||||
}
|
||||
public void Write_html(Bry_bfr bfr, byte[] src, byte[] page_ttl, Xop_hdr_tkn hdr, byte[] toc_text) {
|
||||
public void Write_html(Bry_bfr bfr, byte[] page_ttl, byte[] section_key, byte[] section_hint) {
|
||||
if (bry__edit_text == null) { // LAZY: cannot call in Init_by_wiki b/c of circularity; section_mgr is init'd by parser_mgr which is init'd before msg_mgr which is used below
|
||||
this.bry__edit_text = wiki.Msg_mgr().Val_by_key_obj("editlink");
|
||||
this.fmt__edit_hint.Fmt_(String_.new_u8(wiki.Msg_mgr().Val_by_key_obj("editsectionhint")));
|
||||
}
|
||||
|
||||
toc_text = wiki.Parser_mgr().Uniq_mgr().Convert(toc_text); // need to swap out uniqs for Math; DATE:2016-12-09
|
||||
byte[] edit_hint = fmt__edit_hint.Bld_many_to_bry(tmp_bfr, toc_text);
|
||||
fmt__section_editable.Bld_many(bfr, page_ttl, toc_text, edit_hint, bry__edit_text);
|
||||
section_key = wiki.Parser_mgr().Uniq_mgr().Convert(section_key); // need to swap out uniqs for Math; DATE:2016-12-09
|
||||
byte[] edit_hint = fmt__edit_hint.Bld_many_to_bry(tmp_bfr, section_hint);
|
||||
fmt__section_editable.Bld_many(bfr, page_ttl, section_key, edit_hint, bry__edit_text);
|
||||
}
|
||||
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");
|
||||
|
||||
Reference in New Issue
Block a user