summaryrefslogtreecommitdiff
path: root/src/model/styles.rs
diff options
context:
space:
mode:
authorSébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com>2023-04-04 19:21:25 +0200
committerGitHub <noreply@github.com>2023-04-04 19:21:25 +0200
commitf347ed4314e32383dc09ff234180e8ea6fef7b8b (patch)
treedba4296812a131e52da4eb0079fd0d240860d832 /src/model/styles.rs
parent5b0297464efc131beb7be84fa7a02b9a8670b5dd (diff)
Improved figure numbering, labelling and referencing (#491)
Diffstat (limited to 'src/model/styles.rs')
-rw-r--r--src/model/styles.rs17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/model/styles.rs b/src/model/styles.rs
index 82ec2ed5..4b309ed0 100644
--- a/src/model/styles.rs
+++ b/src/model/styles.rs
@@ -1,3 +1,4 @@
+use std::any::{Any, TypeId};
use std::fmt::{self, Debug, Formatter, Write};
use std::iter;
use std::mem;
@@ -260,8 +261,12 @@ pub enum Selector {
Label(Label),
/// Matches text elements through a regular expression.
Regex(Regex),
+ /// Matches elements with a specific capability.
+ Can(TypeId),
/// Matches if any of the subselectors match.
Any(EcoVec<Self>),
+ /// Matches if all of the subselectors match.
+ All(EcoVec<Self>),
}
impl Selector {
@@ -270,6 +275,11 @@ impl Selector {
Self::Regex(Regex::new(&regex::escape(text)).unwrap())
}
+ /// Define a simple [`Selector::Can`] selector.
+ pub fn can<T: ?Sized + Any>() -> Self {
+ Self::Can(TypeId::of::<T>())
+ }
+
/// Whether the selector matches for the target.
pub fn matches(&self, target: &Content) -> bool {
match self {
@@ -285,7 +295,9 @@ impl Selector {
target.func() == item!(text_func)
&& item!(text_str)(target).map_or(false, |text| regex.is_match(&text))
}
+ Self::Can(cap) => target.can_type_id(*cap),
Self::Any(selectors) => selectors.iter().any(|sel| sel.matches(target)),
+ Self::All(selectors) => selectors.iter().all(|sel| sel.matches(target)),
}
}
}
@@ -303,8 +315,9 @@ impl Debug for Selector {
}
Self::Label(label) => label.fmt(f),
Self::Regex(regex) => regex.fmt(f),
- Self::Any(selectors) => {
- f.write_str("any")?;
+ Self::Can(cap) => cap.fmt(f),
+ Self::Any(selectors) | Self::All(selectors) => {
+ f.write_str(if matches!(self, Self::Any(_)) { "any" } else { "all" })?;
let pieces: Vec<_> =
selectors.iter().map(|sel| eco_format!("{sel:?}")).collect();
f.write_str(&pretty_array_like(&pieces, false))