#For Loop Without Additional Scope

9 messages · Page 1 of 1 (latest)

low quartz
#

Is there any way to create a for loop without inducing a higher scope. The main goal of this is to avoid the repetition of calling many show rules.

In particular, consider something like:

let theorem_kinds = ("theorem", "corollary", "conjecture", "lemma", "problem")

for kind in theorem_kinds {
  show figure.where(kind: "theorem"): it => { ... }
}

where it would be desirable for the show rules to apply in the scope beyond the for loop.

I tried building a string and using eval but it didn't seem to work.

limber valley
#

You could have the show rule without the where and do the check inside the function

#
#show figure: it => {
  if it.kind in theroem-kinds {
    ...
  } else {
    it
  }
}
covert igloo
#

see here: #1216679685182722058 message

The trick is not to get rid of the scope, but to have the for loop generate content on each iteration that includes one more show rule

low quartz
limber valley
low quartz
#

I did end up getting it to work by doing it recursively, like so

let apply_theorem_like(body, kinds : ()) = {
  if kinds.len() == 0 {
    body
  } else {
    show figure.where(kind: kinds.at(0)): it => { ... }
    show: apply_theorem_like.with(kinds: kinds.slice(1));

    body
  }
}
  
show: apply_theorem_like.with(kinds: theorem_kinds);
limber valley
#

?r

#let theroem-kinds = ("theorem", "corollary", "conjecture", "lemma", "problem")

#show figure: it => if it.kind in theroem-kinds {
  set block(fill: red)
  it
} else { it }

#for kind in theroem-kinds {
  figure(kind, kind: kind, supplement: kind)
}

#figure("some other", kind: "some other", supplement: "")