Can contextual math attachments be properly aligned?

If I have this code (the final version)

#let my-counter = counter("my-counter")

#let alternate(it) = {
  context {
    let value = my-counter.get().first()
    if calc.even(value) {
      it
     }
  }
  my-counter.step()
}



$
  alternate(integral)_1^2 \
  integral_1^2 \
  alternate(integral)_1^2 
$

the function alternate doesn’t properly alternate the integral, if you will (in typst 12 and 13).
{E915078B-53A2-4A1E-A911-C93697A2EC5A}

I was told this due to the fact that typst no longer knows how to attach the accents because of the context. But maybe there’s a way to take this into account for this function?

You can pass the entire integral with the attachments to the function alternate() and then disable the integral symbol with a conditional show rule. This will correctly align the attachments relative to the integral symbol.

#let my-counter = counter("my-counter")

#let alternate(it) = {
  context {
    let value = my-counter.get().first()
    show sym.integral: if calc.odd(value) { none } else { it => it }
    it
  }
  my-counter.step()
}

$
  alternate(integral_1^2) \
  integral_1^2 \
  alternate(integral_1^2)
$

I find this solution very specific and not extensible, yet it achieves the goal in this very specific case.

For instance, to include the sum symbol I’d have to manually add it as well as any other new symbol. And what about alternating just content without the math mode, how would I know which part to keep (i.e. what would be the attachment)?

I would argue that my solution just matches the specificity of your question. :grinning:

If you want to adapt the solution to other (math) symbols, you can use the following show rule

show it.base.text: if calc.odd(value) { none } else { it => it }

Note that this requires the input to have at least one attachment. Otherwise it.base is not available and you would have to use it.text directly. You could parse the function parameter it to figure out what you need to extract to further generalize your show rule.

Do you have an example what you would want to alternate without math mode? Maybe the counter + context approach is not even necessary and there is an easier solution available.

I guess you’re right. It’s just this particular function is of low interest to me I picked it because of this post thinking it’s of some importance since it’s been discussed before. My very initial motivation was this usage and there my first design was very similar to the alternate function

#let my-counter = counter("my-counter")
#let k = 1
#let group(it) = {
  context {
    let value = my-counter.get().first()
    if value==k{
      hide(it)
     }
   else{
      it   
     }
  }
  my-counter.step()
}

This function suffers from that same problem with attachments. This particular usage with manim gives natural examples of the use outside of math context e.g.

#group[= Introduction]
... 

But maybe if I combined these two approaches making 2 functions and using this one only if there’s an attachment it would make more sense than trying to write one huge function for each edge case.

If I understand it correctly that you would like to selectively hide elements to build animations, it could be worth it to take a look at the source code of the Touying package? They have implemented functions to hide content based on the current slide.

1 Like