Make figure text the width of the figure?

Hello!

Suppose I have a figure:

How to do this in typst?

A MWE using rect here:

#figure(
  rect(width:10cm, height: 5cm),
  caption: 
    [_A coastal hydrodynamics simulation of wave impact on a light house using a particle based approach. Figure courtesy of Ihmsen et al._]
) 

Can I make it a default somehow?

Kind regards

Hi, you can use a show rule on the figure to measure its size, and use a nested show rule on the caption to restraining its size to the previously measured one.

I believe this to be what you’re going for:

#set page(width: auto, height: auto, margin: 2em)
#show figure: it => {
	let w = measure(it.body).width
	set par(justify: true)
	show figure.caption: cap => box(width: w, cap)
	it
}

#figure(
  rect(width:10cm, height: 5cm),
  caption:
    [_A coastal hydrodynamics simulation of wave impact on a light house using a particle based approach. Figure courtesy of Ihmsen et al._]
)

which creates
image

1 Like

Amazing!

Just one question, if you use an actual image and set width to: width: 60% does the function you made also break for you? I get a width of 0pt in that case…

Kind regards

in that case you need to still wrap in in a layout call, to give it the context it needs

#show figure: it => layout( sz => {
	let w = measure(
			it.body,
			width: sz.width
		).width
	set par(justify: true)
	show figure.caption: cap => box(width: w, align(left,emph(cap)))
	it
})

2 Likes

Amazing, thanks a ton!

What is it that the layout does and how do I know when to use it? I don’t think I would have realized that on my own…

I find typst has great documentation, it’s worth going through to find out what’s even possible.

The layout function makes the dimensions of the parent container available. Setting your width: 60% is 60% of the parent’s dimensions + 0pt of absolute size. Without the knowledge of the parent’s dimensions only the 0pt remains, which is why the first solution broke for relative sizes.

2 Likes