Expose baseline through `measure()`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 56.1k
- Forks
- 1.7k
- Avg merge
- 3d 10h
- Merged PRs (30d)
- 22
Description
Motivation
Diagramming packages like CeTZ and Fletcher need to align text and equation nodes along their baselines. To get this working properly, they need access to the vertical offset from the top of the content frame to its baseline.
#8150 laid the foundation for this by implementing baseline tracking and propagation in frames. Currently, the laid-out frame already carries correct baseline information, but measure does not expose it, so there is no clean way to access it.
To address this, I propose extending measure() to return the frame's baseline alongside width and height.
API design
Option 1: Opt-in baseline measurement
A backwards-compatible design would be to add a parameter such as:
measure(
width: auto,
height: auto,
baseline: false,
content,
) -> dictionary
With baseline: false, measure would behave exactly as it currently does and return only:
(width: ..., height: ...)
With baseline: true, it would additionally return the baseline:
(width: ..., height: ..., baseline: ...)
Option 2: Always return the baseline
The simpler API would be for measure to always return:
(width: ..., height: ..., baseline: ...)
Conceptually, I find this quite natural. However, this is not completely backward-compatible. For example, existing code like rect(..measure(body)) may not work anymore. (Note that code like let (width, height) = measure(..) won't break, since Typst allows ignoring extra keys when destructuring a dictionary.)
Use Case
CeTZ and Fletcher need to align text and equation along their baselines. This has come up in several downstream discussions (e.g., cetz-package/cetz#683, cetz-package/cetz#794, and Jollywatt/typst-fletcher#44), where getting a proper baseline alignment is currently impossible or requires verbose workarounds.
Initial implementation
I put together an initial implementation in #8799 following Option 1 to keep it backward-compatible. I don't have a strong preference between the two designs, though. Happy to adjust based on what maintainers prefer.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the baseline tracking work in #8150 and the initial implementation in #8799, then inspect the existing measure() API. Determine which API design maintainers want to support and how its compatibility implications are handled. The work is done when measure() exposes the frame baseline in the accepted form for downstream alignment use cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend-api-design, compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100