mirror of https://github.com/gnosygnu/xowa
parent
32fdbc6fbe
commit
62c81e6d77
@ -1,98 +0,0 @@
|
||||
/*
|
||||
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.math; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.core.brys.fmtrs.*;
|
||||
import gplx.xowa.htmls.*; import gplx.langs.htmls.entitys.*; import gplx.xowa.htmls.core.htmls.*;
|
||||
import gplx.xowa.parsers.*; import gplx.xowa.parsers.xndes.*; import gplx.xowa.parsers.vnts.*;
|
||||
public class Xof_math_html_wtr {
|
||||
public static final byte[] Bry__id_prefix = Bry_.new_a7("xowa_math_txt_");
|
||||
private final Bry_fmtr math_fmtr_latex = Bry_fmtr.new_("<img id='xowa_math_img_~{math_idx}' src='' width='' height=''/><span id='xowa_math_txt_~{math_idx}'>~{math_text}</span>", "math_idx", "math_text");
|
||||
private final Bry_fmtr math_fmtr_mathjax = Bry_fmtr.new_("<span id='xowa_math_txt_~{math_idx}'>~{math_text}</span>", "math_idx", "math_text");
|
||||
public void Write(Xoh_html_wtr wtr, Xop_ctx ctx, Xoh_wtr_ctx opts, Bry_bfr bfr, byte[] src, Xop_xnde_tkn xnde) {
|
||||
Xoae_app app = ctx.App(); Xowe_wiki wiki = ctx.Wiki(); Xoae_page page = ctx.Page();
|
||||
boolean renderer_is_latex = !app.File_mgr().Math_mgr().Renderer_is_mathjax();
|
||||
byte[] math_bry = Bry_.Mid(src, xnde.Tag_open_end(), xnde.Tag_close_bgn());
|
||||
Bry_bfr tmp_bfr = wiki.Utl__bfr_mkr().Get_b512();
|
||||
try {
|
||||
math_bry = Escape_tex(tmp_bfr, !renderer_is_latex, math_bry);
|
||||
byte[] math_bry_clean = wiki.Html_mgr().Js_cleaner().Clean(wiki, math_bry, 0, math_bry.length); // check for js;
|
||||
if (math_bry_clean != null) math_bry = math_bry_clean; // js found; use clean version; DATE:2013-08-26
|
||||
boolean enabled = app.File_mgr().Math_mgr().Enabled();
|
||||
Xof_math_itm math_itm = ctx.Tmp_mgr().Math_itm();
|
||||
if (renderer_is_latex && app.File_mgr().Math_mgr().Find_itm(math_itm, page.Wiki().Domain_str(), math_bry)) {
|
||||
bfr.Add(Xoh_consts.Img_bgn);
|
||||
bfr.Add_str_u8(math_itm.Png_url().To_http_file_str());
|
||||
bfr.Add(Xoh_consts.__inline_quote);
|
||||
}
|
||||
else
|
||||
Write_for_mathjax(bfr, page, enabled, renderer_is_latex, math_bry, tmp_bfr, math_itm);
|
||||
} finally {tmp_bfr.Mkr_rls();}
|
||||
}
|
||||
private void Write_for_mathjax(Bry_bfr bfr, Xoae_page page, boolean enabled, boolean renderer_is_latex, byte[] math_bry, Bry_bfr tmp_bfr, Xof_math_itm math_itm) {
|
||||
int id = page.File_math().Count();
|
||||
Xof_math_itm new_math_itm = math_itm.Clone().Id_(id);
|
||||
|
||||
// boolean armor_math = page.Lang().Vnt_mgr().Enabled() && !renderer_is_latex; // REF.MW:LangConverter.php|armourMath
|
||||
// if (armor_math) bfr.Add(Vnt_convert_lang.Bry__armor_bgn);
|
||||
// bfr.Add_bfr_and_clear(tmp_bfr);
|
||||
// if (armor_math) bfr.Add(Vnt_convert_lang.Bry__armor_end);
|
||||
byte[] unique_bry = page.Wikie().Parser_mgr().Uniq_mgr().Add(math_bry);
|
||||
Bry_fmtr math_fmtr = renderer_is_latex ? math_fmtr_latex : math_fmtr_mathjax;
|
||||
math_fmtr.Bld_bfr_many(tmp_bfr, id, unique_bry);
|
||||
bfr.Add_bfr_and_clear(tmp_bfr);
|
||||
|
||||
if (enabled && renderer_is_latex) // NOTE: only generate images if math is enabled; otherwise "downloading" prints at bottom of screen, but no action (also a lot of file IO)
|
||||
page.File_math().Add(new_math_itm);
|
||||
}
|
||||
private static byte[] Escape_tex(Bry_bfr tmp_bfr, boolean mathjax, byte[] bry) {return Escape_tex(false, tmp_bfr, mathjax, bry, 0, bry.length);}
|
||||
private static byte[] Escape_tex(boolean write_to_bfr, Bry_bfr bfr, boolean mathjax, byte[] bry, int bgn, int end) {
|
||||
if (bry == null) return null;
|
||||
boolean dirty = write_to_bfr ? true : false; // if write_to_bfr, then mark true, else bfr.Add_mid(bry, 0, i); will write whole bry again
|
||||
byte[] escaped = null;
|
||||
for (int i = bgn; i < end; i++) {
|
||||
byte b = bry[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Lt: if (mathjax) escaped = gplx.langs.htmls.entitys.Gfh_entity_.Lt_bry; break;
|
||||
case Byte_ascii.Gt: if (mathjax) escaped = gplx.langs.htmls.entitys.Gfh_entity_.Gt_bry; break;
|
||||
// case Byte_ascii.Amp: escaped = Const_amp; break; // TOMBSTONE:never escape ampersand; PAGE:s.w:Matrix_(mathematics); DATE:2014-07-19
|
||||
// case Byte_ascii.Quote: if (mathjax) escaped = gplx.langs.htmls.Gfh_entity_.Quote_bry; break; // TOMBSTONE:do not escape quote; PAGE:s.w:Matrix_(mathematics); DATE:2014-07-19
|
||||
default:
|
||||
if (dirty || write_to_bfr)
|
||||
bfr.Add_byte(b);
|
||||
continue;
|
||||
}
|
||||
// handle lt, gt, amp, quote; everything else handled by default: continue above
|
||||
if (escaped == null) { // handle do-not-escape calls; EX: Escape(y, y, n, y);
|
||||
if (dirty || write_to_bfr)
|
||||
bfr.Add_byte(b);
|
||||
}
|
||||
else {
|
||||
if (!dirty) {
|
||||
bfr.Add_mid(bry, 0, i);
|
||||
dirty = true;
|
||||
}
|
||||
bfr.Add(escaped);
|
||||
escaped = null;
|
||||
}
|
||||
}
|
||||
if (write_to_bfr)
|
||||
return null;
|
||||
else
|
||||
return dirty ? bfr.To_bry_and_clear() : bry;
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
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.math; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.core.brys.fmtrs.*; import gplx.core.strings.*; import gplx.core.consoles.*; import gplx.core.envs.*;
|
||||
import gplx.xowa.apps.progs.*;
|
||||
public class Xof_math_mgr implements Gfo_invk {
|
||||
private static final gplx.core.security.Hash_algo md5_hash = gplx.core.security.Hash_algo_.New__md5();
|
||||
private Xoae_app app;
|
||||
public Process_adp Cmd_convert_tex_to_dvi() {return cmd_convert_tex_to_dvi;} private Process_adp cmd_convert_tex_to_dvi = new Process_adp();
|
||||
public Process_adp Cmd_convert_dvi_to_png() {return cmd_convert_dvi_to_png;} private Process_adp cmd_convert_dvi_to_png = new Process_adp();
|
||||
public void Init_by_app(Xoae_app app) {
|
||||
this.app = app;
|
||||
Xoa_prog_mgr app_mgr = app.Prog_mgr();
|
||||
cmd_convert_tex_to_dvi = app_mgr.App_convert_tex_to_dvi();
|
||||
cmd_convert_dvi_to_png = app_mgr.App_convert_dvi_to_png();
|
||||
app.Cfg().Bind_many_app(this, Cfg__enabled, Cfg__renderer);
|
||||
}
|
||||
private Io_url Make_math_dir(String wiki_key) {return app.Fsys_mgr().Root_dir().GenSubDir_nest("file", wiki_key, "math");}
|
||||
public Xof_math_html_wtr Html_wtr() {return html_wtr;} private final Xof_math_html_wtr html_wtr = new Xof_math_html_wtr();
|
||||
public void Make_itm(Xof_math_itm rv, String wiki_key, byte[] math_bry) {
|
||||
Io_url math_dir = Make_math_dir(wiki_key);
|
||||
math_bry = app.Math_subst_regy().Subst(math_bry);
|
||||
String md5 = md5_hash.Hash_bry_as_str(math_bry);
|
||||
Io_url png_fil = Make_png_fil(math_dir, md5);
|
||||
rv.Ctor(math_bry, md5, png_fil);
|
||||
}
|
||||
public boolean Find_itm(Xof_math_itm rv, String wiki_key, byte[] math_bry) {
|
||||
Make_itm(rv, wiki_key, math_bry);
|
||||
return Io_mgr.Instance.ExistsFil(rv.Png_url());
|
||||
}
|
||||
public boolean Renderer_is_mathjax() {return renderer_is_mathjax;} public void Renderer_is_mathjax_(boolean v) {renderer_is_mathjax = v;} private boolean renderer_is_mathjax = true;
|
||||
private Io_url Make_png_fil(Io_url math_dir, String hash) {
|
||||
String Math_dir_spr = math_dir.Info().DirSpr();
|
||||
tmp_sb.Clear().Add(math_dir.Raw())
|
||||
.Add(String_.CharAt(hash, 0)).Add(Math_dir_spr)
|
||||
.Add(String_.CharAt(hash, 1)).Add(Math_dir_spr)
|
||||
.Add(String_.CharAt(hash, 2)).Add(Math_dir_spr)
|
||||
.Add(hash).Add(".png");
|
||||
return Io_url_.new_fil_(tmp_sb.To_str_and_clear());
|
||||
}
|
||||
public boolean MakePng(byte[] math, String hash, Io_url png_url, String prog_fmt) {
|
||||
if (!enabled) return false;
|
||||
Io_url tmp_dir = app.Usere().Fsys_mgr().App_temp_dir().GenSubDir("math"); // cmd_convert_tex_to_dvi.Tmp_dir();
|
||||
Io_url tex_url = tmp_dir.GenSubFil("xowa_math_temp.tex");
|
||||
String latex = Latex_wrap(math);
|
||||
prog_fmt = String_.Replace(prog_fmt, "~", "~~"); // double-up ~ or else will break in progress bar
|
||||
Io_mgr.Instance.SaveFilStr(tex_url, latex);
|
||||
cmd_convert_tex_to_dvi.Prog_fmt_(prog_fmt + " tex_to_dvi: ~{process_seconds} second(s); ~{process_exe_name} ~{process_exe_args}");
|
||||
boolean pass = cmd_convert_tex_to_dvi.Run(tex_url.Raw(), tmp_dir.Xto_api()).Exit_code_pass();
|
||||
if (!pass) {
|
||||
app.Usr_dlg().Warn_many("", "tex_to_dvi.fail", "fail: tex_to_dvi: error=~{0} latex=~{1}", cmd_convert_tex_to_dvi.Rslt_out(), latex);
|
||||
}
|
||||
// NOTE: latex sometimes throws errors, but will generate .dvi; for sake of simplicity; always try to run dvipng
|
||||
Io_mgr.Instance.CreateDirIfAbsent(png_url.OwnerDir());
|
||||
cmd_convert_dvi_to_png.Prog_fmt_(prog_fmt + " dvi_to_png: ~{process_seconds} second(s); ~{process_exe_name} ~{process_exe_args}");
|
||||
pass = cmd_convert_dvi_to_png.Run(tex_url.GenNewExt(".dvi"), png_url, tmp_dir.Xto_api()).Exit_code_pass();
|
||||
if (!pass) {
|
||||
app.Usr_dlg().Warn_many("", "dvi_to_png.fail", "fail: dvi_to_png: error=~{0} latex=~{1}", cmd_convert_tex_to_dvi.Rslt_out(), latex);
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
private String_bldr tmp_sb = String_bldr_.new_();
|
||||
private String Latex_wrap(byte[] math) {return Latex_doc_fmtr.Bld_str_many(String_.Replace(String_.new_u8(math), "\n\n", "\n"));} // NOTE: remove lines that are completely blank; not sure if this is right; PAGE:en.w:Standard Model (mathematical formulation); <math>(\mathbf{1},\mathbf\n\n{1},0)</math>
|
||||
private static Bry_fmtr Latex_doc_fmtr = new Bry_fmtr()
|
||||
.Fmt_(String_.Concat_lines_nl_skip_last
|
||||
( "\\documentclass{article}"
|
||||
, "\\usepackage{amsmath}"
|
||||
, "\\usepackage{amsfonts}"
|
||||
, "\\usepackage{amssymb}"
|
||||
, "\\usepackage{color}"
|
||||
, "\\usepackage[landscape]{geometry}"
|
||||
, "\\pagestyle{empty}"
|
||||
, "\\begin{document}"
|
||||
, "\\begin{Large}"
|
||||
, "\\nonumber"
|
||||
, "$\\displaystyle"
|
||||
, "~{0}"
|
||||
, "$\\end{Large}"
|
||||
, "\\end{document}"
|
||||
));
|
||||
public boolean Enabled() {return enabled;} public Xof_math_mgr Enabled_(boolean v) {enabled = v; return this;} private boolean enabled = true;
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Cfg__enabled)) enabled = m.ReadYn("v");
|
||||
else if (ctx.Match(k, Cfg__renderer)) renderer_is_mathjax = String_.Eq(m.ReadStr("v"), "mathjax");
|
||||
else return Gfo_invk_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
private static final String
|
||||
Cfg__enabled = "xowa.addon.math.enabled"
|
||||
, Cfg__renderer = "xowa.addon.math.renderer"
|
||||
;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
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.math; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.xowa.parsers.*; import gplx.xowa.parsers.xndes.*;
|
||||
public class Xomath_core implements Gfo_invk {
|
||||
private final Xomath_html_wtr html_wtr = new Xomath_html_wtr();
|
||||
public boolean Enabled() {return enabled;} private boolean enabled = true;
|
||||
public boolean Renderer_is_mathjax() {return renderer_is_mathjax;} private boolean renderer_is_mathjax = true;
|
||||
public void Renderer_is_mathjax_(boolean v) {renderer_is_mathjax = v;} // TEST:
|
||||
public void Init_by_wiki(Xow_wiki wiki) {
|
||||
wiki.App().Cfg().Bind_many_wiki(this, wiki, Cfg__enabled, Cfg__renderer);
|
||||
}
|
||||
public void Write(Bry_bfr bfr, Xop_ctx ctx, Xop_xnde_tkn xnde, byte[] src) {
|
||||
html_wtr.Write(bfr, ctx, xnde, src, !renderer_is_mathjax, enabled);
|
||||
}
|
||||
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
|
||||
if (ctx.Match(k, Cfg__enabled)) enabled = m.ReadYn("v");
|
||||
else if (ctx.Match(k, Cfg__renderer)) renderer_is_mathjax = String_.Eq(m.ReadStr("v"), "mathjax");
|
||||
else return Gfo_invk_.Rv_unhandled;
|
||||
return this;
|
||||
}
|
||||
private static final String
|
||||
Cfg__enabled = "xowa.addon.math.enabled"
|
||||
, Cfg__renderer = "xowa.addon.math.renderer";
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
/*
|
||||
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.math; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.core.envs.*;
|
||||
import gplx.langs.htmls.*; import gplx.langs.htmls.entitys.*; import gplx.xowa.htmls.core.htmls.*;
|
||||
import gplx.xowa.parsers.*; import gplx.xowa.parsers.xndes.*;
|
||||
class Xomath_html_wtr {
|
||||
private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(512);
|
||||
private final Xomath_subst_mgr subst_mgr = new Xomath_subst_mgr();
|
||||
private final gplx.core.security.Hash_algo md5_wkr = gplx.core.security.Hash_algo_.New__md5();
|
||||
private final Bry_fmt
|
||||
fmt__latex = Bry_fmt.Auto( "<img id='xowa_math_img_~{math_idx}' src='' width='' height=''/><span id='xowa_math_txt_~{math_idx}'>~{math_text}</span>")
|
||||
, fmt__mathjax = Bry_fmt.Auto("<span id='xowa_math_txt_~{math_idx}'>~{math_text}</span>");
|
||||
|
||||
public void Write(Bry_bfr bfr, Xop_ctx ctx, Xop_xnde_tkn xnde, byte[] src, boolean is_latex, boolean enabled) {
|
||||
// init vars
|
||||
Xoae_app app = ctx.App(); Xowe_wiki wiki = ctx.Wiki(); Xoae_page page = ctx.Page();
|
||||
|
||||
// get math_bry; also, escape if mathjax and check js
|
||||
byte[] math_bry = Bry_.Mid(src, xnde.Tag_open_end(), xnde.Tag_close_bgn());
|
||||
if (!is_latex) math_bry = Escape_for_mathjax(tmp_bfr, math_bry);
|
||||
byte[] scrubbed_js = wiki.Html_mgr().Js_cleaner().Clean(wiki, math_bry, 0, math_bry.length);
|
||||
if (scrubbed_js != null) math_bry = scrubbed_js; // js found; use clean version; DATE:2013-08-26
|
||||
|
||||
// if latex, (a) calc md5 and url; (b) write <img> or add to queue
|
||||
int uid = page.File_math().Count();
|
||||
if (is_latex) {
|
||||
byte[] math_src = subst_mgr.Subst(math_bry);
|
||||
byte[] md5 = md5_wkr.Hash_bry_as_bry(math_src);
|
||||
|
||||
// make url
|
||||
byte dir_spr = Op_sys.Cur().Fsys_dir_spr_byte();
|
||||
tmp_bfr
|
||||
.Add_str_u8(app.Fsys_mgr().Root_dir().GenSubDir_nest("file", wiki.Domain_str(), "math").Raw()) // add dir
|
||||
.Add_byte(md5[0]).Add_byte(dir_spr)
|
||||
.Add_byte(md5[1]).Add_byte(dir_spr)
|
||||
.Add_byte(md5[2]).Add_byte(dir_spr)
|
||||
.Add(md5).Add_str_a7(".png");
|
||||
Io_url png = Io_url_.new_fil_(tmp_bfr.To_str_and_clear());
|
||||
|
||||
// if url exists, just write <img> directly
|
||||
if (Io_mgr.Instance.ExistsFil(png)) {
|
||||
Gfh_tag_.Bld_lhs_bgn(bfr, Gfh_tag_.Bry__img);
|
||||
Gfh_atr_.Add(bfr, Gfh_atr_.Bry__src, png.To_http_file_bry());
|
||||
Gfh_tag_.Bld_lhs_end_nde(bfr);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// if enabled, add to pending queue; NOTE: must check enabled, else "downloading" prints at bottom of screen; also avoids file IO
|
||||
if (enabled)
|
||||
page.File_math().Add(new Xomath_latex_itm(uid, math_src, md5, png));
|
||||
}
|
||||
}
|
||||
|
||||
// write html: <span>math_expr</math>
|
||||
byte[] unique_bry = wiki.Parser_mgr().Uniq_mgr().Add(math_bry);
|
||||
Bry_fmt fmt = is_latex ? fmt__latex : fmt__mathjax;
|
||||
fmt.Bld_many(tmp_bfr, uid, unique_bry);
|
||||
bfr.Add_bfr_and_clear(tmp_bfr);
|
||||
}
|
||||
private static byte[] Escape_for_mathjax(Bry_bfr tmp, byte[] src) {
|
||||
if (src == null) return null;
|
||||
boolean dirty = false;
|
||||
byte[] escaped = null;
|
||||
|
||||
// loop bytes
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
byte b = src[i];
|
||||
switch (b) {
|
||||
case Byte_ascii.Lt: escaped = Gfh_entity_.Lt_bry; break;
|
||||
case Byte_ascii.Gt: escaped = Gfh_entity_.Gt_bry; break;
|
||||
// case Byte_ascii.Amp: escaped = Const_amp; break; // TOMBSTONE:do not escape ampersand; PAGE:s.w:Matrix_(mathematics); DATE:2014-07-19
|
||||
// case Byte_ascii.Quote: escaped = Gfh_entity_.Quote_bry; break; // TOMBSTONE:do not escape quote; PAGE:s.w:Matrix_(mathematics); DATE:2014-07-19
|
||||
default:
|
||||
if (dirty)
|
||||
tmp.Add_byte(b);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add escaped; note that only lt / gt will enter here; all other bytes are handled by "default / continue" above
|
||||
if (!dirty) {
|
||||
dirty = true;
|
||||
tmp.Add_mid(src, 0, i);
|
||||
}
|
||||
tmp.Add(escaped);
|
||||
escaped = null;
|
||||
}
|
||||
return dirty ? tmp.To_bry_and_clear() : src;
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
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.math; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*;
|
||||
import gplx.core.envs.*;
|
||||
public class Xomath_latex_bldr {
|
||||
public static void Async(Xoae_app app, Xoae_page page, gplx.xowa.guis.cbks.js.Xog_js_wkr js_wkr) {
|
||||
// get len; if 0, exit
|
||||
Gfo_usr_dlg usr_dlg = app.Usr_dlg();
|
||||
int len = page.File_math().Count();
|
||||
if (len == 0) return;
|
||||
|
||||
usr_dlg.Prog_one("", "", "page.async.math; count=~{0}", len);
|
||||
// loop each item
|
||||
for (int i = 0; i < len; ++i) {
|
||||
// if canceled, exit
|
||||
if (usr_dlg.Canceled()) {
|
||||
usr_dlg.Prog_none("", "", "");
|
||||
app.Log_wtr().Queue_enabled_(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// get itm and generate png
|
||||
Xomath_latex_itm itm = (Xomath_latex_itm)page.File_math().Get_at(i);
|
||||
String queue_msg = usr_dlg.Prog_many("", "", "generating math ~{0} of ~{1}: ~{2}", i + List_adp_.Base1, len, itm.Src());
|
||||
Generate_png(app, itm.Src(), itm.Md5(), itm.Png(), queue_msg);
|
||||
|
||||
// get png size; update <img> src; delete <span>
|
||||
gplx.gfui.SizeAdp size = app.File_mgr().Img_mgr().Wkr_query_img_size().Exec(itm.Png());
|
||||
js_wkr.Html_img_update("xowa_math_img_" + itm.Uid(), itm.Png().To_http_file_str(), size.Width(), size.Height());
|
||||
js_wkr.Html_elem_delete("xowa_math_txt_" + itm.Uid());
|
||||
}
|
||||
catch (Exception e) {
|
||||
usr_dlg.Warn_many("", "", "page.async.math: page=~{0} err=~{1}", page.Ttl().Raw(), Err_.Message_gplx_log(e));
|
||||
}
|
||||
}
|
||||
page.File_math().Clear();
|
||||
}
|
||||
private static void Generate_png(Xoae_app app, byte[] math, byte[] hash, Io_url png_url, String prog_fmt) {
|
||||
// init
|
||||
Io_url tmp_dir = app.Usere().Fsys_mgr().App_temp_dir().GenSubDir("math");
|
||||
Io_url tex_fil = tmp_dir.GenSubFil("xowa_math_temp.tex");
|
||||
|
||||
// make tex_bry
|
||||
byte[] tex_doc = Bry_.Replace(math, Bry_.new_a7("\n\n"), Byte_ascii.Nl_bry); // remove completely blank lines; not sure if this is right; PAGE:en.w:Standard Model_(mathematical_formulation); EX:<math>(\mathbf{1},\mathbf\n\n{1},0)</math>
|
||||
tex_doc = fmt__latex_doc.Bld_many_to_bry(Bry_bfr_.New(), tex_doc);
|
||||
Io_mgr.Instance.SaveFilBry(tex_fil, tex_doc);
|
||||
|
||||
// run tex to dvi
|
||||
Process_adp tex_to_dvi_cmd = app.Prog_mgr().App__tex_to_dvi();
|
||||
prog_fmt = String_.Replace(prog_fmt, "~", "~~"); // double-up ~ or else will break in progress bar
|
||||
tex_to_dvi_cmd.Prog_fmt_(prog_fmt + " tex_to_dvi: ~{process_seconds} second(s); ~{process_exe_name} ~{process_exe_args}");
|
||||
boolean pass = tex_to_dvi_cmd.Run(tex_fil.Raw(), tmp_dir.Xto_api()).Exit_code_pass();
|
||||
if (!pass)
|
||||
app.Usr_dlg().Warn_many("", "tex_to_dvi.fail", "fail: tex_to_dvi: error=~{0} latex=~{1}", tex_to_dvi_cmd.Rslt_out(), tex_doc);
|
||||
|
||||
// run dvi to png; NOTE: latex sometimes throws errors, but will generate .dvi; for sake of simplicity; always try to run dvipng
|
||||
Io_mgr.Instance.CreateDirIfAbsent(png_url.OwnerDir());
|
||||
Process_adp dvi_to_png_cmd = app.Prog_mgr().App__dvi_to_png();
|
||||
dvi_to_png_cmd.Prog_fmt_(prog_fmt + " dvi_to_png: ~{process_seconds} second(s); ~{process_exe_name} ~{process_exe_args}");
|
||||
pass = dvi_to_png_cmd.Run(tex_fil.GenNewExt(".dvi"), png_url, tmp_dir.Xto_api()).Exit_code_pass();
|
||||
if (!pass)
|
||||
app.Usr_dlg().Warn_many("", "dvi_to_png.fail", "fail: dvi_to_png: error=~{0} latex=~{1}", dvi_to_png_cmd.Rslt_out(), tex_doc);
|
||||
}
|
||||
private static final Bry_fmt fmt__latex_doc = Bry_fmt.Auto(Bry_.new_a7(String_.Concat_lines_nl_skip_last
|
||||
( "\\documentclass{article}"
|
||||
, "\\usepackage{amsmath}"
|
||||
, "\\usepackage{amsfonts}"
|
||||
, "\\usepackage{amssymb}"
|
||||
, "\\usepackage{color}"
|
||||
, "\\usepackage[landscape]{geometry}"
|
||||
, "\\pagestyle{empty}"
|
||||
, "\\begin{document}"
|
||||
, "\\begin{Large}"
|
||||
, "\\nonumber"
|
||||
, "$\\displaystyle"
|
||||
, "~{0}"
|
||||
, "$\\end{Large}"
|
||||
, "\\end{document}"
|
||||
)));
|
||||
}
|
Loading…
Reference in new issue