Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility between pagedown and flextable #216

Closed
tvroylandt opened this issue Feb 20, 2021 · 8 comments
Closed

Compatibility between pagedown and flextable #216

tvroylandt opened this issue Feb 20, 2021 · 8 comments

Comments

@tvroylandt
Copy link
Contributor

tvroylandt commented Feb 20, 2021

Hi,

This is both a flextable and a pagedown issue but I post it here to begin and will change it if needed.

Generating multiples tables in an Rmd is hard. I followed the method here https://community.rstudio.com/t/mixing-purrr-flextable-and-rmarkdown-for-table-outputs/17312/3 which work perfectly with an rmarkdown::html_document.

But as soon as I tried to change the output format to pagedown::html_paged, this create a blank space instead.
My guess is that the JS erased the tables since when we look at the HTML output before running the JS, they are here.

I'm using the last CRAN flextable version and pagedown dev version.

Exemple here :

this is ok :

---
title: "Test flextable"
output:
  rmarkdown::html_document
knit: pagedown::chrome_print
---

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


```{r, include = FALSE}
library(flextable)
library(knitr)
library(tidyverse)

# fake data
df_test <-
  tibble(
    nb = seq(1:10),
    type = c(rep("a", 2), rep("b", 3), rep("c", 1), rep("d", 4)),
    info = rnorm(10)
  )

# function to generate
table_filter <- function(type_filter){
  df_test %>% 
    filter(type == {{type_filter}}) %>% 
    flextable()
}
```


```{r}
render_custom <- function(x, ...) {
map_chr(x, ~ knit_print(.x)) %>% 
  # collapse all the results
  paste(collapse = "\n") %>% 
  # knir must use this result `asis`
  asis_output()
}
```


```{r, render = render_custom}
map(letters[1:4],
  table_filter)
```

while this is not:

---
title: "Test flextable"
output:
  pagedown::html_paged:
knit: pagedown::chrome_print
---

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


```{r, include = FALSE}
library(flextable)
library(knitr)
library(tidyverse)

# fake data
df_test <-
  tibble(
    nb = seq(1:10),
    type = c(rep("a", 2), rep("b", 3), rep("c", 1), rep("d", 4)),
    info = rnorm(10)
  )

# function to generate
table_filter <- function(type_filter){
  df_test %>% 
    filter(type == {{type_filter}}) %>% 
    flextable()
}
```


```{r}
render_custom <- function(x, ...) {
  map_chr(x, ~ knit_print(.x)) %>% 
    # collapse all the results
    paste(collapse = "\n") %>% 
    # knir must use this result `asis`
    asis_output()
}
```


```{r, render = render_custom}
map(letters[1:4],
    table_filter)
```

Exemple output without any problem

exemple_flex_pb.pdf

And with problem

exemple_flex_pb.pdf

@RLesur
Copy link
Collaborator

RLesur commented Mar 7, 2021

This comes from the fact that flextable uses shadow DOMs and pagedown::html_paged() does not yet support shadow DOM or web components (because pagedown::html_paged() uses the automatic preview mode of Paged.js).

I guess that adding support for web components in pagedown::html_paged() would be feasible. However, this would be a major change in pagedown internals which could break a lot of things. I'm not sure to have the time in the next weeks to dive into this topic. Any help would be greatly appreciated.

@RLesur RLesur changed the title Flextable covered by pagedown Add support for shadow DOM for compatibility with flextable Mar 7, 2021
@RLesur
Copy link
Collaborator

RLesur commented Mar 7, 2021

see the related issue in the Paged.js project https://gitlab.pagedmedia.org/tools/pagedjs/issues/148 and also w3c/DOM-Parsing#58

@RLesur
Copy link
Collaborator

RLesur commented Mar 7, 2021

@tvroylandt In order to give a clue, here's an ugly hack. It works with your MWE but I cannot guarantee you that this is safe to use. Please, do not use it!

---
title: "Test flextable"
output:
  pagedown::html_paged
knit: pagedown::chrome_print
---

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

```{js, echo=FALSE}
// Please, do not use this code in production! This is an unreliable hack...
window.PagedConfig = window.PagedConfig || {};
const {before: beforePaged, after: afterPaged} = window.PagedConfig;

window.PagedConfig.before = async () => {
  document.querySelectorAll('template').forEach(el => {
    nextElement = el.nextElementSibling;
    nextElement.innerHTML = nextElement.shadowRoot.innerHTML;
  });
  if (beforePaged) await beforePaged();
};
```


```{r, include = FALSE}
library(flextable)
library(knitr)
library(tidyverse)

# fake data
df_test <-
  tibble(
    nb = seq(1:10),
    type = c(rep("a", 2), rep("b", 3), rep("c", 1), rep("d", 4)),
    info = rnorm(10)
  )

# function to generate
table_filter <- function(type_filter){
  df_test %>% 
    filter(type == {{type_filter}}) %>% 
    flextable()
}
```


```{r}
render_custom <- function(x, ...) {
  map_chr(x, ~ knit_print(.x)) %>% 
    # collapse all the results
    paste(collapse = "\n") %>% 
    # knir must use this result `asis`
    asis_output()
}
```


```{r, render = render_custom}
map(letters[1:4],
    table_filter)
```

@tvroylandt
Copy link
Contributor Author

Thanks Romain. This is a big issue in fact.

I will make some tests with the ft.shadow mentioned by David in his issue and this should be enough for this issue.

Do you think it would be useful in general to implement such support or is it too small to be worthy ?

@RLesur
Copy link
Collaborator

RLesur commented Mar 8, 2021

I've tested the ft.shadow option mentioned by @davidgohel in davidgohel/flextable#302 (comment). It leads to the same result of the hack proposed in #216 (comment).

Since flextable provides a builtin option to disable its use of the shadow DOM, I think that pagedown::html_paged() could set the ft.shadow option to FALSE.

@davidgohel
Copy link

Hi

I did try to detect pagedown while knit_printing flextable but did not succeed. I am able for example to detect xaringan:

is_xaringan <- !is.null(getOption("xaringan.page_number.offset"))

Do you think there is such a test I could do so that I could set ft.shadow to FALSE - if this was possible, I could do it in flextable rather than forcing you to make a hook in pagedown...

@RLesur
Copy link
Collaborator

RLesur commented Mar 8, 2021

Thanks, @davidgohel but this can be easily achieved in pagedown because flextable provides the ft.shadow option. IMO, this is more logical that pagedown::html_paged() sets the ft.shadow option to FALSE waiting a support for the shadow DOM on the Paged.js end.

@RLesur RLesur changed the title Add support for shadow DOM for compatibility with flextable Compatibility between pagedown and flextable Mar 8, 2021
@RLesur RLesur closed this as completed in 92f8278 Mar 8, 2021
@RLesur
Copy link
Collaborator

RLesur commented Mar 8, 2021

@tvroylandt, this is now fixed: the MWE you provided now works well with the development version of pagedown. Thanks for the report! Also thanks to @davidgohel for the tip!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants