PgBiel / typst-tablex

More powerful and customizable tables in Typst
MIT License
370 stars 12 forks source link

Feature request: Nice Matrix support #95

Open fyuniv opened 8 months ago

fyuniv commented 8 months ago

There is a LaTeX package NiceMatrix that is similar to tabular but support nice matrix output. For example, one may add row and/or indices, and add colors, draw vertical or horizontal line segments. I think typst-tablex is totally cable of producing nicer matrix. The following is an example.

#import "@preview/tablex:0.0.6": *
#tablex(
  columns: (auto, 3pt,)+(auto,)*3+(3pt,), 
  auto-lines: false, 
  align: center + horizon,
  map-cells: cell => {
    cell.content = {show math.equation: set text(0.8em); cell.content}
    if cell.x == 0 {cell.content = text(red, cell.content)}
    if cell.y == 0 {cell.content = text(blue, cell.content)}
    cell
    },
  [], [],  $C_1$,$ C_2$, $C_3$, [],
  $R_1$, rowspanx(2)[$lr("(", size: #300%)$], $a_11$, $a_12$, $a_13$, rowspanx(2)[$lr(")", size: #300%)$],
  $R_2$, $a_21$, $a_22$, $a_23 + a_(12)$,
)

Is it possible that typst-tablex provides an function that similar to the original mat() function, but can easily place the delimiter after the $k$-th column below the $j$-th row?

PgBiel commented 8 months ago

Hi! Indeed, seems like tablex could be helpful to simulate matrices, though I'm not yet sure to which extent that should be supported by default. Perhaps that could become a separate package? Not sure. But it's certainly possible to investigate.

Regarding the delimiter, can you show a sample ideal tablex (or other function) call with your proposed parameters / functions / other kinds of API, and then show the expected output? That could be helpful for some initial design discussion. Thanks!

fyuniv commented 8 months ago

I don't know how to effectively slice and arrange an array of matrix entries so that tablex will produce a desired matrix. Maybe define a function matx as follows

#let matx(delim: "(", row-index:true, column-index: true, dimension: (3,3), row-color:(1, red), column-color: (1, blue), align: center + horizon, auto-lines: false, array) = {
  $
  tablex(
    columns: if column-index {(auto,)+(3pt,)+(auto,)*columns+(3pt,)} else {(3pt,)+(auto,)*9+(3pt,)}, 
    auto-lines: auto-line, 
    align: align,
    map-cells: cell => {
      cell.content = {show math.equation: set text(0.8em); cell.content}
      if cell.x == row-color.at(0) {cell.content = text(row-color.at(1), cell.content)}
      if cell.y == column-color.at(0) {cell.content = text(column-color.at(1), cell.content)}
      cell
      },
      // codes that arrange the matrix array to get the desired outlook
    )
  $
}

Then produce a matrix by calling

#matx(
[], [],  $C_1$,$ C_2$, $C_3$, [],
  $R_1$, $a_11$, $a_12$, $a_13$, 
  $R_2$, $a_21$, $a_22$, $a_23 + a_(12)$,
)

Sorry that I couldn't provide an working example.

PgBiel commented 7 months ago

Thanks for the suggestion. I'll definitely consider adding this at some point.