The default limits(lim_(rightarrow))_(i in I) (displayed as the leftmost formula in the equation above) does not produce the desired vertical spacing. To fix this, I defined a function movebase to adjust the baseline. Using this function, varinjlim(i in I) (the rightmost formula) achieves the correct vertical spacing.
However, injlim_(i in I) (the middle formula) still fails to produce the desired vertical spacing. To correctly position the subscript, I had to define an additional function: #let varinjlim(subscript) = $injlim_movebase(#(-2.8pt), subscript)$. While this workaround is effective, it is far less convenient compared to LaTeX’s $\varinjlim$.
Is there a way to define injlim such that injlim_(i in I) F(U_i) automatically produces the correct vertical spacing without requiring the extra function?
#let rightarrow = pad(top: -0.6em, math.stretch(math.arrow, size: 1.9em))
$
limits(lim_(rightarrow))_(i in I)
$
![image|90x108](upload://vPXwuvG92cqzpUsbgxqZO0UP3uP.png)
(the image copy-paste doesn't seem to work for some reason...)
Thanks! pad works perfectly here and simplifies things significantly. As I have shown in the above example, I also want precise control over the vertical spacing between the arrow and the subscript i in I. Following your suggestion, I found that adding padding to the bottom as shown below
This approach lets me achieve the desired vertical spacing. As a result, movebaselim can replicate the vertical spacing of the varinjlim I defined earlier, without relying on any additional functions. Here’s what I have:
$
limits(lim_(myrightarrow))_(i in I) F(U_i)
= limits(padlim)_(i in I) F(U_i)
= limits(movebaselim)_(i in I) F(U_i)
= varinjlim(i in I) F(U_i)
$
The third formula visually matches the fourth one in the above image.
However, ideally, I would like to use a single parameter to control the vertical spacing between the arrow and the subscript. My current approach relies on trial and error to determine the values for #pad(bottom: 0.43em, ..) and movebase(0.085em, padlim). While the adjusted baseline appears almost visually accurate, it lacks precision and requires a cumbersome process of fine-tuning.
My question is: how can I use only one parameter to control the vertical spacing between the arrow and the subscript?
If you use the subscript with the function limits(), the spacing between lim, the arrow and the actual subscript will already be correct by default as long as you include everything in a single subscript separated by a linebreak(). This is the “default” example in the image above. I know that the arrow does not have the correct width, it is just supposed to show how the vertical spacing in the subscript works. See the function simple-subscript() to also get the correct width for the arrow.
If you wrap the arrow in the function pad(), it will be “promoted” from a low-case height to the upper-case height. This already messes up the spacing even if you use pad(top: 0.0em). I tried to illustrate this by wrapping the arrow and the subscript in red boxes. Both pad() and box() seem to use the "cap-height" as the top-edge regardless of the content. While you can get the correct box for the arrow with the rule set text(top-edge: "bounds"), I couldn’t get the right spacing between lim, the arrow and the subscript with the function pad() and a varying shift.
If you use the function text(baseline: shift), you can apply a shift to the arrow and the subscript without messing up the height of the arrow. The baseline of the subscript is shifted by 2 * shift since it is not aware of the shifted arrow.
This is a clean implementation and produces aesthetically pleasing results.
I was wondering if there’s a way to define a new symbol, injlim, that behaves like the standard lim but allows me to customize its vertical spacing for the subscript.
My current attempt more or less achieves something close, but it feels a bit hacky. I haven’t tested it thoroughly, so it may cause issues elsewhere.
Now I’m aware that this might not be an easy task in Typst, but I’m still curious if there’s a more optimal way to define new math symbols like injlim.
I’m not sure that I know what you would still like to optimize? Do you want the implementation to be even shorter? In that case you could create another function that directly includes limits() etc…
If you want to set the baseline shift for the entire document, you can use a state variable that is used by default unless you specify a certain shift.