I can achieve the result with the following approach, based on using markdown::mark to turn any markdown I want into html, and then I can work entirely with HTML within tagLists.
```
---
title: "R Notebook"
output:
html_document: default
---
```{r echo=FALSE}
suppressWarnings({
suppressMessages({
library(plotly)
library(htmltools)
})})
l <- htmltools::tagList()
for(i in 1:3) {
l[[i]] <- tagList(HTML(markdown::mark(text=paste0("\n\n#### ", i, "\n"))),
plot_ly(x = rnorm(10), type="histogram"))
}
```
```{r results='asis'}
l
```
Little follow-up question. I inserted your code after
"### Plot {.tabset .tabset-fade .tabset-pills}" in a Markdown document,
but it doesn't create tabs in the html output. Is this a result of the "HTML(markdown::mark(text=paste0("\n\n#### ", i, "\n")))" part?