summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-02-02 15:25:19 +0100
committerGitHub <noreply@github.com>2024-02-02 14:25:19 +0000
commit2594b367010028277240273e99ab32ac352461f3 (patch)
treec589b155f0f425fb38c1114a007d669c7b3bc9ac
parent356032bf8cdb759e93c2c6b853fe77b9c5f57c07 (diff)
Support for and/or selectors in show rules (#3326)
-rw-r--r--crates/typst/src/foundations/selector.rs22
-rw-r--r--tests/ref/compiler/show-selector-logical.pngbin0 -> 8207 bytes
-rw-r--r--tests/typ/compiler/show-selector-logical.typ21
-rw-r--r--tests/typ/compiler/show-selector.typ4
4 files changed, 34 insertions, 13 deletions
diff --git a/crates/typst/src/foundations/selector.rs b/crates/typst/src/foundations/selector.rs
index 16bd721d..ee7691b0 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<LocatableSelector>,
+ others: Vec<Selector>,
) -> 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<LocatableSelector>,
+ others: Vec<Selector>,
) -> 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<Self> {
- 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 00000000..4d1be5ed
--- /dev/null
+++ b/tests/ref/compiler/show-selector-logical.png
Binary files differ
diff --git a/tests/typ/compiler/show-selector-logical.typ b/tests/typ/compiler/show-selector-logical.typ
new file mode 100644
index 00000000..a11e20b6
--- /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(<special>): highlight
+I am *strong*, I am _emphasized_, and I am #[special<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 48a26014..db6db40f 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