rmarkdownquarto

Why Quarto TOC is not recoqnising markdown headers?


I'm trying to programm content of the HTML quarto document. I.e. I have several functions which return a Markdown/HTML content. The markdown itself renders OK, however the quarto's table of contents(TOC) does not recognise the headers!

For example, this document has several headers. First was rendered using shiny::markdown(), second with the help of shiny::HTML() while the third one was written in a plain markdown. The quarto's TOC rendered only the lastone. Is there a possibility to include programmatically written headers in the TOC?

enter image description here

The code itself:

---
title: "Test"
toc: true
format: html
---

```{r, echo = FALSE}
library(shiny)

foo_md <- function(){
  shiny::markdown("## Header generated with foo_md()")
}

foo_html <- function(){
  shiny::HTML("<h2> Header generated with foo_html() </h2>")
}

```

```{r, echo = FALSE}
# First header
foo_md()
```

Lorem ipsum dolor sit amet, in at in sed nibh. Neque dignissim 
ad imperdiet urna urna. In id erat aliquam, dolor ut odio. 
Congue at, non justo fermentum urna suscipit ad torquent posuere. 

```{r, echo = FALSE}
# Second header
foo_html()
```

Suspendisse ad sed, amet nec nunc conubia faucibus. Sociis in
pellentesque nibh. Venenatis at ut imperdiet ornare lectus diam ex
vitae. Id, aenean turpis diam, eget a justo consectetur finibus 
mauris.Vehicula viverra sed volutpat metus placerat tellus non. 
Et nisl. Et duis vel in.

## Ordinary markdown header

Vehicula viverra sed volutpat metus placerat tellus non. Et nisl. Et duis vel in.

I'm using Windows machine with quarto version 1.0.38


Solution

  • To include programmatically written headers in TOC, one option is to create that header with paste (or with paste0), then simply cat it with chunk option results=asis. Then pandoc filters for quarto will render this header in output HTML document with proper id and class so that TOC can target it.

    ---
    title: "Test"
    toc: true
    format: html
    ---
    
    ```{r, echo = FALSE}
    
    foo_md <- function(){
      x <- "Quarto Header"
      y <- "dynamically generated"
      header <- paste("## ",x, y, "with foo_md()")
      cat(header)
    }
    
    ```
    
    ```{r, echo = FALSE, results='asis'}
    # First header
    foo_md()
    ```
    
    Lorem ipsum dolor sit amet, in at in sed nibh. Neque dignissim ad
    imperdiet urna urna. In id erat aliquam, dolor ut odio. Congue at, 
    non justo fermentum urna suscipit ad torquent posuere. 
    
    
    ## Ordinary markdown header
    
    Vehicula viverra sed volutpat metus placerat tellus non. Et nisl. Et duis vel in
    

    The rendered document look like this,

    html_doc_with_generated_header_in_TOC


    But when we create them with shiny::HTML or shiny::markdown, they are not rendered in the HTML document with the necessary id or tag and TOC can not target them. They are simply rendered as h2 and we could see them as level2 header in our documnet but not in the TOC.