Hi, I would like to write a function that does the following:
- for any given paragraph (
par
)
- if this paragraph is followed by a code block (
raw
)
- make this paragraph a block with (
sticky: true
)
That way I wouldn’t have codeblocks start a page but have the explanatory line above it which makes it much nicer.
I just could not figure out enough of the typst scripting syntax yet :P
WARNING: This may NOT be the intended way to use Typst. The code below may interfere with other parts of your document.
#let stick-par-raw(it) = {
let func-seq = [].func()
let func-space = [ ].func()
let func-styled = [#set text(style: "normal")].func()
let is-space(e) = (e.func() == func-space or e.func() == parbreak)
if (it.func() == func-seq) {
let children = it.children
let processed = false
let breaked = true
for i in range(children.len()) {
let child = children.at(i)
if (child.func() == par or (child.func() == text and breaked)) {
if (i + 2 < children.len()) {
let next-child = children.at(i + 1)
let next-next-child = children.at(i + 2)
if (is-space(next-child) and (next-next-child.func() == raw)) {
block(sticky: true, child)
next-child
block(sticky: true, next-next-child)
processed = true
continue
}
}
}
breaked = false
if (child.func() == parbreak) {
breaked = true
}
if (child.func() == raw and processed) {
processed = false
continue
}
if (child.func() == func-seq) {
stick-par-raw(child)
continue
}
if (child.func() == func-styled) {
func-styled(stick-par-raw(child.child), child.styles)
continue
}
child
}
} else {
it
}
}
#show: stick-par-raw
#set page(height: 100pt, width: 300pt)
#lorem(10)
#lorem(10)
```cpp
int main();
```
How it works
The function stick-par-raw
processes everything in your document, which is likely a sequence
, and retrieves all of its children.
Within its children, the function identifies consecutive elements like par
(or text
with a preceding parbreak
) followed by a space
or parbreak
, then followed by raw
. It wraps the par
and raw
in a sticky block
, and for elements that do not match this pattern, it returns them as they are.
The reason I mentioned that this code might break other parts of your document is due to the simplicity of my test case. In a real document, there may be incomplete cases or unforeseen edge cases. Therefore, you might need to enhance this script further to fully meet your requirements.
1 Like