yzane / vscode-markdown-pdf

Markdown converter for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf
Other
1.01k stars 206 forks source link

LaTex fomula lines not Breaking #333

Open GitHubonline1396529 opened 1 year ago

GitHubonline1396529 commented 1 year ago

To export Markdown with $\LaTeX$ fomula, I've append those two lines to the end of the file C:/Users/<myUserName>/.vscode/extensions/yzane.markdown-pdf-1.4.4/template/template.html

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({ tex2jax: {inlineMath: [['$', '$']]}, messageStyle: "none" });
    </script>

Now the fomulas can be shown... but here is still one thing :

here 's my $\LaTeX$ fomula :

正浮平衡条件
\begin{cases}
W = \Delta = \rho V \\
x_g = x_b \\
y_g = y_b \\
\end{cases}

It should be shown as the following :

$$ 正浮平衡条件 \begin{cases} W = \Delta = \rho V \ x_g = x_b \ y_g = y_b \ \end{cases} $$

But this is how it look like after I explorted it as pdf :

This is Not Correct

All the math symbols are shown in one line... When math formula is execptionally long, this can be vary annoying

I exported the Markdown file with that formula as HTML, And this is how it looks like in HTML code :

<p>$$
正浮平衡条件
\begin{cases}
W = \Delta = \rho V \
x_g = x_b \
y_g = y_b \
\end{cases}
$$</p>

It seems that for some reason, the original \\ Is replaced with \ so the formula lines are not breaking

karutt commented 9 months ago

I've encountered the same conversion issues in markdown-pdf that have been mentioned. Specifically, the transformation of & to &amp;, \\ to \, and new lines to <br />, significantly impacts MathJax rendering, with the double backslashes being a notable concern.

As a workaround, I've added the following code to template.html, which avoids these issues by replacing certain characters within LaTeX blocks. However, this approach feels like a temporary fix rather than a robust solution.

<script>
    document.addEventListener("DOMContentLoaded", function () {
        var pElements = document.querySelectorAll("p");
        pElements.forEach(function (element) {
            var html = element.innerHTML;
            var updatedHtml = html.replace(
                /(\$\$?)([\s\S]+?)\1/g,
                function (match, delimiter, code) {
                    var newCode = code
                        .replace(/&amp;/g, "&")
                        .replace(/<br>/g, "")
                        .replace(/\\(?![a-zA-Z])/g, "\\\\"); // Convert \ at the end of a sentence to \, but exclude \frac etc.
                    return delimiter + newCode + delimiter;
                }
            );
            element.innerHTML = updatedHtml;
        });
    });
</script>
marcdus commented 9 months ago

Thank you @karutt for the workaround script, I am encountering the same issue. I don't quite understand though where I need to put it for the script to be applied. I tried in template.html right before {{{body}}} (and after some already existing mermaid script), as well as at the beginning of my document. However, I don't see a change in the pdf or html output. For example:

$$
\begin{align}
v_{i+1} &= 
\underbrace{M \cdot v_i}_{\text{momentum}} - 
\underbrace{\eta \cdot \left \langle \frac{\partial L}{\partial w} |_{w_i} \right \rangle_{D_i}}_{\text{gradient}} - 
\underbrace{\mu \cdot \eta \cdot w_i}_\text{weight decay} \\
w_{i+1} &= w_i + v_{i+1}
\end{align}
$$

still becomes:

<p>$$
\begin{align}
v_{i+1} &amp;=
\underbrace{M \cdot v_i}<em>{\text{momentum}} -
\underbrace{\eta \cdot \left \langle \frac{\partial L}{\partial w} |</em>{w_i} \right \rangle_{D_i}}<em>{\text{gradient}} -
\underbrace{\mu \cdot \eta \cdot w_i}</em>\text{weight decay} \
w_{i+1} &amp;= w_i + v_{i+1}
\end{align}
$$</p>
karutt commented 9 months ago

The complete code, including the loading of MathJax, is as follows. Please copy this and add it to the bottom of the head tag in your template.js file.

<script>
    window.onload = function () {
        var pElements = document.querySelectorAll("p");
        pElements.forEach(function (element) {
            var html = element.innerHTML;
            var updatedHtml = html.replace(
                /(\$\$?)([\s\S]+?)\1/g,
                function (match, delimiter, code) {
                    var newCode = code
                        .replace(/&amp;/g, "&")
                        .replace(/<br>/g, "")
                        .replace(/<em>/g, "_")
                        .replace(/<\/em>/g, "_")
                        .replace(/\\(?![a-zA-Z])/g, "\\\\"); // Convert \ at the end of a sentence to \, but exclude \frac etc.
                    return delimiter + newCode + delimiter;
                }
            );
            element.innerHTML = updatedHtml;
        });
        window.MathJax = {
            tex: {
                inlineMath: [["$", "$"]],
            },
            svg: {
                fontCache: "global",
            },
        };

        (function () {
            var script = document.createElement("script");
            script.src =
                "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js";
            script.async = true;
            document.head.appendChild(script);
        })();
    };
</script>

Additionally, I noticed an issue while running your sample LaTeX code: in certain cases, _ is converted to <em> among others. I have corrected this issue as well.

marcdus commented 9 months ago

Alright, that worked. Thanks a bunch!

shyu216 commented 2 months ago
<script>
    window.onload = function () {
        var pElements = document.querySelectorAll("p");
        pElements.forEach(function (element) {
            var html = element.innerHTML;
            var updatedHtml = html.replace(
                /(\$\$?)([\s\S]+?)\1/g,
                function (match, delimiter, code) {
                    var newCode = code
                        .replace(/&amp;/g, "&")
                        .replace(/<br>/g, "")
                        .replace(/<em>/g, "*") // Multiplication sign
                        .replace(/<\/em>/g, "*")
                        .replace(/\\(?![a-zA-Z])/g, "\\\\"); // Convert \ at the end of a sentence to \, but exclude \frac etc.
                    return delimiter + newCode + delimiter;
                }
            );
            element.innerHTML = updatedHtml;
        });
        window.MathJax = {
            tex: {
                inlineMath: [["$", "$"]],
            },
            svg: {
                fontCache: "global",
            },
        };
        (function () {
            var script = document.createElement("script");
            script.src =
                "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js";
            script.async = true;
            document.head.appendChild(script);
        })();
    };
</script>

Thanks a lot! There are some modification for my case (just for personally backup):

  1. remove newline before " (function () { "...
  2. replace "" by "*"