0

Using officer package I would like to change the background colour of a given text say from yellow to green. Here is the colored text and the desired output. I have used body_replace_all_text function in officer as shown below but not yielding the desired output. Suggestions are welcome.

pattern <- '<highlight\s+style=\"yellow\"\>)([^\<]+)(\<\/highlight>' 
replacement <- '<highlight style="green"\>$2\<\/highlight>'
  doc<- read_docx(path = "template.docx")
  doc<- body_replace_all_text(doc, pattern, replacement)
Maurice
  • 1
  • 1

1 Answers1

1

Here's a hacky solution that incorporates some functions from the officer package, though the crux of it (changing underlying xml) depends on the xml2 package:

library(officer)
library(xml2)

doc1 <- read_docx("tempfile.docx")

# find nodes with background shading
doc.nodes <- xml_find_all(docx_body_xml(doc1), "//w:shd")

doc.nodes
# result (note background colour is described under w:fill, in hexcode format)
# {xml_nodeset (2)}
# [1] <w:shd w:val="clear" w:color="auto" w:fill="FFDD11"/>
# [2] <w:shd w:val="clear" w:color="auto" w:fill="FFDD11"/>

# change background colour to a shade of green
lapply(doc.nodes,
       function(x) {
         xml_attr(x, "w:fill", ns = xml_ns(x)) <- "22FF55" 
       })

doc.nodes
# check result (node colour has changed)
# {xml_nodeset (2)}
# [1] <w:shd w:val="clear" w:color="auto" w:fill="22FF55"/>
# [2] <w:shd w:val="clear" w:color="auto" w:fill="22FF55"/>

print(doc1, "tempfile_changed.docx")

Creation of the input word document for reprex:

library(officer)
library(dplyr)

# define a specific shade of yellow for ease of identification later
yellow.formatting <- fp_text(shading.color = "#FFDD11") 

doc <- read_docx() %>%
  body_add_fpar(fpar(ftext("hello", yellow.formatting),
                     " world")) %>%
  body_add_par("good morning") %>%
  body_add_fpar(fpar("and ",
                     ftext("good night", yellow.formatting)))

print(doc, "tempfile.docx")

Side by side comparison of tempfile.docx & tempfile_changed.docx: before & after

Z.Lin
  • 28,055
  • 6
  • 54
  • 94