I want to create a template that allows to reuse labels between sections, but having difficulty working with queries and not have them cause issues due to not being able to converge.
The goal of my template is to have multiple sections with the same subsections, and be able to use label and references to jump between the subsections.
For example:
= Section 1
== Sub 1<sub1>
== Sub 2<sub2>
Go to @sub1
= Section 2
== Sub 1<sub1>
Go to @sub2
== Sub 2<sub2>
Is there a way to limit reference or query scopes to within a single section?
You can do it like this. In this case - find the top level headings and decide a “bounding box” - only look locally inside the current top level heading. Then place a custom link to that (not using ref)
#let maybelast(x) = {
if x.len() > 0 { return x.last() }
}
#let maybefirst(x) = {
if x.len() > 0 { return x.first() }
}
#let localref(lab) = context {
let mysections = query(heading.where(level: 1).before(here()))
let nextsections = query(heading.where(level: 1).after(here()))
let mysection = maybelast(mysections)
let nextsection = maybefirst(nextsections)
let sel = selector(lab)
if mysection != none {
sel = sel.after(mysection.location())
}
if nextsection != none {
sel = sel.before(nextsection.location())
}
let locations = query(sel)
for loc in locations {
link(loc.location())[Section #loc.body]
break
}
}
= Section 1
== Sub 1<sub1>
== Sub 2<sub2>
Go to #localref(<sub1>)
= Section 2
== Sub 1<sub1>
Go to #localref(<sub2>)
== Sub 2<sub2>
We can do this because labels don’t need to be unique. But labels used with ref seem to need to be unique, so then we can’t do this with ref.
Ahh I see! I was considering going this way at first, but, wanted to make sure there wasn’t an easier way to modify the @ref behavior to do it. And your code looks a lot simpler and clean than what I would have done lol! I was trying to loop over queries and compare heading levels and stuff…
I don’t understand why for loop is used if each subsection has a unique name, and you want to reference one at a time. There should be either query(sel).first() or an additional assertion before this.