Home > Mobile >  How can I render selectively colored text in an R Shiny app?
How can I render selectively colored text in an R Shiny app?

Time:12-24

I have a shiny app with a tab in which users can upload their resume. I'm using AI to extract skills from the resume, and I would like to render the text from their resume with the skills in a different color from the rest of the text.

The closest I have gotten so far was by asking chatGPT, go figure. He/she/it gave me this "solution":

library(shiny)
library(stringi)

highlight_keywords <- function(text, keywords) {
  for (keyword in keywords) {
    text <- stri_replace_all_fixed(text, keyword, 
                               paste0("<span style='color:red'>", keyword, "</span>"),    vectorize_all = FALSE)
  }
  return(text)
}

ui <- fluidPage(
  textInput("text", "Text"),
  textInput("keywords", "Keywords"),
  textOutput("text")
)

server <- function(input, output) {
  output$text <- renderText({
    highlight_keywords(input$text, strsplit(input$keywords, ",")[[1]])
  })
}

shinyApp(ui, server)`

But what is actually rendered is the input text in black with the html tags in plain text - e.g.:

"I have a background in data science and over five years of hands-on experience conducting complex statistical analyses and building and deploying machine learning models"

Does anyone know why this is happening or how to accomplish what I am trying to accomplish?

Thanks in advance!

CodePudding user response:

The issue is that by default all HTML in a string is escaped and hence gets rendered as text. To prevent that you have to wrap your text in HTML() and switch from textOutput to e.g. htmlOutput.

library(shiny)
library(stringi)

highlight_keywords <- function(text, keywords) {
  for (keyword in keywords) {
    text <- stri_replace_all_fixed(
      text, keyword,
      paste0("<span style='color:red'>", keyword, "</span>"),
      vectorize_all = FALSE
    )
  }
  return(text)
}

ui <- fluidPage(
  textInput("text", "Text"),
  textInput("keywords", "Keywords"),
  htmlOutput("text")
)

server <- function(input, output) {
  output$text <- renderText({
    text_high <- highlight_keywords(input$text, strsplit(input$keywords, ",")[[1]])
    HTML(text_high)
  })
}

shinyApp(ui, server)

enter image description here

  • Related