Why my set and show rules in might be ignored when using if condition? (scope issue)

I have a template which I need to use different code to achieve the same behaviour in different versions

here my bib file

@article{test2024,
  title     = {Recent Advances in Something Important},
  author    = {Test, John A. and Example, Jane B.},
  journal   = {Journal of Important Things},
  year      = {2024},
  volume    = {42},
  number    = {1},
  pages     = {123--145},
  publisher = {Academic Publishers}
}

@book{test1999,
  title     = {Classic Book on Important Topics},
  author    = {Test, Robert C.},
  year      = {1999},
  publisher = {Classic Publishing House},
  address   = {New York},
  edition   = {2nd}
}

Code that should work

#let spacing = 0.65em

#set page(
  paper: "a4",
  margin: (x: 2.5cm, y: 2.5cm),
)

#set heading(numbering: "1.")

// Bibliography settings
#set bibliography(
  title: "References",
  style: "ieee",
)

// Configure bibliography spacing based on Typst version
#if sys.version >= version(0, 12, 0) {
  show bibliography: set par(spacing: spacing, leading: spacing)
} else {
  show bibliography: set block(spacing: spacing)
}



= Introduction

This is a sample document demonstrating bibliography settings in Typst. Here's a citation to a something @test2024 and another reference @test1999.

Some more text here to show the spacing...

= Conclusion

The bibliography will appear below with custom spacing and styling.

// Define bibliography data in YAML format



#bibliography("bibliography.bib")

but it work only if I apply it directly outside of #if - is this issue of scope of #if?

#show bibliography: set par(spacing: spacing, leading: spacing)

I was able to solve similar problem with using if clause options, but I am not so sure anymore :(

  // Set space between paragraphs
  if sys.version >= version(0,12,0) {
    set par(spacing: spacing)
  } else {
    show par: set block(spacing: spacing)
  }

Hi @danborek,

you are correct, it is a scope issue. Set and show rules are scoped and only apply inside the scope, in your case inside the if.

You can avoid the scope issue by using set-if rules.

#show bibliography: set par(spacing: spacing, leading: spacing) if sys.version >= version(0, 12, 0)
#show bibliography: set block(spacing: spacing) if sys.version < version(0, 12, 0)

Or the other option would be this:

#show bibliography: it => {
  if sys.version >= version(0, 12, 0) {
    set par(spacing: spacing, leading: spacing)
    it
  } else {
    set block(spacing: spacing)
    it
  }
}
1 Like

Thanks @floki!

not so nice option would be this:

Is this rather esthetic preference about code or is there something about the use of it in typst that I should be careful over and not to overuse it?
As I am doing mostly Python recently, my first idea would be to use 2nd pattern as this more reflect my thinking (in pseudocode)

1 Like

I don’t know why I added “not so nice” to the answer, the first option is just my preference. I edited the answer to not confuse anyone else.

1 Like