davidgohel / flextable

table farming
https://ardata-fr.github.io/flextable-book/
562 stars 81 forks source link

`flextable_to_rmd()` does not respond to `knitr::asis_output()` #546

Closed montesmariana closed 1 year ago

montesmariana commented 1 year ago

Hi! Thank you for all your work on this package!

I need to be able to print a sequence of tables programmatically from inside a package (glossr), so I'd rather not require users to add results='asis' to their chunks if I can avoid it. Normally I use knitr::asis_output() instead, which is supposed to mimic the output from results='asis'. Until a few months ago, this worked fine with flextable::flextable_to_rmd(), but since the last update or so it is broken and it ONLY works when results='asis', regardless of the use of knitr::asis_output().

I'm not sure to what degree this is entirely an issue of flextable or something to do with knitr or officedown (I'm only using this for Word output). When printing a normal string, the output is also different depending on whether I include knitr::asis_output() or not.

Another difference is that before, if I did knitr::asis_output() on a vector that had first a string and then a flextable, they were printed in the right order, whereas now the table is printed first and the string follows. If I have a sequence of them (string, table, string, table...), all the tables are printed first followed by all the strings. I can work around it, but... what changed?

I'm attaching an example rendered with the following Rmd:

---
title: "Testing Flextable output"
output: officedown::rdocx_document
date: "2023-06-01"
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, collapse = TRUE)
library(flextable)

Normal table

flextable(head(iris))

Using results='asis'

paste("This is", "some text")
flextable_to_rmd(flextable(head(iris)))

Using knitr::asis_output()

knitr::asis_output(paste("This is", "some text"))
knitr::asis_output(flextable_to_rmd(flextable(head(iris))))

Sessioninfo

sessionInfo()

[flextable-test.docx](https://github.com/davidgohel/flextable/files/11627287/flextable-test.docx)

---
Mariana
davidgohel commented 1 year ago

hello @montesmariana

I will add a better explanation later (sorry) on how you should do it and an illustration. Basically, the solution is there: https://bookdown.org/yihui/rmarkdown-cookbook/knit-expand.html

This is recommended by the team of R Markdown and I think it is the correct solution.

davidgohel commented 1 year ago

When using knitr::knit_child(), the LaTeX and HTML dependencies required to render the content from the included file are automatically detected and integrated into the parent document. This means that if your included file contains elements that require specific LaTeX or HTML packages (this is the case for 'flextable'), knitr::knit_child() will ensure that all these dependencies are properly handled and included in the final document.

flextable_to_rmd() does not directly handle LaTeX and HTML dependencies. If you use flextable_to_rmd() to generate the R Markdown code for a 'flextable', you will need to manually ensure that all the necessary dependencies are included in your document. This can be an additional task and potentially prone to errors if you are not familiar with the specific dependencies required by 'flextable'.

Here is an illustration with 'flextable'. We will need two files, the child document child.Rmd and the main document knit_expand.Rmd.

---- child.Rmd -----

### `r txt`

```{r echo=FALSE}
flextable::as_flextable(dat) |> 
  set_table_properties(layout = "autofit")

---- `knit_expand.Rmd` -----

title: "Testing Flextable output" output: word_document date: "2023-06-01"

knitr::opts_chunk$set(echo = TRUE, collapse = TRUE)
library(flextable)

Normal table

qflextable(head(iris))

Using knit_expand

purrr::map2_chr(
  .x = c("cars", "iris"),
  .y = list(cars, iris), 
  function(txt, dat) {
    knitr::knit_child(input = "child.Rmd", envir = environment(), quiet = TRUE)
  }) |> 
  cat(sep = '\n')


Here is the result.

<img width="1235" alt="Capture d’écran 2023-06-05 à 23 36 22" src="https://github.com/davidgohel/flextable/assets/4331618/73b30071-6587-46cb-a1f6-7b01ab133db6">
davidgohel commented 1 year ago

[...] what changed?

The change start happening here: https://github.com/davidgohel/flextable/issues/511

That's where we learned about knit_child() and knit-expand().

There were some issues that appeared with Quarto, and we had to change some codes. flextable_to_rmd() is going to disappear or be unuseful.

I don't know if glossr can avoid the result='asis' option for word, I think it is possible by creating your knitr_print method. That's what flextable is doing.

As an alternative, maybe you could be interested in the method to_wml applied to flextable(), see https://github.com/davidgohel/flextable/blob/master/R/printers.R#L173

davidgohel commented 1 year ago

I am closing the issue, I will reopen if necessary :)

montesmariana commented 1 year ago

Thank you for the thorough explanations :) I'm still having trouble implementing them but your latest messages should help more. Thank you so much!

github-actions[bot] commented 11 months ago

This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary.