init: WordFileParse docx→HTML 解析服务(含 Word EQ 域公式修复)
服务:Spring Boot 3.2 + docx4j 8.3.9,POST /api/v3/server_office_file/file/parse
接受 .docx,返回 HTML(公式 → LaTeX,图片 → RustFS 外链)
公式支持三类来源:
- OMML(Word 2007+ 公式) → Python omml_mathml2latex
- MathType OLE 对象 → Ruby mathtype2mathml → MathML → LaTeX
- Word EQ 域(老教辅主力) → EqToLatexUtil(本次新增)
本次改动:
1. 新增 java-svc/.../core/EqToLatexUtil.java:
移植自 jby backend-services office-core,EQ 语法 → LaTeX
(\f→\dfrac、\r→\sqrt、\i→\int/\sum/\prod、\s→^{}/_{}、\b→\left\right、
\a→array、\x→\boxed/\overline、\o\al 堆叠、圈码、化学符号、极限、连等式)
品牌标记 JBYU* → WPU*,与采集端一致
2. CtoMathFinder:接上 EQ 分支(原为 not-ported 桩),域代码经
EqToLatexUtil.convert 转 LaTeX 写入 eqLatexMap(WPEQNUM 占位符)
3. WordParseUtil.dealPlaceholder:EQ 的 LaTeX 同样加 \( \) 包裹
(原先因 WPEQNUM 例外不加包裹,前端/MathJax 不渲染)
修前症状:教辅 Word 里分式/方程组/上下标整段丢失(如 {−1/3, 1} 变成 {-,1})
修后实测:46 份教辅 2908 处 EQ 域全部还原,公式总数 2954 处、零未包裹残留
安全:application.yml(含 RustFS 密钥)不入库,提供 application.yml.example;
OssService 的 @Value 默认密钥已清空
This commit is contained in:
501
java-src/utils/LatexUtil.java
Normal file
501
java-src/utils/LatexUtil.java
Normal file
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* cn.hutool.core.thread.ThreadUtil
|
||||
* com.alibaba.fastjson.JSON
|
||||
* com.alibaba.fastjson.JSONObject
|
||||
* com.alibaba.fastjson.TypeReference
|
||||
* com.alibaba.fastjson.parser.Feature
|
||||
* com.fasterxml.jackson.databind.ObjectMapper
|
||||
* com.fasterxml.jackson.databind.SerializationFeature
|
||||
* com.jby.common.util.FileUtil
|
||||
* com.jby.common.util.HttpClientUtil
|
||||
* com.jby.common.util.UniqueUtil
|
||||
* fmath.conversion.ConvertFromLatexToMathML
|
||||
* fmath.conversion.ConvertFromMathMLToLatex
|
||||
* org.apache.commons.collections4.MapUtils
|
||||
* org.apache.commons.exec.CommandLine
|
||||
* org.apache.commons.exec.DefaultExecutor
|
||||
* org.apache.commons.exec.ExecuteStreamHandler
|
||||
* org.apache.commons.exec.PumpStreamHandler
|
||||
* org.apache.commons.lang3.StringUtils
|
||||
* org.scilab.forge.jlatexmath.TeXFormula
|
||||
* org.scilab.forge.jlatexmath.TeXIcon
|
||||
* org.slf4j.Logger
|
||||
* org.slf4j.LoggerFactory
|
||||
* org.springframework.beans.factory.annotation.Autowired
|
||||
* org.springframework.stereotype.Component
|
||||
*/
|
||||
package com.jby.officecore.utils;
|
||||
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.alibaba.fastjson.parser.Feature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.jby.common.util.FileUtil;
|
||||
import com.jby.common.util.HttpClientUtil;
|
||||
import com.jby.common.util.UniqueUtil;
|
||||
import com.jby.officecore.config.OfficeCoreConfig;
|
||||
import com.jby.officecore.domain.bo.LatexInfoBO;
|
||||
import com.jby.officecore.utils.MapUtil;
|
||||
import fmath.conversion.ConvertFromLatexToMathML;
|
||||
import fmath.conversion.ConvertFromMathMLToLatex;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JLabel;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.ExecuteStreamHandler;
|
||||
import org.apache.commons.exec.PumpStreamHandler;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.scilab.forge.jlatexmath.TeXFormula;
|
||||
import org.scilab.forge.jlatexmath.TeXIcon;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class LatexUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(LatexUtil.class);
|
||||
private static final String LATEX_PATTERN_STR = "\\$\\$(.*?)\\$\\$|\\\\\\((.*?)\\\\\\)";
|
||||
private static final Pattern LATEX_PATTERN = Pattern.compile("\\$\\$(.*?)\\$\\$|\\\\\\((.*?)\\\\\\)");
|
||||
private static final String LATEX_SELF_PATTERN_STR = "(?<=\\$\\$)(.*?)(?=\\$\\$)|(?<=\\\\\\()(.*?)(?=\\\\\\))";
|
||||
private static final Pattern LATEX_SELF_PATTERN = Pattern.compile("(?<=\\$\\$)(.*?)(?=\\$\\$)|(?<=\\\\\\()(.*?)(?=\\\\\\))");
|
||||
private static final Pattern CHINESE_PATTERN = Pattern.compile("[\u4e00-\u9fa5]");
|
||||
private static final String LATEX_REPLACE = "@@@";
|
||||
public static final String LATEX_SPLIT = "###";
|
||||
private static OfficeCoreConfig officeCoreConfig;
|
||||
private static final ObjectMapper MAPPER;
|
||||
|
||||
@Autowired
|
||||
public void setOfficeCoreConfig(OfficeCoreConfig officeCoreConfig) {
|
||||
LatexUtil.officeCoreConfig = officeCoreConfig;
|
||||
}
|
||||
|
||||
public static String dealLatexContent(String content, Map<String, LatexInfoBO> latexMap, Boolean newTransferVersion) {
|
||||
String result = content.replaceAll(LATEX_PATTERN_STR, LATEX_REPLACE);
|
||||
Matcher mather = LatexUtil.getLatexMatcher(content);
|
||||
while (mather.find()) {
|
||||
String latex = mather.group();
|
||||
String latexKey = "";
|
||||
if (StringUtils.isNotBlank((CharSequence)latex)) {
|
||||
String cleanLatex;
|
||||
Matcher matcher;
|
||||
latex = latex.replaceAll(" ", " ");
|
||||
latex = latex.replaceAll(">", ">");
|
||||
latex = latex.replaceAll("<", "<");
|
||||
latex = latex.replace("<br/>", "").replace("\\ ", "");
|
||||
if (Boolean.TRUE.equals(newTransferVersion)) {
|
||||
latexKey = latex.replaceAll(LATEX_SELF_PATTERN_STR, UniqueUtil.getUuid());
|
||||
matcher = LATEX_SELF_PATTERN.matcher(latex);
|
||||
if (matcher.find() && StringUtils.isNotBlank((CharSequence)(cleanLatex = matcher.group()))) {
|
||||
latex = cleanLatex;
|
||||
}
|
||||
} else {
|
||||
latex = LatexUtil.formatLatex(latex);
|
||||
latexKey = latex.replaceAll(LATEX_SELF_PATTERN_STR, UniqueUtil.getUuid());
|
||||
matcher = LATEX_SELF_PATTERN.matcher(latex);
|
||||
if (matcher.find() && StringUtils.isNotBlank((CharSequence)(cleanLatex = matcher.group()))) {
|
||||
latex = cleanLatex;
|
||||
}
|
||||
latex = LatexUtil.wrapLatexExpressionWithBraces(latex);
|
||||
}
|
||||
latexMap.put(latexKey, new LatexInfoBO().setLatexKey(latexKey).setLatex(latex));
|
||||
}
|
||||
result = StringUtils.replaceOnce((String)result, (String)LATEX_REPLACE, (String)(" ###" + latexKey + LATEX_SPLIT + " "));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String wrapLatexExpressionWithBraces(String latex) {
|
||||
String[] simpleOperators;
|
||||
String[] limitsOperators;
|
||||
if (StringUtils.isBlank((CharSequence)latex)) {
|
||||
return latex;
|
||||
}
|
||||
latex = latex.replaceAll("\\\\xleftrightarrow\\[([^\\]]+)\\]\\{([^}]+)\\}", "\\\\underset{$1}{\\\\overset{$2}{\\\\longleftrightarrow}}");
|
||||
latex = latex.replaceAll("\\\\xrightleftharpoons\\[([^\\]]+)\\]\\{([^}]+)\\}", "\\\\underset{$1}{\\\\overset{$2}{\\\\mathop{\\\\rightleftharpoons }}}\\\\,");
|
||||
latex = latex.replaceAll("\\\\enclose\\{madruwb\\}\\{([^}]+)\\}", "\\\\left. \\{\\\\underline \\{$1\\}\\} \\\\right|");
|
||||
latex = latex.replaceAll("\\\\enclose\\{actuarial\\}\\{([^}]+)\\}", "\\\\left. \\{\\\\overline \\{$1\\}\\} \\\\right|");
|
||||
String[] operators = new String[]{"prod", "coprod", "sum", "int", "bigcap", "bigcup", "iint", "iiint", "oint"};
|
||||
for (String op : limitsOperators = new String[]{"prod", "coprod", "sum", "bigcap", "bigcup", "iint", "iiint", "oint"}) {
|
||||
latex = latex.replaceAll("(\\\\displaystyle\\\\" + op + "\\\\limits(?:\\s*_\\{[^}]*\\})?(?:\\s*\\^\\{[^}]*\\}|\\s*_\\{[^}]*\\})\\s*)([a-zA-Z0-9]+)(?![a-zA-Z0-9])", "$1{$2}");
|
||||
}
|
||||
for (String op : operators) {
|
||||
latex = latex.replaceAll("(\\\\displaystyle\\\\" + op + "(?:\\s*_\\{[^}]*\\})?(?:\\s*\\^\\{[^}]*\\}|\\s*_\\{[^}]*\\})\\s*)([a-zA-Z0-9]+)(?![a-zA-Z0-9])", "$1{$2}");
|
||||
}
|
||||
for (String op : simpleOperators = new String[]{"iint", "iiint", "oint"}) {
|
||||
latex = latex.replaceAll("(\\\\" + op + "\\s*_\\{[^}]*\\}\\s*)([a-zA-Z0-9]+)(?![a-zA-Z0-9])", "$1{$2}");
|
||||
}
|
||||
return latex;
|
||||
}
|
||||
|
||||
public static String formatLatex(String latex) {
|
||||
if (StringUtils.isBlank((CharSequence)latex)) {
|
||||
return latex;
|
||||
}
|
||||
StringBuilder latexBuilder = new StringBuilder();
|
||||
try {
|
||||
latex = latex.replace("leqslant", "leq");
|
||||
latex = latex.replace("geqslant", "geq");
|
||||
boolean inChinese = false;
|
||||
char[] cArray = latex.toCharArray();
|
||||
int n = cArray.length;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Character c = Character.valueOf(cArray[i]);
|
||||
Matcher chineseMatch = CHINESE_PATTERN.matcher(c.toString());
|
||||
if (chineseMatch.find()) {
|
||||
if (inChinese) {
|
||||
latexBuilder.append(c);
|
||||
continue;
|
||||
}
|
||||
latexBuilder.append("\\mbox{").append(c);
|
||||
inChinese = true;
|
||||
continue;
|
||||
}
|
||||
if (inChinese) {
|
||||
inChinese = false;
|
||||
latexBuilder.append("}");
|
||||
}
|
||||
latexBuilder.append(c);
|
||||
}
|
||||
if (inChinese) {
|
||||
latexBuilder.append("}");
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("formatLatex error, latex:{}, result:{}", new Object[]{latex, latexBuilder.toString(), e});
|
||||
}
|
||||
return latexBuilder.toString();
|
||||
}
|
||||
|
||||
public static void latexToImg(String latex, String path) {
|
||||
try {
|
||||
TeXFormula formula = new TeXFormula(latex);
|
||||
TeXIcon icon = formula.createTeXIcon(0, 40.0f);
|
||||
icon.setInsets(new Insets(5, 5, 5, 5));
|
||||
BufferedImage bImg = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), 6);
|
||||
Graphics2D g2d = bImg.createGraphics();
|
||||
g2d.setColor(Color.white);
|
||||
g2d.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight());
|
||||
JLabel jl = new JLabel();
|
||||
jl.setForeground(new Color(0, 0, 0));
|
||||
icon.paintIcon((java.awt.Component)jl, (Graphics)g2d, 0, 0);
|
||||
File out = FileUtil.getFile((String)path);
|
||||
ImageIO.write((RenderedImage)bImg, "png", out);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("latexToImg error\uff1alatex={}, path={}, ", new Object[]{latex, path, e});
|
||||
}
|
||||
}
|
||||
|
||||
public static void latexToMathML(Map<String, LatexInfoBO> latexMap) {
|
||||
Collection<Map<String, LatexInfoBO>> maps = MapUtil.splitMap(latexMap, 500);
|
||||
HashMap convertMap = new HashMap();
|
||||
maps.forEach(map -> {
|
||||
if (MapUtils.isEmpty((Map)map)) {
|
||||
return;
|
||||
}
|
||||
HashMap convertParam = new HashMap();
|
||||
String result = null;
|
||||
try {
|
||||
HashMap param = new HashMap();
|
||||
map.values().forEach(info -> param.put(info.getLatexKey(), info.getLatex()));
|
||||
convertParam.put("latex", param);
|
||||
long ts = System.currentTimeMillis();
|
||||
result = HttpClientUtil.doPost((String)officeCoreConfig.getForeLatexToMathMlApi(), (String)JSON.toJSONString(convertParam));
|
||||
log.info("latex\u8f6cmathML\u8c03\u7528python\u63a5\u53e3\u6210\u529f, \u8017\u65f6\uff1a{}\u6beb\u79d2", (Object)(System.currentTimeMillis() - ts));
|
||||
Map convertResult = (Map)HttpClientUtil.parseResult((String)result, (TypeReference)new TypeReference<Map<String, String>>(){});
|
||||
if (MapUtils.isNotEmpty((Map)convertResult)) {
|
||||
convertMap.putAll(convertResult);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("latex\u8f6cmathML\u8c03\u7528python\u63a5\u53e3\u5f02\u5e38, param:{}, result:{}", new Object[]{JSON.toJSONString(convertParam), result, e});
|
||||
}
|
||||
});
|
||||
latexMap.values().forEach(info -> {
|
||||
String mathMl = (String)convertMap.get(info.getLatexKey());
|
||||
if (StringUtils.isBlank((CharSequence)mathMl)) {
|
||||
try {
|
||||
mathMl = LatexUtil.convertFromLatexToMathML(info.getLatex());
|
||||
log.info("latex\u8f6cmathML\u672c\u5730\u8f6c\u6362,latex:{}", (Object)info.getLatex());
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("latex\u8f6cmathML\u672c\u5730\u8f6c\u6362\u5f02\u5e38, info:{}", (Object)JSON.toJSONString((Object)info), (Object)e);
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank((CharSequence)mathMl)) {
|
||||
mathMl = mathMl.replaceAll("(?i)⟂", "⊥");
|
||||
}
|
||||
info.setMathMl(mathMl);
|
||||
});
|
||||
}
|
||||
|
||||
private static String convertFromLatexToMathML(String latex) {
|
||||
String mathMl = ConvertFromLatexToMathML.convertToMathML((String)latex);
|
||||
mathMl = mathMl.replace("\n", "").replaceFirst("<math", "<math xmlns=\"http://www.w3.org/1998/Math/MathML\" ").replace("∗", "\u2217").replace("∴", "\u2234").replace("∝", "\u221d").replace("≈", "\u2248").replace("≠", "\u2260").replace("∋", "\u220b").replace("∈", "\u2208").replace("∉", "\u2209").replace("α", "\u03b1").replace("β", "\u03b2").replace("γ", "\u03b3").replace("δ", "\u03b4").replace("ϵ", "\u03b5").replace("ε", "\u03f5").replace("ζ", "\u03b6").replace("η", "\u03b7").replace("θ", "\u03b8").replace("ϑ", "\u03d1").replace("ι", "\u03b9").replace("κ", "\u03ba").replace("λ", "\u03bb").replace("μ", "\u03bc").replace("ν", "\u03bd").replace("ρ", "\u03c1").replace("σ", "\u03c3").replace("φ", "\u03d5").replace("ϕ", "\u03c6").replace("ω", "\u03c9").replace("Λ", "\u039b").replace("Σ", "\u03a3").replace("Ω", "\u03a9").replace("⊂", "\u2282").replace("⊃", "\u2283").replace("⊆", "\u2286").replace("⊇", "\u2287").replace("∇", "\u2207").replace("…", "\u2026").replace("↓", "\u2193").replace("⇓", "\u21d3").replace("↑", "\u2191").replace("⇑", "\u21d1").replace("→", "\u2192").replace("⇒", "\u21d2").replace("←", "\u2190").replace("⇐", "\u21d0").replace("↔", "\u2194").replace("⇔", "\u21d4").replace("ℜ", "\u211c").replace("ℑ", "\u2111").replace("∂", "\u2202").replace("∞", "\u221e").replace("ℵ", "\u2135").replace("∃", "\u2203").replace("∅", "\u2205").replace("∪", "\u222a").replace("∩", "\u2229").replace("°", "\u00b0").replace("∠", "\u2220").replace("∫", "\u222b").replace("∏", "\u220f").replace("∐", "\u2210");
|
||||
return mathMl;
|
||||
}
|
||||
|
||||
public static void mathMlToLatex(Map<String, String> formulaMap, Path path) {
|
||||
if (!MapUtils.isEmpty(formulaMap)) {
|
||||
log.info("mathML\u8f6clatex\u6570\u91cf:{}", (Object)formulaMap.size());
|
||||
}
|
||||
Collection<Map<String, String>> maps = MapUtil.splitMap(formulaMap, 500);
|
||||
HashMap convertMap = new HashMap();
|
||||
maps.forEach(map -> {
|
||||
block11: {
|
||||
if (MapUtils.isEmpty((Map)map)) {
|
||||
return;
|
||||
}
|
||||
HashMap<String, Map> convertParam = new HashMap<String, Map>();
|
||||
String result = "";
|
||||
if (Boolean.TRUE.equals(officeCoreConfig.getMathMlToLatexApiSwitch())) {
|
||||
try {
|
||||
convertParam.put("mathml_dict", (Map)map);
|
||||
long ts = System.currentTimeMillis();
|
||||
result = HttpClientUtil.doPost((String)officeCoreConfig.getMathMlToLatexApi(), convertParam, (int)5000, (int)15000);
|
||||
log.info("mathML\u8f6clatex\u8c03\u7528python\u63a5\u53e3\u6210\u529f, \u8017\u65f6\uff1a{}\u6beb\u79d2", (Object)(System.currentTimeMillis() - ts));
|
||||
result = result.replace("<", "\\\\lt ");
|
||||
Map convertResult = (Map)HttpClientUtil.parseResult((String)result, (TypeReference)new TypeReference<Map<String, String>>(){});
|
||||
if (MapUtils.isNotEmpty((Map)convertResult)) {
|
||||
convertMap.putAll(convertResult);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("mathML\u8f6clatex\u8c03\u7528python\u63a5\u53e3\u5f02\u5e38, param:{}, result:{}", new Object[]{JSON.toJSONString(convertParam), result, e});
|
||||
}
|
||||
ThreadUtil.sleep((long)2000L);
|
||||
} else {
|
||||
try {
|
||||
Map convertResult;
|
||||
JSONObject json;
|
||||
String data;
|
||||
convertParam.put("mathml_dict", (Map)map);
|
||||
File tempFile = File.createTempFile("mathml_input-", ".json", new File(path.toString()));
|
||||
String absolutePath = tempFile.getAbsolutePath();
|
||||
if (!StringUtils.isNotBlank((CharSequence)absolutePath) || map.isEmpty()) break block11;
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.writeValue(tempFile, convertParam);
|
||||
CommandLine cmdLine = CommandLine.parse((String)officeCoreConfig.getPythonCommand());
|
||||
cmdLine.addArgument(officeCoreConfig.getTransformScriptPath() + "/mathml2latex/batch_converter.py");
|
||||
cmdLine.addArgument("--input-file=" + absolutePath);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
PumpStreamHandler streamHandler = new PumpStreamHandler((OutputStream)output, (OutputStream)output);
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
executor.setStreamHandler((ExecuteStreamHandler)streamHandler);
|
||||
long ts = System.currentTimeMillis();
|
||||
try {
|
||||
executor.execute(cmdLine);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("mathml2latex/batch_converter.py error, \n\u8f93\u51fa:{}", (Object)output, (Object)e);
|
||||
}
|
||||
log.info("mathml2latex/batch_converter.py end, \u6570\u91cf:{}, \u8017\u65f6:{}\u6beb\u79d2", (Object)map.size(), (Object)(System.currentTimeMillis() - ts));
|
||||
String fullOutput = output.toString();
|
||||
CharSequence[] lines = fullOutput.split("\n");
|
||||
result = String.join((CharSequence)"", lines);
|
||||
result = result.replace("<", "\\\\lt ");
|
||||
if (StringUtils.isNotBlank((CharSequence)result) && Objects.nonNull(data = (json = JSONObject.parseObject((String)result)).getString("data")) && MapUtils.isNotEmpty((Map)(convertResult = (Map)JSON.parseObject((String)data, (TypeReference)new TypeReference<Map<String, String>>(){}, (Feature[])new Feature[0])))) {
|
||||
convertMap.putAll(convertResult);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("mathML\u8f6clatex\u8c03\u7528\u672c\u5730python\u7a0b\u5e8f\u5f02\u5e38,param:{}, result:{}", new Object[]{JSON.toJSONString(convertParam), result, e});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
formulaMap.forEach((formulaKey, mathMl) -> {
|
||||
String latex = (String)convertMap.get(formulaKey);
|
||||
if (StringUtils.isBlank((CharSequence)latex)) {
|
||||
try {
|
||||
latex = ConvertFromMathMLToLatex.convertToLatex((String)mathMl);
|
||||
log.info("mathML\u8f6clatex\u672c\u5730\u8f6c\u6362,latex:{}", (Object)latex);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("mathML\u8f6clatex\u672c\u5730\u8f6c\u6362\u5f02\u5e38, mathMl:{}, latex:{}", new Object[]{mathMl, latex, e});
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank((CharSequence)latex) && latex.length() > 2) {
|
||||
formulaMap.put((String)formulaKey, latex.substring(1, latex.length() - 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static Matcher getLatexMatcher(String content) {
|
||||
return LATEX_PATTERN.matcher(content);
|
||||
}
|
||||
|
||||
public static void mathMlToLatexIgnoreNull(Map<String, String> formulaMap, String copyrightAddresses, Path path) {
|
||||
Map<String, String> map = formulaMap.entrySet().stream().filter(f -> Objects.nonNull(f.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
LatexUtil.mathMlToLatex(map, path);
|
||||
String[] original = copyrightAddresses.split(",");
|
||||
String[] transformed = (String[])Arrays.stream(original).map(s -> s.chars().mapToObj(c -> {
|
||||
if (c == 46) {
|
||||
return ".";
|
||||
}
|
||||
return "\\mathrm{" + (char)c + "}";
|
||||
}).collect(Collectors.joining())).toArray(String[]::new);
|
||||
String[] splits = (String[])Stream.concat(Arrays.stream(original), Arrays.stream(transformed)).toArray(String[]::new);
|
||||
map.replaceAll((key, value) -> {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Arrays.stream(splits).anyMatch(value::contains) ? null : value;
|
||||
});
|
||||
formulaMap.putAll(map);
|
||||
}
|
||||
|
||||
public static void ommlAndMathMlToLatex(Map<String, String> formulaMap, Path path) {
|
||||
if (!MapUtils.isEmpty(formulaMap)) {
|
||||
log.info("Omml\u6216MathML\u8f6clatex\u6570\u91cf:{}", (Object)formulaMap.size());
|
||||
}
|
||||
Collection<Map<String, String>> maps = MapUtil.splitMap(formulaMap, 1000);
|
||||
maps.forEach(map -> {
|
||||
block6: {
|
||||
if (MapUtils.isEmpty((Map)map)) {
|
||||
return;
|
||||
}
|
||||
String result = "";
|
||||
try {
|
||||
Map convertResult;
|
||||
File tempFile = File.createTempFile("input-", ".json", new File(path.toString()));
|
||||
String absolutePath = tempFile.getAbsolutePath();
|
||||
if (!StringUtils.isNotBlank((CharSequence)absolutePath) || map.isEmpty()) break block6;
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
mapper.writeValue(tempFile, map);
|
||||
CommandLine cmdLine = CommandLine.parse((String)officeCoreConfig.getPythonCommand());
|
||||
cmdLine.addArgument(officeCoreConfig.getTransformScriptPath() + "/omml_mathml2latex/omml_mathml2latex.py");
|
||||
cmdLine.addArgument("--json");
|
||||
cmdLine.addArgument(absolutePath);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
PumpStreamHandler streamHandler = new PumpStreamHandler((OutputStream)output, (OutputStream)output);
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
executor.setStreamHandler((ExecuteStreamHandler)streamHandler);
|
||||
long ts = System.currentTimeMillis();
|
||||
try {
|
||||
executor.execute(cmdLine);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("/omml_mathml2latex/omml_mathml2latex.py error, \n\u8f93\u51fa:{}", (Object)output, (Object)e);
|
||||
}
|
||||
log.info("/omml_mathml2latex/omml_mathml2latex.py end, \u6570\u91cf:{}, \u8017\u65f6:{}\u6beb\u79d2", (Object)map.size(), (Object)(System.currentTimeMillis() - ts));
|
||||
String fullOutput = output.toString();
|
||||
CharSequence[] lines = fullOutput.split("\n");
|
||||
result = String.join((CharSequence)"", lines);
|
||||
if (StringUtils.isNotBlank((CharSequence)result) && MapUtils.isNotEmpty((Map)(convertResult = (Map)JSON.parseObject((String)result, (TypeReference)new TypeReference<Map<String, String>>(){}, (Feature[])new Feature[0])))) {
|
||||
formulaMap.putAll(convertResult);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Omml\u6216MathML\u8f6clatex\u8c03\u7528\u672c\u5730python\u7a0b\u5e8f\u5f02\u5e38,param:{}, result:{}", new Object[]{JSON.toJSONString((Object)map), result, e});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void ommlMathMlToLatexIgnoreNull(Map<String, String> formulaMap, String copyrightAddresses, Path path) {
|
||||
Map<String, String> map = formulaMap.entrySet().stream().filter(f -> Objects.nonNull(f.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
LatexUtil.ommlAndMathMlToLatex(map, path);
|
||||
String[] original = copyrightAddresses.split(",");
|
||||
String[] transformed = (String[])Arrays.stream(original).map(s -> s.chars().mapToObj(c -> {
|
||||
if (c == 46) {
|
||||
return ".";
|
||||
}
|
||||
return "\\mathrm{" + (char)c + "}";
|
||||
}).collect(Collectors.joining())).toArray(String[]::new);
|
||||
String[] splits = (String[])Stream.concat(Arrays.stream(original), Arrays.stream(transformed)).toArray(String[]::new);
|
||||
map.replaceAll((key, value) -> {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Arrays.stream(splits).anyMatch(value.replace(" ", "")::contains) ? null : value;
|
||||
});
|
||||
formulaMap.putAll(map);
|
||||
}
|
||||
|
||||
public static void latexAndMathMlToOmml(Map<String, String> latexMathmlMap) {
|
||||
if (!MapUtils.isEmpty(latexMathmlMap)) {
|
||||
log.info("Latex\u6216MathML\u8f6cOmml\u6570\u91cf:{}", (Object)latexMathmlMap.size());
|
||||
}
|
||||
String tempFolder = officeCoreConfig.getTmpPath() + "/download" + File.separator + UniqueUtil.getUuid() + File.separator;
|
||||
Collection<Map<String, String>> maps = MapUtil.splitMap(latexMathmlMap, 1000);
|
||||
maps.forEach(map -> {
|
||||
block10: {
|
||||
if (MapUtils.isEmpty((Map)map)) {
|
||||
return;
|
||||
}
|
||||
String result = "";
|
||||
try {
|
||||
Map convertResult;
|
||||
File tempFile = FileUtil.getFile((String)(tempFolder + UniqueUtil.getUuid() + ".json"));
|
||||
String absolutePath = tempFile.getAbsolutePath();
|
||||
if (!StringUtils.isNotBlank((CharSequence)absolutePath) || map.isEmpty()) break block10;
|
||||
MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
MAPPER.writeValue(tempFile, map);
|
||||
CommandLine cmdLine = CommandLine.parse((String)officeCoreConfig.getPythonCommand());
|
||||
cmdLine.addArguments(new String[]{officeCoreConfig.getTransformScriptPath() + "/latex_mathml2omml/latex_mathml2omml.py", "--json", absolutePath}, false);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
PumpStreamHandler streamHandler = new PumpStreamHandler((OutputStream)output, (OutputStream)output);
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
executor.setStreamHandler((ExecuteStreamHandler)streamHandler);
|
||||
long ts = System.currentTimeMillis();
|
||||
try {
|
||||
executor.execute(cmdLine);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("/latex_mathml2omml/latex_mathml2omml.py error, \n\u8f93\u51fa:{}", (Object)output, (Object)e);
|
||||
}
|
||||
log.info("/latex_mathml2omml/latex_mathml2omml.py end, \u6570\u91cf:{}, \u8017\u65f6:{}\u6beb\u79d2", (Object)map.size(), (Object)(System.currentTimeMillis() - ts));
|
||||
String fullOutput = output.toString();
|
||||
CharSequence[] lines = fullOutput.split("\n");
|
||||
result = String.join((CharSequence)"", lines);
|
||||
if (StringUtils.isNotBlank((CharSequence)result) && MapUtils.isNotEmpty((Map)(convertResult = (Map)JSON.parseObject((String)result, (TypeReference)new TypeReference<Map<String, String>>(){}, (Feature[])new Feature[0])))) {
|
||||
latexMathmlMap.putAll(convertResult);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Latex\u6216MathML\u8f6cOmml\u8c03\u7528\u672c\u5730python\u7a0b\u5e8f\u5f02\u5e38,param:{}, result:{}", new Object[]{JSON.toJSONString((Object)map), result, e});
|
||||
}
|
||||
finally {
|
||||
if (Boolean.TRUE.equals(officeCoreConfig.getDeleteTmpFile())) {
|
||||
FileUtil.delFolder((String)tempFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static {
|
||||
MAPPER = new ObjectMapper();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user