Hello. This seems kind of complicated without use case context (for labels). Sounds like "Real" absolute option for `place` (or alternative function) · Issue #5233 · typst/typst · GitHub.
To get consistent positioning, you need the global scope, which can only be achieved with a wrapper. Because of https://typst.app/docs/reference/layout/place/#effect-on-other-elements, I had to save the start Y position first and then place the marker there. It probably won’t work when the bottom of the quote goes to the new page.
#set page(margin: 2.5cm)
#place(rect(width: 100%, height: 100%))
#let QI(label, ..args) = {
let qi = counter("qi")
qi.step()
context [#metadata(here())<pos>]
[#metadata("qi")#label]
quote(..args)
context {
let count-marker = text(0.8em, red, weight: "semibold", qi.display())
let pos = query(selector(<pos>).before(here())).last().value.position()
place(right + top, dx: 15mm, dy: -page.margin + pos.y, count-marker)
}
}
Synesius wrote (as translated by Robert Burton): #QI(<RB2>)[It is a greater offence to ſteale dead mens labours, than their clothes.]
#QI(<NOGOOD>, block: true, attribution: [Synesius of Cyrene (_circa_ 370--_circa_ 413) in modernized Greek])[
ἡγοῦμαι δὲ ἀσεβέστερον ἀποθανόντων λόγους κλέπτειν ἢ θοἰμάτια, ὃ καλεῖται τυμβωρυχεῖν.
]
I guess you can move out this completely to a different place, that is not bounded by the margins, however, since you need it to be relative to the margin, then you need to use it anyway:
#let qi = counter("qi")
#let QI(label, ..args) = {
qi.step()
context [#metadata(here())<pos>]
quote(..args)
[#metadata("qi")#label]
}
#set page(margin: 2.5cm, background: context {
let positions = query(<pos>)
.map(x => x.value)
.filter(x => x.page() == here().page())
for pos in positions {
let num = qi.at(pos).first()
let body = text(0.8em, red, weight: "semibold")[#num]
place(right + top, dx: -page.margin + 15mm, dy: pos.position().y, body)
}
})
#place(rect(width: 100%, height: 100%))
Synesius wrote (as translated by Robert Burton): #QI(<RB2>)[It is a greater offence to ſteale dead mens labours, than their clothes.]
#QI(<NOGOOD>, block: true, attribution: [Synesius of Cyrene (_circa_ 370--_circa_ 413) in modernized Greek])[
ἡγοῦμαι δὲ ἀσεβέστερον ἀποθανόντων λόγους κλέπτειν ἢ θοἰμάτια, ὃ καλεῖται τυμβωρυχεῖν.
]
There is a slight Y shift that I don’t know how to easily fix.