I am trying to find a way to style different parts of a heading body separately.
To do this I need to read the heading body content as a string → Locate the “:” character → Split the string → Render it with different styling:
#show heading.where(level: 5): it => {
// str(it.body) // ERROR: content can not be converted to str
// it.body.position(":") // ERROR: Element sequence has no method `position`
// I need a way to split it.body into "SOLUTION:" and
// " Two and three is five" so I can style them separately.
text(weight: 600, [SOLUTION: ])
text(weight: 300, [ Two and three is five])
}
===== SOLUTION: Two and three is five
Needed output (first word is bold, the rest is regular text):
SOLUTION: Two and three is five
Further, if anyone knows how to output the different methods on an object I would be greatfull. E.g. what are the methods on the heading? (it.body, it.numbering… what else?)
Short description of my actual use-case:
I am typesetting a book written in markdown, using cmarker to read the markdown and convert to Typst. To style unique part of the markdown, I give it a heading as a handle to grab via Typst show rules, in this case heading with depth 5 is used for math solutions and math notes.
There’s no need to do any string manipulation, you can use regex to match the part of the body that comes after “:” and style that differently:
#show heading.where(level: 5): it => {
set text(weight: 600)
show ":": set text(weight: 600) // undo matching of ":" in show rule
show regex(":.*"): set text(weight: 300)
it
}
(possibly the show rule matching only “:” could be combined into the regex one, but I am bad with regex…)
I don’t know exactly how cmarker works, but if it’s possible i’d pass this data to a custom solution function, instead of doing semi-hacky things with headings It works here, but for more complex tasks doing it this way is easier, and doesn’t lead to weird artefacts (e.g. you might not want that solutions are headings)