I'm creating this issue for discussion purposes, as I think it's going to be impossible to fix/implement without changes to typst itself.
As it stands, there's no way to figure out where a page break will occur in the rendered PDF, meaning there's no way to re-order the pages. I did some experimenting with some of the introspection methods, but got stuck.
I was able to get an array of content blocks from within a piece of text:
let paragraphChildren(body) = {
let contents = body.fields().at("children")
}
On a content block, the fields() method returns a dictionary, but with only one key (children). This in turn contains an array of various content blocks; sometimes it's a full paragraph, sometimes not.
My original idea was to use this plus layout() to get a running tally of the height of each content block, and then compare that to the page height. But there doesn't seem to be a way to do this. Variable scope rules (a for loop can't write to a variable not stored within the loop itself, for example) mean just storing the total in a variable is out. I played with state as a possible solution, but because of the way this works, it broke typst's built-in loop protections. Here's the full code I tried so far:
let contentMeasure(body) = {
let blockHeight = state("b", 0) // height of a given block
let contentHeight = state("c", 0) // cumulative total
let everything = body.fields()
let contents = body.fields().at("children")
for c in contents {
layout(size => [
#let (height, ) = measure(block(width: 100%, c))
#blockHeight.update(height)
])
context {
let oldHeight = contentHeight.get()
contentHeight.update(
oldHeight + blockHeight.get()
)
}
}
}
I'm not sure where to go from here, unfortunately. But who knows, maybe this will give someone else an idea?
I'm creating this issue for discussion purposes, as I think it's going to be impossible to fix/implement without changes to
typst
itself.As it stands, there's no way to figure out where a page break will occur in the rendered PDF, meaning there's no way to re-order the pages. I did some experimenting with some of the introspection methods, but got stuck.
I was able to get an array of content blocks from within a piece of text:
On a content block, the
fields()
method returns a dictionary, but with only one key (children
). This in turn contains an array of various content blocks; sometimes it's a full paragraph, sometimes not.My original idea was to use this plus
layout()
to get a running tally of the height of each content block, and then compare that to the page height. But there doesn't seem to be a way to do this. Variable scope rules (afor
loop can't write to a variable not stored within the loop itself, for example) mean just storing the total in a variable is out. I played withstate
as a possible solution, but because of the way this works, it broketypst
's built-in loop protections. Here's the full code I tried so far:I'm not sure where to go from here, unfortunately. But who knows, maybe this will give someone else an idea?