Hi there!
I recently created a travel photo book using typst, and a major annoyance was laying out the images such that
- their aspect-ratio is preserved,
- orderly alignment at edges,
- constant gap between images,
- varying layouts between pages.
So I created automosaic. You can either manually specify a course arrangement and let the cell sizes be computed internally, like so:
#import "@preview/automosaic:0.1.0": *
#context display-content-tree(
(
image("a.jpg"), // root level
(
image("b.jpg"), // sub-group
(
image("c.jpg"), // subsub-group
image("d.jpg"),
// (...) // can be nested infinitely
),
),
),
axis: "horizontal", // root-level direction, horizontal or vertical
)
, or pass a flat list of images (or other content) to compute the optimal layout like so:
#import "@preview/automosaic:0.1.0": *
#context display-auto-layout(
(
image("a.jpg"),
image("b.jpg"),
image("c.jpg"),
(body: image("d.jpg"), weight: 2), // specify a weight (default: 1) to give this element more space in the auto-layout
// (body: [Some Text], aspect: 0, constant-size: 3cm) // work-around for text or other content which can't be scaled the same way as images
),
selector: "1", // select the "best" layout
// selector: "1.", "1..", ... // equally well-scored reorderings of the same layout
// selector: "2", "3", ... // next-best layouts, in descending order of score
)
To determine the optimal layout, a cost function weights:
- the amount of used-up space by the entire layout (compared to the available space),
- and the relative area of each image (i.e., ‘weight: 2’ means that image ideally gets double the space as other ‘weight: 1’ images).
Examples
Example of the same auto-layout in varying parent containers:
An auto-layout with a few more elements:
Let me know what you think! I hope it is useful to some.
Thoughts
I do not think there is a way to force typst to preserve aspect ratios in, for example, grids (without manually computing cell sizes). If you have an idea, please share it.
Also, text content requires a constant area constraint, as opposed to the constant aspect-ratio constraint implemented here. This would be a great addition in the future! Right now (unscaled) text needs some workarounds, and the auto-layout can need some tuning if text is involved.

