I’m creating a theorem/problem environment where the number sits to the left, aligned with the first line’s baseline
The MWE below works perfect when body is inline text,
but breaks when body starts with a block element (grid, block, etc.)
The number aligns with the empty first line instead of the actual first line of content inside the grid.
Question: Is there a way to make the number always align with the baseline of the first visible line of text, regardless of whether content is inline or block-level?
#set page(
margin: 2cm,
)
#set text(
size: 16pt,
)
#let theorem(number, body) = block(width: 100%, stroke: 0.5pt)[
#box(width: 0pt, stroke: 2pt + red, height: 1em)[
#place(bottom + right, dx: -8pt)[#text(weight: "bold", str(number) + ".")]
]#h(0pt, weak: true)#body
]
#theorem(234)[
this is desired behavior $display(1/2) + display(1/2)/display(1/2)$. \
Number on the left is aligned with the first line's baseline.
]
#theorem(22)[
#grid(
columns: (1.5fr, 1fr),
block[
But it works until content of theorem is another block, like this grid, for example.
Since there is an inline element in the first line,
this block starts with the new line...
],
[
#align(center, square(fill: blue, height: 2cm))
],
)
]
Claude partially solved it by iterating through theorem’s body.fields.at(“children”) and looking for either the first non-empty content block or grid. If it finds grid then it looks for the first cell.
In both cases it pastes 0-width box inside and places the number relative to this box.
Works for simple grids of structure #grid([], [], ...), where the first cell is indeed a text, but fails if it has enum items for example, or another blocks…
Also works if #theorem’s body is block
Any other cases it fails…
Found out that my problem is related to
hopefully developers will come up with solution to this issue. To be fair, in LaTeX, it is also impossible to get consistent aligning without heavy hacking
I don’t think there is any other way than to do what you describe, and try to place from inside the block element.
You could extend this to do this recursively, e.g. if the first element is a block, look at its first child and so on, until you land at some inline content (or some block element you don’t know how to process.
As you correctly recognized, this requires handling all the different block-level elements separately, making it annoying to implement.