How can a subscript be attached to existing content at same level?

Hello,

to get my document consistent I am abstracting symbols/modifiers/… in functions.

E.g. instead of directly writing $hat(arrow(x))_0$ I defined functions to replace the layout/symbols in case I want to change it in the whole document:

#let vector(vec) = {
  // $bold(vec)$  // Bold symbols for vectors
  $accent(vec, arrow)$ // Arrow over symbol for vectors
}

#let estimatedValue(val) = (
  $hat(val)$
)

#let trueState(
  step-index,
) = {
  $vector(x)_#step-index$
}

I am now trying to combine estimatedValue and trueState

  • Simple approaches fail:

    #let kfEstState_1(
      step-index,
    ) = {
      $estimatedValue(trueState("")) _#step-index$
    }
    
    1. `kfEstState_1`\
       #kfEstState_1($3$) vs. $hat(arrow(x))_3$\
       (typst attaches it to the already superscripted trueState)
    
    #let kfEstState_2(
      step-index,
    ) = {
      $estimatedValue(trueState(#step-index))$
    }
    2. `kfEstState_2`\
       #kfEstState_2($3$) vs. $hat(arrow(x))_3$\
       (hat goes over the whole symbol)
    

  • Best approach so far is:

    #let kfEstState_3(
      step-index,
    ) = {
      $estimatedValue(trueState(""))zws_#step-index$
    }
    3. `kfEstState_3`\
       #kfEstState_3($3$) vs. $hat(arrow(x))_3$\
    

    image
    But it has a too large whitespace in front of the subscript.

  • I tried playing around with the move function, but that feels wrong and didn’t really work :sweat_smile:
    Best result was a combination of move, measure and hide e.g.

    #let kfEstState_4(
      step-index,
    ) = {
      context $estimatedValue(trueState(""))#move(dx: -measure(estimatedValue(trueState(""))).width, $#hide[x]_#step-index$)$
    }
    4. `kfEstState_4`\
       #kfEstState_4($3$) vs. $hat(arrow(x))_3$\
    

    • white space after the symbol
    • 3 is also to low (move function seems to not only shift in x direction, visible when removing hide function from x)
  • Looking into the underlying “typst object” also didn’t really give me clues

Does anyone have a hint how it can be achieved?

1 Like

Function kfEstState_1() works if trueState() is changed so that it only applies a subscript if there is actually something to subscript:

#let trueState(
  step-index,
) = {
  if step-index == "" {
    $vector(x)$
  } else {
    $vector(x)_#step-index$
  }
}
#kfEstState_1($3$) vs. $hat(arrow(x))_3$\

Thanks :man_facepalming: Now I’m like: why didn’t I see it?!? :rofl:

For my problem this definitely is the simplest solution.

1 Like