This repository has been archived by the owner on Nov 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LaTeXMLConverter.java
155 lines (141 loc) · 5.66 KB
/
LaTeXMLConverter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package com.formulasearchengine.mathmlconverters.latexml;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import com.formulasearchengine.mathmlconverters.util.CommandExecutor;
/**
* Main approach for conversion from a latex formula to
* a MathML representation via LaTeXML.
*
* @author Vincent Stange
*/
public class LaTeXMLConverter {
private static Logger logger = Logger.getLogger(LaTeXMLConverter.class);
private final LateXMLConfig lateXMLConfig;
public LaTeXMLConverter(LateXMLConfig lateXMLConfig) {
this.lateXMLConfig = lateXMLConfig;
}
/**
* Converts a latex formula string into mathml and includes
* pmml, cmml and tex semantics. If no url in the config is given,
* the local installation is used.
*
* @param latex Latex Formula
* @return MathML output in the result of LaTeXMLServiceResponse
* @throws Exception Execution of latexmlc failed.
*/
public LaTeXMLServiceResponse convertLatexml(String latex) throws Exception {
// no url = use the local installation of latexml, otherwise use: url = online service
if (StringUtils.isEmpty(lateXMLConfig.getUrl())) {
logger.debug("local latex conversion");
return runLatexmlc(latex);
} else {
logger.debug("service latex conversion");
return convertLatexmlService(latex);
}
}
/**
* This methods needs a LaTeXML installation. It converts a latex formula
* string into mathml and includes pmml, cmml and tex semantics.
* Conversion is executed by "latexmlc".
*
* @param latex Latex Formula
* @return MathML output in the result of LaTeXMLServiceResponse
* @throws Exception Execution of latexmlc failed.
*/
public LaTeXMLServiceResponse runLatexmlc(String latex) throws Exception {
CommandExecutor latexmlmath = new CommandExecutor("latexmlc",
"--includestyles",
"--format=xhtml",
"--whatsin=math",
"--whatsout=math",
"--pmml",
"--cmml",
"--nodefaultresources",
"--linelength=90",
"--quiet",
"--preload", "LaTeX.pool",
"--preload", "article.cls",
"--preload", "amsmath.sty",
"--preload", "amsthm.sty",
"--preload", "amstext.sty",
"--preload", "amssymb.sty",
"--preload", "eucal.sty",
"--preload", "[dvipsnames]xcolor.sty",
"--preload", "url.sty",
"--preload", "hyperref.sty",
"--preload", "[ids]latexml.sty",
"--preload", "texvc",
"literal:" + latex);
return new LaTeXMLServiceResponse(latexmlmath.exec(2000L), "Conversion via local installation of latexmlc");
}
/**
* Call a LaTeXML service.
*
* @param latex LaTeX formula
* @return MathML String
*/
public LaTeXMLServiceResponse convertLatexmlService(String latex) {
try {
latex = UriComponentsBuilder.newInstance().queryParam("tex", latex).build().encode(StandardCharsets.UTF_8.toString()).getQuery();
} catch (UnsupportedEncodingException ignore) {
logger.warn("encoding not supported", ignore);
}
String payload = "format=xhtml" + configToUrlString(lateXMLConfig.getParams()) + "&" + latex;
RestTemplate restTemplate = new RestTemplate();
try {
LaTeXMLServiceResponse rep = restTemplate.postForObject(lateXMLConfig.getUrl(), payload, LaTeXMLServiceResponse.class);
logger.debug(String.format("LaTeXMLServiceResponse:\n"
+ "statusCode: %s\nstatus: %s\nlog: %s\nresult: %s",
rep.getStatusCode(), rep.getStatus(), rep.getLog(), rep.getResult()));
return rep;
} catch (HttpClientErrorException e) {
logger.error(e.getResponseBodyAsString());
throw e;
}
}
/**
* Create a URL Path consisting of the mapped values.
*
* @param values map of properties converted into a URL path.
* @return String representation of the URL path.
*/
String configToUrlString(Map<String, Object> values) {
StringBuilder sb = new StringBuilder();
values.forEach((k, v) -> {
if (v instanceof List) {
for (Object ele : (List) v) {
appendParameterToUrlString(sb, k, ele);
}
} else if (v instanceof Map) {
final Map map = (Map) v;
map.forEach((o, o2) -> appendParameterToUrlString(sb, k, o2));
} else {
appendParameterToUrlString(sb, k, v);
}
});
return sb.toString();
}
private void appendParameterToUrlString(StringBuilder sb, String key, Object rawValue) {
String value = String.valueOf(rawValue);
sb.append("&").append(key);
if (!"".equals(value)) {
sb.append("=").append(value);
}
}
public static boolean latexmlcPresent() {
CommandExecutor executor = new CommandExecutor("which", "latexmlc");
try {
executor.exec(100);
} catch (Exception e) {
return false;
}
return executor.getProcess().exitValue() == 0;
}
}