I can format the first row, I need to get the last row also
#set table(
inset: (x:0.5em,y:.4em),
stroke:_gridlines,
fill: (x, y) => if y==0 { rgb(_shadecolor) },
)
I can format the first row, I need to get the last row also
#set table(
inset: (x:0.5em,y:.4em),
stroke:_gridlines,
fill: (x, y) => if y==0 { rgb(_shadecolor) },
)
Hello @mgholam,
Unfortunately, I don’t seem to have found a programatic way to shade the last row of your table. You should be able to using a variable, and changing n-rows appropriately for each table.
#let n-rows = 3
#set table(
inset: (x:0.5em,y:.4em),
stroke:_gridlines,
fill: (x, y) => if y==0 or y == n-rows { rgb(_shadecolor) },
)
don’t hesitate to provide a full minimal example the next time you ask a question, as stated in How to post in the Questions category.
Thanks!
That is what I did, set a variable and checked against that.
I had proposed one potential way around this in this issue: Resolve further fields in `grid` and `table` show rules · Issue #3697 · typst/typst · GitHub
Though I’m not fully sure whether that is the best way forward. Frankly I agree that this is quite an annoying limitation. I hope we can find a good design that solves it.
If you put you cells in an array, you can automatically compute the number of rows according to the number of columns, like so:
#let n-cols = 3
#let cells = ([A], [B], [C], [D], [E], [F], [G])
#let n-rows = calc.ceil(cells.len() / n-cols)
#table(
columns: n-cols,
fill: (_, y) => if y == n-rows - 1 {
gray.lighten(50%)
} else {
none
},
..cells
)
If this is something you need in multiple places, you could even wrap it in a function, for example:
#let my-table(cells, ..args) = {
let columns = args.named().at("columns", default: 1)
let n-cols = if type(columns) == int {
columns
} else {
columns.len()
}
let n-rows = calc.ceil(cells.len() / n-cols)
table(
columns: columns,
..args,
fill: (_, y) => if y == n-rows - 1 {
gray.lighten(50%)
} else {
none
},
..cells
)
}
Taking @LordBaryhobal’s solution one step further so that it handles cells that span columns and rows:
#let my-table(cells, ..args) = {
let columns = args.named().at("columns", default: 1)
let n-cols = if type(columns) == int {
columns
} else {
columns.len()
}
let n-cells = cells.fold(
0,
(curVal, cell) => curVal + cell.at("colspan", default: 1) * cell.at("rowspan", default: 1)
)
let n-rows = calc.ceil(n-cells / n-cols)
table(
columns: columns,
..args,
fill: (_, y) => if y == n-rows - 1 {
gray.lighten(50%)
} else {
none
},
..cells
)
}
Then it can be used as before:
#my-table(
(
table.cell(colspan: 2, [A]), table.cell(rowspan: 2, [B]),
[C], [D],
table.cell(colspan: 3, [E]),
[F]
),
columns: 3
)
The change was to not trust the length of the cells
array, but to use fold
to process each one, checking for colspan
and rowspan
, getting the total number of spaces taken up by the given cells.
Now you’re thinking in tables
Good job!
You can customize some cell properties based on the table size like this :
#show table: t => {
let width = t.columns.len()
let height = t.children.len() / width
show table.cell.where(y: height - 1): strong
show table.cell.where(x: width - 1): c => {
set align(right)
c
}
t
}
Unfortunately I couldn’t make it work with the fill
property.