summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMALO <57839069+MDLC01@users.noreply.github.com>2023-05-30 10:13:27 +0200
committerGitHub <noreply@github.com>2023-05-30 10:13:27 +0200
commit644bbf99145042266ea8cf2890cef5771bd04be4 (patch)
treeb19aaeb5d9ad95dee18bf182804ca93d6719f1fd
parentb6b6666efdde33a3727955fb2254ba16a886e1d3 (diff)
Add `fields` method to content (#1340)
-rw-r--r--docs/src/reference/types.md7
-rw-r--r--src/eval/methods.rs9
-rw-r--r--src/model/content.rs9
-rw-r--r--tests/typ/compiler/methods.typ5
4 files changed, 28 insertions, 2 deletions
diff --git a/docs/src/reference/types.md b/docs/src/reference/types.md
index 13ca8720..715427f3 100644
--- a/docs/src/reference/types.md
+++ b/docs/src/reference/types.md
@@ -604,6 +604,13 @@ field does not exist or fails with an error if no default value was specified.
A default value to return if the field does not exist.
- returns: any
+### fields()
+Return the fields of this content.
+
+```example
+#repr(rect(width: 10cm, height: 10cm).fields())
+```
+
### location()
The location of the content. This is only available on content returned by
[query]($func/query), for other content it will fail with an error. The
diff --git a/src/eval/methods.rs b/src/eval/methods.rs
index 7de3bc20..f57bf84d 100644
--- a/src/eval/methods.rs
+++ b/src/eval/methods.rs
@@ -81,6 +81,7 @@ pub fn call(
"at" => content
.at(&args.expect::<EcoString>("field")?, args.named("default")?)
.at(span)?,
+ "fields" => Value::Dict(content.dict()),
"location" => content
.location()
.ok_or("this method can only be called on content returned by query(..)")
@@ -332,7 +333,13 @@ pub fn methods_on(type_name: &str) -> &[(&'static str, bool)] {
("starts-with", true),
("trim", true),
],
- "content" => &[("func", false), ("has", true), ("at", true), ("location", false)],
+ "content" => &[
+ ("func", false),
+ ("has", true),
+ ("at", true),
+ ("fields", false),
+ ("location", false),
+ ],
"array" => &[
("all", true),
("any", true),
diff --git a/src/model/content.rs b/src/model/content.rs
index 8b60ab44..f262d027 100644
--- a/src/model/content.rs
+++ b/src/model/content.rs
@@ -12,7 +12,7 @@ use super::{
};
use crate::diag::{SourceResult, StrResult};
use crate::doc::Meta;
-use crate::eval::{Cast, Str, Value, Vm};
+use crate::eval::{Cast, Dict, Str, Value, Vm};
use crate::syntax::Span;
use crate::util::pretty_array_like;
@@ -251,6 +251,13 @@ impl Content {
.ok_or_else(|| missing_field_no_default(field))
}
+ /// Return the fields of the content as a dict.
+ pub fn dict(&self) -> Dict {
+ self.fields()
+ .map(|(key, value)| (key.to_owned().into(), value))
+ .collect()
+ }
+
/// The content's label.
pub fn label(&self) -> Option<&Label> {
match self.field_ref("label")? {
diff --git a/tests/typ/compiler/methods.typ b/tests/typ/compiler/methods.typ
index 8b36dea9..864ed8ad 100644
--- a/tests/typ/compiler/methods.typ
+++ b/tests/typ/compiler/methods.typ
@@ -48,3 +48,8 @@
---
// Error: 2-5 cannot mutate a constant: box
#box.push(1)
+
+---
+// Test content fields method.
+#test([a].fields(), (text: "a"))
+#test([a *b*].fields(), (children: ([a], [ ], strong[b])))