I know officer is built more for creating documents from scratch rather than updating existing ones but I still find it tremendously helpful for my project.
I have a word document with many tables for which I need to replace placeholder text, and add or delete rows. So far I've been able to replace text by reaching the table with cursor_reach followed by:
replacements <- ... # vector of strings to replace placeholder text in original document
node <- doc |> docx_current_block_xml()
textNodes <- node |>
xml_children() |>
xml_children()
xml_text(textNodes[seq(8, 34, 2)]) <- replacements
Using the xml2 functions like this is "clean" enough for me—the table node itself has a child row for each row, and each row has a child node for each cell. Then I can select the exact cells I want and replace all of the text in one line. But now I need to make some of the text red. Thus far the way I have found to do this is:
xml_replace(
(textNodes[8] |> xml_children() |> xml_children())[4],
read_xml(to_wml(ftext(replacements[1], fp_text_lite(color = "red"))))
)
But this seems dirty. I first have to find the specific <w:r> node to match the equivalent of what is created by ftext. Then to get the result of ftext as an actual XML node I have to call to_wml which returns a string, which I then have to convert to XML with read_xml.
Like I said this may be out of scope for officer's intended use case so there may not be a better way. But figured I would ask here before I paste this code everywhere in my script.
I know officer is built more for creating documents from scratch rather than updating existing ones but I still find it tremendously helpful for my project.
I have a word document with many tables for which I need to replace placeholder text, and add or delete rows. So far I've been able to replace text by reaching the table with
cursor_reachfollowed by:Using the
xml2functions like this is "clean" enough for me—the table node itself has a child row for each row, and each row has a child node for each cell. Then I can select the exact cells I want and replace all of the text in one line. But now I need to make some of the text red. Thus far the way I have found to do this is:But this seems dirty. I first have to find the specific
<w:r>node to match the equivalent of what is created byftext. Then to get the result offtextas an actual XML node I have to callto_wmlwhich returns a string, which I then have to convert to XML withread_xml.Like I said this may be out of scope for officer's intended use case so there may not be a better way. But figured I would ask here before I paste this code everywhere in my script.