How to change theme of `raw` depending on state?

Hello,
I have a global state for the mode of my document - such as screen or print. My goal is to make raw blocks have no formatting, regardless of language. Something like this:

#let docmode = state("mode", "screen")

#docmode.update("print")

```python
print("Hello world")
```

The closest I have got is this, it seems to

#show raw: it => context {
	if docmode.get() == "print" {
		set text(fill: black);
		it
	} else {
		it
	}
}

However, it only seems to set the color of otherwise non styled parts of the code. Is there an easy way to do this without wrapping the entire document in #context?

Does your docmode change across the document? If not, then #let docmode = "screen" would be enough.

#let docmode = "screen"
// Or #let docmode = "print"

#set raw(theme: if docmode == "print" { none } else { auto })
// Equivalent code: #set raw(theme: none) if docmode == "print"

```python
print("Hello world")
```

See also the docs for raw.theme.

1 Like

If the state does change in the document, then a show rule on raw can do this:

#let docmode = state("mode", "screen")

#docmode.update("print")

// https://github.com/typst/typst/issues/1331
#show raw: set text(11pt * 0.8)

#show raw: it => context {
  if docmode.get() != "print" or it.theme == none { return it }
  let fields = it.fields()
  let text = fields.remove("text")
  _ = fields.remove("lines")
  fields.theme = none
  raw(..fields, text)
}

// #docmode.update("screen")

```python
print("Hello world")
```

This won’t work, as context will be applied once in-place, and not per raw element:

#show: it => context {
  set raw(theme: none) if docmode.get() == "print"
  it
}
2 Likes

Yes, unfortunately it does

Thank you! That’s exactly what I wanted!

1 Like