1

I'd like to create a template with tags which are highlighted. The tags should be replaced with some data with R. I have highlighted text in the template file and want a blank background in the output file.

I've tried officer because that seems to be the most mature R-package for manipulating word documents. I've tried the body_replace_all_text and the body_replace_text_at_bkm function but neither seems to provide options to change the formatting.

I am completely open to a different approach. The hard requirements are that the template and the output file must be editable by non-technical co-worker (thus a word document) and the input fields in the template must be somehow highlighted. That means if a co-worker manually edit the template he wouldn't miss any tags.

Code

library(officer)
library(magrittr)

template <- read_docx("template.docx")

pattern <- "<tags>"
replacement <- "tags"
template <- template %>%
  body_replace_all_text(pattern, replacement)

pattern <- "<color.*?/color>"
replacement <- "yellow"
template <- template %>%
  body_replace_all_text(pattern, replacement)

print(template, target = "output.docx")

template.docx

template.docx

output.docx

enter image description here

desired_output.docx

enter image description here

Edit

Solved that problem by monkey-patching the officer package. It's kind of hacky so I'm still open for a cleaner solution.

replace_all_text.custom = function( oldValue, newValue, onlyAtCursor=TRUE, warn = TRUE, ... ) {

  oldValue <- enc2utf8(oldValue)
  newValue <- enc2utf8(newValue)

  replacement_count <- 0

  base_node <- if (onlyAtCursor) self$get_at_cursor() else self$get()

  # For each matching text node...
  for (text_node in xml_find_all(base_node, ".//w:t")) {
    # ...if it contains the oldValue...
    if (grepl(oldValue, xml_text(text_node), ...)) {
      replacement_count <- replacement_count + 1
      # Replace the node text with the newValue.
      xml_text(text_node) <- gsub(oldValue, newValue, xml_text(text_node), ...)
      # remove background color
      xml_remove(xml_find_all(text_node, "..//w:highlight"))
    }
  }

  # Alert the user if no replacements were made.
  if (replacement_count == 0 && warn) {
    search_zone_text <- if (onlyAtCursor) "at the cursor." else "in the document."
    warning("Found 0 instances of '", oldValue, "' ", search_zone_text)
  }

  self
}

docx_part.custom <- officer:::docx_part
docx_part.custom$public_methods$replace_all_text <- replace_all_text.custom

assignInNamespace("docx_part", docx_part.custom, ns = "officer")
Birger
  • 1,111
  • 7
  • 17
  • It doesn't give me yellow in my system. Are you using tracked changes by any chance? – bob1 Oct 29 '18 at 19:49
  • Just a plain docx-file. I've shared it for you: https://drive.google.com/file/d/1qHnuj10aAY_8pmn50PClyi1-Mrlu6qpc/view – Birger Oct 29 '18 at 20:00
  • Using Microsoft Word 2013, I still don't get any background color, have you tested it outside Google Docs? I see there is a `fp_text` option in the Officer package, that has a few color options [link](https://cran.r-project.org/web/packages/officer/officer.pdf) (pdf - see pg 33). – bob1 Oct 29 '18 at 20:10
  • I guess you could just copy/paste the text in a new document and color it by yourself. Don't get `fp_text` to work with `body_replace_all_text`. – Birger Oct 29 '18 at 20:24
  • I see what you mean now, you have highlighted them in the doc and then want the highlight removed in output. I thought you meant that the tags were coming out yellow as a result of the code. I have no idea.... – bob1 Oct 29 '18 at 20:31
  • Jepp, sorry for the confusion :) – Birger Oct 29 '18 at 20:33
  • You might want to edit the question to read something like: "I have highlighted text in the input and want a blank background in the output" – bob1 Oct 29 '18 at 21:06
  • I am afraid this can not be done with `body_replace_all_text` that only replace text, not formatting properties. Maybe bookmarks and function `body_replace_at` would be better here. – David Gohel Oct 29 '18 at 22:32
  • Thanks for your comments. I've updated my question, please have look. – Birger Oct 30 '18 at 08:26

0 Answers0