rstudio / gt

Easily generate information-rich, publication-quality tables from R
https://gt.rstudio.com
Other
1.97k stars 199 forks source link

Footnote marker placement when using `gt::md()` in Quarto in gt v0.11.0 #1773

Open ddsjoberg opened 1 month ago

ddsjoberg commented 1 month ago

Prework

Description

When a footnote is placed next to text that has been processed with gt::md(), the footnote marker is placed in a separate row when rendered with Quarto. I spotted this behaviour in both column labels and footnotes (I haven't checked all location types, e.g. table cells, grouped row headers, summary rows, etc FYI). Note this does not occur when running the code interactively in the RStudio IDE. I think this is new behavior in gt 0.11.0.

Reproducible example

In the example below, I am using gt::md() in the column label and in the actual footnote text. In both cases, the use of gt::md() drives the footnote marker so its own row.

---
title: "Untitled"
format:
  html:
    embed-resources: true
---

## Quarto

gt footnotes without `gt::md()`: no issues.

```{r}
mtcars[1:2, 1:2] |> 
  gt::gt() |> 
  gt::cols_label(mpg = "**MPG**") |> 
  gt::tab_footnote(
    "_Adding footnote_",
    locations = gt::cells_column_labels(columns = gt::everything())
  )

gt footnotes WITH gt::md(): footnote markers appear on their own line.

mtcars[1:2, 1:2] |> 
  gt::gt() |> 
  gt::cols_label(mpg = gt::md("**MPG**")) |> 
  gt::tab_footnote(
    gt::md("_Adding footnote_"),
    locations = gt::cells_column_labels(columns = gt::everything())
  )


<img width="1215" alt="image" src="https://github.com/user-attachments/assets/f9c230b5-3b45-4e24-a822-28fcc6e122e0">

Thank you again!!! 🕺🏼 

PS This issue could be related to https://github.com/rstudio/gt/issues/1541. But that doesn't mention Quarto?
olivroy commented 1 month ago

Thanks for the report!

Will have to double check, but it seems like the issue you mentioned (#1541) has been fixed. We'll have to check for this one and Quarto rendering. This is probably related to #1769 and base64encoding. We will have to investigate. It is maybe an issue of /

. I am not too familiar.

ddsjoberg commented 1 month ago

Thanks @olivroy ! Let me know if I can help in any way. The issues that only pop up in quarto sound vvv tricky

olivroy commented 1 month ago

Discussed also in https://github.com/quarto-dev/quarto-cli/discussions/10512.

Confirmed this is a gt bug. The generated html is invalid.

I looked for the diff between the html code generated under Quarto

In yellow is the html code gt emits outside Quarto (which renders correctly) In blue is the html code gt emits in Quarto (that causes this bug)

Here is the (unhelpful) diff image

@ddsjoberg A way I have found to test output is the following.

gt_tbl <- mtcars[1:2, 1:2] |> 
  gt::gt() |> 
  gt::cols_label(mpg = gt::md("**MPG**")) |> 
  gt::tab_footnote(
    gt::md("_Adding footnote_"),
    locations = gt::cells_column_labels(columns = gt::everything())
  )
# inside Quarto
html_code_quarto <- withr::with_envvar(c("QUARTO_BIN_PATH" = "true"), gt:::render_as_html(gt_tbl))
# out of Quarto
html_code <- withr::with_envvar(c("QUARTO_BIN_PATH" = ""), gt:::render_as_html(gt_tbl))
# or another diffing helper
waldo::compare(html_code, html_code_quarto, x_arg = "html", y_arg = "quarto")

To use a richer diffing. There is also this strategy (inspired by testthat snapshot files

html_file <- withr::local_tempfile(lines = html_code, pattern = "html")
quarto_file <- withr::local_tempfile(lines = html_code_quarto, pattern = "quarto")
diffviewer::visual_diff(
  html_file,
  quarto_file
)

image

I am pretty sure the problem occurs in the md_to_html() function.

But I really have no idea what the correct html code should be in this context.

ddsjoberg commented 1 month ago

If you know how to fix something, we'd welcome PRs too!

I think this one is beyond me. (I am no HTML 🧙🏼 !) Sorry @olivroy !

bzkrouse commented 1 month ago

I've tested a few more locations and the stub columns are affected too:

mtcars[1:2, 1:2] |>
  tibble::rownames_to_column(var = "name") |>
  gt::gt(rowname_col = "name", process_md = TRUE) |>  
  gt::tab_footnote(
    gt::md("_Adding footnote_"),
    locations = gt::cells_stub(rows = 1)
  )

and

mtcars[1:2, 1:2] |>
  tibble::rownames_to_column(var = "name") |>
  gt::gt(groupname_col = "name", process_md = TRUE) |>  
  gt::tab_footnote(
    gt::md("_Adding footnote_"),
    locations = gt::cells_row_groups()
  )

(Rmarkdown seems fine!) Thanks!!