Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions R/docx_exporter_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,47 @@ dps_markup_df_docx <- tibble::tibble(
replace_by = c("flextable::as_sup", "flextable::as_sub")
)

remove_trHeight_nodes_XML <- function(doc) {
# this function is only called when exporting a table or listing.
# in the parsing process, there is a large spacing separating the rows.
# in 'trHeight' nodes, we should not have both 'w:val' and 'w:hRule'
# attributes together:
# <w:trHeight w:val="617" w:hRule="auto"/>
# Ideally, we'd like to remove only "w:hRule" attribute, but a simpler
# solution is to completely remove all 'trHeight' nodes
nodes <- xml2::xml_find_all(doc$doc_obj$get(), ".//w:trHeight")
# remove all row height nodes entirely
xml2::xml_remove(nodes)
}

fix_namespaces_Graphs_XML <- function(doc) {
# nolint start
# This function is only called when exporting a Graph, and
# fixes the "parsing failed" error.
# The root cause of this error is that namespace definitions are moved to the parent node:
# <w:tbl
# xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
# xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
# but they should appear at the children level:
# <a:graphicFrameLocks
# xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
# <a:graphic
# xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
# <pic:pic
# xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
#
# in order to prevent this moving, we just remove those 2 namespace definitions
# from the parent node 'w:tbl'
# nolint end

# remove namespaces from parent node
nodes <- xml2::xml_find_all(doc$doc_obj$get(), ".//w:tbl")
for (node in nodes) {
xml2::xml_attr(node, "xmlns:a") <- NULL
xml2::xml_attr(node, "xmlns:pic") <- NULL
}
}

align_rows_with_rtf <- function(doc) {
# when we have vertical pagination in the case of tables and listings,
# from page 2 onwards, the rows visually look a little bit shifted downwards
Expand Down Expand Up @@ -117,6 +158,9 @@ insert_fake_watermark_XML <- function(doc, watermark, orientation, tlgtype) {
# to shift upwards, decrease margin_top
margin_left <- -24
margin_top <- ifelse(tlgtype == "Listing", 165, 176)
if (tlgtype == "Figure") {
margin_left <- -30
}
}


Expand Down Expand Up @@ -179,7 +223,7 @@ insert_fake_watermark_XML <- function(doc, watermark, orientation, tlgtype) {
' xmlns:w10="urn:schemas-microsoft-com:office:word"',
' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"',
' xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"',
' xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14">',
' xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14"',
' xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"',
' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"',
'>',
Expand Down Expand Up @@ -1313,7 +1357,6 @@ tt_to_flextable_j <- function(
)
}


footers_with_blank_line <- c()
if (length(formatters::all_footers(tt)) > 0 && isTRUE(integrate_footers)) {
footers_with_blank_line <- formatters::all_footers(tt)
Expand Down Expand Up @@ -1860,6 +1903,7 @@ export_as_docx_j <- function(
}
add_vertical_pagination_XML(doc)
remove_security_popup_page_numbers_XML(doc, tlgtype, pagenum)
remove_trHeight_nodes_XML(doc)
if (!is.null(watermark)) {
insert_fake_watermark_XML(doc, watermark, orientation, tlgtype)
}
Expand Down Expand Up @@ -2071,6 +2115,7 @@ export_graph_as_docx <- function(g = NULL,
doc <- officer::body_set_default_section(doc, section_properties)
doc <- flextable::body_add_flextable(doc, flx, align = "center")
add_hanging_indent_in_title_XML(doc)
fix_namespaces_Graphs_XML(doc)
if (!is.null(watermark)) {
insert_fake_watermark_XML(doc, watermark, orientation, "Figure")
}
Expand Down
13 changes: 12 additions & 1 deletion tests/testthat/test-docx_exporter_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -488,9 +488,15 @@ testthat::test_that("export_TLG_as_docx() works with pagination", {
# open the files and check the XML
doc <- officer::read_docx(paste0(output_dir, "/test1234part1of2.docx"))
snapshot_test_docx(doc)
# check that the XML does not contain "w:trHeight" nodes
nodes <- xml2::xml_find_all(doc$doc_obj$get(), ".//w:trHeight")
testthat::expect_length(nodes, 0)

doc <- officer::read_docx(paste0(output_dir, "/test1234part2of2.docx"))
snapshot_test_docx(doc)
# check that the XML does not contain "w:trHeight" nodes
nodes <- xml2::xml_find_all(doc$doc_obj$get(), ".//w:trHeight")
testthat::expect_length(nodes, 0)


file.remove(c(
Expand Down Expand Up @@ -636,7 +642,12 @@ testthat::test_that("export_TLG_as_docx() works with basic example", {
# open the file and check the XML
doc <- officer::read_docx(output_docx)
snapshot_test_docx(doc, detailed = FALSE)

# check that the XML "w:tbl" node does not contain namespace definitions
nodes <- xml2::xml_find_all(doc$doc_obj$get(), ".//w:tbl")
testthat::expect_length(nodes, 1)
node_str <- as.character(nodes[[1]])
node_str <- gsub("\n.*", "", node_str)
testthat::expect_false(grepl("xmlns", node_str))
file.remove(c(pn1, pn2, output_docx))
})

Expand Down
Loading