如何使用htmlOutput

时间:2017-11-22 23:12:56

标签: javascript html shiny syntax-highlighting

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

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

enter image description here

使用此R文件(以及Shiny应用程序的www文件夹中的prism.css和prism.js)

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

在DOM资源管理器中我可以看到,在Shiny生成的网页中,第三个(不可用)块位于<div class="shiny-html-output shiny-bound-output">内,然后正确包装在<pre><code class="language-sql">中标签就像第一块。所以被包裹在那个div中就是阻止prism.js做突出事情。

如何让第三个块像第一个一样突出显示?

1 个答案:

答案 0 :(得分:3)

Prism.js在加载后立即运行,因此之后动态添加的任何代码块都不会突出显示。一种选择是在服务器功能中动态加载prism.js

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

但这不是很强大。您可以轻松加载脚本的多个副本。如果您将其设为shiny::singleton或使用htmltools::htmlDependency仅加载脚本一次,您就可以轻松找回自己的原始状态。

更好的解决方案 - Prism提供了一个API,可让您以编程方式突出显示代码块:http://prismjs.com/extending.html#api

渲染任何代码块后运行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.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)

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