From 6d0c159e97a9274fedcdd269b886385e987da6e0 Mon Sep 17 00:00:00 2001 From: HaeNoe <57222371+haenoe@users.noreply.github.com> Date: Mon, 6 May 2024 17:21:35 +0200 Subject: [PATCH] Indent configuration for multiline headings (#3459) --- crates/typst/src/model/heading.rs | 52 ++++++++++++++++++++---- tests/ref/outline-first-line-indent.png | Bin 10876 -> 10873 bytes 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/crates/typst/src/model/heading.rs b/crates/typst/src/model/heading.rs index d3976948e..0744687eb 100644 --- a/crates/typst/src/model/heading.rs +++ b/crates/typst/src/model/heading.rs @@ -3,12 +3,14 @@ use std::num::NonZeroUsize; use crate::diag::SourceResult; use crate::engine::Engine; use crate::foundations::{ - elem, Content, NativeElement, Packed, Show, ShowSet, Smart, StyleChain, Styles, - Synthesize, + elem, Content, NativeElement, Packed, Resolve, Show, ShowSet, Smart, StyleChain, + Styles, Synthesize, }; use crate::introspection::{Count, Counter, CounterUpdate, Locatable}; -use crate::layout::{BlockElem, Em, HElem, VElem}; -use crate::model::{Numbering, Outlinable, Refable, Supplement}; +use crate::layout::{ + Abs, Axes, BlockElem, Em, HElem, LayoutMultiple, Length, Regions, VElem, +}; +use crate::model::{Numbering, Outlinable, ParElem, Refable, Supplement}; use crate::text::{FontWeight, LocalName, SpaceElem, TextElem, TextSize}; use crate::util::NonZeroExt; @@ -163,6 +165,18 @@ pub struct HeadingElem { #[default(Smart::Auto)] pub bookmarked: Smart, + /// The indent all but the first line of a heading should have. + /// + /// The default value of `{auto}` indicates that the subsequent heading + /// lines will be indented based on the width of the numbering. + /// + /// ```example + /// #set heading(numbering: "1.") + /// #heading[A very, very, very, very, very, very long heading] + /// ``` + #[default(Smart::Auto)] + pub hanging_indent: Smart, + /// The heading's title. #[required] pub body: Content, @@ -201,15 +215,39 @@ impl Synthesize for Packed { impl Show for Packed { #[typst_macros::time(name = "heading", span = self.span())] fn show(&self, engine: &mut Engine, styles: StyleChain) -> SourceResult { + const SPACING_TO_NUMBERING: Em = Em::new(0.3); + let span = self.span(); let mut realized = self.body().clone(); + + let hanging_indent = self.hanging_indent(styles); + + let mut indent = match hanging_indent { + Smart::Custom(length) => length.resolve(styles), + Smart::Auto => Abs::zero(), + }; + if let Some(numbering) = (**self).numbering(styles).as_ref() { - realized = Counter::of(HeadingElem::elem()) + let numbering = Counter::of(HeadingElem::elem()) .display_at_loc(engine, self.location().unwrap(), styles, numbering)? - .spanned(span) - + HElem::new(Em::new(0.3).into()).with_weak(true).pack() + .spanned(span); + + if hanging_indent.is_auto() { + let pod = Regions::one(Axes::splat(Abs::inf()), Axes::splat(false)); + let size = numbering.measure(engine, styles, pod)?.into_frame().size(); + + indent = size.x + SPACING_TO_NUMBERING.resolve(styles); + } + + realized = numbering + + HElem::new(SPACING_TO_NUMBERING.into()).with_weak(true).pack() + realized; } + + if indent != Abs::zero() { + realized = realized.styled(ParElem::set_hanging_indent(indent.into())); + } + Ok(BlockElem::new().with_body(Some(realized)).pack().spanned(span)) } } diff --git a/tests/ref/outline-first-line-indent.png b/tests/ref/outline-first-line-indent.png index dd995f31943f2b23f943fbb09561351625342d3a..91a494f7a98e62efa124fe7bd8897493aa71f600 100644 GIT binary patch delta 6587 zcmZXY^;;ASmxf_z7;5Mkx*O>jVCW7>>2@TPmePTtySs)?C8SHbI|P&laS$bjR8aPP zzujMU_xuOvx}I}C_jMjjewn0lU@A3pu9Ct_s3F;Wz+J2tk(#JGz!>Hs?GW zYM-u7vaWhE&9@IOv>gtJ39*oJMMI z&S+8MdzSMb!?0&Jrvg-D=-;V#L`nE2$|w4+tN6hnCOgk_iT~h9Xci0^i6lgk_`*9b|6@_+8K|Z(IK?NkQM=FnILm>kdpQmN^N35g+}qy*o(ffdz67p>U=xINO!AHQ2aYNA2%^* zTk=|=DRk%DM`>Yxd?6LB^^E~OZEm9AeZ*l)@5|!3bC7%f>;u?-DC}$9JTX`kPNL(* z51H=8rnN4J!5r*fG=7sb7T^F8T<0&OoYK;9E(QLI_TVye;$+@};pAu3hO>t%_+;In z7TL|SFwC#jzPcM6W`3J585jGZls+n@nPcG>^#(`q8BNnJs@+0(xRMs`tvT+d3=0$J zR$js&wR&wYgF~L9p-EYIIU=V?h&WAeUmOg&+g-LG{&ge~9m<9E(J6HaM33P>_|-|H zmhr7U<*@ZSV`in_7;9X=Jw&}lAk-2uF_ar8mLTCb7g^*SE;YjAK#zU@p%UXJh)kwj zIE0Kk%pck;m&+y4kVFaxKS~pb&xrPNJ9YH>eoHQ%P79#l$_jQQcah-4@#PQ6y(Gxa zix|-=)ru@}==6?86`8~qGgO147S1d=<6|YJKs)HCN4aJ|qGAUhO9%5U)kCtT$~YQ0E@1ov1x`l@yL zRkGDiUNzD!;jghk>`jdsKHcN0{~BgiyaA7aIC{w`Y6$5*1C?A{F9Sm<`4D>uhe!x^ z+;sSqQGa0}BMSYgmOgR1s{4DFE^)Uc-lzptrjqc%lr;6+s$k(Ukh~1|bG}@!JrhLq zGv}i!_gig!F+BJ%*-hdz)k_AvR+(w?55TE}sxq$`Le*iv_p{|KlO zSD+M;sKVl6H$kVgi)n#zlFH)j z%SOdAL3??1D^jivX|+&fxe&vLQl0s;d#@OJxmbcLI|4U=-z2mF3E!&j+z+Po|2|#w zW{TE<|D9Gm=O@|Wg()J_1CTb`IqOWp#*D8DN;2g??iU=U+cFcLr;UGBev@%YWr7)(p-IgN=qSl}MXgNh`l?d+?cQY!lczaWV3KW~Hu&$q=}wtRx3qDqq^2u|ibZ z!`@j;iq!pd**8>4ys4E{1R}Qg#?Hat?G`9u#M=Rrh_SHw_hLxXh0U88*cCQ$*;X-e zxr(H|(7lPxE|tYTi4-~vV4{CbdVZV!2S@>5%nH2_1@Sv2f75-t%CyM)Cgw77kV%-B zr)6yVrUi!ocCZn}xalB{aYezGKS8nYKE~ZpDD$+ThA{A<7sA(_ct-@%wDMp$uXmcG zrlQ2Fi61Pv!y&Ux<&Qd8gmD)qZ>sob`Vv>z5unWn2uKlt5OOa$qk#b8aWEivP8EMcBph;#6x$8^Z-4Gh5lPOxcfy6JR(Sl3dK{E?BBWbqQ+)SV+&) zH)i7#v4o~7u2F5QP^X@8kN{F@;XtTq)HuKPq+Ct18n$3<4g5Ndr75{9=I9SNp(EWx z`RXnQ;lmh>D=fr;7`F^oGqPL%K+0xoM@nox=?!RuC-dP~Ry;w$ z-j1FVC`Pjz&OQGkct{I2)Hzu!F!}VoSx9$*^@^6cY%8+CI3-*21DmD8%!rJ@yk5!r z9oxNF))BTPVF#?^a62}{xB{%K5eikR$vK2PS5BUL=b>WE8_=mbHKDyUV3kqzoX@ad zBbTA<&qEKm70Op zmOK<{+$(?z{?VDFzw64hS>4x)qnP0~$6~?k;fRpdGo>ex9Zt!3nY2IGJ3d+DUV9d- z&^{DO{&FA3A;=qc)ku}`%`qyCG5n(bFGb>wuf!m z_=0@1j6?4Po!WO9F7yI$_L|kFh%tG90+fdgh6D{^7Ph%APzT1Of(QnJSO`vCuqc|S zr9GigcEcbHKaHj@shpCWk)mW0Gi0(F`{y1|QE$gN6V@<_A0(~;hHo~;xVDMn+bN9+ z61k8(->taS{)2n= zK-z;5u@U_!_<_s}u&OXsA8=2p60RLSNix_jYEw9(K`?7=>~XE|MbKW z`&1;mmcFSG7!B4lbwCtGcE{g-cbOs?yqLx#7SM{N?IGA!&uh|=V#3&LHijDqHaI5f3-VJiXP9+(emkTGMGP*IR(K|W3P(E9d!x~y_nlGI}nr|D9H%_yl55G2Yt|-ghgvF2L{rY zZP`;F_D&82fvp9QSK7o81ZE>fDHFCwF#CL&Z=)67<^e)WJ>Ue}1KOX9qGiylmV8?3 z4cB2&xGegqtnB3UiLe4k?{?wC_rt6!azEKVEMc8*$`oq7!-*GMtjjf!+DW>(x@|}j zcT7j@o~A67ijEG$go8Ui!i=#pGMwFRS=h1eZQV@1q&%Wq=bhV~Tyj}GsKv_i&fdte zhBt2GEwtz3V#*bUWBlUxjnDGFi;S+6f30~e;5_MvGbTDw*D^CCU%)`~gQfCd0v?P?5=q#0|))W@#kHM(eJUNxE#)hi33r|1r7f10@i z=jnfQFZr&Fj%>1U2AKCSswYQ@jWZ zskLDs3g+qZR4)Mqvsp(LS9wGo$*tX!=3PrL-<0_;PCv<2*A3qO#Q9OP8x?$&LN{iX z;>|$rUa~u(Tqw$Uu=-2L1mPnt2uTIN7rR3r?`9^>bNmcuksAVD&SbhX9~M_3drt~rivC7<~)N2i~syL~&p^T?wOb$94oTqBvuLo;{1Q<+EC zMb;P`Kb!D13HTyArEXZEHjt>$E%NUqifdI0&K3`RD`$}g@ zGcG5o^2^U5&pPPx8>5iFP%U}Qp<-+i<;YMKGR`I@22q`>Y~{>UO-!xAm@U8q$t@lb zpU0w42RGm~v9Dl2_w!(GIHiU3ft1yGlaqw1ymy+C*_Q|{?5B0`6PiMN44^s3_G#*) zM=8P`Nf$XWp>qAQ|3>%P5)uw<4TmW0vd=}B&^9=%pAvQ+NGn{&q`OMuo5Pn{x2CHgMexoEBsCYN{0JuCg3-8v1%Fx1Ru^W! z=0J~{Vyr>gc&R8mKA|?3rsyTx=1HD_S49ziJ|I$z&MoDN z=h;PKBsC*pY1E4^yq@phYJGT{0cD|v?`?B90ivLqWDwcs?-P@&h(A8jl4KpB>G%n39@8c6i*dPtHQd4aW;zdmt=vd{bH%uGxRW z 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