From ad598f559e4284fabe45aff63b0eb7c5e5499b7d Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 17 May 2024 12:59:31 +0200 Subject: [PATCH] Fix show rules on queried elements (#4166) --- crates/typst/src/realize/process.rs | 35 ++++++++++++++---------- tests/ref/issue-3726-query-show-set.png | Bin 0 -> 2295 bytes tests/suite/introspection/query.typ | 16 +++++++++++ 3 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 tests/ref/issue-3726-query-show-set.png diff --git a/crates/typst/src/realize/process.rs b/crates/typst/src/realize/process.rs index f5fcf1cb4..7aa8b9279 100644 --- a/crates/typst/src/realize/process.rs +++ b/crates/typst/src/realize/process.rs @@ -198,9 +198,14 @@ fn prepare( // Generate a location for the element, which uniquely identifies it in // the document. This has some overhead, so we only do it for elements // that are explicitly marked as locatable and labelled elements. - if target.can::() || target.label().is_some() { + // + // The element could already have a location even if it is not prepared + // when it stems from a query. + let mut located = target.location().is_some(); + if !located && (target.can::() || target.label().is_some()) { let location = engine.locator.locate(hash128(&target)); target.set_location(location); + located = true; } // Apply built-in show-set rules. User-defined show-set rules are already @@ -220,24 +225,24 @@ fn prepare( // available in rules. target.materialize(styles.chain(map)); + if located { + // Apply metadata to be able to find the element in the frames. Do this + // after synthesis and materialization, so that it includes the + // synthesized fields. Do it before marking as prepared so that show-set + // rules will apply to this element when queried. This adds a style to + // the whole element's subtree identifying it as belonging to the + // element. + map.set(MetaElem::set_data(smallvec![Meta::Elem(target.clone())])); + } + // Ensure that this preparation only runs once by marking the element as // prepared. target.mark_prepared(); - // Apply metadata be able to find the element in the frames. - // Do this after synthesis, so that it includes the synthesized fields. - if target.location().is_some() { - // Add a style to the whole element's subtree identifying it as - // belonging to the element. - map.set(MetaElem::set_data(smallvec![Meta::Elem(target.clone())])); - - // Return an extra meta elem that will be attached so that the metadata - // styles are not lost in case the element's show rule results in - // nothing. - return Ok(Some(Packed::new(MetaElem::new()).spanned(target.span()))); - } - - Ok(None) + // If the element is located, return an extra meta elem that will be + // attached so that the metadata styles are not lost in case the element's + // show rule results in nothing. + Ok(located.then(|| Packed::new(MetaElem::new()).spanned(target.span()))) } /// Apply a step. diff --git a/tests/ref/issue-3726-query-show-set.png b/tests/ref/issue-3726-query-show-set.png new file mode 100644 index 0000000000000000000000000000000000000000..3f5c88846fc74f5812a11e2d173309883ccf34e7 GIT binary patch literal 2295 zcmV;w85Aam0tyU|9{$nIbVp&!Y1d~psQgJ$+1VMN_o_@a% zo6%_G^Z6_mi_K;$6bi86I1WaZWf9t#>2#V-r!~RJWMW>9$K&8g)3m;6wOX(tNm3g{ zQOsmA%jFWGjp_Az?RMMm_k-7LHZw0LlS!!6YBhb+>2zQdi^cTKZnxWRw+Q|FkR%CS z^ZEQH(4|u8>s1(r(V-WMh1ctak)kMsz60oRIQ;x7kw`>`hE%Inf*^9a976vswE3r_ z*=z!IKA%TuguYj3_!@v0&-2=tN~Ma$;;*$tA^|mqVGMsA(P&f~>-9Q7XR}#^HfFtE zQxs*jS^+2&3U#|(Ns=562b>K}nx9wGE~ z&P~H{oZb`!;rupfG#Utfouz3un~mO-WqEm3_>F`LSqmbp)m-J&>SIat=^nz}VOZV;dVg zn4t4QTxJl|c3s!4UAuN=-PNsIkNHbq__lQLrOlis_IdMUd7t-tzLNaD zP`GsZ)M~=6O|HA|Yx@;RmY26RmAXO#T5m_cSK>MDW5d%KPUhHxy&brtSK9P<^yn2f z!jgXVGJkPv6Z45B9s#Wf`omoBYTgb%Q?WyH_<3mK+8>KKxa^lIv#9 zzTVYz_$O|etCtBsnPcC$dvh!S0Ua~w_scxfE80dZFkiLEvb8S2I=GMj#DLBGzD<1x z!zLTmW}mXB^@f!CN7Ec<&oHG_bqeTcK|}NTY!?u3S!%s-uKCkFtt#^N6;?iB4M8T4 zZ){}o;q{KOS+0@GtPiZU3+R}0GMnvYiZ%iwY|Q4yM3q?j8QYm%ACIZy-QwnGjNPi;(&`K9 z2T!YL`|3~M^(l3Q4!y{fDsLQt-csw2#`0_d?G}G9q#u0A!dmh*xt>Z+CyZYRd8st0 zmr7}d?oFm1`7gK(0WF|q2xtKbH##7PED#RPOD=xmFB zT)vw#Lr(KnAN1+(=ttH&2%EIKRSSS=|5I~hG|y%_Gt7Pg9m#I)Pwi-ku1>bVix>9# zpr6>(NZ8cx+L-s(>fOKAu3RPaAbSYtqo)qGB)rn21C8#KQ(a}VerVS~vynL}@XWw$P~YM`;nyIXNz%NNl4pa-2gRLVwnBcKKJe+pVjyw(}Il}nPP zv=|7QTtOHQPwmDzkPU0Sl#Bchcbue-fuIp3y;<0Na)J@P79uW`%hU{~CK!3FMZn^@ zM;#5v8^5ey9#-X24vt!GWd+Ie)NfliR`)1H*_BC_<@>t?bl*_b7^*|+Uko`u+*!=6 z4-8a-u}FXlLqDbjW7$XU#kd7m1#n3~_l=2V9vx$MYmv_O04vcO<+*_F8%PdyY`Zm} zMf&_9R-(5Yi(f#?+dFyjFQ8=zXaOytWe8{iEki&HXaOxlK+B)MNlzsKEuaN-UzafS zT?o1^nr~KJ!fsw#kIRvjewQ!;2%~imUBWo@db_B(+%2GWcl7w;W={FWY<4ooK#xni z9{nACTllC@^)H~Q3Uhi(2Cdkoba;# zLXL|AbxdhLkeJd!<(-|)N|-=i;**EZHPhNkK*s=@?k8wv=;uh68ct(XBs96S<_{lp zIuO!+kV)!+F66wh=Ft6=1S6s{0UdMdpp6fz-xDSo(v01jb_uDC3PYs8X^EmDjR_Xx(>T%{6ITsf$ z%B6GZ2W2e-L9-<_&~(J49~J%AP%7bK6T+W)#3=&V@J7iF3YbYh-3pC0u zs$if{M}rvcoyrMkPOqL8ewv*#)5N6+C|n{yNys3Gh@A$5TGKnM$R0Xtx(T&d|6*fg zICqn&(T~yCF}^^PKoPrS*7`GQdQfwr2h&_s