最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Getting bold math expression when converting MathJax to png via html2canvas - Stack Overflow

programmeradmin8浏览0评论

I am using MathJax to render math expresion in the text and want to convert it to pdf. But when I open pdf the expresion is like bold or it looks like two expresions are overlaped. (below is my code)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MathJax to PDF</title>
    <script src=".4.0/jspdf.umd.min.js"></script>
    <script src="@3/es5/tex-mml-chtml.js"></script>
    <script src=".4.1/html2canvas.min.js"></script>
</head>
<body>
    <div id="math-container" style="font-size: 20px;">
        This is some text with MathJax: \(E = mc^2\)
    </div>
    <button onclick="generatePDF()">Generate PDF</button>

    <script>
        async function generatePDF() {
            const mathContainer = document.getElementById("math-container");
            
            // Step 1: Render MathJax in the container
            await MathJax.typesetPromise([mathContainer]);

            // Step 2: Remove the raw LaTeX source (e.g., \(E = mc^2\)) after rendering
            // MathJax inserts the rendered output in an element with class 'mjx-chtml'
            const renderedMath = mathContainer.querySelector('.mjx-chtml');
            if (renderedMath) {
                // Clear the container and only append the rendered output
                mathContainer.innerHTML = ''; 
                mathContainer.appendChild(renderedMath); // Keep only the rendered content
            }

            // Step 3: Convert the container to an image using html2canvas
            const canvas = await html2canvas(mathContainer, {
                backgroundColor: "#ffffff", // Set background color to white for clarity
                scale: 2, // Higher scale for better resolution
            });
            const imgData = canvas.toDataURL("image/png");

            // Step 4: Add the image to the PDF using jsPDF
            const { jsPDF } = window.jspdf;
            const pdf = new jsPDF();
            pdf.text("MathJax in PDF Example", 10, 10);
            pdf.addImage(imgData, "PNG", 10, 20, 180, canvas.height / canvas.width * 180); // Scale to fit
            pdf.save("mathjax_fixed.pdf");
        }
    </script>
</body>
</html>

How can I fix this problem?

I am using MathJax to render math expresion in the text and want to convert it to pdf. But when I open pdf the expresion is like bold or it looks like two expresions are overlaped. (below is my code)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MathJax to PDF</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
</head>
<body>
    <div id="math-container" style="font-size: 20px;">
        This is some text with MathJax: \(E = mc^2\)
    </div>
    <button onclick="generatePDF()">Generate PDF</button>

    <script>
        async function generatePDF() {
            const mathContainer = document.getElementById("math-container");
            
            // Step 1: Render MathJax in the container
            await MathJax.typesetPromise([mathContainer]);

            // Step 2: Remove the raw LaTeX source (e.g., \(E = mc^2\)) after rendering
            // MathJax inserts the rendered output in an element with class 'mjx-chtml'
            const renderedMath = mathContainer.querySelector('.mjx-chtml');
            if (renderedMath) {
                // Clear the container and only append the rendered output
                mathContainer.innerHTML = ''; 
                mathContainer.appendChild(renderedMath); // Keep only the rendered content
            }

            // Step 3: Convert the container to an image using html2canvas
            const canvas = await html2canvas(mathContainer, {
                backgroundColor: "#ffffff", // Set background color to white for clarity
                scale: 2, // Higher scale for better resolution
            });
            const imgData = canvas.toDataURL("image/png");

            // Step 4: Add the image to the PDF using jsPDF
            const { jsPDF } = window.jspdf;
            const pdf = new jsPDF();
            pdf.text("MathJax in PDF Example", 10, 10);
            pdf.addImage(imgData, "PNG", 10, 20, 180, canvas.height / canvas.width * 180); // Scale to fit
            pdf.save("mathjax_fixed.pdf");
        }
    </script>
</body>
</html>

How can I fix this problem?

Share Improve this question edited Jan 18 at 20:03 K J 11.7k4 gold badges23 silver badges61 bronze badges asked Jan 18 at 16:44 Aren VanyanAren Vanyan 11 bronze badge 0
Add a comment  | 

1 Answer 1

Reset to default 0

What you are seeing as the duplicate is the MathML that MathJax inserts for use by assistive technology like screen readers. There is CSS that hides this MathML visually but allows it to be available to the screen readers. Either html2canvas or the canvas's toDataUrl() isn't handling the CSS that hides the MathML and it is being rendered along with the usual MathJax output, giving you the duplicate version.

You can turn off the assistive MathML either in the MathJax contextual menu (at the bottom of the "Assistive" submenu), or by adding

<script>
MathJax = {
  options: {
    menuOptions: {
      settings: {
        assistiveMml: false
      }
    }
  }
};
</script>

before the script that loads tex-mml-chtml.js. Note also that you may want to use tex-chtml.js instead, as you are not using MathML input, and don't need that part of MathJax to be loaded.

发布评论

评论列表(0)

  1. 暂无评论