首页 文章

MathJax mPDF SVG方程不可见

提问于
浏览
1

我在使用mPDF将MathJax SVG转换为PDF时遇到了问题 .

HTML只是mPDF示例中的一个简单公式:

\[ \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \]

应该表现为:

example

但当然最终的PDF文件没什么 .

HTML通过POST发送到PHP文件

$path = (getenv('MPDF_ROOT')) ? getenv('MPDF_ROOT') : __DIR__;
require_once $path . '/vendor/autoload.php';
$mpdf = new \Mpdf\Mpdf(['debug' => false, 'allow_output_buffering' => true]);
$sizeConverter = new \Mpdf\SizeConverter($mpdf->dpi, $mpdf->default_font_size);

if (strpos($_REQUEST['bodydata'], 'id%3D%22MathJax_SVG_Hidden%22') === false) {
    die('Hacking attempt');
}

$html = $_POST['bodydata'];
$html = urldecode($html);

preg_match('/<svg[^>]*>\s*(<defs.*?>.*?<\/defs>)\s*<\/svg>/', $html, $m);
$defs = $m[1];

$html = preg_replace('/<svg[^>]*>\s*<defs.*?<\/defs>\s*<\/svg>/', '', $html);
$html = preg_replace('/(<svg[^>]*>)/', "\\1" . $defs, $html);

preg_match_all('/<svg([^>]*)style="(.*?)"/', $html, $m);

for ($i = 0; $i < count($m[0]); $i++) {
    $style = $m[2][$i];
    preg_match('/width: (.*?);/', $style, $wr);
    $w = $sizeConverter->convert($wr[1], 0, $mpdf->FontSize) * $mpdf->dpi / 25.4;

    preg_match('/height: (.*?);/', $style, $hr);
    $h = $sizeConverter->convert($hr[1], 0, $mpdf->FontSize) * $mpdf->dpi / 25.4;

    $replace = '<svg' . $m[1][$i] . ' width="' . $w . '" height="' . $h . '" style="' . $m[2][$i] . '"';
    $html = str_replace($m[0][$i], $replace, $html);
}
if ($_POST['PDF'] === 'PDF') {
    $stylesheet = '
        img {
            vertical-align: middle;
        }
        .MathJax_SVG_Display {
            padding: 1em 0;
        }
        #mpdf-create {
            display: none;
        }
    ';
    $mpdf->WriteHTML($stylesheet, 1);
    $mpdf->WriteHTML($html);
    $mpdf->Output();
}
exit;

它的副本:official mPDF example,相当错误,在POST请求JS复制'width'和'height'属性为'styles'属性之前,所以mPDF可以正确读取它 .

生成的SVG:

<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="35.62ex" height="7.841ex" style="vertical-align: -3.082ex; width: 35.62ex; height: 7.841ex;" viewBox="0 -2049.4 15336.2 3376.2"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)"><use xlink:href="#MJSZ4-28"></use><g transform="translate(792,0)"><use xlink:href="#MJSZ2-2211" x="0" y="0"></use><g transform="translate(85,-1110)"><use transform="scale(0.707)" xlink:href="#MJMATHI-6B" x="0" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-3D" x="521" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-31" x="1300" y="0"></use></g><use transform="scale(0.707)" xlink:href="#MJMATHI-6E" x="721" y="1627"></use><g transform="translate(1611,0)"><use xlink:href="#MJMATHI-61" x="0" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMATHI-6B" x="748" y="-213"></use></g><g transform="translate(2609,0)"><use xlink:href="#MJMATHI-62" x="0" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMATHI-6B" x="607" y="-213"></use></g></g><use xlink:href="#MJSZ4-29" x="4300" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-32" x="7202" y="2090"></use><use xlink:href="#MJMAIN-2264" x="5824" y="0"></use><g transform="translate(6880,0)"><use xlink:href="#MJSZ4-28"></use><g transform="translate(792,0)"><use xlink:href="#MJSZ2-2211" x="0" y="0"></use><g transform="translate(85,-1110)"><use transform="scale(0.707)" xlink:href="#MJMATHI-6B" x="0" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-3D" x="521" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-31" x="1300" y="0"></use></g><use transform="scale(0.707)" xlink:href="#MJMATHI-6E" x="721" y="1627"></use><g transform="translate(1611,0)"><use xlink:href="#MJMATHI-61" x="0" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-32" x="748" y="488"></use><use transform="scale(0.707)" xlink:href="#MJMATHI-6B" x="748" y="-463"></use></g></g><use xlink:href="#MJSZ4-29" x="3401" y="0"></use></g><g transform="translate(11241,0)"><use xlink:href="#MJSZ4-28"></use><g transform="translate(792,0)"><use xlink:href="#MJSZ2-2211" x="0" y="0"></use><g transform="translate(85,-1110)"><use transform="scale(0.707)" xlink:href="#MJMATHI-6B" x="0" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-3D" x="521" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-31" x="1300" y="0"></use></g><use transform="scale(0.707)" xlink:href="#MJMATHI-6E" x="721" y="1627"></use><g transform="translate(1611,0)"><use xlink:href="#MJMATHI-62" x="0" y="0"></use><use transform="scale(0.707)" xlink:href="#MJMAIN-32" x="607" y="488"></use><use transform="scale(0.707)" xlink:href="#MJMATHI-6B" x="607" y="-463"></use></g></g><use xlink:href="#MJSZ4-29" x="3301" y="0"></use></g></g></svg>

