From 3680c854a21db665d64cdb8f31aa0f9a1af16ceb Mon Sep 17 00:00:00 2001 From: Laurenz Date: Wed, 26 Apr 2023 13:46:42 +0200 Subject: Touch up docs --- src/eval/library.rs | 12 +++++------ src/eval/mod.rs | 8 +++++--- src/geom/stroke.rs | 10 +++++----- src/model/content.rs | 1 - src/model/styles.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/syntax/parser.rs | 15 ++++++++++---- 6 files changed, 79 insertions(+), 23 deletions(-) (limited to 'src') 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, - bottom: Option, + t: Option, + b: Option, // Fixed positions. - topleft: Option, - bottomleft: Option, - topright: Option, - bottomright: Option, + tl: Option, + bl: Option, + tr: Option, + br: Option, ) -> 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 { let selector = self .selector() - .map(|sel| sel.eval(vm)?.cast::().at(sel.span())) - .transpose()?; + .map(|sel| sel.eval(vm)?.cast::().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 => { Self { array, @@ -314,14 +314,14 @@ cast_from_value! { .transpose()?.map(Smart::Custom).unwrap_or(Smart::Auto)) } - let paint = take::(&mut dict, "color")?; + let paint = take::(&mut dict, "paint")?; let thickness = take::(&mut dict, "thickness")?; let line_cap = take::(&mut dict, "cap")?; let line_join = take::(&mut dict, "join")?; let dash_pattern = take::>(&mut dict, "dash")?; let miter_limit = take::(&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 { /// 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 { fn validate(selector: &Selector) -> StrResult<()> { - match &selector { + match selector { Selector::Elem(elem, _) => { if !elem.can::() { 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 { + 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 ::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; } -- cgit v1.2.3