mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
v2.7.2.1
This commit is contained in:
85
400_xowa/src/gplx/xowa/xtns/poems/Poem_nde.java
Normal file
85
400_xowa/src/gplx/xowa/xtns/poems/Poem_nde.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
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.xtns.poems; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.html.*; import gplx.xowa.html.*;
|
||||
public class Poem_nde implements Xox_xnde {
|
||||
private Xop_root_tkn xtn_root;
|
||||
public void Xtn_parse(Xowe_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) {// REF.MW: Poem.php|wfRenderPoemTag
|
||||
int itm_bgn = xnde.Tag_open_end(), itm_end = xnde.Tag_close_bgn();
|
||||
if (itm_bgn == src.length) return; // NOTE: handle inline where there is no content to parse; EX: <poem/>
|
||||
if (itm_bgn >= itm_end) return; // NOTE: handle inline where there is no content to parse; EX: a<poem/>b
|
||||
if (src[itm_bgn] == Byte_ascii.Nl) ++itm_bgn; // ignore 1st \n;
|
||||
if (src[itm_end - 1] == Byte_ascii.Nl // ignore last \n;
|
||||
&& itm_end != itm_bgn) --itm_end; // ...if not same as 1st \n; EX: <poem>\n</poem>
|
||||
Poem_xtn_mgr xtn_mgr = (Poem_xtn_mgr)wiki.Xtn_mgr().Get_or_fail(Poem_xtn_mgr.XTN_KEY);
|
||||
byte[] poem_bry = Parse_lines(wiki.Utl__bfr_mkr(), src, itm_bgn, itm_end);
|
||||
xtn_root = xtn_mgr.Parser().Parse_text_to_wdom_old_ctx(ctx, poem_bry, true); // NOTE: ignoring paragraph mode; technically MW enables para mode, but by replacing "\n" with "<br/>\n" all the logic with para/pre mode is skipped
|
||||
}
|
||||
public void Xtn_write(Bry_bfr bfr, Xoae_app app, Xop_ctx ctx, Xoh_html_wtr html_wtr, Xoh_wtr_ctx hctx, Xop_xnde_tkn xnde, byte[] src) {
|
||||
if (xtn_root == null) return; // inline poem; write nothing; EX: <poem/>
|
||||
bfr.Add(Div_poem_bgn);
|
||||
html_wtr.Write_tkn(bfr, ctx, hctx, xtn_root.Root_src(), xnde, Xoh_html_wtr.Sub_idx_null, xtn_root);
|
||||
bfr.Add(Div_poem_end);
|
||||
}
|
||||
private static byte[] Parse_lines(Bry_bfr_mkr bfr_mkr, byte[] src, int src_bgn, int src_end) {
|
||||
Bry_bfr bfr = bfr_mkr.Get_k004().Mkr_rls();
|
||||
int line_bgn = src_bgn; boolean line_is_1st = true;
|
||||
while (line_bgn < src_end) { // iterate over each \n
|
||||
boolean indent_enabled = false;
|
||||
if (line_is_1st) line_is_1st = false;
|
||||
else {
|
||||
int line_end_w_br = line_bgn + Xowa_br_mark.length;
|
||||
if ( line_end_w_br < src_end // check for out of bounds; PAGE:en.s:The Hebrew Nation did not write it; DATE:2015-01-31
|
||||
&& Bry_.Match(src, line_bgn, line_end_w_br, Xowa_br_mark)) // "<br/>\n" already inserted by XOWA; do not insert again; DATE:2014-10-20
|
||||
bfr.Add_byte_nl();
|
||||
else
|
||||
bfr.Add(Html_tag_.Br_inl).Add_byte_nl().Add(Xowa_br_mark); // add "<br/>\n" unless 1st line; EX: "<poem>\n\s" should not add leading "<br/>\n"
|
||||
}
|
||||
switch (src[line_bgn]) {
|
||||
case Byte_ascii.Space: // "\n\s" -> "\n "
|
||||
int space_end = Bry_finder.Find_fwd_while(src, line_bgn, src_end, Byte_ascii.Space);
|
||||
int space_count = space_end - line_bgn;
|
||||
line_bgn = space_end;
|
||||
for (int i = 0; i < space_count; ++i)
|
||||
bfr.Add(Html_entity_.Nbsp_num_bry);
|
||||
break;
|
||||
case Byte_ascii.Colon: { // "\n:" -> <span class='mw-poem-indented' style='display: inline-block; margin-left: #em;'>
|
||||
int colon_end = Bry_finder.Find_fwd_while(src, line_bgn, src_end, Byte_ascii.Colon);
|
||||
int colon_count = colon_end - line_bgn;
|
||||
line_bgn = colon_end;
|
||||
bfr.Add(Indent_bgn).Add_int_variable(colon_count).Add(Indent_end); // add <span class='mw-poem-indented' style='display: inline-block; margin-left: #em;'>
|
||||
indent_enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int line_end = Bry_finder.Find_fwd(src, Byte_ascii.Nl, line_bgn, src_end); // find end "\n"
|
||||
if (line_end == Bry_finder.Not_found) line_end = src_end; // no "\n"; use eos;
|
||||
bfr.Add_mid(src, line_bgn, line_end); // add everything from line_bgn to line_end
|
||||
if (indent_enabled) bfr.Add(Html_tag_.Span_rhs); // if "\n:", add </span>
|
||||
line_bgn = line_end + 1; // +1 to skip over end "\n"
|
||||
}
|
||||
return bfr.Xto_bry_and_clear();
|
||||
}
|
||||
private static byte[]
|
||||
Div_poem_bgn = Bry_.new_a7("<div class=\"poem\">\n<p>\n") // NOTE: always enclose in <p>; MW does this implicitly in its modified parse; DATE:2014-04-27
|
||||
, Div_poem_end = Bry_.new_a7("\n</p>\n</div>")
|
||||
, Indent_bgn = Bry_.new_a7("\n<span class='mw-poem-indented' style='display: inline-block; margin-left: ")
|
||||
, Indent_end = Bry_.new_a7("em;'>")
|
||||
, Xowa_br_mark = Bry_.new_a7("<!--xowa.br-->")
|
||||
;
|
||||
}
|
||||
285
400_xowa/src/gplx/xowa/xtns/poems/Poem_nde_tst.java
Normal file
285
400_xowa/src/gplx/xowa/xtns/poems/Poem_nde_tst.java
Normal file
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
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.xtns.poems; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import org.junit.*;
|
||||
public class Poem_nde_tst {
|
||||
@Before public void init() {fxt.Wiki().Xtn_mgr().Init_by_wiki(fxt.Wiki());} private Xop_fxt fxt = new Xop_fxt();
|
||||
@Test public void Lines() { // NOTE: first \n (poem\n) and last \n (\n</poem>)ignored
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, "a"
|
||||
, "b"
|
||||
, "c"
|
||||
, "d"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<br/>"
|
||||
, "b<br/>"
|
||||
, "c<br/>"
|
||||
, "d"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Nbsp_basic() {
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, "a 1"
|
||||
, " b 1"
|
||||
, "c 1"
|
||||
, " d 1"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a 1<br/>"
|
||||
, "  b 1<br/>"
|
||||
, "c 1<br/>"
|
||||
, "  d 1"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Nbsp_line_0() {// PURPOSE: indent on 1st line caused page_break
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, " a"
|
||||
, " b"
|
||||
, " c"
|
||||
, " d"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "  a<br/>"
|
||||
, "  b<br/>"
|
||||
, "  c<br/>"
|
||||
, "  d"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Nbsp_blank_lines() {// PURPOSE: check blank lines; PAGE:none
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, " a"
|
||||
, " "
|
||||
, " "
|
||||
, " b"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "  a<br/>"
|
||||
, "  <br/>"
|
||||
, "  <br/>"
|
||||
, "  b"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Comment() {
|
||||
fxt.Test_parse_page_wiki_str("<poem>a<!-- b --> c</poem>", String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a c"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Xtn() { // NOTE: behavior as per MW: DATE:2014-03-03
|
||||
fxt.Init_defn_clear();
|
||||
fxt.Init_defn_add("test_print", "{{{1}}}");
|
||||
fxt.Init_defn_add("test_outer", String_.Concat_lines_nl_skip_last
|
||||
( "{{test_print|a <poem>b}}c</poem>}}"
|
||||
));
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "{{test_outer}}"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "a <div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "b}}c"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
fxt.Init_defn_clear();
|
||||
}
|
||||
@Test public void Err_empty_line() {// PURPOSE: one \n caused poem to fail
|
||||
fxt.Test_parse_page_wiki_str("<poem>\n</poem>", String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, ""
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Err_dangling_comment() {// PURPOSE: ArrayIndexOutOfBoundsError if poem has <references/> and ends with <!--; PAGE:en.s:The Hebrew Nation did not write it; DATE:2015-01-31
|
||||
fxt.Test_parse_page_wiki_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, "<references/>"
|
||||
, "<!--"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "<br/>"
|
||||
, ""
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Ref() { // PURPOSE: <ref> inside poem was not showing up; DATE:2014-01-17
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>a<ref>b</ref></poem>"
|
||||
, "<references/>"), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<sup id=\"cite_ref-0\" class=\"reference\"><a href=\"#cite_note-0\">[1]</a></sup>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
, "<ol class=\"references\">"
|
||||
, "<li id=\"cite_note-0\"><span class=\"mw-cite-backlink\"><a href=\"#cite_ref-0\">^</a></span> <span class=\"reference-text\">b</span></li>"
|
||||
, "</ol>"
|
||||
, ""
|
||||
));
|
||||
}
|
||||
@Test public void Template_tkn() { // PURPOSE: make sure {{{1}}} is interpreted as invk_prm, not as text; DATE:2014-03-03
|
||||
fxt.Test_parse_tmpl("<poem>{{{1}}}</poem>"
|
||||
, fxt.tkn_xnde_(0, 20).Subs_
|
||||
( fxt.tkn_tmpl_prm_find_(fxt.tkn_txt_(9, 10))
|
||||
)
|
||||
);
|
||||
}
|
||||
@Test public void Template_parse() { // PURPOSE: <poem> inside template was not evaluating args; EX:en.s:The_Canterville_Ghost; DATE:2014-03-03
|
||||
fxt.Init_page_create("Template:A", "<poem>{{{1}}}</poem>");
|
||||
fxt.Test_parse_page_all_str("{{A|b}}", String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "b" // was {{{1}}}
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Nested() { // PURPOSE: handled nested poems; EX:en.s:The_Canterville_Ghost; DATE:2014-03-03
|
||||
fxt.Test_parse_page_all_str("a<poem>b<poem>c</poem>d</poem>e", String_.Concat_lines_nl_skip_last
|
||||
( "a<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "b<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "c"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
, "</p>"
|
||||
, "</div>de"
|
||||
));
|
||||
}
|
||||
@Test public void Indent_line_0() { // PURPOSE: handle colon on 1st line; PAGE:en.w:Mary_Wollstonecraft DATE:2014-10-19
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, ":a"
|
||||
, ":b"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>a</span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>b</span>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Indent_many() { // PURPOSE: handle colon on 2nd line; PAGE:vi.s:Văn_Côi_thánh_nguyệt_tán_tụng_thi_ca DATE:2014-10-15
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, "a"
|
||||
, ":b"
|
||||
, "::c"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>b</span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 2em;'>c</span>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Indent_blank() { // PURPOSE: check blank lines; PAGE:none DATE:2014-10-19
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, ":a"
|
||||
, ":"
|
||||
, ":b"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>a</span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'></span><br/>"
|
||||
, "<span class='mw-poem-indented' style='display: inline-block; margin-left: 1em;'>b</span>"
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void List_does_not_end() {// PURPOSE: list does not end with "\ntext"; PAGE:vi.s:Dương_Từ_Hà_Mậu_(dị_bản_mới); li.s:Sint_Servaes_legende/Nuuj_fergmènter DATE:2014-10-19
|
||||
fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
|
||||
( "<poem>"
|
||||
, "a"
|
||||
, "*b"
|
||||
, "**c"
|
||||
, "d"
|
||||
, "</poem>"
|
||||
), String_.Concat_lines_nl_skip_last
|
||||
( "<div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<br/>"
|
||||
, "<ul>"
|
||||
, " <li>b<br/>"
|
||||
, " <ul>"
|
||||
, " <li>c<br/>"
|
||||
, " </li>"
|
||||
, " </ul>"
|
||||
, " </li>"
|
||||
, "</ul>"
|
||||
, "d" // was being embedded directly after <li>c
|
||||
, "</p>"
|
||||
, "</div>"
|
||||
));
|
||||
}
|
||||
@Test public void Page() { // PURPOSE: handled dangling poems across pages; PAGE:ca.s:Llibre_de_Disputació_de_l'Ase DATE:2014-10-19
|
||||
fxt.Init_xtn_pages();
|
||||
fxt.Init_page_create("Page:A/1", "<poem>a\nb\n");
|
||||
fxt.Init_page_create("Page:A/2", "<poem>c\nd\n");
|
||||
fxt.Test_parse_page_wiki_str("<pages index=\"A\" from=1 to=2 />", String_.Concat_lines_nl_skip_last
|
||||
( "<p><div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "a<br/>"
|
||||
, "b"
|
||||
, "</p>"
|
||||
, "</div> <div class=\"poem\">"
|
||||
, "<p>"
|
||||
, "c<br/>" // NOTE: "<br/>" not "<br/><br/>"
|
||||
, "d"
|
||||
, "</p>"
|
||||
, "</div> "
|
||||
, "</p>"
|
||||
));
|
||||
}
|
||||
}
|
||||
28
400_xowa/src/gplx/xowa/xtns/poems/Poem_xtn_mgr.java
Normal file
28
400_xowa/src/gplx/xowa/xtns/poems/Poem_xtn_mgr.java
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
XOWA: the XOWA Offline Wiki Application
|
||||
Copyright (C) 2012 gnosygnu@gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.xtns.poems; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
public class Poem_xtn_mgr extends Xox_mgr_base {
|
||||
@Override public byte[] Xtn_key() {return XTN_KEY;} public static final byte[] XTN_KEY = Bry_.new_a7("poem");
|
||||
@Override public Xox_mgr Clone_new() {return new Poem_xtn_mgr();}
|
||||
public Xop_parser Parser() {return parser;} private Xop_parser parser;
|
||||
@Override public void Xtn_init_by_wiki(Xowe_wiki wiki) {
|
||||
parser = new Xop_parser(wiki, wiki.Parser().Tmpl_lxr_mgr(), wiki.Parser().Wtxt_lxr_mgr());
|
||||
parser.Init_by_wiki(wiki);
|
||||
parser.Init_by_lang(wiki.Lang());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user