1

I am trying to return a dynamic code chunk in R as part of a shiny app. A simple example of what I am trying to do is,

library(shiny)
runApp(list(
  ui = bootstrapPage(
    sliderInput("mu", "Mean", min=-30, max=30, value=0, step=0.2),
    uiOutput('chunk')
  ),
  server = function(input, output) {
    output$chunk <- renderUI({ 
       HTML(markdown::markdownToHTML(text=paste0("```{r}",
                                     "\n dnorm(0, ", input$mu,", 2)"), 
                                     options=c("highlight_code"))) })
    }
))

This produces an unformatted code chunk. I would like to be able to use pygments/another-solution to highlight this code, and also python/other-language code which will form part of a web app.

Any ideas?

ben18785
  • 356
  • 1
  • 5
  • 15

1 Answers1

3

Additional Languages

Here's a solution that works for highlighting many different languages. It's based on this answer, which uses Prism. We load the Prism dependencies and then load dependencies for each language we want to highlight.

## from: https://stackoverflow.com/a/47445785/8099834
## get prism dependencies 
prismDependencies <- tags$head(
    tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.8.4/prism.min.js"),
    tags$link(rel = "stylesheet", type = "text/css",
              href = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.8.4/themes/prism.min.css")
)
prismLanguageDependencies <- function(languages) {
    lapply(languages, function(x) {
        tags$head(
            tags$script(
                src = paste0("https://cdnjs.cloudflare.com/ajax/libs/prism/1.8.4/components/prism-",
                             x, ".min.js")
            )
        )
    })
}

## format code with tags and language
prismAddTags <- function(code, language = "r") {
    paste0("<pre><code class = 'language-", language, "'>",
           code, 
           "</code></pre>")
}
prismCodeBlock <- function(code, language = "r") {
    tagList(
        HTML(prismAddTags(code, language = language)),
        tags$script("Prism.highlightAll()")
    )
}

## run app
library(shiny)
runApp(list(
    ui = bootstrapPage(
        prismDependencies,
        prismLanguageDependencies(c("sql", "r", "python")),
        sliderInput("mu", "Mean", min=-30, max=30, value=0, step=0.2),
        uiOutput('r_chunk'),
        uiOutput('python_chunk'),
        uiOutput('sql_chunk')
    ),
    server = function(input, output) {
        output$r_chunk <- renderUI({ 
            prismCodeBlock(
                code = paste0("# this is R code\ndnorm(0, ", input$mu,", 2)"),
                language = "r"
                )
        })
        output$python_chunk <- renderUI({
            prismCodeBlock(
                    code = '# this is python code
# Say hello, world.
print ("Hello, world!")',
                    language = "python"
            )
        })
        output$sql_chunk <- renderUI({
            prismCodeBlock(
                code = "-- this is SQL code
SELECT * FROM mytable WHERE 1=2",
                language = "sql"
            )
        })
    }
))

prism_shiny_app_example

Updated Answer

As pointed out in the comments, the original answer doesn't work. Turns out getting the highlighting to work takes a little more effort.

Fortunately, someone has already figured it out! They have written two functions: renderCode for the server and outputCode for the ui which seem to work well. The package is here and the relevant functions are here.

Here's an example:

## install the package
library(devtools)
install_github("statistikat/codeModules")

## run the app
library(codeModules)
library(shiny)
runApp(list(
    ui = bootstrapPage(
        sliderInput("mu", "Mean", min=-30, max=30, value=0, step=0.2),
        codeOutput('chunk')
    ),
    server = function(input, output) {
        output$chunk <- renderCode({ 
            paste0("dnorm(0, ", input$mu,", 2)")
        })
    }
))

sample_highlighting

Original Answer -- Doesn't work

highlight.js will format your code and is included in shiny. Per this answer, it supports 169 languages at this time.

You just need to tag your code. Try something like this:

library(shiny)
highlightCode <- function(code) {
    HTML(
        paste0("<pre><code class='html'>",
               code,
               "</code></pre>")
        )
}
runApp(list(
    ui = bootstrapPage(
        sliderInput("mu", "Mean", min=-30, max=30, value=0, step=0.2),
        uiOutput('chunk')
    ),
    server = function(input, output) {
        output$chunk <- renderUI({ 
            highlightCode(paste0("dnorm(0, ", input$mu,", 2)"))
        })
    }
))
Community
  • 1
  • 1
Hallie Swan
  • 2,714
  • 1
  • 15
  • 23
  • Thanks. This doesn't appear to work for me, however. The code just appears unhighlighted. This is the case if I change the code to class='r' or class='R' (since the code is written in R) or if I change the R code to be 'return(c(1,2,3))', for example. – ben18785 Nov 17 '18 at 21:58
  • 1
    @ben18785 sorry about that! I was wrong. I've updated with a working answer. Hope it works for you! – Hallie Swan Nov 29 '18 at 19:21
  • Thanks. I am actually looking for a more general answer than just supporting R syntax highlighting as am coding in multiple languages. Will bear this in mind though. – ben18785 Nov 30 '18 at 00:56
  • 1
    @ben18785 ah yeah, sorry -- missed that part of the question. Hopefully the new answer will work better for you! – Hallie Swan Dec 01 '18 at 01:54
  • That's really great. Thank you very much. This has been a pain for a while for me! If I could upvote your answer another time, I would! Best, Ben – ben18785 Dec 01 '18 at 14:15
  • @ben18785 you're welcome! I'm glad it works for you. Good luck on your project! – Hallie Swan Dec 04 '18 at 18:01