Rendering markdown text?

Hello!

I have some markdown text ("tips" in my example) stored in yml files that I'd like to render in an interactive RMarkdown. If I use results = "asis", I can do this just fine with either markdown or html syntax. However, if I try to interactively render the text, it doesn't work.

So far I've thought about the following solutions:

Here's a minimal example with a screenshot of the output as a gist.

---
output:
  html_document:
    df_print: paged
runtime: shiny
---

```{r include = FALSE}
knitr::opts_chunk$set(echo = FALSE)
```

```{r}
library(shiny)

yml_info <- list(
    tip1 = list(tip = 'This is a [link](https://forum.posit.co/).'),
    tip2 = list(tip = 'Here is an HTML <a href = "https://forum.posit.co/">link</a>!'))

selectInput("whichtip", label = "Select puzzle:",
            choices = c("tip1", "tip2"))
                        
actionButton("tip", "Tip")

show_tip <- eventReactive(input$tip, {
    yml_info[[input$whichtip]]$tip
})
```

The text here does not render (click tip to see):
```{r results = "asis"}
renderUI(show_tip())
```

The text here does:  
```{r results = "asis"}
yml_info[["tip1"]]$tip
yml_info[["tip2"]]$tip
```

Any help would be appreciated!

-Irene

2 Likes

Not an answer to your question (sorry!) but an answer to this part:

Use 4-backtick fences to include R Markdown source here:

````
---
output:
  html_document:
    df_print: paged
runtime: shiny
---

```{r include = FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
````

(It's actually n+1 backticks for code fences, so I used a 5-backtick fence to show the 4-backtick fence example!)

Also good to know: you can edit your posts by clicking the little grey pencil icon at the bottom of each post)

6 Likes

Thanks @jcblum! I've edited it now.

Hi,

As you are trying to use renderUI, I do not think it render a text output that could be render asis by rmarkdown. Maybe with renderText output. However, when I try that, markdown is not converted to HTML and HTML is not render as HTML but as text. So, I would suggest an approach where you really decide what you want to print.

  • TIps are in HTML or Markdown. Render them in html string using knitr::knit2html. Use text input here, and fragment.only=TRUE beacause you don't want any <body> or <header> tag. Just the text converted to HTML string.
  • Use renderUI to render this HTML but do not forget to use shiny::HTML() to tell shiny that the string contains HTML tags that you do not want to be escaped. Otherwise your links won't appear as links.

Here is how:

---
output:
  html_document:
  df_print: paged
runtime: shiny
---

```{r include = FALSE}
knitr::opts_chunk$set(echo = FALSE)
```

```{r}
library(shiny)

yml_info <- list(
  tip1 = list(tip = 'This is a [link](https://forum.posit.co/).'),
  tip2 = list(tip = 'Here is an HTML <a href = "https://forum.posit.co/">link</a>!'))

selectInput("whichtip", label = "Select puzzle:",
            choices = c("tip1", "tip2"))

actionButton("tip", "Tip")

show_tip <- eventReactive(input$tip, {
  tip <- yml_info[[input$whichtip]]$tip
  # render markdown tip to HTML
  out <- knitr::knit2html(text = tip, fragment.only = TRUE)
  # output non-escaped HTML string
  HTML(out)
})

```

Here is the tip: 
```{r}
renderUI(show_tip())
```

And you wil get that
image

6 Likes

@cderv - AMAZING answer, thank you so much! Thanks especially for explaining all the pieces and how they fit together. :grinning:

1 Like