quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.77k stars 309 forks source link

Option to disable table striping in computational tables? #6945

Closed andrewheiss closed 4 months ago

andrewheiss commented 12 months ago

Bug description

In this issue, https://github.com/quarto-dev/quarto-cli/issues/922#issuecomment-1640093837, there's a difference in how tables are rendered by default: non-computational tables made with Markdown don't have the .striped class included, while tables generated with chunks (like with knitr::kable() or with gt::gt() do.

The rational for including stripes and condensed spacing by default makes sense, since tables full of numbers often need to be more information-dense. Sometimes, though, {kable} and {gt} can be used to create less number-heavy tables and just present text. As of Quarto 1.4.376, the .striped class seems hard-baked-in and can't be removed, though (though I might be missing some option to disable it)

Steps to reproduce

This example uses {gt} to generate a text-based table. Row striping appears (<table class="gt_table table table-sm table-striped small" ...>) regardless of the row_striping option in gt::opt_row_striping() (which is a gt thing, not a quarto thing, but quarto's table rendering is inserting its own table class here)

---
title: "Testing"
---

```{r}
dplyr::tibble(Animal = c("Bat", "Cat", "Dog"), `Has wings` = c("Yes", "No", "No")) |> 
  gt::gt() |> 
  gt::opt_row_striping(row_striping = FALSE)

<img width="191" alt="image" src="https://github.com/quarto-dev/quarto-cli/assets/73663/f3173987-8b88-47c3-b642-e5bfa8d61a39">

### Expected behavior

It would be nice to have a table without stripes. [In the documentation](https://quarto.org/docs/prerelease/1.3/tables.html#bootstrap-classes-can-be-added-to-tables) it shows that it's possible to add a bunch of different bootstrap classes to non-computational tables:
fruit price
apple 2.05
pear 1.37
orange 3.09

: Fruit prices {.striped .hover}


### Actual behavior

However, that `.striped` class is hard-coded for computational output and there's no way I can find to disable it, so all kable and gt tables have stripes regardless of controlling stripes with kable- and gt-specific settings.

### Your environment

- Quarto: 1.4.376
- IDE: 2023.06.2+561
- R: 4.3.1
- OS: macOS Ventura 13.5.2

### Quarto check output

```bash
Quarto 1.4.376
[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.1.8: OK
      Dart Sass version 1.55.0: OK
      Deno version 1.33.4: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
      Version: 1.4.376
      Path: /Applications/quarto/bin

[✓] Checking tools....................OK
      TinyTeX: v2022.08
      Chromium: (not installed)

[✓] Checking LaTeX....................OK
      Using: TinyTex
      Path: /Users/andrew/Library/TinyTeX/bin/universal-darwin
      Version: 2022

[✓] Checking basic markdown render....OK

[✓] Checking Python 3 installation....OK
      Version: 3.11.3
      Path: /opt/homebrew/opt/python@3.11/bin/python3.11
      Jupyter: 5.3.0
      Kernels: python3

(|) Checking Jupyter engine render....0.00s - Debugger warning: It seems that frozen modules are being used, which may
0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
0.00s - to python to disable frozen modules.
0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.
(|) Checking Jupyter engine render....0.00s - Debugger warning: It seems that frozen modules are being used, which may
0.00s - make the debugger miss breakpoints. Please pass -Xfrozen_modules=off
0.00s - to python to disable frozen modules.
0.00s - Note: Debugging will proceed. Set PYDEVD_DISABLE_FILE_VALIDATION=1 to disable this validation.
[✓] Checking Jupyter engine render....OK

[✓] Checking R installation...........OK
      Version: 4.3.1
      Path: /Library/Frameworks/R.framework/Resources
      LibPaths:
        - /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
      knitr: 1.43
      rmarkdown: 2.21

[✓] Checking Knitr engine render......OK
mcanouil commented 12 months ago

There is an option to disable Quarto processing which also exists directly in gt, see https://quarto.org/docs/authoring/tables.html#disabling-quarto-table-processing and https://gt.rstudio.com/reference/tab_options.html (last options listed).

cderv commented 12 months ago

We indeed apply some bootstrap class by default for computational table https://github.com/quarto-dev/quarto-cli/blob/591bae83ce26e1374afebdf9394d49308e945365/src/format/html/format-html-bootstrap.ts#L388-L396

It does not see we have a way to opt out this default style... maybe there should be one 🤔

Also @rich it seems a bit disturbing that gt::opt_row_striping() won't have any effect inside Quarto without the user manually switching to quarto-disable-processing="true". Should it be set automatically if some specific function like are used ? Otherwise no matter what gt does, it will always produce something that will tweaked by Quarto.

But maybe this is only about the default bootstrap classes mentioned above 🤷‍♂️

andrewheiss commented 12 months ago

Using quarto-disable-processing=TRUE in tab_options() works, but it also breaks the citation handling from https://github.com/quarto-dev/quarto-cli/issues/3340:

---
format: html
references:
- type: article-journal
  id: Lovelace1842
  author:
  - family: Lovelace
    given: Augusta Ada
  issued:
    date-parts:
    - - 1842
  title: >-
    Sketch of the analytical engine invented by Charles Babbage, by LF Menabrea, 
    officer of the military engineers, with notes upon the memoir by the translator
  title-short: Molecular structure of nucleic acids
  container-title: Taylor’s Scientific Memoirs
  volume: 3
  page: 666-731
  language: en-GB
---

```{r}
library(gt)

# This is striped and ignores opt_row_striping but it has the citation
tibble::tribble(
  ~Thing, ~Citation,
  1234, "@Lovelace1842"
) |>
  gt() |> 
  fmt_markdown(columns = Citation) |> 
  opt_row_striping(row_striping = FALSE)
# This is not striped but doesn't have the citation
tibble::tribble(
  ~Thing, ~Citation,
  1234, "@Lovelace1842"
) |>
  gt() |> 
  fmt_markdown() |>
  tab_options(quarto.disable_processing = TRUE)


Actually, any column with `fmt_markdown()` seems to disappear when `quarto.disable_processing = TRUE` is enabled, which seems to be a separate quarto and/or gt bug?

<img width="858" alt="image" src="https://github.com/quarto-dev/quarto-cli/assets/73663/fa16cf93-ae53-493e-b276-70574efe8dbd">
cscheid commented 12 months ago

Using quarto-disable-processing=TRUE in tab_options() works, but it also breaks the citation handling from https://github.com/quarto-dev/quarto-cli/issues/3340:

Well, you asked us to disable processing of the content, and so we did :) That's not really breaking the citation handling; that's you asking us not to do it.

Actually, any column with fmt_markdown() seems to disappear when quarto.disable_processing = TRUE is enabled, which seems to be a separate quarto and/or gt bug?

It's not exactly a bug, but I agree we could improve the situation. @rich-iannone, is it possible for gt to emit the regular HTML output that you would in HTML format, as the content of the span, in addition to the markdown you're emitting in the data-qmd attribute? Something like <span data-qmd="_fancy markdown_"><em>fancy markdown</em></span>. If we're processing that table, then we will strip the content of spans with data-qmd attributes, but if we don't, we'll just send it along (and then of course we won't get citation processing, etc.)

(Irrespective of my comments above, I agree that we should improve user control of gt+quarto tables somehow, either in quarto or gt!)

andrewheiss commented 12 months ago

Yeah some way to opt out of/control the default bootstrap classes might be helpful, but I don't know the best way to do it. Maybe something like a tbl-class option?

```{r}
#| tbl-cap: "Fruit prices"
#| tbl-class: .striped .hover
tibble::tribble(
  ~fruit,   ~price,
  "apple",  2.05,
  "pear",   1.37,
  "orange", 3.09
) |> 
  gt()

It would be parallel-ish to the pandoc-style class settings:
fruit price
apple 2.05
pear 1.37
orange 3.09

: Fruit prices {.striped .hover}



But then that gets into weird interactions with table-making packages like gt and kable/kableExtra that have their own ways of inserting custom css classes 🤷‍♂️
rich-iannone commented 12 months ago

Using quarto-disable-processing=TRUE in tab_options() works, but it also breaks the citation handling from #3340:

Well, you asked us to disable processing of the content, and so we did :) That's not really breaking the citation handling; that's you asking us not to do it.

Actually, any column with fmt_markdown() seems to disappear when quarto.disable_processing = TRUE is enabled, which seems to be a separate quarto and/or gt bug?

It's not exactly a bug, but I agree we could improve the situation. @rich-iannone, is it possible for gt to emit the regular HTML output that you would in HTML format, as the content of the span, in addition to the markdown you're emitting in the data-qmd attribute? Something like <span data-qmd="_fancy markdown_">\<em\>fancy markdown\</em\></span>. If we're processing that table, then we will strip the content of spans with data-qmd attributes, but if we don't, we'll just send it along (and then of course we won't get citation processing, etc.)