当然还有警告:

[29-Dec-2017 21:42:39 UTC] PHP Notice:  Undefined index: x in D:\Praca\ENVIROMENTS\laragon-apache\laragon\www\wp-content\plugins\szalpdf\pdf\vendor\mpdf\mpdf\src\Image\Svg.php on line 3027
[29-Dec-2017 21:42:39 UTC] PHP Notice:  Undefined index: y in D:\Praca\ENVIROMENTS\laragon-apache\laragon\www\wp-content\plugins\szalpdf\pdf\vendor\mpdf\mpdf\src\Image\Svg.php on line 3027
[29-Dec-2017 21:42:39 UTC] PHP Notice:  Undefined index: w in D:\Praca\ENVIROMENTS\laragon-apache\laragon\www\wp-content\plugins\szalpdf\pdf\vendor\mpdf\mpdf\src\Image\Svg.php on line 3027
[29-Dec-2017 21:42:39 UTC] PHP Notice:  Undefined index: h in D:\Praca\ENVIROMENTS\laragon-apache\laragon\www\wp-content\plugins\szalpdf\pdf\vendor\mpdf\mpdf\src\Image\Svg.php on line 3027
[29-Dec-2017 21:42:39 UTC] PHP Warning:  Division by zero in D:\Praca\ENVIROMENTS\laragon-apache\laragon\www\wp-content\plugins\szalpdf\pdf\vendor\mpdf\mpdf\src\Tag.php on line 4015

读取viewBox数据可能会出错,但即使是刚性值,PDF文件似乎也是空的 . 没有错误,只需忽略SVG . 从昨天起我一直坐在这里,我仍然在同一个地方 . MathJax必须在这里 . 我正在考虑将mPDF更改为其他内容,但我更愿意避免使用它 .

没有想法,我被困住了 .

最新MathJax / mPDF v7.0.0 / PHP:启用7.1.1 / PHP GD2扩展

1 回答

  • 3

    所以,我明白了 . 如果有人在寻找答案(我们现在正在谈论mPDF MathJaxProcess.php文件)

    • SVG中的该死的 fill="currentColor" 属性在mPDF中不起作用 .

    • 示例完全破碎 .

    • 首先要避免mPDF sizeConverter中带有NULL的错误和警告,您必须将 widthheight 属性复制到内联SVG样式 . 在使用html发送表单之前,我使用JS完成了它 . 它实际上是错误的,而不是lib bug .

    • 第二,第29行, $m[1][$i] 破坏了一切 . 变量具有自己的 widthheight 属性,具有使用ex单位的未转换值 . 这会与我们自己的 widthheight 属性发生冲突,然后会出现 Undefined IndexDivision by zero 等通知 .

    修复上面的mPDF后应正确使用MathJax . 我也在发送表单之前清理SVG . 通过消毒我的意思是:

    • 将样式属性复制到内联样式

    • 删除像focusable,aria-hidden,role这样的属性 . (非数字值)

    • g 标签的填充属性设置为#000

    • 删除 .MJX_Assistive_MathML class元素以避免重复内容 .

    相当混乱的JS代码,但你会明白的 .

    我们在循环中跳过第一个SVG,因为它只有定义,可以直接复制到PHP脚本中的SVG标记中 .

    <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_SVG">
       MathJax.Hub.Register.StartupHook("End",function () {
         var list = document.getElementsByTagName("svg");
         for (var i = 1; i < list.length; i++) {
           var w = list[i].getAttribute("width");
           var h = list[i].getAttribute("height");
            list[i].style.width = w;
            list[i].style.height = h;
            list[i].removeAttribute("focusable");
            list[i].removeAttribute("aria-hidden");
            list[i].removeAttribute("role");
          }
    
          var gList = document.getElementsByTagName("g");
          for (var i = 0; i < gList.length; i++) {
            gList[i].setAttribute("fill", "#000");
           }
    
           document.querySelectorAll(".MJX_Assistive_MathML").forEach(function(a){
             a.remove()
           });
    
         document.getElementById("bodydata").value=encodeURIComponent(document.body.innerHTML);
         var el = document.getElementById("pdfform");
         el.submit();
       });
     </script>
    

    Related mPDF issue on Github

    编辑:如果您在chrome或firefox中破坏了svg:从Firefox渲染时mPDF需要参数 viewbox 从Chrome渲染时mPDF需要参数 viewBox 它区分大小写 . 我一个星期就在追捕这个虫子 .

相关问题