8

I've been developing a RMarkdown document to generate HTML reports with knitr package.

I succeed to include a HTML file containing with the includes: option in the YAML header.

The problem is that I can only choose between 3 options (https://rmarkdown.rstudio.com/html_document_format.html#includes):

  • in_header:
  • before_body:
  • or after_body:

I'd like to include this HTML file where I want in my RMarkdown document, like in a specific section for example.

Do you know how I can do that?

I found a similar question but answers did not help me.

thbtmntgn
  • 151
  • 2
  • 8

3 Answers3

14

Why not using htmltools package? As in this similar answer

```{r, echo=FALSE}
htmltools::includeHTML("my_text.html")
```
Robert
  • 5,038
  • 1
  • 25
  • 43
10

If you want to include a standalone HTML file, it is a very bad practice to include it with in_header, before_body or after_body or with cat(readLines(...)).

Why is it a bad practice?

A standalone HTML file is a simple text file with tags. A minimal HTML file looks like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>title</title>
  </head>
  <body>
    <!-- page content -->
  </body>
</html> 

To be valid, an HTML file must comply with many constraints. For instance, there can be only one <body> element. Therefore, if you include a standalone HTML document in another HTML document, you get an HTML file with two <body> elements. So, it is an invalid HTML file.
Such a file can be badly rendered in a browser (most of browsers try to "understand" it even it is invalid) or can crash it. So, you have to choose a solution that produce a valid HTML file.

I see two options to render a valid HTML file.

Use knitr child document

See the documentation about child document here. I think this is the most adapted solution to your problem.

Include external HTML file in an <iframe> element

You can embed any external HTML file in an <iframe> element. Here's a reproducible example.

Assume that you have the following file named embedded_file.Rmd

---
title: "Embedded file"
output: html_document
---

This is the content of the embedded file.

Here's the content of main.Rmd file:

---
title: "Include external html file"
output: html_document
---

```{r generate-external-report, include=FALSE}
rmarkdown::render('embedded_file.Rmd')
```

External `HTML` file can be included in an `<iframe>` element:

```{r, echo=FALSE}
htmltools::tags$iframe(title = "My embedded document", src = "embedded_file.html")
```

When you render main.Rmd, you get an <iframe> with your embedded file. You have to set the width and height of the <iframe> to get a good looking <iframe>.

RLesur
  • 5,810
  • 1
  • 18
  • 53
  • You are completely right on your comment, that it is a bad practice to just use `readLines` within an `asis` code chunk, I updated my answer accordingly. I am wondering if this is still a bad idea though. – drmariod Feb 26 '18 at 05:05
  • Your edit is right: there's no problem with an html *fragment*. It's important to distinguish html *standalone* and html *fragment*. However, the question was about including html *standalone* file. – RLesur Feb 26 '18 at 06:43
  • Thank you, it seems to work with the – thbtmntgn Feb 26 '18 at 16:09
3

Maybe this is an ugly hack but just create your html file and within your markdown, create a code chunk like this:

```{r, results='asis'}
cat(readLines('my_text.html'))
```

Don't forget to have an empty line at the end, otherwise you get an ugly warning.

Maybe this is what @Clock Slave was referring to.

EDIT:

Since I got a downvote on this, I want to at least comment. As @romles pointed out, an html file is only allowed to have one body tag. So with my readLines command, you shouldn't read a complete HTML file, but you can for example read paragraphs or tables, etc. This shouldn't be a problem. So a little example could be

<h1>My test html file</h1>
<p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</p>
<ul>
  <li>bla</li>
  <li>blubb</li>
</ul>
drmariod
  • 11,106
  • 16
  • 64
  • 110