yagarea / jektex

A Jekyll plugin for fast server-side cached LaTeX rendering, with support for macros. Enjoy the comfort of LaTeX and Markdown without cluttering your site with bloated JavaScript.
https://rubygems.org/gems/jektex
GNU General Public License v3.0
24 stars 5 forks source link

Expressions inside html within markdown are not rendered #7

Open unennhexium opened 4 months ago

unennhexium commented 4 months ago
---
layout: page
title: test
---

$$\alpha$$
<div>$$\beta$$</div>

renders to

unennhexium commented 4 months ago

You can think of this as a feature request. This is absolutely necessary in my case, because I have a lot of HTML markup on my pages, for example to create collapsible blocks with <details> and <summary> tags.

yagarea commented 4 months ago

Hello, thank you for creating a issue.

This is inherited behavior from kramdown. Kramdown uses HTML blocks as whole and does not render their contents. I am not sure if I it is a good idea to make jektex behave differently then parser it depends on.

I reproduced your issue like this:

---
title:  "Jektex test"
---

Lorem ipsum dolor sit amet, consectetur adipiscing elit. $$e^{i\pi} + 1 = 0$$ Suspendisse et molestie quam.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

$$
i\hbar\frac{\partial}{\partial t} \Psi(\mathbf{r},t) = \left [ \frac{-\hbar^2}{2\mu}\nabla^2 + V(\mathbf{r},t)\right ] \Psi(\mathbf{r},t) 
$$

Suspendisse et molestie quam.

<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. $$e^{i\pi} + 1 = 0$$ Suspendisse et molestie quam.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

$$
i\hbar\frac{\partial}{\partial t} \Psi(\mathbf{r},t) = \left [ \frac{-\hbar^2}{2\mu}\nabla^2 + V(\mathbf{r},t)\right ] \Psi(\mathbf{r},t) 
$$

Suspendisse et molestie quam.
</div>

This is a result: image

Solution

As per kramdown documentation you can explicitly declare block to render using markdown="1" attribute.

So this:

---
title:  "Jektex test"
---

Lorem ipsum dolor sit amet, consectetur adipiscing elit. $$e^{i\pi} + 1 = 0$$ Suspendisse et molestie quam.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

$$
i\hbar\frac{\partial}{\partial t} \Psi(\mathbf{r},t) = \left [ \frac{-\hbar^2}{2\mu}\nabla^2 + V(\mathbf{r},t)\right ] \Psi(\mathbf{r},t) 
$$

Suspendisse et molestie quam.

<div markdown="1">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. $$e^{i\pi} + 1 = 0$$ Suspendisse et molestie quam.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

$$
i\hbar\frac{\partial}{\partial t} \Psi(\mathbf{r},t) = \left [ \frac{-\hbar^2}{2\mu}\nabla^2 + V(\mathbf{r},t)\right ] \Psi(\mathbf{r},t) 
$$

Suspendisse et molestie quam.
</div>

renders like this: image

What do you think? Are you satisfied with this solution?

unennhexium commented 4 months ago

Thanks for the fast answer. I'm used to not getting help with issues but you're so reasonable.

It's a very good idea. I agree with the reason you don't want to change behavior. I followed your advice and added this attribute. I think this might work for me, but I have to check whether nested blocks will be processed. Currently I have the following result:

---
layout: page
title: test
---

$$\alpha$$

<div markdown="1">$$\beta$$</div>

div processed to pre block. Do you have any ideas what I did wrong?

I looked at the code and see that you get the entire page | document, convert it to string and then extract the expressions using gsub. I also noticed that you aren't looking for $$ delimiters, because... most likely kramdown replaced them in the previous step with \[...\] and \(...\), therefore you're working only with LaTeX delimiters in the post_render hook.

In this case, it's not clear why a separate render_kramdown_notation() exist and why its registration as the pre_render hook are needed. Perhaps this is a legacy piece of code or a template for future changes. From this I concluded that you're strongly relying on the markdown processor behavior. Implement handling $$ is prone to errors when designing a suitable regexp.

unennhexium commented 4 months ago

Another suggestion would be to support passing the delimiters option to katex.renderToString via configuration similar to the option for macros. Its signature isn't much more complicated:

delimiters: [{left: string, right: string, display: bool}, ...]

Now my autorender is configured using this to process $ notation.

I think this could be a compromise solution. But it mightn't be worth the time if I can get markdown="1" to work

unennhexium commented 4 months ago

Do you have any ideas what I did wrong?

It seems to be disgustingly unstable. After several restarts without changing the markup, I got a different result (also not satisfactory):

It seems to work when I add line breaks between the opening and closing tags.

I checked whether the attribute applies to nested elements. And the answer is no. It turns out that I'll have to set this attribute on each element directly containing $$. And that doesn't particularly suit me.

Any suggestions on how to fix the incorrect render? What do you think about providing the ability to specify delimiters instead of changing the notation handling code?

unennhexium commented 4 months ago

Another suggestion would be to support passing the delimiters option to katex.renderToString

Oh. I apologize. It seems I was a little hasty. This option's only for the renderMathInElement of auto-render extension. KaTeX itself doesn't provide any functionality for finding expressions in plain string. You do it yourself as I described above.

In order to use it, you will have to include autorender.min.js in addition to katex.min.js, which you'll obviously want to avoid, as well as hard code behavior inconsistent with kramdown.

This all looks hopeless and seems to really require major changes to the code to start looking for $$ that kramdown doesn't convert to LaTeX notation, or to provide the ability to specify delimiters, similar to the auto-render extensions.