/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012-2017 gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.parsers.tmpls; import gplx.*; import gplx.xowa.*; import gplx.xowa.parsers.*;
import gplx.core.envs.*;
import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.miscs.*;
public class Xot_tmpl_wtr {
public static byte[] Write_all(Xop_ctx ctx, Xop_root_tkn root, byte[] src) {
Bry_bfr bfr = ctx.Wiki().Utl__bfr_mkr().Get_m001().Reset_if_gt(Io_mgr.Len_mb);
Write_tkn(bfr, ctx, src, src.length, root);
byte[] rv = bfr.To_bry_and_rls();
return ctx.Wiki().Parser_mgr().Uniq_mgr().Parse(rv); // NOTE: noops if no UNIQs; // UNIQ; DATE:2017-03-31
}
private static 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(rslt_bfr, ctx, src, src_len, sub_tkn);
}
break;
case Xop_tkn_itm_.Tid_bry:
Xop_bry_tkn bry = (Xop_bry_tkn)tkn;
rslt_bfr.Add(bry.Val());
break;
case Xop_tkn_itm_.Tid_space:
if (tkn.Tkn_immutable())
rslt_bfr.Add_byte(Byte_ascii.Space);
else
rslt_bfr.Add_byte_repeat(Byte_ascii.Space, tkn.Src_end() - tkn.Src_bgn());
break;
case Xop_tkn_itm_.Tid_xnde:
Xop_xnde_tkn xnde = (Xop_xnde_tkn)tkn;
int xnde_tag_id = xnde.Tag().Id();
switch (xnde_tag_id) {
case Xop_xnde_tag_.Tid__onlyinclude: {
// NOTE: originally "if (ctx.Parse_tid() == Xop_parser_tid_.Tid__tmpl) {" but if not needed; Xot_tmpl_wtr should not be called for tmpls and <oi> should not make it to page_wiki
Bry_bfr tmp_bfr = Bry_bfr_.New();
ctx.Only_include_evaluate_(true);
xnde.Tmpl_evaluate(ctx, src, Xot_invk_temp.Page_is_caller, tmp_bfr);
ctx.Only_include_evaluate_(false);
rslt_bfr.Add_bfr_and_preserve(tmp_bfr);
break;
}
case Xop_xnde_tag_.Tid__includeonly: // noop; DATE:2014-02-12
break;
case Xop_xnde_tag_.Tid__nowiki: {
if (xnde.Tag_close_bgn() == Int_.Min_value)
rslt_bfr.Add_mid(src, tkn.Src_bgn(), tkn.Src_end()); // write src from bgn/end
else { // NOTE: if nowiki then "deactivate" all xndes by swapping out < for < nowiki_xnde_frag; DATE:2013-01-27
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_k004();
int nowiki_content_bgn = xnde.Tag_open_end(), nowiki_content_end = xnde.Tag_close_bgn();
boolean escaped = gplx.xowa.parsers.tmpls.Nowiki_escape_itm.Escape(tmp_bfr, src, nowiki_content_bgn, nowiki_content_end);
rslt_bfr.Add_bfr_or_mid(escaped, tmp_bfr, src, nowiki_content_bgn, nowiki_content_end);
tmp_bfr.Mkr_rls();
}
break;
}
case Xop_xnde_tag_.Tid__xowa_cmd:
gplx.xowa.xtns.xowa_cmds.Xop_xowa_cmd xowa_cmd = (gplx.xowa.xtns.xowa_cmds.Xop_xowa_cmd)xnde.Xnde_xtn();
rslt_bfr.Add(xowa_cmd.Xtn_html());
break;
default:
rslt_bfr.Add_mid(src, tkn.Src_bgn(), tkn.Src_end()); // write src from bgn/end
break;
}
break;
default:
rslt_bfr.Add_mid(src, tkn.Src_bgn(), tkn.Src_end()); break; // write src from bgn/end
case Xop_tkn_itm_.Tid_ignore: break; // hide comments and <*include*> ndes
case Xop_tkn_itm_.Tid_tmpl_prm:
tkn.Tmpl_evaluate(ctx, src, Xot_invk_temp.Page_is_caller.Src_(src), rslt_bfr);
break;
case Xop_tkn_itm_.Tid_tvar:
gplx.xowa.xtns.translates.Xop_tvar_tkn tvar_tkn = (gplx.xowa.xtns.translates.Xop_tvar_tkn)tkn;
rslt_bfr.Add(tvar_tkn.Wikitext());
break;
case Xop_tkn_itm_.Tid_tmpl_invk:
try {
tkn.Tmpl_evaluate(ctx, src, Xot_invk_temp.Page_is_caller.Src_(src), rslt_bfr);
}
catch (Exception e) {
String err_string = String_.new_u8(src, tkn.Src_bgn(), tkn.Src_end()) + "|" + Type_adp_.NameOf_obj(e) + "|" + Err_.Cast_or_make(e).To_str__log();
if (Env_.Mode_testing())
throw Err_.new_exc(e, "xo", err_string);
else
ctx.App().Usr_dlg().Warn_many("", "", "failed to write tkn: page=~{0} err=~{1}", String_.new_u8(ctx.Page().Ttl().Page_db()), err_string);
}
break;
}
}
}