1

I'm working on an App that generates large amounts of text in response to user definitional questions. I'm coding text in using HTML in separate modules, and it is becoming very cumbersome to code in all this text mainly due to the HTML coding conventions. Is there a simplified way to pull in the text of a Word document, including formats, into the UI section of a Shiny App, instead of manually coding in all text in HTML? Below is a super-simple example code of my current approach, I wonder if there's an easier approach than what I'm doing in the HTML() function in the server() section:

library(shiny)

ui <- fluidPage(uiOutput("coxModel"))

server <- function(input, output) {
  output$coxModel <- renderUI(
    tags$div(
      style="text-align:justify",
      HTML(
        "<b>Select</b> from <i>`Multiple-predictors for Cox model`</i> menu to run Cox model.",
      )
    )
  )
}

shinyApp(ui, server)
Village.Idyot
  • 1,359
  • 2
  • 8
  • 3
    Are you aware of the fact that MS Word can export html files? You could visualize them using an `iframe` or `includeHTML()`. – ismirsehregal Mar 16 '23 at 09:38
  • 1
    Thank you, I wasn't aware of that MS Word feature. I'll explore that now. – Village.Idyot Mar 16 '23 at 11:16
  • 2
    If your Word files are dynamic, it might be easier to convert your word documents to markdown and then include the markdown directly into your UI using `includeMarkdown()`: a single line solution that keeps the flow of logic in your app free of "convert to HTML" clutter. See, for example, [here](https://shiny.rstudio.com/gallery/including-html-text-and-markdown-files.html). I've taken this approach myself. Otherwise, @ismirsehregal's suggestion is spot on. – Limey Mar 16 '23 at 12:00
  • 1
    Regarding @Limey's comment (.docx -> .md) check example 35. [here](https://pandoc.org/demos.html): `pandoc -s example30.docx -t markdown -o example35.md` or use `rmarkdown::pandoc_convert()`. – ismirsehregal Mar 16 '23 at 13:04
  • MSword export to html creates image for every subscript/superscript in the document in a separate folder, which in turn cause error in includeHTML() because of relative directory within html file I think? Anyway to circumvent this? – aiorr Aug 29 '23 at 19:59

2 Answers2

1

I wonder if there's an easier approach than what I'm doing in the HTML() function...

You can use shiny tags like so:

library(shiny)

ui <- fluidPage(uiOutput("coxModel"))

server <- function(input, output) {
  output$coxModel <- renderUI(
    tags$div(
      style="text-align:justify",

      tags$p(
        tags$b("Select"),
        " from",
        tags$i(
          " `Multiple-predictors for Cox model`"
        ),
        " menu to run Cox model."
      )
    )
  )
}

shinyApp(ui, server)

Also, if none of the elements being rendered has interactivity, I'd recommend you put it all in the UI. Like this:

library(shiny)

ui <- fluidPage(
  tags$div(
    style = "text-align:justify",
    tags$p(
      tags$b("Select"),
      " from",
      tags$i(
        " `Multiple-predictors for Cox model`"
      ),
      " menu to run Cox model."
    )
  )
)

server <- function(input, output) {

}

shinyApp(ui, server)
Mwavu
  • 1,826
  • 6
  • 14
1

The cleanest solution for me is to follow limey's suggestion where I:

  1. Saved the formatted paragraph in a Word document
  2. Resaved the document as filtered HTML file
  3. Then accessed the saved html file in Shiny using the markdown package

Here is the code for this solution:

library(htmltools)
library(markdown)
library(shiny)

text <- readLines("C:\\Users\\...\\OneDrive\\Desktop\\Sample1.htm")
html <- markdownToHTML(text)

ui <- fluidPage(
  includeMarkdown(html)
)

server <- function(input, output) {}

shinyApp(ui, server)

Adapting ismirsehregal's comment, I did the following:

  1. Saved the Word doc as an html file
  2. Right-clicked on the saved html file to reveal the code (see image at the bottom)
  3. Copied the highlighted section of the code and pasted it into the R code, under the HTML() function

And it renders correctly!

Here's the revised code:

library(shiny)

ui <- fluidPage(uiOutput("coxModel"))

server <- function(input, output) {
  output$coxModel <- renderUI(
    tags$div(
      style="text-align:justify",
      HTML("               
           <body lang=EN-GB style='word-wrap:break-word'>
           <div class=WordSection1>
           <p class=MsoNormal>Testing reading of a <b>Word</b> document into an <i><span
           style='color:#0070C0'>R Shiny App</span></i></p>
           </div>
           </body>
           "
      )
    )
  )
}

shinyApp(ui, server)

Here's the code that was revealed when I right-clicked on the HTML file:

enter image description here

Village.Idyot
  • 1,359
  • 2
  • 8