diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-04-26 13:46:42 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-04-26 15:37:21 +0200 |
| commit | 3680c854a21db665d64cdb8f31aa0f9a1af16ceb (patch) | |
| tree | 39dfa33059293251f1e2890f9b3d0e3dc178ed03 /src | |
| parent | 59957746e91c1322a8ca6d228bcaa0f31941ee1b (diff) | |
Touch up docs
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/library.rs | 12 | ||||
| -rw-r--r-- | src/eval/mod.rs | 8 | ||||
| -rw-r--r-- | src/geom/stroke.rs | 10 | ||||
| -rw-r--r-- | src/model/content.rs | 1 | ||||
| -rw-r--r-- | src/model/styles.rs | 56 | ||||
| -rw-r--r-- | src/syntax/parser.rs | 15 |
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; } |
