pagedown icon indicating copy to clipboard operation
pagedown copied to clipboard

Unnecessary white space between body area and footnote area

Open atusy opened this issue 4 years ago • 5 comments

Though I guess this issue is quite difficult to solve, let me report for the sake of others.

I found kable with many rows and a long footnote creates unnecessary white space when paged-footnotes: true. You can see the kable output is split into pages, but the first part still have more space to include more rows.

image

image

When I knitted a large file and took a relatively large time, I saw footnotes were once in the body of kable and then moved to the footnote area. Thus, I think the kable output was splitted based on its size before footnote goes footnote area.

Source

---
title: test
output: pagedown::html_paged
paged-footnotes: true
---

# Test

```{r, echo = FALSE}
txt <- as.character(1:32)
df <- data.frame(
 x = txt,
 y = txt,
 stringsAsFactors = FALSE
)

df[1, 1] <- "a[^fn]"
knitr::kable(df, escape = FALSE)
```


[^fn]: looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong footnote

atusy avatar Jul 10 '19 15:07 atusy

I found the problem is not limited to kable, but to any text. AND I also found a work around.

Just add foolowing CSS.

.footnote {font-size: 0}

This is possible because footnotes' font-size are overwritten to x-small when they are moved to footnote area.

Before

image

After

image

Source

---
title: test
output: pagedown::html_paged
paged-footnotes: true
---



# Test

```{css, eval=FALSE}
.footnote {font-size: 0}
```

```{r, echo = FALSE, results='asis'}
cat(
    "a[^fn]",
    rep(letters, 100L),
    sep = " "
)
```



[^fn]: looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong looooooooooooooooooooooooooooooooong footnote

atusy avatar Jul 10 '19 15:07 atusy

Thanks a lot @atusy for diving into this hard topic. The paged-footnotes option is presented in the pagedown documentation as experimental but I have to confess that this is mostly a hack. The footnotes support is still a missing feature in Paged.js but the dev team works on this topic. I have to admit that the trick used in the footnotes hook is far from perfect.

The source code of the footnotes handler in pagedown is the following: https://github.com/rstudio/pagedown/blob/65bd7f10aae5e439021a1ba8ad0f06f096a310c3/inst/resources/js/hooks.js#L152-L258

Finding how to allow the right amount of space to the footnotes area is a difficult challenge because the pages breaks location may also change and we must prevent overflows. As an aside, the most difficult one is to span footnotes across multiple pages (I haven't deal with that, this is too difficult for me).

The blank between the content area and the margin area is a side effect of this hack: before the Paged.js parser runs, all the footnotes are placed in a <p> element (using a <p> element in another <p> element is illegal that's why this is a hack). The goal of using a <p> element was to keep sufficient room in the page sheet for the footnotes area.

When I developed this support I ran many tests (but no one with footnotes in a table) and the main problem I tried to resolve was overflows (particularly if the footnote call is at the bottom of a page).

In short, the blank area is a side effect of overflow prevention.

I've tried your last Rmd example with .footnote {font-size: 0} (I found this idea extremely interesting) but ran in an infinite loop.

If anyone is interested in improving the footnotes handler, here is a tip: comment on the afterRendered hook of the footnotes handler. You will obtain this result withoutafterRendered

You can see the <p> elements which handle footnotes. They are of class footnoteHandler. So, you can try playing with CSS for these handlers, maybe it can help.

RLesur avatar Jul 13 '19 15:07 RLesur

Thanks @RLesur for sharing the background of paged-footnotes. Now I understand about the side effect. I just don't understand what is "an infinite loop" happened by .footnote {font-size: 0}?

Anyway, I noticed that font-size: 0 won't keep sufficient room in the page sheet for the footnotes area when there are many long footnotes.

On the other hand, I also noticed that font-size: 1px can be an intermediate solution. It keeps the sufficient room and relatively small extra margins than the default.

font-size: 0

image

fonti-size: 1px

image

atusy avatar Jul 14 '19 21:07 atusy

I just don't understand what is "an infinite loop" happened by .footnote {font-size: 0}?

Sometimes, Paged.js builds an infinite number of pages. You can inspect the number of pages while Paged.js is running:

  • in Chrome, open the Developer Tools panel
  • the second child of <body> is
    <div class="pagedjs_pages" style="--pagedjs-page-count:XX;">
    

If you observe that the CSS variable --pagedjs-page-count does not stop to increase (more than 200 pages for instance), this is an infinite loop.

RLesur avatar Jul 14 '19 21:07 RLesur

Interesting. It seems that the infinite loop is not caused by footnote, but something else

Here's a reproducible example.

---
output: pagedown::html_paged
---

```{r, echo = FALSE, results='asis'}
cat(rep(letters, 100L), sep = " ")
```

The infinite loop likely happen when repeating too much. rep(letters, 50L) worked without infinite loop. I guess Paged.js has some limitation or bug in rendering very long of paragraphs.

atusy avatar Jul 14 '19 21:07 atusy