1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2016-01-24 22:50:55 -05:00
parent 235228976e
commit 686d56fdab
77 changed files with 1543 additions and 487 deletions

View File

@@ -54,4 +54,7 @@ public class Gfh_atr_ {
public static byte[] Make(Bry_bfr bfr, byte[] key, byte[] val) {
return bfr.Add_byte_space().Add(key).Add_byte_eq().Add_byte_quote().Add(val).Add_byte_quote().To_bry_and_clear();
}
public static void Add(Bry_bfr bfr, byte[] key, byte[] val) {
bfr.Add_byte_space().Add(key).Add_byte_eq().Add_byte_quote().Add(val).Add_byte_quote();
}
}

View File

@@ -178,6 +178,18 @@ public class Gfh_utl {
return bfr.To_bry_and_clear();
}
public static String Replace_apos(String s) {return String_.Replace(s, "'", "\"");}
public static String Replace_apos_concat_lines(String... lines) {
Bry_bfr bfr = Bry_bfr.new_();
int len = lines.length;
for (int i = 0; i < len; ++i) {
String line_str = lines[i];
byte[] line_bry = Bry_.new_u8(line_str);
Bry_.Replace_all_direct(line_bry, Byte_ascii.Apos, Byte_ascii.Quote, 0, line_bry.length);
if (i != 0) bfr.Add_byte_nl();
bfr.Add(line_bry);
}
return bfr.To_str_and_clear();
}
public static void Log(Exception e, String head, byte[] page_url, byte[] src, int pos) {
Err err = Err_.cast_or_make(e); if (err.Logged()) return;
String msg = String_.Format("{0}; page={1} err={2} mid={3} trace={4}", head, page_url, Err_.To_str(e), Bry_.Escape_ws(Bry_.Mid_by_len_safe(src, pos, 255)), err.To_str__log());

View File

@@ -41,7 +41,7 @@ public class Json_parser__list_nde__base extends Json_parser__itm__base {
for (int j = 0; j < atr_len; ++j) {
Json_kv atr = nde.Get_at_as_kv(j);
Object idx_obj = hash.Get_by_bry(atr.Key_as_bry());
if (idx_obj == null) {Warn("unknown key", atr); continue;}
if (idx_obj == null) {Warn("unknown json parser key", atr); continue;}
int idx_int = ((Int_obj_val)idx_obj).Val();
atrs[idx_int] = atr;
}

View File

@@ -0,0 +1,54 @@
/*
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.langs.mustaches; import gplx.*; import gplx.langs.*;
import gplx.langs.jsons.*;
interface Mustache_doc_itm {
byte[] Get_by_key(byte[] key);
Mustache_doc_itm Get_owner();
void Move_next();
void Move_down(byte[] key);
void Move_up();
}
class Mustache_doc_itm_ {
public static final byte[] Null_val = null;
public static final Mustache_doc_itm Null_itm = null;
}
class Mustache_doc_itm__json implements Mustache_doc_itm {
// private Json_doc jdoc;
private final List_adp stack = List_adp_.new_();
private Json_nde cur; private int cur_idx = -1;
public void Init_by_jdoc(Json_doc jdoc) {
// this.jdoc = jdoc;
this.cur = jdoc.Root_nde();
}
public byte[] Get_by_key(byte[] key) {return cur.Get_bry_or_null(key);}
public Mustache_doc_itm Get_owner() {return Mustache_doc_itm_.Null_itm;}
public void Move_next() {
++cur_idx;
// cur = cur.Owner().Get_at();
}
public void Move_down(byte[] key) {
stack.Add(cur);
cur_idx = 0;
cur = (Json_nde)cur.Get_itm(key);
}
public void Move_up() {
if (cur_idx == 0) {}
cur = (Json_nde)stack.Get_at_last();
}
}

View File

@@ -16,21 +16,12 @@ 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.langs.mustaches; import gplx.*; import gplx.langs.*;
/*
root
txt
key
txt
section
txt
key
txt
txt
*/
interface Mustache_elem_itm {
int Tid();
byte[] Key();
Mustache_elem_itm[] Subs();
Mustache_elem_itm[] Subs_ary();
void Subs_ary_(Mustache_elem_itm[] v);
void Render(Bry_bfr bfr, Mustache_render_ctx ctx);
}
class Mustache_elem_itm_ {// for types, see http://mustache.github.io/mustache.5.html
public static final int Tid__root = 0, Tid__text = 1, Tid__variable = 2, Tid__escape = 3, Tid__section = 4, Tid__inverted = 5, Tid__comment = 6, Tid__partial = 7, Tid__delimiter = 8;
@@ -40,16 +31,42 @@ abstract class Mustache_elem_base implements Mustache_elem_itm {
public Mustache_elem_base(int tid, byte[] key) {this.tid = tid; this.key = key;}
public int Tid() {return tid;} private final int tid;
public byte[] Key() {return key;} private final byte[] key;
@gplx.Virtual public Mustache_elem_itm[] Subs() {return Mustache_elem_itm_.Ary_empty;}
@gplx.Virtual public Mustache_elem_itm[] Subs_ary() {return Mustache_elem_itm_.Ary_empty;}
@gplx.Virtual public void Subs_ary_(Mustache_elem_itm[] v) {}
@gplx.Virtual public void Render(Bry_bfr bfr, Mustache_render_ctx ctx) {}
}
class Mustache_elem_root extends Mustache_elem_base { // EX: {{variable}} -> &lt;a&gt;
private Mustache_elem_itm[] subs_ary;
public Mustache_elem_root() {super(Mustache_elem_itm_.Tid__root, Bry_.Empty);}
@Override public Mustache_elem_itm[] Subs_ary() {return subs_ary;}
@Override public void Subs_ary_(Mustache_elem_itm[] v) {subs_ary = v;}
@Override public void Render(Bry_bfr bfr, Mustache_render_ctx ctx) {
int subs_len = subs_ary.length;
for (int i = 0; i < subs_len; ++i) {
Mustache_elem_itm sub = subs_ary[i];
sub.Render(bfr, ctx);
}
}
}
class Mustache_elem_text extends Mustache_elem_base { // EX: text -> text
public Mustache_elem_text(byte[] val) {super(Mustache_elem_itm_.Tid__text, Bry_.Empty);
this.val = val;
private final byte[] src; private final int src_bgn, src_end;
public Mustache_elem_text(byte[] src, int src_bgn, int src_end) {super(Mustache_elem_itm_.Tid__text, Bry_.Empty);
this.src = src;
this.src_bgn = src_bgn;
this.src_end = src_end;
}
@Override public void Render(Bry_bfr bfr, Mustache_render_ctx ctx) {
bfr.Add_mid(src, src_bgn, src_end);
}
public byte[] Val() {return val;} private final byte[] val;
}
class Mustache_elem_val extends Mustache_elem_base { // EX: {{variable}} -> &lt;a&gt;
public Mustache_elem_val(byte[] key) {super(Mustache_elem_itm_.Tid__variable, key);}
class Mustache_elem_variable extends Mustache_elem_base { // EX: {{variable}} -> &lt;a&gt;
public Mustache_elem_variable(byte[] key) {super(Mustache_elem_itm_.Tid__variable, key);}
@Override public void Render(Bry_bfr bfr, Mustache_render_ctx ctx) {
byte[] key = this.Key();
byte[] val = ctx.Render_variable(key);
if (val != Mustache_doc_itm_.Null_val) // if not found, return empty String by default
bfr.Add(val);
}
}
class Mustache_elem_escape extends Mustache_elem_base { // EX: {{{variable}}} -> <a>
public Mustache_elem_escape(byte[] key) {super(Mustache_elem_itm_.Tid__escape, key);}

View File

@@ -0,0 +1,110 @@
/*
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.langs.mustaches; import gplx.*; import gplx.langs.*;
import gplx.core.btries.*;
class Mustache_itm_parser {
private byte[] src; private int src_end;
private final Mustache_tkn_def tkn_def = new Mustache_tkn_def();
public Mustache_elem_itm Parse(byte[] src, int src_bgn, int src_end) {
this.src = src; this.src_end = src_end;
Mustache_elem_root root = new Mustache_elem_root();
Parse_grp(root, src_bgn);
return root;
}
private void Parse_grp(Mustache_elem_itm owner, int src_bgn) {
List_adp subs_list = List_adp_.new_();
int pos = src_bgn;
boolean loop = true;
while (loop) {
int tkn_lhs_bgn = Bry_find_.Find_fwd(src, tkn_def.Variable_lhs, pos, src_end); // next "{{"
if (tkn_lhs_bgn == Bry_find_.Not_found) { // no "{{"; EOS
loop = false;
tkn_lhs_bgn = src_end;
}
subs_list.Add(new Mustache_elem_text(src, pos, tkn_lhs_bgn)); // add everything between last "}}" and cur "{{"
if (!loop) break;
pos = Parse_itm(subs_list, tkn_lhs_bgn + tkn_def.Variable_lhs_len);
}
if (subs_list.Count() > 0)
owner.Subs_ary_((Mustache_elem_itm[])subs_list.To_ary_and_clear(Mustache_elem_itm.class));
}
private int Parse_itm(List_adp subs_list, int tkn_lhs_end) {
if (tkn_lhs_end >= src_end) throw Fail(tkn_lhs_end, "early eos");
byte b = src[tkn_lhs_end];
int tkn_rhs_bgn = Bry_find_.Find_fwd(src, tkn_def.Variable_rhs, tkn_lhs_end, src_end);
if (tkn_rhs_bgn == Bry_find_.Not_found) throw Fail(tkn_lhs_end, "dangling tkn");
byte[] tkn_val = Bry_.Mid(src, tkn_lhs_end, tkn_rhs_bgn);
Mustache_elem_itm elem = null;
byte rhs_chk_byte = Byte_ascii.Null;
switch (b) {
default: elem = new Mustache_elem_variable(tkn_val); break;
case Mustache_tkn_def.Comment: elem = new Mustache_elem_comment(tkn_val); break;
case Mustache_tkn_def.Partial: elem = new Mustache_elem_partial(tkn_val); break;
case Mustache_tkn_def.Delimiter_bgn: elem = new Mustache_elem_delimiter(tkn_val); rhs_chk_byte = Mustache_tkn_def.Delimiter_end; break; // TODO: change tkn_def{{=<% %>=}}
case Mustache_tkn_def.Escape_bgn: elem = new Mustache_elem_escape(tkn_val); rhs_chk_byte = Mustache_tkn_def.Escape_end; break;
case Mustache_tkn_def.Section: elem = new Mustache_elem_section(tkn_val); break;
case Mustache_tkn_def.Inverted: elem = new Mustache_elem_inverted(tkn_val); break;
case Mustache_tkn_def.Grp_end: break;
}
subs_list.Add(elem);
if (rhs_chk_byte != Byte_ascii.Null) {
if (src[tkn_rhs_bgn] != rhs_chk_byte) throw Fail(tkn_lhs_end, "invalid check byte");
++tkn_rhs_bgn;
}
return tkn_rhs_bgn + tkn_def.Variable_rhs_len;
}
private Err Fail(int pos, String fmt, Object... args) {
return Err_.new_("mustache", fmt, "excerpt", Bry_.Mid_by_len_safe(src, pos, 32));
}
}
class Mustache_tkn_def {
public byte[] Variable_lhs = Dflt_variable_lhs;
public byte[] Variable_rhs = Dflt_variable_rhs;
public int Variable_lhs_len;
public int Variable_rhs_len;
public static final byte[]
Dflt_variable_lhs = Bry_.new_a7("{{")
, Dflt_variable_rhs = Bry_.new_a7("}}")
;
public static final byte
Escape_bgn = Byte_ascii.Curly_bgn // {{{escape}}}
, Escape_end = Byte_ascii.Curly_end // {{{escape}}}
, Section = Byte_ascii.Hash // {{#section}}
, Grp_end = Byte_ascii.Slash // {{/section}}
, Inverted = Byte_ascii.Pow // {{^inverted}}
, Comment = Byte_ascii.Bang // {{!comment}}
, Partial = Byte_ascii.Angle_bgn // {{>partial}}
, Delimiter_bgn = Byte_ascii.Eq // {{=<% %>=}}
, Delimiter_end = Byte_ascii.Curly_end // {{=<% %>=}}
;
public Mustache_tkn_def() {
Variable_lhs_len = Variable_lhs.length;
Variable_rhs_len = Variable_rhs.length;
}
}
/*
root
txt
key
txt
section
txt
key
txt
txt
*/

View File

@@ -0,0 +1,39 @@
/*
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.langs.mustaches; import gplx.*; import gplx.langs.*;
import org.junit.*;
public class Mustache_itm_parser_tst {
private final Mustache_itm_parser_fxt fxt = new Mustache_itm_parser_fxt();
@Test public void Basic() {
fxt.Test_parse("a{{b}}c", "ac");
}
@Test public void Comment() {
fxt.Test_parse("a{{!b}}c", "ac");
}
}
class Mustache_itm_parser_fxt {
private final Mustache_itm_parser parser = new Mustache_itm_parser();
private final Mustache_render_ctx ctx = new Mustache_render_ctx();
private final Bry_bfr tmp_bfr = Bry_bfr.new_();
public void Test_parse(String src_str, String expd) {
byte[] src_bry = Bry_.new_a7(src_str);
Mustache_elem_itm actl_itm = parser.Parse(src_bry, 0, src_bry.length);
actl_itm.Render(tmp_bfr, ctx);
Tfds.Eq_str_lines(expd, tmp_bfr.To_str_and_clear());
}
}

View File

@@ -0,0 +1,32 @@
/*
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.langs.mustaches; import gplx.*; import gplx.langs.*;
class Mustache_render_ctx {
private Mustache_doc_itm doc;
public void Init_dom_doc(Mustache_doc_itm doc) {this.doc = doc;}
public byte[] Render_variable(byte[] key) {
byte[] rv = Mustache_doc_itm_.Null_val;
Mustache_doc_itm cur = doc;
while (cur != Mustache_doc_itm_.Null_itm) {
rv = doc.Get_by_key(key);
if (rv != Mustache_doc_itm_.Null_val) break;
cur = cur.Get_owner();
}
return rv;
}
}