I’m unsure what you mean by “thickness”, but if you want to make the spacing be relative to the current font size you should use “em” length units instead of “pt”.
What I refer to by thickness is really just that: The default value for stroke.thickness that Typst will choose when using, say, stroke(dash: "loosely-dotted").
So, in other words, what I’m asking is the default value for stroke.thickness in the context of an underline. Maybe, that’s just a documentation issue (if it turns out to be something like 0.1em as you suggest). But if it’s somehow derived differently from other font metrics, I’d be curious if and how the default value can be obtained in code.
Your second link points to the definition of the dash pattern, which doesn’t adjust the thickness. All it does is adjust the length and spacing of the underlined dashes.
From the first link, it states that the thickness is derived as follows: “If set to auto, the value is inherited, defaulting to 1pt.”
Sorry, it seems that I haven’t described sufficiently precise what my goal is:
For underlines, the default is different, namely it is based on the font, not simply 1pt. This becomes obvious when changing font size: The line thickness will scale as well in this situation.
You’re right that the dash pattern is in principle independent of stroke thickness. However, as the link to the Typst source code shows, it is in fact based on the thickness for dotted patterns (by setting dash length = thickness to obtain dots).
What I want to achieve is
keep the default thickness of the underline, which depends on the font in some undocumented way
have a dash pattern with dots, i.e. set the first element of the pattern array to the same value as the thickness
adjust the dot spacing, i.e. the second value of the pattern array, to be different from both the dotted, loosely-dotted and densely-dotted defaults (because I don’t like their looks)
Indeed if you pass a troke to the underline function, the thickness default is based on the font thickness, or defaulted to 0.06em.
Because this value is based on the actual font you are using (i.e. some fonts will set it to different values), the pt/em value is not exposed through typst.
#underline(stroke: stroke(
// works
dash: ("dot", 7pt)
),)[#lorem(10)]
Downside with this is that you can’t set it to 0.7 times the thickness, so this wouldn’t work
#underline(stroke: stroke(
// does not work
dash: ("dot", 0.7 * "dot")
),)[#lorem(10)]
It seems the best way to achieve “relative thickness” would be through trial and error, or by exploring the .otf themselves. Maybe somebody else knows a better solution.
Nice, thanks, this is actually very helpful already: I’m pretty happy with dash: ("dot", "dot") in this case, which is even denser than densely-dotted for the font in question.
I completely missed the info on "dot" when reading the documentation. I’ll probably open a GitHub issue, asking to amend the docs slightly: I feel like it would be helpful if the actual values for the shorthands would be specified. (e.g. densely-dotted is ("dot", 1pt) but if I wanted to slightly tweak that, I currently need to first read the Typst source to figure out what densely-dotted corresponds to.)
No problem. I agree that the docs could do with some improvement, and it would also be nice if instead of "dot" we had something concrete like underline.thickness which we could use set rules on, and that we could e.g. multiply (it wouldn’t quite work like this because of the way stroke is implemented, but still). Of course, this would be a separate issue