1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

Math: Add math.log_check command

This commit is contained in:
gnosygnu
2017-01-03 11:27:48 -05:00
parent 87ee507220
commit e69c557595
9 changed files with 187 additions and 22 deletions

View File

@@ -0,0 +1,29 @@
/*
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.addons.*;
import gplx.xowa.bldrs.wkrs.*;
public class Xomath_addon implements Xoax_addon_itm, Xoax_addon_itm__bldr {
public Xob_cmd[] Bldr_cmds() {
return new Xob_cmd[]
{ gplx.xowa.xtns.math.bldrs.Xomath_check_cmd.Prototype
};
}
public String Addon__key() {return "xowa.parsers.math";}
}

View File

@@ -0,0 +1,33 @@
/*
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.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.math.*;
import gplx.xowa.bldrs.*; import gplx.xowa.bldrs.wkrs.*;
public class Xomath_check_cmd extends Xob_cmd__base {
public Xomath_check_cmd(Xob_bldr bldr, Xowe_wiki wiki) {super(bldr, wiki);}
@Override public void Cmd_run() {
wiki.Init_assert();
new Xomath_check_mgr().Exec(wiki);
}
@Override public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
return super.Invk(ctx, ikey, k, m);
}
@Override public String Cmd_key() {return BLDR_CMD_KEY;} private static final String BLDR_CMD_KEY = "math.log_check";
public static final Xob_cmd Prototype = new Xomath_check_cmd(null, null);
@Override public Xob_cmd Cmd_clone(Xob_bldr bldr, Xowe_wiki wiki) {return new Xomath_check_cmd(bldr, wiki);}
}

View File

@@ -0,0 +1,97 @@
/*
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.bldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.math.*;
import gplx.dbs.*;
import gplx.xowa.bldrs.*; import gplx.xowa.parsers.logs.*;
import gplx.xowa.xtns.math.texvcs.*; import gplx.xowa.xtns.math.texvcs.tkns.*;
class Xomath_check_mgr {
private int count_total, count_xnde_invalid, count_xnde_w_atrs, count_texvc_invalid, count_texvc_adjusted;
public void Exec(Xowe_wiki wiki) {
// get db, conn, rdr
Xob_db_file log_db = Xob_db_file.New__file_make(wiki.Fsys_mgr().Root_dir());
Db_conn log_conn = log_db.Conn();
Db_rdr rdr = log_conn.Stmt_sql("SELECT * FROM " + Xop_log_basic_tbl.TBL_NAME).Exec_select__rls_auto();
// loop
try {
while (rdr.Move_next()) {
// get page_id, src
int page_id = rdr.Read_int(Xop_log_basic_tbl.Fld_page_id);
byte[] src = rdr.Read_bry_by_str(Xop_log_basic_tbl.Fld_src_str);
count_total++;
src = Assert_flanking_math_ndes(page_id, src);
if (src == null) {
count_xnde_invalid++;
continue;
}
Check_texvc(page_id, src);
}
} finally {rdr.Rls();}
Gfo_usr_dlg_.Instance.Note_many("", "", "done: total=~{0}, xnde_invalid=~{1} xnde_w_atrs=~{2} texvc_invalid=~{3} texvc_adjusted=~{4}"
, count_total, count_xnde_invalid, count_xnde_w_atrs, count_texvc_invalid, count_texvc_adjusted);
}
private final byte[] math_lhs_bry = Bry_.new_a7("<math"), math_rhs_bry = Bry_.new_a7("</math>"), nl_repl_bry = Bry_.new_a7(" ");
private byte[] Assert_flanking_math_ndes(int page_id, byte[] src) {
// assert "<math" at start
if (!Bry_.Has_at_bgn(src, math_lhs_bry)) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "math.check:xnde_invalid b/c '<math' is not at beginning; page_id=~{0}, src=~{1}", page_id, Bry_.Replace(src, Byte_ascii.Nl_bry, nl_repl_bry));
return null;
}
// assert "</math>" at end
if (!Bry_.Has_at_end(src, math_rhs_bry)) {
Gfo_usr_dlg_.Instance.Warn_many("", "", "math.check:xnde_invalid b/c '</math>' is not at end; page_id=~{0}, src=~{1}", page_id, Bry_.Replace(src, Byte_ascii.Nl_bry, nl_repl_bry));
return null;
}
// assert "<math>"
int math_lhs_end = Bry_find_.Find_fwd(src, Byte_ascii.Gt_bry, math_lhs_bry.length);
if (math_lhs_end != math_lhs_bry.length) {
count_xnde_w_atrs++;
Gfo_usr_dlg_.Instance.Log_many("", "", "math.check:xnde_w_atrs; page_id=~{0}, src=~{1}", page_id, Bry_.Replace(src, Byte_ascii.Nl_bry, nl_repl_bry));
}
// remove "<math>", "</math>"
return Bry_.Mid(src, math_lhs_end + 1, src.length - math_rhs_bry.length);
}
private final Texvc_parser parser = new Texvc_parser();
private final Texvc_checker checker = new Texvc_checker();
private final Texvc_ctx ctx = new Texvc_ctx();
private final Bry_bfr tmp_bfr = Bry_bfr_.New();
private void Check_texvc(int page_id, byte[] src) {
try {
Texvc_root root = new Texvc_root();
ctx.Clear();
parser.Parse(ctx, root, src);
checker.Check(src, root);
tmp_bfr.Clear();
root.Print_tex_bry(tmp_bfr, src, 0);
byte[] texvc_bry = tmp_bfr.To_bry_and_clear();
if (!Bry_.Eq(src, texvc_bry)) {
count_texvc_adjusted++;
Gfo_usr_dlg_.Instance.Log_many("", "", "math.check:texvc_adjusted; page_id=~{0}, src=~{1} texvc=~{2}", page_id, Bry_.Replace(src, Byte_ascii.Nl_bry, nl_repl_bry), Bry_.Replace(texvc_bry, Byte_ascii.Nl_bry, nl_repl_bry));
}
} catch (Exception exc) {
count_texvc_invalid++;
Gfo_usr_dlg_.Instance.Warn_many("", "", "math.check:texvc_invalid; page_id=~{0}, src=~{1} err=~{2}", page_id, Bry_.Replace(src, Byte_ascii.Nl_bry, nl_repl_bry), Err_.Message_gplx_log(exc));
}
}
}

View File

@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.math.texvcs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.math.*;
import gplx.xowa.xtns.math.texvcs.tkns.*; import gplx.xowa.xtns.math.texvcs.funcs.*;
class Texvc_checker {
public class Texvc_checker {
private final List_adp func_stack = List_adp_.New();
private Texvc_root root; private int root_idx, root_len;
private boolean fail;

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.xtns.math.texvcs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.math.*;
import org.junit.*; import gplx.xowa.xtns.math.texvcs.tkns.*; import gplx.xowa.xtns.math.texvcs.funcs.*;
public class Texvc_checker_tst {
private final Texvc_checker_fxt fxt = new Texvc_checker_fxt();
private final Texvc_checker_fxt fxt = new Texvc_checker_fxt();
@Before public void init() {fxt.Clear();}
@Test public void Mathrm_tkns() {
fxt.Test_check("\\mathrm\\frac{a}{b}"
@@ -40,7 +40,7 @@ public class Texvc_checker_tst {
fxt.Test_check("\\frac a b" , "\\frac a b");
}
}
class Texvc_checker_fxt extends Texvc_parser_fxt { private final Texvc_checker checker = new Texvc_checker();
class Texvc_checker_fxt extends Texvc_parser_fxt { private final Texvc_checker checker = new Texvc_checker();
public void Test_check(String src_str, Texvc_tkn... expd_tkns) {
byte[] src_bry = Bry_.new_u8(src_str);
Texvc_root actl_root = this.Exec_parse(src_bry);

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.xtns.math.texvcs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.math.*;
import gplx.core.btries.*;
import gplx.xowa.xtns.math.texvcs.lxrs.*; import gplx.xowa.xtns.math.texvcs.tkns.*;
class Texvc_parser {
public class Texvc_parser {
private final Btrie_rv trv = new Btrie_rv();
public void Parse(Texvc_ctx ctx, Texvc_root root, byte[] src) {
int src_len = src.length;

View File

@@ -18,9 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.xtns.math.texvcs.tkns; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.math.*; import gplx.xowa.xtns.math.texvcs.*;
import gplx.core.primitives.*;
public class Texvc_root implements Texvc_tkn {
private final Texvc_regy_tkn regy_tkn;
private final Texvc_regy_nde regy_nde = new Texvc_regy_nde();
private final Texvc_regy_sub regy_sub = new Texvc_regy_sub();
private final Texvc_regy_tkn regy_tkn;
private final Texvc_regy_nde regy_nde = new Texvc_regy_nde();
private final Texvc_regy_sub regy_sub = new Texvc_regy_sub();
public Texvc_root() {
this.regy_tkn = new Texvc_regy_tkn(this);
}