From 2594b367010028277240273e99ab32ac352461f3 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 2 Feb 2024 15:25:19 +0100 Subject: [PATCH] Support for and/or selectors in show rules (#3326) --- crates/typst/src/foundations/selector.rs | 22 +++++++++++-------- tests/ref/compiler/show-selector-logical.png | Bin 0 -> 8207 bytes tests/typ/compiler/show-selector-logical.typ | 21 ++++++++++++++++++ tests/typ/compiler/show-selector.typ | 4 ---- 4 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 tests/ref/compiler/show-selector-logical.png create mode 100644 tests/typ/compiler/show-selector-logical.typ diff --git a/crates/typst/src/foundations/selector.rs b/crates/typst/src/foundations/selector.rs index 16bd721d6..ee7691b04 100644 --- a/crates/typst/src/foundations/selector.rs +++ b/crates/typst/src/foundations/selector.rs @@ -176,9 +176,9 @@ impl Selector { self, /// The other selectors to match on. #[variadic] - others: Vec, + others: Vec, ) -> Selector { - Self::Or(others.into_iter().map(|s| s.0).chain(Some(self)).collect()) + Self::Or(others.into_iter().chain(Some(self)).collect()) } /// Selects all elements that match this and all of the the other selectors. @@ -187,9 +187,9 @@ impl Selector { self, /// The other selectors to match on. #[variadic] - others: Vec, + others: Vec, ) -> Selector { - Self::And(others.into_iter().map(|s| s.0).chain(Some(self)).collect()) + Self::And(others.into_iter().chain(Some(self)).collect()) } /// Returns a modified selector that will only match elements that occur @@ -407,13 +407,17 @@ cast! { impl FromValue for ShowableSelector { fn from_value(value: Value) -> StrResult { - fn validate(selector: &Selector) -> StrResult<()> { + fn validate(selector: &Selector, nested: bool) -> StrResult<()> { match selector { Selector::Elem(_, _) => {} Selector::Label(_) => {} - Selector::Regex(_) => {} - Selector::Or(_) - | Selector::And(_) + Selector::Regex(_) if !nested => {} + Selector::Or(list) | Selector::And(list) => { + for selector in list { + validate(selector, true)?; + } + } + Selector::Regex(_) | Selector::Location(_) | Selector::Can(_) | Selector::Before { .. } @@ -429,7 +433,7 @@ impl FromValue for ShowableSelector { } let selector = Selector::from_value(value)?; - validate(&selector)?; + validate(&selector, false)?; Ok(Self(selector)) } } diff --git a/tests/ref/compiler/show-selector-logical.png b/tests/ref/compiler/show-selector-logical.png new file mode 100644 index 0000000000000000000000000000000000000000..4d1be5edc2c9d472732389979c6ec7a33dba2bb6 GIT binary patch literal 8207 zcmaiY1yo$k)+Nw54Ri?7xC9FXXe3B*4K5wrgS%UBYc#ke!QCZDaDuzLOMu|+KK;F! z^{<(E@1Lnvw{G22>y{kZYu5=^R{V&KNrH)hfPgI{EdfP9KtzT=qUcC)3B`+4AOZsA ztc--Hs>kBt@|fJzXR`LQ=aR4JG~#=qu@ab{CD8aUiCma40|SFW**KC^s;bH<=y9in z9%1duA;J+Ab~P?m9}1Tkk~?#Cu$4NN4|<$EZ-olSZbneO=BeRp{8Mfzk#Iol{$LRx z6)Ff2hS-f@gz)d5S!%{bszyG7viXcD#yVe^xg&nI5vHc1iZl1bevg>y+w9(0oN?p| z$piz-@x;$R(=IMSG2HEYq}Z?RE!i^!qn_KqE%wP=)+}J6|1!}Z0 z*)jg``ptsGn|UXRgq|LDn`G~e8-?{7Er_>8{|bi+7{gHaER+z+{VUbpJai0x+z z_%TVXkur@Cihp4yJU_emh>!WR39q!&PiqLa50H!W!cBgYxwK&L?CfUBhbcFc4)eCb z$0qPY|Bq()KaBKfwzI6CgWkpaXdb06vx#RRhgQ|pFOAeSg3gnKKNNP@izM?|t}1nx zepjq>Sl2Q;r#l}ep99F@Trx7RGONei(4fTejx9?G7XEK!%Zkn^>r# zh(yxB>$Q~?&|J31?_*6hTXv;^^eYkrFs(kFv}?hFAxAXv?UgXg9R!!wY{yoV`qk;#>m^e`6s4uB#W*T`wbl3z;7F(Z(?fa~} z#NHTfR&dx}!_edg!>7jM7#6JOc)U@EQrlC?X$;ENecOal@K^mRm^Hg{iKUSc3ps06 z4-s3vUTdAm&Li2c?Pxr9pihUI^-rIw)sZD1Fmg&nRCSr23PzdM`qk?)lod$n9loFQ zv98&-mfz`C`95IEU(@IWKNdM_m#hr#3G;(UOu-0BdTLyGnWdsq$W4Uo0#~UTD3<0l zpA>-ufeHX`9!&6{O4++k~QVRv-QkFw{mXD=9gk&*J4&JIM_pgwXaIQG9R~Zb7I3G3}JMqhL@WJ zn|<1XYxTsP8!f*lR-S$v{A;QF^7Dsu5@3jDD=TI5N(H!NYL7JqD>bOe2&7+`a>h-7M=_5B|TV+dN!a%ptPYW)RFBTB6Zn?S*j@4ID-%pDt zH+9+y89Gc!^JLQmT@0l&On>j6e7Vu;x*=pZnPY{Q)P#}Yje9OXMno;yY4O4<>oetqV30ndf(pn`fZD z2@Bc`>K>!GI#CsNAZm~_?fKP+4R@#*b;?lwj8)H1Wyby#y9o=`+=*N7HXH7PD^Hzr zLjIshqlOi`=9Oa)fegjM3*5pf`|D%+yb*q!_1hX`fv;bbaf!9ZUD;erw&s|Gc&g9<>ldg>r_M$2N!o6*5Kmcuzu$8=qp@^La~7whWL;1 z;qdj}b^f!zfB^q;rT_JBg&r_K#L&{x($rLPitEnZ(b3VzC;dW1pclf!qoJi$tUEY7 ze7L&{(%3&aasQCs+}un?YIJHHZzD3n!p0WKjE##+8rAFPI}l(j4(wHiLXE~zf<(_w z+}zxtpFR;tQloZ1;F2XLCGnBr1Vw{Ezu7M@FEz_&zkeq-64C9eYHhXUP8H7vu~V%Y zGqSLdgTb*x-Tn>H9Y=0D?+Cw$0>f^=lT%aW>ZNiTIy%mnJ7C%Sua1ICe`)OSg084z^E0pV*5^tj6!Wg&ZwSOu9`t!rc|*<-slq2?_B1 zvxGc7`S4w$>Y1DGtgf!^@0YYl%g79jjS<<0OVGT3{~lFOPj98C2ZbSYKK!$T!zqzo zN3*J05*;rYj-#csb4^2oCTmGkOG`^mPEL6_3l6S8C-(m{eE%!5m(bub`!5^(Pg?M= zwt*zZ7(pNv`TsKo<+OpyrIA#402m(r|9kzzA98)|rly7kFD~${cc1zh?;ahoj1Sl* zrtUfLf_E)iIXzlegM)*+yCr_F`S~0J)f(3-}_8 zW8n%NHoK_1|DmdOm6XG{urQ$VDku@IytK4o#*aQgVq#(~Ev-4GkfnNI4SYJbvCCJ0 z)4S)``T_=};SNLCEn8z_BYi@+O7s($o10r(N9V}R%fMi5Z?AZqoSYmR8~Z&M*YMaF z7IklLF9|8>irvk^!go;T<{5AL=>7dY3bI~P{gGbRpOldBz^4D` zvDsS~k+a-#w=h+>Hk6V!w6by@9-cEhd-&sr&be)+ev**)?bYRFI#12RxoI2O^7*;T zT|igYe(IIO?ep+3dCEZ{8gARAhi?*dLPAdrh0n$9&%3LGwbcw?zRR(UCx??&BKMO5 zo$~s3$+e4%_Shjxo}RwGFJNyW109{z5wipxd`ws{D;Z8qbTs$-_fau1SkwiDh1;&~ z?l)&=KS5$sTq#3z^*&Zs5#VRDu}86-;ZDe?)pkS2S60r0XvQFxO}k`l{#d&H$pXUW zTTnsSd(JR3@ zkMwY|0nHGY{%~I-@7P5K-nE8=2weGS~ucpn%`nUH&&eT!Qd&`?+f(!8vC@5<~N)ZuXMFcX6%Vtk@mu!gp z5twDGG@;vi8_P*a1wm-8;o&dC2^r5UzX|9Byxe9@7GuyUh2AwfZ4;F-C_RJ1xjY2& zDTTSa8AFPT-_|S$2n+viX^}5c$RH1wSoaa4JV_Al&6r$RxSK1C#IN}IGj34|?t2CX zl&@@{(8>LMD_tNz8!A~-e!k>=8gMy|4!_~oFH|m)s9g!Lx?=8xypj?Y87Zl8`|`4` zDm$5ANuTE)l=Ufvjk%_#&c$NTWnZ;P#M0)DCIpLUSaGKk2J6+SS8UG|e#yl{J=&YX zB%WQ(cr$#lW4^6N&R@`nx#@u44^BDYA)cCy$1bZB7J2Ck^;8);T4LxX$pxQZT*%4E zOW&vMEywLjuixK) zh|M*?t|%^M2Lmyk+BglJoH$Crr>y|pN;bB#X?EVNf%DVF=C{!vO3d+kn#6m8C zjg2V4sI6X<*r}+g;TWM6mxjl|FfsRn4~Y7j_GL7kzujQc>SndUQTKMfXWiuk20b}W z-`~G~2M1+!fz28~`h)?apAzrS2*T}UR#sLn>mvhl(3G`uBLZMwnNXKs)xXwg_7zmh zfJMYY`1qQR^3~!k&%A#BhQ@6;2oBUPPUow<3S8$2Gd$drhR7Wp># zT@qm;xC-V!o@lk0ovk{Q4 zR(MYm#RR^`LY+NKO7hZ(mlRAG`1ZjNy>aC@E-uc27p`Qc+o5zta|rkyKBiD+4Ay`| zdtwf!Zpn&WA&M_rCV%S4=;$aEW+a;rRp-Q@NZ4y@+%u!DU&yex_2HslJ3dZFVWTW~ zd*Ni<^HB8?T<#jL`KE z(O+V76_tMe!FoEW>{5wips*=G1ZId(V77W`k}O?v zg>1eU;*rin72{tgK8Man!q>@8%`0}?sgEhTnye{w453K17%U+A;8l_+)SE>9xdT^b zu$|p==P@O@kEvuRJ_m|FbJ7VKTBJ)XleaJq4-WfLe*BsPsb`S&A+>V8_a-9g5fPE_ z-k6%M9OCPP{e2$y1VV0N8b^VFg@u^nxBQk=zAyanaJxuC3_sSa-?D4eW$iSXwfNCO zZgtb(+W71?LX{hDgZ1p}q)4H^K0%EHO+xUQJI)7|VZ9SV(6teH*x2Q30%3>lDt z;id!Aqx|4N7;or}zo78T-}CbnienXsKzWzosrEOSJeD|+WR<<^)zjHeC8egfU{zIo zAQKZNDggmXP((zasH9{^R!)wgvWf}>7~=AQoTGhUAyHf(z_^tbkDe$`&)4{Z&=u#Y z`i>CJKz7LR0ZLfFt?zMQ=Fl~JG$^l!h!d+)e?S`=IJ&z{glb&j{Aq0U=>bY8;fP>g zl!yn54~}KTXAH}a4I8ASB8da#Owz!X zMIPE6b#-+~Nd#(6b&y95yLj!)ciDEbULGFG zPDe{wBR|G9lvNt)>u+p-_0QF?KRxJBeerfwi=y^ay#`HdgP)l{D_^f4`mi*H&!V1o zudL{OGL!2LdU$xSUrLyrRgZYlaL?UMqn);!{LKKw6y4B23lVN9C8Y2kU-QPRnpE8= z5_*serXB|znzI1cn1F{I5XuSLPBKJa=j}g##2mvb#3XhFttuyTL65~~B~;PWGP*^z zM_XH4aO#89!6htADec50W_gLLq6WXVjM#|qH5Nz5#3apa6Lhe~$R)|^s~|eNxVX5w z=6lkELIyDMaXjSto~TROnKlngM(rOh41u zAx%T|(k*WjbGr{}Yil3FAw`R=ZEaHFNbeZF%~4PBBKca9rNv80#l(KBBit22E5|P; z48bKKq@6=gzoi+iGt)Ranwm5-C7xlpK3KQY*buf!b8w&PfVV{c`JDce3i z9$Rc@Z@)>X?u=E_`5K~TZeGY5&Q!xJ8vvX8rU}b)C3je+iOtQ;H3D2EtndEGNsD2c z3g&2c-W{-Y93qwZY#LBX>`;PaS3jx7DS}^`GlQqDF^x-mapNV~?jLSws%dF#Y|P2Y zsrzE+7-(YoUc^fD&OX9e%_G7JJPb7`3aOh>N7k_M?&{3)1@%&|1HTHfvwvQaG3(EZ z;^0JL#8OpIQYx)=`yn90m8(3{to?~Dq7KqxsidS-lE%iy2GC2d!26lxk8p5s;Oy*t zi^{M^K}NwEkyVMRf)!sG2k{(jaw zlH^-*r)nX_>JD#wXWbL{CD4cdI+-pk4G{A9adkSqmj!8IcDBIqeb8-{?_W6N>1t|* zeKt2Ym%isBOL_e!fVd-d?&^A@u1*A4b!8*eI6w*d6>)I({3WIP@18{-65U<{l&fjjkOf$&U@81GQZPk4&N{z5iGg}U z)f{Td*_fSbGq{tBFsTx8cN|zK|moH6iY>UxVIN)#HNQ8 zACv%HD4ZmqP^IzEM?}%}^bdLElz7X0D03We(6PHMjU?{*`y1X>HJsZck^-+w@loxy zwdDXvg2Bif%0T1S0E@(Sa|DgAcseE}Q1E;!M^Y%><<>#yNF{8eZi6&ooN?gH6rck= zW=kPibi3ajEv_BHrzMJXktEtA0hwv<(#wfI?HJ-DeV-B*4HB@d_APm|LDKaW-z)Gr z^*}iuVDe98^5^MvG-=4B;Iud3>yzu}EQvDo%oeTA z_A}$%epf%N zd^@rxTxr9p(Q4BLWy(&fF=%y_^eM^6%G%Y!f{aIL=hu#oY!g!SKTV!A`Ez9HIwVy9 z=L`9JDLC>Lo|+&QX&ySNuTW>}*gvm7V`SAV`9p3IqqM>LsRjh>G8v)$9A_6EO^P%d zxsB{i0gt)tBQ4(VnCI{{7MGUvE~!1Vc>#&`_${mq*;!c{ao2XC9W zpZPbO|Lmxdbe7T7A=pf1IFPs2p?|!jVHWvYZu)B+z1pF`2wSt~l!Xq^5(kQmy&yF$ zZGE`CZFrGWodo>x!uq1{R^>(BLunu;^C;a?I!O!M_x7e-%2|GBa$1-4y?G)T5A@9l zONz^KZy+I4PElA6%ncY=B!o{uAn{P26L_yYE+$C|Q?lZsnrTyO{5AaWSLryjK5)o)9uaL_EO~8o)aGWJXn=+{j%QfEi`d z`4jtyvla4QC0wtxDtCA4l9TgDxwo3egRB>fyF-pMAkQ{3GD05@7(*ENDhmLkIE>$2 zI38pCU>6yO{22L>P&*i*87sFr@P3vA-_;`bT+51+(mZVMv{ge2@fn$3yyhJj3!>Sx zd~>pcK~XUCGzQbDA=3^`O}*i5Ob>EY(s_>-GU_2uK2Zru*Y8(^=*)Y*j+kc|NQlZU z-mVHArz@Q}9bz+oZ=vp?h!=^Lh<$OVDBMMMh0{Kt+tuhSY+EIYm)`E(0OM)Fv@#Is zc+QUTOHNAdSNafi)D9{za*!bi7}#-aVf&OilInigZ$haE7pJ`r2|{zG6fAi*`&nI$ zXlG};lvn=?6SZUgD@6CV&=1rYO5p}(*w7G~=av5aJl*K9i9I|x_>nYoGmuc(b~2K>-PqW1@%M?_(a7bu?`kOSj+Pd3AR|1N z(K(o8>pDAwZB%&Xyd(9qhhql1ivI@6Wvwn|dz4jYJyi|QKuJ;xalv)84gv2UyxDD_ z<-I-{`p)%sF)uPwJbb6U_u&RRjYH1Evk4#nlBbbPe>x=CgPb?kS}}!14xZFA{mSrk z@2aQyZS4NalHPhEC+~VKI|VE)t&~Y&Ud?SQ8ye+)vM(d-_e^wEseRQ9w*yX4c8(F1 z&&}Qx$s|0n0wIW9H+*z+-1}US3V`f3f0NHM9}dF;URqeb?fTp3QtWZ|hgRF^a2~yy zkX8Qjbk`E}$K%#vIGM%o2NyuN=NtR*UhyZG_jrjgeSwC8Lc_n7*w~$Tb*bm)=YC&Q zPJj&5<*{4}@Sdx9H(6X9u(8qRyo2+d(;S^LjgON;z%Zz+r3F;|;gZIGB(UQ{hG1zx zvg2lsg}9knEPS$Pmn=2|*0(I=?E)e@{J!2M=8(g+OaSm>^i~26=DED=`AJpZW&kpp zmn%w$QYJ|@BlSi~tC#a?Te*@P7Ctb(%dj2R>X1F}!i$H9Na3ITjL*r3Gndy7nhz=6Ulb ztO10v39hZAC9<|Y67bcvEi1mx-`OmCXGV%tN2}jjLWhMqeAO>4ytGHhG{`3Sq;XK2 zP2IWDT8IMBk*fNTejj0Y8vp^_>(;YkM{W-$#WyspcEjF*i@dM)g&kn_D<$6q_~_Xu z*199*`_Z`>MIcr;$2JjB;oF z&>Ph?n)cSl=Bq#Ua)|8`hqktCc$bvKE!5-T8VE9CQBB@6>*2j3=r{#@UVlQ*AQ&gY zD53a}Xnr8_TANO6&^3A_bxPRJuGWdq!==jAx;ODH`!KH8waL=<@$&bc8mwycxxmn~ z>F-L(tP1pjTzOi;xy-GZ1egIeV%{1MGX|)Z-ao&83?yFH)Xf)?x=Y? z;GzP#o^N&23o^lVLs~iMjCcX@FKH{@?1P b`yM5M+%=Dx=-`Kc((E#liV_uKhJpVB{)kX8 literal 0 HcmV?d00001 diff --git a/tests/typ/compiler/show-selector-logical.typ b/tests/typ/compiler/show-selector-logical.typ new file mode 100644 index 000000000..a11e20b66 --- /dev/null +++ b/tests/typ/compiler/show-selector-logical.typ @@ -0,0 +1,21 @@ +// Test and/or selectors in show rules. + +--- +// Looking forward to `heading.where(level: 1 | 2)` :) +#show heading.where(level: 1).or(heading.where(level: 2)): set text(red) += L1 +== L2 +=== L3 +==== L4 + +--- +// Test element selector combined with label selector. +#show selector(strong).or(): highlight +I am *strong*, I am _emphasized_, and I am #[special]. + +--- +// Ensure that text selector cannot be nested in and/or. That's too complicated, +// at least for now. + +// Error: 7-41 this selector cannot be used with show +#show heading.where(level: 1).or("more"): set text(red) diff --git a/tests/typ/compiler/show-selector.typ b/tests/typ/compiler/show-selector.typ index 48a26014a..db6db40f4 100644 --- a/tests/typ/compiler/show-selector.typ +++ b/tests/typ/compiler/show-selector.typ @@ -37,7 +37,3 @@ the ```rs &mut T``` reference. = Red == Blue === Green - ---- -// Error: 7-35 this selector cannot be used with show -#show selector(heading).or(figure): none