summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-04-26 13:46:42 +0200
committerLaurenz <laurmaedje@gmail.com>2023-04-26 15:37:21 +0200
commit3680c854a21db665d64cdb8f31aa0f9a1af16ceb (patch)
tree39dfa33059293251f1e2890f9b3d0e3dc178ed03 /src
parent59957746e91c1322a8ca6d228bcaa0f31941ee1b (diff)
Touch up docs
Diffstat (limited to 'src')
-rw-r--r--src/eval/library.rs12
-rw-r--r--src/eval/mod.rs8
-rw-r--r--src/geom/stroke.rs10
-rw-r--r--src/model/content.rs1
-rw-r--r--src/model/styles.rs56
-rw-r--r--src/syntax/parser.rs15
6 files changed, 79 insertions, 23 deletions
diff --git a/src/eval/library.rs b/src/eval/library.rs
index a92d8bd1..13825d7e 100644
--- a/src/eval/library.rs
+++ b/src/eval/library.rs
@@ -91,13 +91,13 @@ pub struct LangItems {
pub math_attach: fn(
base: Content,
// Positioned smartly.
- top: Option<Content>,
- bottom: Option<Content>,
+ t: Option<Content>,
+ b: Option<Content>,
// Fixed positions.
- topleft: Option<Content>,
- bottomleft: Option<Content>,
- topright: Option<Content>,
- bottomright: Option<Content>,
+ tl: Option<Content>,
+ bl: Option<Content>,
+ tr: Option<Content>,
+ br: Option<Content>,
) -> Content,
/// A base with an accent: `arrow(x)`.
pub math_accent: fn(base: Content, accent: char) -> Content,
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index e8e1af51..68163bf6 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -48,8 +48,9 @@ use unicode_segmentation::UnicodeSegmentation;
use crate::diag::{
bail, error, At, SourceError, SourceResult, StrResult, Trace, Tracepoint,
};
+use crate::model::ShowableSelector;
use crate::model::{
- Content, Introspector, Label, Recipe, Selector, StabilityProvider, Styles, Transform,
+ Content, Introspector, Label, Recipe, StabilityProvider, Styles, Transform,
Unlabellable, Vt,
};
use crate::syntax::ast::AstNode;
@@ -1428,8 +1429,9 @@ impl Eval for ast::ShowRule {
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let selector = self
.selector()
- .map(|sel| sel.eval(vm)?.cast::<Selector>().at(sel.span()))
- .transpose()?;
+ .map(|sel| sel.eval(vm)?.cast::<ShowableSelector>().at(sel.span()))
+ .transpose()?
+ .map(|selector| selector.0);
let transform = self.transform();
let span = transform.span();
diff --git a/src/geom/stroke.rs b/src/geom/stroke.rs
index 344da3c5..ead30cbb 100644
--- a/src/geom/stroke.rs
+++ b/src/geom/stroke.rs
@@ -256,9 +256,9 @@ cast_from_value! {
"dashed" => vec![Abs::pt(3.0).into(), Abs::pt(3.0).into()].into(),
"densely-dashed" => vec![Abs::pt(3.0).into(), Abs::pt(2.0).into()].into(),
"loosely-dashed" => vec![Abs::pt(3.0).into(), Abs::pt(6.0).into()].into(),
- "dashdotted" => vec![Abs::pt(3.0).into(), Abs::pt(2.0).into(), DashLength::LineWidth, Abs::pt(2.0).into()].into(),
- "densely-dashdotted" => vec![Abs::pt(3.0).into(), Abs::pt(1.0).into(), DashLength::LineWidth, Abs::pt(1.0).into()].into(),
- "loosely-dashdotted" => vec![Abs::pt(3.0).into(), Abs::pt(4.0).into(), DashLength::LineWidth, Abs::pt(4.0).into()].into(),
+ "dash-dotted" => vec![Abs::pt(3.0).into(), Abs::pt(2.0).into(), DashLength::LineWidth, Abs::pt(2.0).into()].into(),
+ "densely-dash-dotted" => vec![Abs::pt(3.0).into(), Abs::pt(1.0).into(), DashLength::LineWidth, Abs::pt(1.0).into()].into(),
+ "loosely-dash-dotted" => vec![Abs::pt(3.0).into(), Abs::pt(4.0).into(), DashLength::LineWidth, Abs::pt(4.0).into()].into(),
array: Vec<DashLength> => {
Self {
array,
@@ -314,14 +314,14 @@ cast_from_value! {
.transpose()?.map(Smart::Custom).unwrap_or(Smart::Auto))
}
- let paint = take::<Paint>(&mut dict, "color")?;
+ let paint = take::<Paint>(&mut dict, "paint")?;
let thickness = take::<Length>(&mut dict, "thickness")?;
let line_cap = take::<LineCap>(&mut dict, "cap")?;
let line_join = take::<LineJoin>(&mut dict, "join")?;
let dash_pattern = take::<Option<DashPattern>>(&mut dict, "dash")?;
let miter_limit = take::<f64>(&mut dict, "miter-limit")?;
- dict.finish(&["color", "thickness", "cap", "join", "dash", "miter-limit"])?;
+ dict.finish(&["paint", "thickness", "cap", "join", "dash", "miter-limit"])?;
Self {
paint,
diff --git a/src/model/content.rs b/src/model/content.rs
index c2c70f9d..4af4e655 100644
--- a/src/model/content.rs
+++ b/src/model/content.rs
@@ -584,7 +584,6 @@ impl Fold for Vec<Meta> {
/// The missing key access error message.
#[cold]
-#[track_caller]
fn missing_field(key: &str) -> EcoString {
eco_format!("content does not contain field {:?}", Str::from(key))
}
diff --git a/src/model/styles.rs b/src/model/styles.rs
index 9ef74276..6757ed5d 100644
--- a/src/model/styles.rs
+++ b/src/model/styles.rs
@@ -412,9 +412,7 @@ impl Selector {
Self::Or(selectors) => selectors.iter().any(move |sel| sel.matches(target)),
Self::And(selectors) => selectors.iter().all(move |sel| sel.matches(target)),
Self::Location(location) => target.location() == Some(*location),
- Self::Before { .. } | Self::After { .. } => {
- panic!("Cannot match a `Selector::Before` or `Selector::After` selector")
- }
+ Self::Before { .. } | Self::After { .. } => false,
}
}
}
@@ -491,7 +489,7 @@ impl Cast for LocatableSelector {
fn cast(value: Value) -> StrResult<Self> {
fn validate(selector: &Selector) -> StrResult<()> {
- match &selector {
+ match selector {
Selector::Elem(elem, _) => {
if !elem.can::<dyn Locatable>() {
Err(eco_format!("{} is not locatable", elem.name()))?
@@ -533,6 +531,56 @@ impl Cast for LocatableSelector {
])
}
}
+
+/// A selector that can be used with show rules.
+#[derive(Clone, PartialEq, Hash)]
+pub struct ShowableSelector(pub Selector);
+
+impl Cast for ShowableSelector {
+ fn is(value: &Value) -> bool {
+ matches!(value, Value::Str(_) | Value::Label(_) | Value::Func(_))
+ || value.type_name() == "regular expression"
+ || value.type_name() == "selector"
+ }
+
+ fn cast(value: Value) -> StrResult<Self> {
+ fn validate(selector: &Selector) -> StrResult<()> {
+ match selector {
+ Selector::Elem(_, _) => {}
+ Selector::Label(_) => {}
+ Selector::Regex(_) => {}
+ Selector::Or(_)
+ | Selector::And(_)
+ | Selector::Location(_)
+ | Selector::Can(_)
+ | Selector::Before { .. }
+ | Selector::After { .. } => {
+ Err("this selector cannot be used with show")?
+ }
+ }
+ Ok(())
+ }
+
+ if !Self::is(&value) {
+ return <Self as Cast>::error(value);
+ }
+
+ let selector = Selector::cast(value)?;
+ validate(&selector)?;
+ Ok(Self(selector))
+ }
+
+ fn describe() -> CastInfo {
+ CastInfo::Union(vec![
+ CastInfo::Type("function"),
+ CastInfo::Type("label"),
+ CastInfo::Type("string"),
+ CastInfo::Type("regular expression"),
+ CastInfo::Type("selector"),
+ ])
+ }
+}
+
/// A show rule transformation that can be applied to a match.
#[derive(Clone, PartialEq, Hash)]
pub enum Transform {
diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs
index ab73479e..1198774b 100644
--- a/src/syntax/parser.rs
+++ b/src/syntax/parser.rs
@@ -850,12 +850,19 @@ fn item(p: &mut Parser, keyed: bool) -> SyntaxKind {
return SyntaxKind::Spread;
}
- if !p.eat_if(SyntaxKind::Underscore) {
- code_expr_or_pattern(p);
- } else {
- return SyntaxKind::Underscore;
+ if p.at(SyntaxKind::Underscore) {
+ // This is a temporary workaround to fix `v.map(_ => {})`.
+ let mut lexer = p.lexer.clone();
+ let next =
+ std::iter::from_fn(|| Some(lexer.next())).find(|kind| !kind.is_trivia());
+ if next != Some(SyntaxKind::Arrow) {
+ p.eat();
+ return SyntaxKind::Underscore;
+ }
}
+ code_expr_or_pattern(p);
+
if !p.eat_if(SyntaxKind::Colon) {
return SyntaxKind::Int;
}