如何使用htmlOutput在R Shiny应用程序中启用语法高亮显示 [英] How to enable syntax highlighting in R Shiny app with htmlOutput

查看:138
本文介绍了如何使用htmlOutput在R Shiny应用程序中启用语法高亮显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Shiny应用程序,它根据用户输入动态生成计算机代码,并将其呈现给用户,以便他们可以准确查看发送到数据库的查询。我有棱镜语法突出显示为直接在用户界面函数中的代码工作,所以我知道棱镜正在工作;但对于在服务器中生成并通过 renderText htmlOutput 发送给用户的代码,突出显示不起作用。



下面是一个简单示例的图片:



关于在渲染任何代码块后运行 Prism.highlightAll()

  library(shiny)

prismCodeBlock< - function(code){
tagList(
HTML(code),
tags $ script(Prism.highlightAll() )

}

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.c ss)


prismSqlDependency< - tags $ head(
tags $ script(src =https://cdnjs.cloudflare.com/ajax/libs/prism /1.8.4/components/prism-sql.min.js)


ui< - fluidPage(
prismDependencies,
prismSqlDependency,

HTML(< pre>< code class ='language-sql'> SELECT * FROM mytable WHERE 1 = 2
- 这个块应该是语法高亮的,它是$ b $ (< pre> SELECT * FROM mytable WHERE 1 = 2
- 这个块不应该被语法高亮显示
$ lt; / code>< / pre>),

htmlOutput(sql)


server< - function输入,输出){
txt< - < pre>< code class ='language-sql'> SELECT * FROM mytable WHERE 1 = 2
- 但不是由于某种原因,
- 可能与它通过renderText和htmlOutput
< / code>< / p重新>中
$ b $输出$ sql< - renderUI({
prismCodeBlock(txt)
})
}

shinyApp(ui,server)






为了进一步改进,您可以使用 Prism.highlightElement()更高效。也可以从这些Prism代码块中创建一个HTML小部件来抽象出混乱的细节。


I have a Shiny app that generates computer code dynamically based on user inputs and presents it to the user so they can see exactly what query is being sent to a database. I have prism syntax highlighting working for code that is directly in the user interface function, so I know that prism is working; but for code that is generated in the server and sent to the user via renderText and htmlOutput the highlighting doesn't work.

Here is an image of a simple example:

Which was made with this R file (and prism.css and prism.js in the www folder of the Shiny app)

   ui <- shinyUI(fluidPage(
  tags$head(
    tags$link(rel = "stylesheet", type = "text/css", href = "prism.css")
  ),
  tags$body(
    tags$script(src="prism.js")
  ),
  HTML("<pre><code class='language-sql'>SELECT * FROM mytable WHERE 1=2
       -- this chunk should be syntax highlighted and it is
       </code></pre>"),

  HTML("<pre>SELECT * FROM mytable WHERE 1=2
       -- this chunk should not be syntax highlighted
       </code></pre>"),

  htmlOutput("sql")
)
)


# Define the server code
server <- function(input, output) {
  txt <- "<pre><code class='language-sql'>SELECT * FROM mytable WHERE 1=2
       -- this chunk should be syntax highlighted but isn't for some reason,
       -- presumably connected to it getting to the UI via renderText and htmlOutput
       </code></pre>"

  output$sql <- renderText(txt)
}

In the DOM Explorer I can see that in the webpage generated by Shiny, the third (not working) chunk is within a <div class="shiny-html-output shiny-bound-output">, then is correctly wrapped in <pre> and <code class="language-sql"> tags like the first chunk. So being wrapped in that div is what is stopping prism.js from doing its highlighting thing.

What should I do to have the third chunk highlighted like the first?

解决方案

Prism.js runs as soon as its loaded, so any code blocks dynamically added afterward won't get highlighted. One option would be to load prism.js dynamically in the server function as well.

output$sql <- renderUI({
  tagList(
    tags$script(src = "prism.js"),
    HTML(txt)
  )
})

But this is not very robust. You could easily load multiple copies of the script. And if you make it a shiny::singleton or use htmltools::htmlDependency to only load the script once, you could easily find yourself back in the original situation.

A better solution - Prism provides an API that lets you programmatically highlight code blocks: http://prismjs.com/extending.html#api

How about running Prism.highlightAll() after rendering any code block?

library(shiny)

prismCodeBlock <- function(code) {
  tagList(
    HTML(code),
    tags$script("Prism.highlightAll()")
  )
}

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

prismSqlDependency <- tags$head(
  tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.8.4/components/prism-sql.min.js")
)

ui <- fluidPage(
  prismDependencies,
  prismSqlDependency,

  HTML("<pre><code class='language-sql'>SELECT * FROM mytable WHERE 1=2
       -- this chunk should be syntax highlighted and it is
       </code></pre>"),

  HTML("<pre>SELECT * FROM mytable WHERE 1=2
       -- this chunk should not be syntax highlighted
       </code></pre>"),

  htmlOutput("sql")
)

server <- function(input, output) {
  txt <- "<pre><code class='language-sql'>SELECT * FROM mytable WHERE 1=2
  -- this chunk should be syntax highlighted but isn't for some reason,
  -- presumably connected to it getting to the UI via renderText and htmlOutput
  </code></pre>"

  output$sql <- renderUI({
    prismCodeBlock(txt)
  })
}

shinyApp(ui, server)


For further improvement, you could use Prism.highlightElement() to be more efficient. Could also create an HTML widget out of these Prism code blocks to abstract away the messy details.

这篇关于如何使用htmlOutput在R Shiny应用程序中启用语法高亮显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