/*
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.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}"
)));
}