(Irrespective of my comments above, I agree that we should improve user control of gt+quarto tables somehow, either in quarto or gt!)

@cscheid I can make that change in gt (it's a very good idea!).

cderv commented 12 months ago

Good discussion !

We have several topics / ideas now in this :

  1. is it possible for gt to emit the regular HTML output that you would in HTML format, as the content of the span, in addition to the markdown you're emitting in the data-qmd attribute? @rich-iannone seems onto it in gt

  2. How do disable default style applied on computation table, so that it does not required to add some JS hack, or completely disable quarto processing just for a styling issue.

  3. How to improve user control of gt and its impact on Quarto ? Possibly same as 2.

Just trying to sum up a bit 😅

cscheid commented 12 months ago

But then that gets into weird interactions with table-making packages like gt and kable/kableExtra that have their own ways of inserting custom css classes 🤷‍♂️

This already exists. Additional classes are forwarded into the classes. The issue is that we currently add .striped, .hover etc to all tables in bootstrap (we do this to harmonize table output across rendering formats and engines). Understandably, folks like you who care about the particular rendering of your tables want finer-grained control that currently doesn't exactly exist. We should provide that.

2024 EDIT:

the real culprit here is src/format/html/format-html-bootstrap.ts, line 444.

andrewheiss commented 12 months ago

A temporary hacky workaround for this is to add a CSS class to the chunks that create gt tables that turns off the striping, like this:

---
title: gt no-stripe hack
engine: knitr
---

```{css echo=FALSE}
.no-stripe .gt_table tr.odd {
  --bs-table-striped-bg: transparent;
}
#| classes: no-stripe
tibble::tribble(
  ~fruit,   ~price,
  "apple",  2.05,
  "pear",   1.37,
  "orange", 3.09
) |> 
  gt::gt()


<img width="184" alt="image" src="https://github.com/quarto-dev/quarto-cli/assets/73663/3b06c4f8-96cc-46ca-a4f7-532e9d4aae0e">
cscheid commented 11 months ago

This surfaces another relatively major shortcoming of our current YAML schema system, which is that the schemas for code cells are bound to engines, but sometimes we put options there that are only relevant to formats (see the classes example Andrew just shared for a case in point).

The solution that is in "current quarto style" would be to add a YAML option for projects and document metadata in the html schema, as well as an additional option for all engines.

In the long run, I think we should consider adding a format top-level entry to the cell-level YAML that validates independently of the engines, and behaves like "format settings scoped to the code cell". In light of this, I want to hold off an immediate fix until we discuss the design as a group.

rich-iannone commented 11 months ago

@cscheid I've got a gt PR that makes the proposed change discussed above: https://github.com/rstudio/gt/pull/1455

This requires a corresponding change in Quarto to replace the content of the span with the Quarto-mediated Markdown processing.

cscheid commented 11 months ago

This requires a corresponding change in Quarto to replace the content of the span with the Quarto-mediated Markdown processing.

Huh. That's not working right now? extractquartodom.lua should be doing exactly that.

cderv commented 8 months ago

For reference, discussion on computation table style at

RaymondBalise commented 6 months ago

This issue is still causing mischief. I ran into it with {gtsummary} this morning. After removing striping with a custom theme with code like:

my_theme <-
  list(
    # Some gt customization
    "as_gt-lst:addl_cmds" = list(
      tab_spanner = rlang::expr(gt::tab_options()),
      user_added1 = rlang::expr(gt::opt_row_striping(FALSE)),
      user_added2 = rlang::expr(gt::opt_table_lines("none"))
    )
  )

my table was rendering correctly when I ran the code block in the RStudio IDE but when I rendered to html with Quarto ‘1.4.549’ the stripes were back. The solution from @andrewheiss let me get around the problem.

The full table is a lot of code so I don't want to paste it here but I can make a reprex if it would help address the root of the problem.

cderv commented 6 months ago

Thanks for the feedback. The enhancement discussed is stil to be made, so anything discussed here is still valid.

my table was rendering correctly when I ran the code block in the RStudio IDE but when I rendered to html with Quarto ‘1.4.549’ the stripes were back.

As a reminder, you can try opting out Quarto HTML table processing. You can do that for the whole document, or at the cell level (https://quarto.org/docs/authoring/tables.html#disabling-quarto-table-processing) or even do it at gt level with options quarto.disable_processing (https://gt.rstudio.com/reference/tab_options.html)

This way, the styling of your gt table will not be touched at all, as the table should be shown as is.

However some features could be lost (like markdown cells processing in the HTML table), but if you don't need those, that would be ok

olivroy commented 4 months ago

Opposite of this, in pdf output, is there a way to enable row striping natively in Quarto in pdf output? So that the pdf output and html output look more similar.

I opened https://github.com/quarto-dev/quarto-cli/discussions/9408 a few weeks ago

In https://github.com/quarto-dev/quarto-web/commit/ea95cebf17bb08b8a00cfa8c61ca34d20c53392b

Quarto adds additional styling to tables generated by computations. By default, such tables are styled to be smaller and have striped rows. If you want to disable this treatment, add plain to the classes of the code cell:

This is not true for pdf tables, at least in Quarto 1.4...

cscheid commented 4 months ago

Not in Quarto, no. Quarto has relatively little control over PDF styling, and is limited to what GT offers.