I recommend this:
#show: rest => context {
let x-height = measure({
set text(bottom-edge: "baseline", top-edge: "x-height")
[x]
}).height
let ex = x-height / 1em.to-absolute() * 1em
set text(
top-edge: 2.8 * ex * 0.72,
bottom-edge: 2.8 * ex * 0.28,
)
set par(leading: 2.8 * ex * 0.28)
rest
}
#lorem(10)
Explanation:
-
The x-height will depend on the font, so it’s context-sensitive. Therefore, we have to put everything that depends on x-height in a
context {…}.To simplify later writing, I use a
show: rest => …rule to transform the whole document afterwards. -
let x-height = measure(…).heightis your original idea. I use"x-height"instead of"bounds"for thetop-edgeparameter, because it is the metric defined by the font designer, and does not depend on the specific character. -
x-heightis an absolute length (in points), andlet ex = x-height / 1em.to-absolute() * 1emwill make it to relative to the font size. Doing so will make your leading settings look better for headings, where have larger font size.For Libertinus Serif,
exis about0.43em.
Besides, you can go to ```ex``` as a unit · Issue #2405 · typst/typst · GitHub and click
to express the wish for this to be natively supported by typst.