Variants for superior, inferior, projective, and injective limits are an interesting challenge for typesetting engines with mathematical capabilities.
They have both a subscript expression and a stretchy symbol (an arrow or a bar) that indicates the direction and nature of the limit.
The symbol is stacked below or above the limit.
In display mode, the expression is below the limit.
In inline mode, the expression is on the right of the limit, but the symbol remains above or below the limit. So the symbol is not moveable, while the expression is, depending on the context.
\begin[papersize=a7]{document} \nofolios \neverindent \use[module=packages.math] \font[size=12pt] \set[parameter=math.font.family,value=Libertinus Math] \set[parameter=math.font.size,value=12] \begin[mode=display]{math} \projlim_{i \in I} A_i = \varprojlim_{i \in I} A_i \end{math} Inline: \math{\projlim_{i \in I} A_i = \varprojlim_{i \in I} A_i} \begin[mode=display]{math} \injlim_{i \in I} A_i = \varinjlim_{i \in I} A_i \end{math} Inline: \math{\injlim_{i \in I} A_i = \varinjlim_{i \in I} A_i} \begin[mode=display]{math} \limsup_{n \to \infty} a_n = \varlimsup_{n \to \infty} a_n \end{math} Inline: \math{\limsup_{n \to \infty} a_n = \varlimsup_{n \to \infty} a_n} \begin[mode=display]{math} \liminf_{n \to \infty} a_n = \varliminf_{n \to \infty} a_n \end{math} Inline: \math{\liminf_{n \to \infty} a_n = \varliminf_{n \to \infty} a_n} \end{document}
sile -o varlimits-sile.pdf varlimits-sile.sil
\documentclass[12pt]{article} \usepackage[paperheight=105mm,paperwidth=74mm,margin=4mm]{geometry} \pagenumbering{gobble} \setlength{\parindent}{0pt} \usepackage{libertinus} \usepackage{fontspec} \usepackage{unicode-math} \begin{document} $$ \projlim_{i \in I} A_i = \varprojlim_{i \in I} A_i $$ Inline: $\projlim_{i \in I} A_i = \varprojlim_{i \in I} A_i$ $$ \injlim_{i \in I} A_i = \varinjlim_{i \in I} A_i $$ Inline: $\injlim_{i \in I} A_i = \varinjlim_{i \in I} A_i$ $$ \limsup_{n \to \infty} a_n = \varlimsup_{n \to \infty} a_n $$ Inline: $\limsup_{n \to \infty} a_n = \varlimsup_{n \to \infty} a_n$ $$ \liminf_{n \to \infty} a_n = \varliminf_{n \to \infty} a_n $$ Inline: $\liminf_{n \to \infty} a_n = \varliminf_{n \to \infty} a_n$ \end{document}
xelatex -interaction=batchmode -halt-on-error -jobname data/varlimits-xelatex varlimits-xelatex.tex
// 2025, Didier Willis // License: MIT. // Typst does not have these extended limits out of the box: // projlim, injlim, varprojlim, varinjlim, // varlimsup, varliminf. // So here is a possible implementation... // Total newbie, so it's maybe not idiomatic #let varlim(arrow) = context { let lim = "lim" let lim-width = measure(lim).width let arrow-height = measure(arrow).height let varlimop = box( width: lim-width, baseline: arrow-height, box( width: 0pt, baseline: arrow-height, [#math.stretch(arrow, size: lim-width)] ) + box( baseline: 0pt, width: 0pt, lim ) ) return varlimop } // Helpers #let strut = context { // Weird way to do a small adjustment for varliminf // so that the limit expression is a bit lower block(height: measure("").height, width: 0pt) } #let varprojlim = math.limits(varlim(sym.arrow.l), inline:false) #let projlim = math.limits("proj\u{2009}lim", inline: false) #let varinjlim = math.limits(varlim(sym.arrow.r), inline:false) #let injlim = math.limits("inj\u{2009}lim", inline: false) #let varliminf = math.limits(underline("lim"+strut), inline: false) #let varlimsup = math.limits(overline("lim"), inline: false) // --- Now the intended document --- #set page( paper: "a7", margin: 4mm, ) #set text( font: "Libertinus Serif", size: 12pt, ) $ projlim_(i in I) A_i = varprojlim_(i in I) A_i $ Inline: $projlim_(i in I) A_i = varprojlim_(i in I) A_i$ $ injlim_(i in I) A_i = varinjlim_(i in I) A_i $ Inline: $injlim_(i in I) A_i = varinjlim_(i in I) A_i$ $ limsup_(n -> oo) a_n = varlimsup_(n -> oo) a_n $ Inline: $limsup_(n -> oo) a_n = varlimsup_(n -> oo) a_n$ $ liminf_(n -> oo) a_n = varliminf_(n -> oo) a_n $ Inline: $liminf_(n -> oo) a_n = varliminf_(n -> oo) a_n$
typst compile varlimits-typst.typ varlimits-typst.pdf