From 36490f7f7bbe450b12faa24eba500909ccda3f85 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 26 Nov 2022 15:08:23 +0100 Subject: [PATCH] Make text and space nodes unselectable --- library/src/lib.rs | 1 - src/model/cast.rs | 2 +- src/model/eval.rs | 5 ++-- src/model/func.rs | 53 ++++++++++++++++++----------------- tests/typ/style/show-node.typ | 6 +++- 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/library/src/lib.rs b/library/src/lib.rs index ea14c4c1a..11baacc37 100644 --- a/library/src/lib.rs +++ b/library/src/lib.rs @@ -24,7 +24,6 @@ fn scope() -> Scope { let mut std = Scope::new(); // Text. - std.def_node::("space"); std.def_node::("linebreak"); std.def_node::("smartquote"); std.def_node::("text"); diff --git a/src/model/cast.rs b/src/model/cast.rs index 0e7739ac3..d0a4650a4 100644 --- a/src/model/cast.rs +++ b/src/model/cast.rs @@ -185,7 +185,7 @@ dynamic! { Selector: "selector", Value::Str(text) => Self::text(&text), Value::Label(label) => Self::Label(label), - Value::Func(func) => Self::Node(func.node()?, None), + Value::Func(func) => func.select(None)?, @regex: Regex => Self::Regex(regex.clone()), } diff --git a/src/model/eval.rs b/src/model/eval.rs index 6c21a666a..da7036b7b 100644 --- a/src/model/eval.rs +++ b/src/model/eval.rs @@ -932,10 +932,9 @@ impl Eval for ast::SetRule { } let target = self.target(); - let span = target.span(); - let target = target.eval(vm)?.cast::().at(span)?; + let target = target.eval(vm)?.cast::().at(target.span())?; let args = self.args().eval(vm)?; - target.set(args, span) + target.set(args) } } diff --git a/src/model/func.rs b/src/model/func.rs index 4a2a162b0..dcb820275 100644 --- a/src/model/func.rs +++ b/src/model/func.rs @@ -5,11 +5,12 @@ use std::sync::Arc; use comemo::{Track, Tracked}; use super::{ - Args, Eval, Flow, Node, NodeId, Route, Scope, Scopes, Selector, StyleMap, Value, Vm, + Args, Dict, Eval, Flow, Node, NodeId, Route, Scope, Scopes, Selector, StyleMap, + Value, Vm, }; use crate::diag::{bail, SourceResult, StrResult}; use crate::syntax::ast::{self, AstNode, Expr}; -use crate::syntax::{SourceId, Span, SyntaxNode}; +use crate::syntax::{SourceId, SyntaxNode}; use crate::util::EcoString; use crate::World; @@ -108,33 +109,35 @@ impl Func { Self(Arc::new(Repr::With(self, args))) } - /// Execute the function's set rule and return the resulting style map. - pub fn set(&self, mut args: Args, span: Span) -> SourceResult { - let Repr::Native(Native { set: Some(set), .. }) = self.0.as_ref() else { - bail!(span, "this function cannot be customized with set"); - }; - - let styles = set(&mut args)?; - args.finish()?; - Ok(styles) - } - - /// The id of the node to customize with this function's show rule. - pub fn node(&self) -> StrResult { - match self.0.as_ref() { - Repr::Native(Native { node: Some(id), .. }) => Ok(*id), - _ => Err("this function cannot be customized with show")?, - } - } - /// Create a selector for this function's node type, filtering by node's /// whose [fields](super::Content::field) match the given arguments. pub fn where_(self, args: &mut Args) -> StrResult { + let fields = args.to_named(); + args.items.retain(|arg| arg.name.is_none()); + self.select(Some(fields)) + } + + /// Execute the function's set rule and return the resulting style map. + pub fn set(&self, mut args: Args) -> SourceResult { + Ok(match self.0.as_ref() { + Repr::Native(Native { set: Some(set), .. }) => { + let styles = set(&mut args)?; + args.finish()?; + styles + } + _ => StyleMap::new(), + }) + } + + /// Create a selector for this function's node type. + pub fn select(&self, fields: Option) -> StrResult { match self.0.as_ref() { - Repr::Native(Native { node: Some(id), .. }) => { - let named = args.to_named(); - args.items.retain(|arg| arg.name.is_none()); - Ok(Selector::Node(*id, Some(named))) + &Repr::Native(Native { node: Some(id), .. }) => { + if id == item!(text_id) { + Err("to select text, please use a string or regex instead")?; + } + + Ok(Selector::Node(id, fields)) } _ => Err("this function is not selectable")?, } diff --git a/tests/typ/style/show-node.typ b/tests/typ/style/show-node.typ index 0124e61c4..98f36f13e 100644 --- a/tests/typ/style/show-node.typ +++ b/tests/typ/style/show-node.typ @@ -83,9 +83,13 @@ Another text. = Heading --- -// Error: 7-12 this function cannot be customized with show +// Error: 7-12 this function is not selectable #show upper: it => {} +--- +// Error: 7-11 to select text, please use a string or regex instead +#show text: it => {} + --- // Error: 16-20 expected content or function, found integer #show heading: 1234