summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjassler <erifetim@gmail.com>2023-05-12 12:26:14 +0200
committerGitHub <noreply@github.com>2023-05-12 12:26:14 +0200
commitfd84d23ade16fea22e8f8413a5d29c95c2ee1d84 (patch)
tree9cdc3caee2a0ad36d8f03b2ada148f1c87f3e317
parenta8728be9b03f6f19df6adf1ea26a4713562dc0ae (diff)
Support for align parameter in table to take an array (#1087) (#1149)
-rw-r--r--library/src/layout/table.rs24
-rw-r--r--tests/ref/layout/table.pngbin5170 -> 7530 bytes
-rw-r--r--tests/typ/layout/table.typ18
3 files changed, 35 insertions, 7 deletions
diff --git a/library/src/layout/table.rs b/library/src/layout/table.rs
index 6e3e6330..29e2edb8 100644
--- a/library/src/layout/table.rs
+++ b/library/src/layout/table.rs
@@ -87,9 +87,10 @@ pub struct TableElem {
/// How to align the cell's content.
///
- /// This can either be a single alignment or a function that returns an
- /// alignment. The function is passed the cell's column and row index,
- /// starting at zero. If set to `{auto}`, the outer alignment is used.
+ /// This can either be a single alignment, an array of alignments
+ /// (corresponding to each column) or a function that returns an alignment.
+ /// The function is passed the cell's column and row index, starting at zero.
+ /// If set to `{auto}`, the outer alignment is used.
///
/// ```example
/// #table(
@@ -236,9 +237,11 @@ pub enum Celled<T> {
Value(T),
/// A closure mapping from cell coordinates to a value.
Func(Func),
+ /// An array of alignment values corresponding to each column.
+ Array(Vec<T>),
}
-impl<T: Cast + Clone> Celled<T> {
+impl<T: Cast + Clone + Default> Celled<T> {
/// Resolve the value based on the cell position.
pub fn resolve(&self, vt: &mut Vt, x: usize, y: usize) -> SourceResult<T> {
Ok(match self {
@@ -247,6 +250,11 @@ impl<T: Cast + Clone> Celled<T> {
.call_vt(vt, [Value::Int(x as i64), Value::Int(y as i64)])?
.cast()
.at(func.span())?,
+ Self::Array(array) => x
+ .checked_rem(array.len())
+ .and_then(|i| array.get(i))
+ .cloned()
+ .unwrap_or_default(),
})
}
}
@@ -259,19 +267,22 @@ impl<T: Default> Default for Celled<T> {
impl<T: Cast> Cast for Celled<T> {
fn is(value: &Value) -> bool {
- matches!(value, Value::Func(_)) || T::is(value)
+ matches!(value, Value::Array(_) | Value::Func(_)) || T::is(value)
}
fn cast(value: Value) -> StrResult<Self> {
match value {
Value::Func(v) => Ok(Self::Func(v)),
+ Value::Array(array) => {
+ Ok(Self::Array(array.into_iter().map(T::cast).collect::<StrResult<_>>()?))
+ }
v if T::is(&v) => Ok(Self::Value(T::cast(v)?)),
v => <Self as Cast>::error(v),
}
}
fn describe() -> CastInfo {
- T::describe() + CastInfo::Type("function")
+ T::describe() + CastInfo::Type("array") + CastInfo::Type("function")
}
}
@@ -280,6 +291,7 @@ impl<T: Into<Value>> From<Celled<T>> for Value {
match celled {
Celled::Value(value) => value.into(),
Celled::Func(func) => func.into(),
+ Celled::Array(arr) => arr.into(),
}
}
}
diff --git a/tests/ref/layout/table.png b/tests/ref/layout/table.png
index 340d93a7..5c8dbf0e 100644
--- a/tests/ref/layout/table.png
+++ b/tests/ref/layout/table.png
Binary files differ
diff --git a/tests/typ/layout/table.typ b/tests/typ/layout/table.typ
index 5d423e03..5526c4f6 100644
--- a/tests/typ/layout/table.typ
+++ b/tests/typ/layout/table.typ
@@ -14,9 +14,25 @@
#table(columns: 3, stroke: none, fill: green, [A], [B], [C])
---
+// Test alignment with array.
+#table(
+ columns: (1fr, 1fr, 1fr),
+ align: (left, center, right),
+ [A], [B], [C]
+)
+
+// Test empty array.
+#set align(center)
+#table(
+ columns: (1fr, 1fr, 1fr),
+ align: (),
+ [A], [B], [C]
+)
+
+---
// Ref: false
#table()
---
-// Error: 14-19 expected color, none, or function, found string
+// Error: 14-19 expected color, none, array, or function, found string
#table(fill: "hey")