The documentation for text
indeed isn’t very clear about this, but here’s what’s going on:
- The most common named arguments for
text
- mostly unambiguous ones such asfill:
andsize:
- can also be used positionally as an exception, just for convenience. These parameters are not separately listed as positional in the documentation at the moment. Note that you can implement this same behavior in your functions by taking and parsing arbitrary amounts of arguments (see Arguments Type – Typst Documentation). - The two positional arguments you see (
content
andstr
) are currently misleading and need improvement. Basically, what’s going on here is thattext
is a special element, in that its element constructor (the#text(...)[stuff]
function), instead of constructing a newtext
, applies the given parameters as local styles, as if you were applying a set rule on the given content. That is:
This means that the whole#text(red, font: "Arial")[Hello world!] // is equivalent to #[ #set text(red, font: "Arial") Hello world! ]
#text()
function (not the element itself, but its constructor) only exists as a convenience to applytext
element set rules to the given content parameter, which is strictly positional. Therefore, thatcontent
you see is the content to apply the set rules to. (This is similar, for instance, to#align
:#align(center)[abc]
is more or less equivalent to#[ #set align(center); #block[abc]]
.)
But then what is thestr
parameter? That’s where thetext
element part comes in: the realtext
elements are simple wrappers around strings. They contain no formatting at all - they are the most basic element of all text, so it is natural that any formatting would be done by elements (such asstrong
oremph
) containing those more fundamental units, and not the other way around. So, thisstr
“parameter” is actually the.text
field of text elements (the contained text) “leaking” into the docs, but you can’t actually pass that parameter because you cannot construct text elements by yourself: they are automatically generated for you as you type text in a markup block. This means that#text("ABC")
is actually the exact same as#text[ABC]
which is also the exact same as#[ABC]
, sincetext
, when used as a function, only applies styles to the text elements inABC
, but no styles are being configured so nothing happens. It’d certainly be much nicer if this could be displayed properly!
Hope this clears it up. Feel free to open an issue in GitHub - typst/typst: A new markup-based typesetting system that is powerful and easy to learn. to suggest an improvement to this doc page, if there isn’t already one!
Now, just to address your individual questions:
You’d have to look for arguments marked with #[parse]
in the internal code, since those basically take the whole argument list into account (basically the same idea as using ..args
in a function and manually extracting arguments however you want, as I hinted at above). Then, they might be pseudo-positional, or might accept more than one name (as seen in #pad(x: 5pt)
being equivalent to #pad(left: 5pt, right: 5pt)
), and so on.
text
is simply an exception as it’s such a basic element. The same exception was not applied to highlight
.
The relevant line is here: typst/crates/typst/src/text/mod.rs at e0d809680aed778443a4797bc044376dbe15347e · typst/typst · GitHub
Note the usage of named_or_find
onto the argument list instead of just named
.