From 3c42efcfe8b3496406c50790e9e936568567bbb7 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 23 Jan 2025 17:53:57 +0100 Subject: [PATCH] Figure body forces paragraph --- crates/typst-library/src/model/figure.rs | 33 ++++++++++++++--------- tests/ref/figure-par.png | Bin 0 -> 1701 bytes tests/suite/model/figure.typ | 11 ++++++++ 3 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 tests/ref/figure-par.png diff --git a/crates/typst-library/src/model/figure.rs b/crates/typst-library/src/model/figure.rs index ce7460c9b..78a79a8e2 100644 --- a/crates/typst-library/src/model/figure.rs +++ b/crates/typst-library/src/model/figure.rs @@ -19,7 +19,9 @@ use crate::layout::{ AlignElem, Alignment, BlockBody, BlockElem, Em, HAlignment, Length, OuterVAlignment, PlaceElem, PlacementScope, VAlignment, VElem, }; -use crate::model::{Numbering, NumberingPattern, Outlinable, Refable, Supplement}; +use crate::model::{ + Numbering, NumberingPattern, Outlinable, ParbreakElem, Refable, Supplement, +}; use crate::text::{Lang, Region, TextElem}; use crate::visualize::ImageElem; @@ -328,6 +330,7 @@ impl Synthesize for Packed { impl Show for Packed { #[typst_macros::time(name = "figure", span = self.span())] fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult { + let span = self.span(); let target = TargetElem::target_in(styles); let mut realized = self.body.clone(); @@ -341,24 +344,27 @@ impl Show for Packed { seq.push(first); if !target.is_html() { let v = VElem::new(self.gap(styles).into()).with_weak(true); - seq.push(v.pack().spanned(self.span())) + seq.push(v.pack().spanned(span)) } seq.push(second); realized = Content::sequence(seq) } + // Ensure that the body is considered a paragraph. + realized += ParbreakElem::shared().clone().spanned(span); + if target.is_html() { return Ok(HtmlElem::new(tag::figure) .with_body(Some(realized)) .pack() - .spanned(self.span())); + .spanned(span)); } // Wrap the contents in a block. realized = BlockElem::new() .with_body(Some(BlockBody::Content(realized))) .pack() - .spanned(self.span()); + .spanned(span); // Wrap in a float. if let Some(align) = self.placement(styles) { @@ -367,10 +373,10 @@ impl Show for Packed { .with_scope(self.scope(styles)) .with_float(true) .pack() - .spanned(self.span()); + .spanned(span); } else if self.scope(styles) == PlacementScope::Parent { bail!( - self.span(), + span, "parent-scoped placement is only available for floating figures"; hint: "you can enable floating placement with `figure(placement: auto, ..)`" ); @@ -604,14 +610,17 @@ impl Show for Packed { realized = supplement + numbers + self.get_separator(styles) + realized; } - if TargetElem::target_in(styles).is_html() { - return Ok(HtmlElem::new(tag::figcaption) + Ok(if TargetElem::target_in(styles).is_html() { + HtmlElem::new(tag::figcaption) .with_body(Some(realized)) .pack() - .spanned(self.span())); - } - - Ok(realized) + .spanned(self.span()) + } else { + BlockElem::new() + .with_body(Some(BlockBody::Content(realized))) + .pack() + .spanned(self.span()) + }) } } diff --git a/tests/ref/figure-par.png b/tests/ref/figure-par.png new file mode 100644 index 0000000000000000000000000000000000000000..d70bbcb12970dcf6e0b3f228544b2bbdd99cb3fb GIT binary patch literal 1701 zcmV;W23q-vP)66u|orXqvvLCDznXL?}q0$XXEOfdY!qS}Y2ddQnIa2_!^R1j?3}Qe;z>7a&lV zL>3DqMG&woLRl4|3KYs#R@uP?u)jFT4Z+k0q(`JeZ6itGC9S+IhdJkMv@@`h!7 zK#R~ZHtM0H^AU>j$5Od>uNv+wLBEj*FAfeiz>&EpBg($tJ$fX% zK;u;%G@_}g$#Z#md2nzLWqf>GF4KH zSXe0D`}px=kxBEOK7Fcm^TowQ+DRi-0`!g@J2EpfeSCZ#K72^$&CSipEGQ^QPfw>a zv9YmzeSHoN4p*;U9T*tczJ2@9&=9(TfdLS4TWBUEB%C>O27Q&~OP4NTg!tg-=(wur z!i5VwO-xL{x-y@Zq^72NdwVkyd3kwPu3Yi-^lWHoV2W(rx-}*y=G?h+j3N*Z95}#? zX=`hv8UFtM{5L*6J|!h3GBT1Uqhe@iNae7wFbfL{Rq<%NucD#?j(G8&J$uM>adBZv zR##V_J$qJg$;rto zO2QidU0GymYAPHV$L#O#=a0d`!4VM=WC9KkMbXpK!-Y?uK25|UdFRfZz`#Hzfti_^ zFtTmiHhRPWl$Mr~w6U?FR8>NUa;gGOcovv0U%uSi+bcldxN$=XT2xc^>eabP6cXIU z-&aX^csPzMh+}Z&+tt+6l*z2DthBT=;?Yc_7&$lMf36b%gxngt8onXL%UOFm)2!^4AkLT6Yl$yZlb7tzz# z*OxxCbzyZE0v|LuCC|LpC@h*$DEv; zm}iVPnT)Q!zW)9D_w)1fiE`9r4iP$9TU+r4UdIe@b8|~hPNvx>Po5-pGieB1j40e| zYHHpwXu6F@)YjIDWOH*fN!*a|nvs#glim^sDQaqJVnaqipi7O7jZ_ocK@oO9ztSuQ ze}5^MQm$h{s7ZYhOo&d{SqYj^ffPW|8OZYTa%Mes2pWVATo{`aiB*v#ZzqQeyh1dR zzl*h+Ooo4CWCVq7s^|v`ag9Epu&}WDy-)$s($d0D-?uMAmXWx)I94iRiz-lN9