jgm/texmath

Converting left/right math functions to Typst and docx

Closed this issue · 7 comments

Left/right math (https://typst.app/docs/reference/math/lr) is not being converted to Typst correctly.

Simple Typst Example

As a minimal example, I would like to convert the following LaTeX math to Typst.

$$\left\{ x \in \mathbb{R}^n \middle| \lVert x \rVert_2^2 = \sum_{i=1}^n x_i^2 = 1\right\}$$

Using Overleaf, this is rendered as.
image

Using the online tool https://pandoc.org/try/, this produces the wrong output

$ {x in bb(R)^n | parallel x parallel_2^2 = sum_(i = 1)^n x_i^2 = 1} $

which is rendered with Typst as the following.

image

The visual issues are:
a) the mid line | is not being scaled to the same height as the braces { }
b) there is too much space between the double vertical bars and x
c) the super/subscript 2s are placed on top of the double bars rather than beside

I believe the root causes are:

  1. \middle| is not a recognized command (as a part of the \left\right delimiters) and should be converted to mid(|)
  2. \left\lVert and \right\rVert are both converted to parallel when they should be converted to norm() together, or at least lr(bar.v.double and bar.v.double), but norm() is preferred (see typst/typst#4696).

I believe Pandoc should convert the LaTeX to something like

$ {x in bb(R)^n mid(|) norm(x)_2^2=sum_(i=1)^n x_i^2=1} $

which is rendered with Typst as

image

Docx issue

Converting the same example to docx has the same issue b) where there is too much space between the double vertical bars x. But there is also a different issues where there is not enough space to the left of the midline.

image

This should look like

image

Extra info

This bug was originally found downstream through Quarto and explained here: quarto-dev/quarto-cli#10424, before being redirected to Pandoc.

If pandoc is converting \lVert and \rVert to parallel, then that's the wrong symbol. The correct one is bar.v.double

Edit: Context typst/typst#4696 (comment)

(And yes, it needs either lr() or norm() )

jgm commented

Transferring to texmath.

jgm commented

That commit handles the mid issue but not the other issue, so reopening.

parallel is \8741 U+2225 (mathematical operator) https://www.compart.com/en/unicode/U+2225

bar.v.double is \8214 “‖” U+2016 Double Vertical Line Unicode Character

texmath currently converts both \lVert and \rVert to
ESymbol Open "\8741"
and that's why we get parallel.
We could reconsider that conversion, but I'd like to get a better sense what the difference is between U+2016 ad U+2225.

jgm commented

As for putting an lr() around it...we'd need to do this in the TeX reader, recognizing \lVert ... \rVert as an EDelimited element.

parallel is \8741 U+2225 (mathematical operator) https://www.compart.com/en/unicode/U+2225

bar.v.double is \8214 “‖” U+2016 Double Vertical Line Unicode Character

texmath currently converts both \lVert and \rVert to ESymbol Open "\8741" and that's why we get parallel. We could reconsider that conversion, but I'd like to get a better sense what the difference is between U+2016 ad U+2225.

Thanks @Enivex for the clarification and I can see why parallel is not the right symbol to use in this case now. I'll weigh in on how I would use the symbols differently.

Parallel is a binary relation which usual is formatted with extra spacing around both sides. If line AB is parallel to line CD, we would write $AB \parallel BC$ in LaTeX: $AB \parallel BC$. https://en.wikipedia.org/wiki/Parallel_(operator)#Notation

I mainly use the pair \lVert and \rVert as the left and right side of norm. This is usually a unary operation which hugs the input. If I want the norm of a vector, I would write $\lVert x \rVert$ in TeX: $\lVert x \rVert$. https://en.wikipedia.org/wiki/Norm_(mathematics)

For the norm of large expressions, I am used to adding \left \right so that the bars extend completely around the input. For example, \left\lVert \frac{a^2}{b}\right\rVert: $\left\lVert \frac{a^2}{b}\right\rVert$. Without the left/right, it would look like $\lVert \frac{a^2}{b}\rVert$. It looks like Typst automatically handles the sizing of the bars when using norm(x), but would need lr() when matching two copies of bar.v.double.

I've also seen \parallel used as a separator between inputs of a function. For example, the divergence of probability distributions: $D(P \parallel Q)$.