保护私人版权,尊重他人版权。转载请注明出处并附带页面链接
Latex格式html文件转换docx文档
业务功能背景
有需求要展示及导出试卷题目内容,源数据来源于题库,是html格式。
1 | <div> 已知关于\(x\)的不等式组\(\begin{cases}x < 10 \\ x > a\end{cases} \)无解,则\(a\)的取值范围是______. </div> |
题目如上所示,内容里会可能带有latex格式的数学公式。
前端使用mathjax这个js库来展示html内容
后端使用pandoc工具来讲html转换为word导出
实现目标
前端看到的公式效果和导出的word展示的公式效果一致。
遇到的问题
- pandoc 转换后在word中的呈现效果和在浏览器中不引入mathjax这个过分强大的js库的效果一样,所以缺失了展示偏复杂的公式的能力
解决思路
选用中间格式数据mathml,能让mathjax和word同时支持
将完整内容的html内容提取出公式部分,提取策略和mathjax识别公式的策略一样,指定同样的行内公式选择符,参考https://docs.mathjax.org/en/v2.7-latest/options/preprocessors/tex2jax.html
实例演示
题目源数据
1
2
3
4
5
6<p><span>\(a^2 + b^2 = c^2\)</span></p>
<p><span>\(v(t) = v_0 + \frac{1}{2}at^2\)</span></p>
<p><span>\(\gamma = \frac{1}{\sqrt{1 - v^2/c^2}}\)</span></p>
<p><span>\(\exists x \forall y (Rxy \equiv Ryx)\)</span></p>
<p><span>\(\int_{0}^{1} x dx = \left[ \frac{1}{2}x^2 \right]_{0}^{1} = \frac{1}{2}\)</span></p>
<p><span>\(e^x = \sum_{n=0}^\infty \frac{x^n}{n!} = \lim_{n\rightarrow\infty} (1+x/n)^n\)</span></p>加载mathjax生成完整的html文档
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
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Pandoc math demos</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS_CHTML-full" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">Pandoc math demos</h1>
</header>
<p><span>\(a^2 + b^2 = c^2\)</span></p>
<p><span>\(v(t) = v_0 + \frac{1}{2}at^2\)</span></p>
<p><span>\(\gamma = \frac{1}{\sqrt{1 - v^2/c^2}}\)</span></p>
<p><span>\(\exists x \forall y (Rxy \equiv Ryx)\)</span></p>
<p><span>\(\int_{0}^{1} x dx = \left[ \frac{1}{2}x^2 \right]_{0}^{1} = \frac{1}{2}\)</span></p>
<p><span>\(e^x = \sum_{n=0}^\infty \frac{x^n}{n!} = \lim_{n\rightarrow\infty} (1+x/n)^n\)</span></p>
</body>
</html>浏览器上的效果
使用mathjax把html中的公式部分替换为mml
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
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Pandoc math demos</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS_CHTML-full" type="text/javascript"></script>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">Pandoc math demos</h1>
</header>
<p><span><math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup><mo>=</mo><msup><mi>c</mi><mn>2</mn></msup></math></span></p>
<p><span><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>v</mi><mo>(</mo><mi>t</mi><mo>)</mo><mo>=</mo><msub><mi>v</mi><mn>0</mn></msub><mo>+</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>a</mi><msup><mi>t</mi><mn>2</mn></msup></math></span></p>
<p><span><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>γ</mi><mo>=</mo><mfrac><mn>1</mn><msqrt><mn>1</mn><mo>-</mo><msup><mi>v</mi><mn>2</mn></msup><mo>/</mo><msup><mi>c</mi><mn>2</mn></msup></msqrt></mfrac></math></span></p>
<p><span><math xmlns="http://www.w3.org/1998/Math/MathML"><mo>∃</mo><mi>x</mi><mo>∀</mo><mi>y</mi><mo>(</mo><mi>R</mi><mi>x</mi><mi>y</mi><mo>≡</mo><mi>R</mi><mi>y</mi><mi>x</mi><mo>)</mo></math></span></p>
<p><span><math xmlns="http://www.w3.org/1998/Math/MathML"><msubsup><mo>∫</mo><mn>0</mn><mn>1</mn></msubsup><mi>x</mi><mi>d</mi><mi>x</mi><mo>=</mo><msubsup><mfenced open="[" close="]"><mrow><mfrac><mn>1</mn><mn>2</mn></mfrac><msup><mi>x</mi><mn>2</mn></msup></mrow></mfenced><mn>0</mn><mn>1</mn></msubsup><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac></math></span></p>
<p><span><math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>e</mi><mi>x</mi></msup><mo>=</mo><munderover><mo>∑</mo><mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow><mo>∞</mo></munderover><mfrac><msup><mi>x</mi><mi>n</mi></msup><mrow><mi>n</mi><mo>!</mo></mrow></mfrac><mo>=</mo><munder><mi>lim</mi><mrow><mi>n</mi><mo>→</mo><mo>∞</mo></mrow></munder><mo>(</mo><mn>1</mn><mo>+</mo><mi>x</mi><mo>/</mo><mi>n</mi><msup><mo>)</mo><mi>n</mi></msup></math></span></p>
</body>
</html>使用pandoc把html转换为word