How to highlight R or Python code in markdown chunk embedded in shiny app

血红的双手。 提交于 2020-01-03 03:25:30

问题


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?


回答1:


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"
            )
        })
    }
))

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)")
        })
    }
))

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)"))
        })
    }
))


来源:https://stackoverflow.com/questions/52846184/how-to-highlight-r-or-python-code-in-markdown-chunk-embedded-in-shiny-app

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!