How to combine many show rules into one show rule?

How to refactor the following typ code, I see code duplication. It is possible to
combine the 3 show rules into a single show rule? Thank you

#show "one": name => text(green)[#name]
#show "two": name => text(red)[#name]
#show "three": name => text(orange)[#name]
Dummy text one, Dummy text two, Dummy text three 

The solution is as follows:

#show regex("\b(?:one|two|three)\b"): name => {
  if name == [one] {
      text(blue)[#name]
  }
  else if name == [two] {
      text(red)[#name]
  }
  else if name == [three] {
     text(green)[#name]
  }
}
#[Dummy text one, Dummy text two, Dummy text three] 

Another option using the same method but collecting all the text->color conversions into a table:

#let colors = (
  "one": blue,
  "two": red,
  "three": green
)

#show regex("\b(?:" + colors.keys().join("|") + ")\b"): name => {
  let key = name.text
  let color = colors.at(key)
  set text(color)
  name
}

Dummy text one, Dummy text two, Dummy text three

image

The following topic also mentions another way of achieving this, using selector.or():

2 Likes

Thank you for the feedback

1 Like

A single regex show rules might be more expensive than several plain text show rules. As was mentioned in How to combine many show rules into one show rule? - #3 by gezepi, you can automate the creation of multiple show rules with some kind of loop.

#let colors = (
  "one": blue,
  "two": red,
  "three": green,
)

#show: doc => {
  for (selector, color) in colors {
    doc = {
      show selector: set text(color)
      doc
    }
  }
  doc
}

// #show: doc => colors.pairs().fold(doc, (doc, (selector, color)) => {
//   show selector: set text(color)
//   doc
// })

Dummy text one, Dummy text two, Dummy text three

As result, no duplication and potentially more performant code. But the more entries, the slower it will get regardless.

1 Like

A single regex show rules might be more expensive than several plain text show rules.

I haven’t benchmarked but from the way the compiler is implemented, a single regex show rule is very likely to be faster than multiple plain text rules.

1 Like

Considering word bound check and much more complicated syntax?

The regex crate used by Typst supports only “true” regular expressions that can be implemented efficiently with finite automata. This way they can guarantees O(m*n) performance (regex of size m, string of size n). You’d still need to benchmark to make sure what is faster, but at least it tells us we won’t get into pathological cases as can happen with Perl-compatible regular expressions, as explained in this article.