Mc-Zen / zero

Advanced scientific number formatting for Typst.
https://typst.app/universe/package/zero
MIT License
30 stars 2 forks source link

Formatted cells in `ztable` lose text formatting. #9

Closed Alex-Muirhead closed 3 weeks ago

Alex-Muirhead commented 3 weeks ago

When applying formatting to cells (i.e. bold weight) using a show rule, this formatting isn't passed through for cells that are formatted within ztable. In the example below, the last row is meant to have a bold weight.

image

For other modules I've written, I found this snippet to be quite useful to taking an existing cell and applying functions to the body and/or applying parameters to the cell.

#import "@preview/t4t:0.3.2" : is, is-none

#let modify-cell(it, func: none, ..style) = {
  // Default is identity mapping
  if is-none(func) { func = { body => body } }

  if is.elem(table.cell, it) {

    // Reconstruct the modified cell
    let attrs = it.fields()
    let body = attrs.remove("body")
    // Default to individual cells overriding
    table.cell(func(body), ..style, ..attrs)

  } else if is.elem(text, it) or is.elem("sequence", it) {

    // Construct a new cell for basic text
    table.cell(func(it), ..style)

  } else {

    // Let everything else (i.e. hline & vline) pass through
    it

  }
}
Mc-Zen commented 3 weeks ago

Hmm, I will need to investigate that. Thank you for reporting.

For other modules I've written, I found this snippet to be quite useful to taking an existing cell and applying functions to the body and/or applying parameters to the cell.

Can you explain how you use this snippet? Is it for preprocessing all ..children before passing them on to std.table? Because, the way zero works is different:

Mc-Zen commented 3 weeks ago

Okay, so I have tracked the issue and the good news is that there is a solution.

I will explain it here for the posterity but you don't need to read it ^^

At the heart of ztable lies something like

#show table.cell: it => {
  if is-not-numeral(it..) { it }
  else { transform-into-aligned-number(it, ..) }
}    
#table(..children)

This means, that

Since in the second case, there is no table.cell, it cannot be styled with set and show rules.

Now interestingly, with the current design of the package I can somehow wrap the content into a table.cell without getting a recursive show rule after all.... not exactly sure why.

Edit: It seems that returning a cell with a body that is a context expression is the key here.

But it works and now things like

#show table.cell.where(y: 4): strong

behave as they should.

Alex-Muirhead commented 3 weeks ago

Fantastic, thank you for the fix and the explanation! In regards to the snippet, yes it's used to preprocessing ..children or a subset thereof. I can see now how zero relies on a bit more context.

Alex-Muirhead commented 3 weeks ago

Interestingly this doesn't work with the 0.12 release that's on the online editor. I'll give it another go offline when I get a change, with the master version.

Edit: On closer inspection, it doesn't work since call-num returns a context, which no formatting can be applied to. I think the context keywords might need to be moved higher up the call-chain, but I might be missing another solution.

Mc-Zen commented 3 weeks ago

Interestingly this doesn't work with the 0.12 release that's on the online editor.

Can you specify what "this" is which does not work? I did not understand 😅

Mc-Zen commented 3 weeks ago

Taking a guess:

It seems that making the numbers bold does not work in the web app. But this is a different issue, not connected to zero at all.

Using strong with equations just does nothing

#strong[$12a^2+b$]

I wonder why since it works with tinymist ....

Try #show table.cell.where(y: 1): text.with(blue), this works fine.

Alex-Muirhead commented 3 weeks ago

Ah, whoops, yes that's the cause! I was also using a label to add formatting to table headers and footers, which was being lost, but that feels like more of a usage issue.