rstudio / pagedown

Paginate the HTML Output of R Markdown with CSS for Print
https://pagedown.rbind.io
Other
889 stars 129 forks source link

TOC with more than a page stops the render. #314

Open beatrizmilz opened 1 year ago

beatrizmilz commented 1 year ago

Hi! When the document has a table of contents longer than a page, the document does not render. It only renders when I set toc: false.

This is the message that shows up:

Warning: A runtime exception has occured while executing JavaScript
  Runtime exception message:
    TypeError: Cannot read properties of null (reading 'parentElement')
    at findPage (http://127.0.0.1:4058/tese_files/paged-0.20/js/config.js:62:15)
    at tocEntriesInfos (http://127.0.0.1:4058/tese_files/paged-0.20/js/config.js:92:20)
    at window.PagedConfig.after (http://127.0.0.1:4058/tese_files/paged-0.20/js/config.js:122:24)
    at http://127.0.0.1:4058/tese_files/paged-0.20/js/paged.js:31101:17

I'm using the CRAN version of pagedown.

> packageVersion("pagedown")
[1] ‘0.20’

I'm creating this issue because this happened to me more than once. Does anyone know how to handle this? Thanks!

ASNDataAnalytics commented 1 year ago

@beatrizmilz, thank you for sharing this workaround. I'm experiencing the same issue, and confirm that (thankfully) the PDF rendered after changing to toc: false. FWIW, I'm also using pagedown 0.20.

yihui commented 1 year ago

Could you please provide a minimal reproducible example? I can't reproduce this problem with the following Rmd example:

---
title: "A Multi-page HTML Document"
author: "Yihui Xie and Romain Lesur"
date: "`r Sys.Date()`"
output:
  pagedown::html_paged:
    toc: true
---

# Random text

```{r, results='asis', echo = FALSE}
random_markdown = function(len = 100) {
  text = function(len) {
    trimws(paste(sample(c(letters, rep(' ', 10)), len, TRUE), collapse = ''))
  }
  unlist(lapply(seq_len(len), function(i) {
    x = text(sample(10:30, 1))
    paste(if (i %% 2 == 0) '#' else '##', x, '\n\n', x)
  }))
}
cat(random_markdown(40), sep = '\n\n')


I think the error comes from
https://github.com/rstudio/pagedown/blob/466c1c1e8fc4a679aeff25bdd19fd834c0b78bbd/inst/resources/js/config.js#L62
and the fix may be simple (i.e., change `el.parentElement` to `el?.parentElement`), but without a reproducible example, we don't know what really went wrong.

Thanks!
beatrizmilz commented 1 year ago

Hi Yihui! Thanks for responding!

Sorry, one thing that I didn't mention is that I'm using the pagedown::thesis_paged template.

I'll try to create a reprex with the error I'm experiencing!

With your reprex and the thesis_paged template, it does not generate an error, but the toc does not show properly:

---
title: "A Multi-page HTML Document"
author: "Yihui Xie and Romain Lesur"
date: "`r Sys.Date()`"
output:
  pagedown::thesis_paged: 
    toc: true
---

# Random text

```{r, results='asis', echo = FALSE}
random_markdown = function(len = 100) {
  text = function(len) {
    trimws(paste(sample(c(letters, rep(' ', 10)), len, TRUE), collapse = ''))
  }
  unlist(lapply(seq_len(len), function(i) {
    x = text(sample(10:30, 1))
    paste(if (i %% 2 == 0) '#' else '##', x, '\n\n', x)
  }))
}
cat(random_markdown(40), sep = '\n\n')

imagem

ASNDataAnalytics commented 1 year ago

Thank you @yihui for all your incredible work. After trying to recreate the issue I found the problem in my case was the TOC CSS I was using as a template to build off of (pasted below). After commenting out the CSS the PDF rendered perfectly with the TOC. The CSS comes from the nice {pagedreport} package (but of course I'm not blaming that code).

Thanks again. Kurtis

/* ----------------------- Table of contents ----------------------- */
.toc a {
  line-height: 30px;
  text-decoration: none;
  font-size: 14pt;
  padding-right: .33em;
}

.toc ul {
    list-style: none;
    padding-left: 0;
    overflow-x: hidden;
    margin-right: 0%;
}

.toc li li{
  padding-left: 1em;
}

.toc ul, .toc a, .toc a::after {
  background-color: #ffffff;
  color: var(--main-color);
  font-weight: bold;
}

.toc ul > li > ul > li > a {
  color: #000000;
}

/* page number */
.toc a::after {
  content: target-counter(attr(href), page);
  float: right;
  background: white;
}

.toc a.front-matter-ref::after {
  content: target-counter(attr(href), page, lower-roman);
}

.toc .leaders::before {
  float: left;
  width: 0;
  white-space: nowrap;
  content: ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ";
}
yihui commented 1 year ago

@beatrizmilz Thanks for the clarification! Now I can see this output format is indeed problematic when the TOC is longer than one page. Your TOC page was truncated, and my PDF (generated on macOS) was completely truncated after the TOC: toc.pdf. I don't know how to fix it, though (cc @brentthorne).

@ASNDataAnalytics Thanks for sharing the solution!

sylvaine31 commented 8 months ago

Hi ! I have the same issue. The bug seems to be related to all .toc ul tags. If I remove it, the toc can be on two pages (but the layout misses some specs). I don't know if it helps someone to solve the bug, it's too complicated for my knowledge in css....

jonekeat commented 7 months ago
overflow-x: hidden;

Hi all, like @ASNDataAnalytics pointed out, the issue is in the css, I found that if we change the above line in .toc ul to

overflow-x: clip;

Then the toc is able to render, but I am not too sure how this solve the bug

kgilds commented 1 month ago
overflow-x: clip;

This worked for me with the book_crc template. Thank you