Is there a way to make arguments of element function optional/dependent?

Say you have a longer element function where one or multiple parameters depend on something. Is there a way to make single (or multiple) parameters optional without repeating the whole element in an if-clause?

Non-working example to showcase what I mean:

#let warning = true
#block(
  stroke: 1pt + black,
  (if warning { (fill: red) }), //something like that
  inset: 10pt,
  radius: 2pt,
)[Test]
Example Result

test-showcase

PS: I know you could define a variable like fill: some-fillcolor and make that dependent on x. But I was wondering if it was possible, so it is not necessary to restore defaults or change multiple parameters combined at once etc.

You have two options afaik

  1. If in the value:
    #let warning = true
    #block(
      fill: if warning {red} else {none}
    )[test]
    
  2. Args dictionary:
    #let warning = true
    #let args = (:)
    #if warning {
      args.insert("fill", red)
    }
    #block(..args)[Test]
    
1 Like

You were actually already very close to something that works. You just need spread the if statement with the dictionary with .. instead of passing it as is:

#let warning = true
#block(
  stroke: 1pt + black,
  ..if warning { (fill: red) },
  inset: 10pt,
  radius: 2pt,
)[Test]
3 Likes

Aahhh, perfect! Thank you both. I learned from all approaches! I would have marked both answers as solution, but since that is not possible the one @Eric gave is maybe even a little closer to what I want to achieve since it omits the parameter completely and is the very compact at the same time.

:pray::pray:

2 Likes

I think your solution is very idiomatic. To make it even a little more compact, let me note:
else {none} can be omitted altogether since if-statements without an else statement will produce none in the negative branch.

#block(
  fill: if warning {red}
)

This should then be the shortest solution of all :)

1 Like

Erics solution is of course great when you have more than one parameter depending on the warning (which could be a common case). Otherwise, fill: if warning {red} seems a tad more readable.

Eric’s solution is also necessary when the default value of the parameter isn’t none. For example, stroke: if warning { red } for a table would cause it to not have any stroke if warning is false, which might be fair (but might not be the desired behavior, depending on what one wishes to do). Personally, I usually use the if warning { red } solution because what I usually want is precisely to have it be none (i.e. remove stroke / fill / …), but it all depends on your goal :slight_smile:

2 Likes