How do you resolve a length in the current context?

TL;DR: I would like to execute 1.1em.to-absolute() with to-absolute() using the current context.

I suspect this is an instance of the X Y problem, so here’s the actual issue I’m running into.

I have the following show rules in my document.

#show raw: set text(size: 1.1em)
#show raw.where(text: "keyword", lang: none, block: false) : 
  it => raw(it.text, lang: "foo", block: false)

The purpose of the second show rule is to allow me to write `keyword` instead of ```foo keyword``` in my document, as a sort of convenience. However, defining it in this way causes an issue: I feel that the set text(size: 1.1em) is being run twice: once before the transformation happens, and ance afterwards. It occured to me that, to fix it, I could use an absolute length instead of a relative one. However, I would still like this absolute length to be computed relatively to the regular font size. I am not too familiar with contextual functions though, so I don’t know how to achieve the effect I want, or if it’s even possible. Otherwise, I’d be curious to know other ways in which I could solve my issue

Hi @Ayhon,

currently it isn’t possible to use contextual show-set rules.

With the additional context you provided simply applying lang via a show-set rule should have the effect you want without creating a new raw element:

#show raw: set text(size: 1.1em)
#show raw.where(text: "keyword", lang: none, block: false) : set raw(lang: "foo")

Another less elegant solution is to set the size inside the show rule, there text.size is the 1.1em scaled raw text size.

#show raw: set text(size: 1.1em)
#show raw.where(text: "keyword", lang: none, block: false) : it => {
  show raw: set text(size: text.size)
  raw(it.text, lang: "foo", block: false)
}

And the third option is to create a global contextual show rule, but I’m not sure whether it has any side-effects, so I would avoid it if possible.

#show: it => context {
  show raw: set text(size: 0.8*1.1em.to-absolute())
  it
}
#show raw.where(text: "keyword", lang: none, block: false): it => raw(it.text, lang: "foo", block: false)

(The 0.8 scaling is needed, because Typst by default scales raw text by that factor and if you do 1.1em.to-absolute() the that 0.8em scaling gets lost.)