Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gt to word #962

Merged
merged 90 commits into from
Jul 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
0ba02ef
Create gt_word_testing.Rmd
rich-iannone Jul 1, 2021
9c802f1
Create utils_render_xml.R
rich-iannone Jul 1, 2021
82bc79e
Update print.R
rich-iannone Jul 1, 2021
632b0c1
Update export.R
rich-iannone Jul 1, 2021
58d609b
Update NAMESPACE
rich-iannone Jul 1, 2021
77196ce
Update DESCRIPTION
rich-iannone Jul 1, 2021
19b7174
Update help files using roxygen
rich-iannone Jul 1, 2021
6fb885b
Refine (and add more) XML tag generators
rich-iannone Jul 2, 2021
724e9a4
Create raw_word_testing.Rmd
rich-iannone Jul 2, 2021
175df4c
Update export.R
rich-iannone Jul 2, 2021
24feae0
Update NAMESPACE
rich-iannone Jul 2, 2021
93f4b49
Update all XML tag-building fns
rich-iannone Jul 2, 2021
2aa17fe
Update utils_render_xml.R
rich-iannone Jul 2, 2021
9efa242
Update export.R
rich-iannone Jul 2, 2021
c8fdcab
Update utils_render_xml.R
rich-iannone Jul 2, 2021
4411f9f
Modify `context` value
rich-iannone Jul 3, 2021
c74b628
Create table properties component
rich-iannone Jul 3, 2021
79f0bff
Update export.R
rich-iannone Jul 3, 2021
643b844
Add `word` context values
rich-iannone Jul 3, 2021
f72ab9f
Update `all_contexts` vector
rich-iannone Jul 3, 2021
9d7d559
Add XML tag-building functions
rich-iannone Jul 3, 2021
357e8a4
Make corrections to some `xml_*()` fns
rich-iannone Jul 3, 2021
90ee7ea
Update utils_render_xml.R
rich-iannone Jul 3, 2021
cd080c7
Add several xml tags for OOXML formatting
rich-iannone Jul 6, 2021
d5da3fd
Update utils_render_xml.R
rich-iannone Jul 6, 2021
c747f11
Make correction to `xml_tblW()`
rich-iannone Jul 8, 2021
72a6402
Remove `val` attr of `xml_tblLook()`
rich-iannone Jul 8, 2021
3acb244
Update vertical/horizontal-merging XML tag builders
rich-iannone Jul 8, 2021
63f7c14
Update utils_render_xml.R
rich-iannone Jul 8, 2021
6baf4c2
Update XML tag builder fns
rich-iannone Jul 9, 2021
2761b15
Update utils_render_xml.R
rich-iannone Jul 9, 2021
a627fd5
Update utils_render_xml.R
rich-iannone Jul 12, 2021
7562122
Add the `is_xml()` util function
rich-iannone Jul 14, 2021
58ead3c
Add text processing for Word output
rich-iannone Jul 14, 2021
83bf475
Provide replacement text for dashes
rich-iannone Jul 14, 2021
9fc6025
Update utils_render_xml.R
rich-iannone Jul 14, 2021
a21e3c8
Update format_data.R
rich-iannone Jul 14, 2021
c04ff14
Add to `cmark_rules_xml` list
rich-iannone Jul 14, 2021
b3a0c86
Update utils_render_xml.R
rich-iannone Jul 14, 2021
7a348b9
Update utils.R
rich-iannone Jul 15, 2021
264247d
Fix implementation of column spanners
rich-iannone Jul 15, 2021
d40520a
Update utils_render_xml.R
rich-iannone Jul 16, 2021
4f4ee21
Add the `xml_v_align()` tag fn
rich-iannone Jul 19, 2021
bd7a870
Update utils_render_xml.R
rich-iannone Jul 19, 2021
657bf4c
Update utils_render_xml.R
rich-iannone Jul 19, 2021
954eb5c
Update utils.R
rich-iannone Jul 19, 2021
9b4f3cf
Update utils_render_xml.R
rich-iannone Jul 20, 2021
dbe79de
Refactor XML tag builder fns
rich-iannone Jul 20, 2021
7f6f84f
Add `xml_tc_margins()` tag builder fn
rich-iannone Jul 20, 2021
c42320b
Apply small top margin to all body cells
rich-iannone Jul 20, 2021
36c0171
Ensure that any softbreaks are squelched
rich-iannone Jul 20, 2021
931814a
Ensure that `word` context text is character
rich-iannone Jul 20, 2021
10135b2
in progress addition to word outputs
thebioengineer May 18, 2022
b1b0d04
Add officer as a suggests
thebioengineer Jun 13, 2022
9333175
Add tests, separate out title and subtitle as captions as opposed to …
thebioengineer Jun 13, 2022
04ab272
add keep_with_next option, and clean up align vs alignment arg
thebioengineer Jun 14, 2022
ed9ea50
run snapshots and a few additional tests. write tests for long table …
thebioengineer Jun 14, 2022
383e8b6
add missing spanner
thebioengineer Jun 14, 2022
c189dd1
merge main branch in and resolve conflicts
thebioengineer Jun 14, 2022
17920d8
add word output to news
thebioengineer Jun 14, 2022
09cef89
in-progress cell styling support
thebioengineer Jun 14, 2022
46fced4
Update column header and span behavior. update some of the documentat…
thebioengineer Jun 17, 2022
5031d4b
Build documentation
thebioengineer Jun 17, 2022
5481396
Merge branch 'gt_to_word' into word_cell_styling
thebioengineer Jun 17, 2022
78e6256
Add xml_tbl_cell function to define a table cell generally
thebioengineer Jun 22, 2022
a539142
Add as_word and body_add_gt into "Export Functions" section of pkgdow…
thebioengineer Jun 22, 2022
6fc3002
Merge branch 'master' into gt_to_word
thebioengineer Jun 22, 2022
81ba61b
Merge branch 'gt_to_word' into word_cell_styling
thebioengineer Jun 22, 2022
89577c8
styling of table body (row groups, stub, and body)
thebioengineer Jun 23, 2022
4b41fd1
rename font_size to size
thebioengineer Jun 23, 2022
5203aae
Add cell coloring to title, columns, body, stubs, and summaries. incl…
thebioengineer Jun 28, 2022
56f2055
Update as_word snaps
thebioengineer Jun 28, 2022
93c2e3c
remove purrr
thebioengineer Jun 28, 2022
857c702
Add explicit import of `%||%` from rlang
thebioengineer Jun 28, 2022
d71106b
Merge branch 'master' into gt_to_word
thebioengineer Jun 28, 2022
15163bc
correct .[[1]] to be .[1] %>% .[[1]] to be consistent with purrr::pluck
thebioengineer Jun 28, 2022
89ee132
Merge branch 'gt_to_word' of https://github.com/thebioengineer/gt int…
thebioengineer Jun 28, 2022
3eb5a07
Add Ellis to Authors@R
thebioengineer Jun 28, 2022
faf6a59
Modify file name for collation purposes
rich-iannone Jul 5, 2022
614d16b
Modify testthat tests
rich-iannone Jul 5, 2022
d8c199c
Remove commented code
rich-iannone Jul 5, 2022
49ae759
Remove unneeded function
rich-iannone Jul 5, 2022
68c7321
Remove `body_add_gt()`
rich-iannone Jul 5, 2022
998052f
Update NEWS.md
rich-iannone Jul 5, 2022
9f03798
Update NAMESPACE
rich-iannone Jul 5, 2022
a8a9d22
Update DESCRIPTION
rich-iannone Jul 5, 2022
ff1762f
Update .Rbuildignore
rich-iannone Jul 5, 2022
8273573
Update help files
rich-iannone Jul 5, 2022
39fbb91
Merge branch 'master' into gt_to_word
cscheid Jul 5, 2022
db1c3ec
Remove missing fn
cscheid Jul 5, 2022
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
1 change: 1 addition & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ tests/testthat/test-tab_options.R
tests/testthat/test-tab_spanner.R
tests/testthat/test-tab_spanner_delim.R
tests/testthat/test-table_parts.R
tests/testthat/test-as_word.R
5 changes: 4 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Authors@R: c(
person("Joe", "Cheng", , "joe@rstudio.com", "aut"),
person("Barret", "Schloerke", , "barret@rstudio.com", "aut",
comment = c(ORCID = "0000-0001-9986-114X")),
person("Ellis", "Hughes", , "ellis.h.hughes@gsk.com", "aut",
comment = c(ORCID = "0000-0003-0637-4436")),
person("RStudio", role = c("cph", "fnd"))
)
License: MIT + file LICENSE
Expand Down Expand Up @@ -111,10 +113,11 @@ Collate:
'utils_general_str_formatting.R'
'utils_pipe.R'
'utils_render_common.R'
'utils_render_footnotes.R'
'utils_render_html.R'
'utils_render_latex.R'
'utils_render_rtf.R'
'utils_render_xml.R'
'z_utils_render_footnotes.R'
'zzz.R'
Config/testthat/edition: 3
Config/testthat/parallel: true
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export(adjust_luminance)
export(as_latex)
export(as_raw_html)
export(as_rtf)
export(as_word)
export(cell_borders)
export(cell_fill)
export(cell_text)
Expand Down Expand Up @@ -121,6 +122,7 @@ importFrom(dplyr,vars)
importFrom(ggplot2,ggsave)
importFrom(htmltools,css)
importFrom(magrittr,"%>%")
importFrom(rlang,`%||%`)
importFrom(tidyselect,contains)
importFrom(tidyselect,ends_with)
importFrom(tidyselect,everything)
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# gt (development version)

* word table output via `as_word()`. (#929)

# gt 0.6.0

## New features
Expand Down
176 changes: 175 additions & 1 deletion R/export.R
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,180 @@ as_rtf <- function(data) {
rtf_table
}

#' Output a **gt** object as Word
#'
#' @description
#' Get the Open Office XML table tag content from a `gt_tbl` object as as a
#' single-element character vector.
#'
#' @param data A table object that is created using the `gt()` function.
#' @param align left, center (default) or right.
#' @param caption_location top (default), bottom, or embed Indicating if the
#' title and subtitle should be listed above, below, or be embedded in the
#' table
#' @param caption_align left (default), center, or right. Alignment of caption
#' (title and subtitle). Used when `caption_location` is not "embed".
#' @param split TRUE or FALSE (default) indicating whether activate Word option
#' 'Allow row to break across pages'.
#' @param keep_with_next TRUE (default) or FALSE indicating whether a table
#' should use Word option 'keep rows together' is activated when TRUEd
#'
#' @examples
#' # Use `gtcars` to create a gt table;
#' # add a header and then export as
#' # OOXML code for Word
#' tab_rtf <-
#' gtcars %>%
#' dplyr::select(mfr, model) %>%
#' dplyr::slice(1:2) %>%
#' gt() %>%
#' tab_header(
#' title = md("Data listing from **gtcars**"),
#' subtitle = md("`gtcars` is an R dataset")
#' ) %>%
#' as_word()
#'
#' @family Export Functions
#' @section Function ID:
#' 13-5
#'
#' @export
as_word <- function(
data,
align = "center",
caption_location = c("top","bottom","embed"),
caption_align = "left",
split = FALSE,
keep_with_next = TRUE
) {

# Perform input object validation
stop_if_not_gt(data = data)
caption_location <- match.arg(caption_location)

# Build all table data objects through a common pipeline
value <- build_data(data = data, context = "word")

gt_xml <- c()

# Composition of Word table OOXML -----------------------------------------------
if (caption_location %in% c("top")) {
header_xml <- as_word_tbl_header_caption(data = value, align = caption_align, split = split, keep_with_next = keep_with_next)
gt_xml <- c(gt_xml, header_xml)
}

tbl_xml <- as_word_tbl_body(data = value, align = align, split = split, keep_with_next = keep_with_next, embedded_heading = identical(caption_location, "embed"))
gt_xml <- c(gt_xml, tbl_xml)


if (caption_location %in% c("bottom")) {
## set keep_with_next to false here to prevent it trying to keep with non-table content
header_xml <- as_word_tbl_header_caption(data = value, align = caption_align, split = split, keep_with_next = FALSE)
gt_xml <- c(gt_xml, header_xml)
}

gt_xml <- paste0(gt_xml, collapse = "")

gt_xml

}

#' Generate ooxml for the table caption
#'
#' @param data A processed table object that is created using the `build_data()` function.
#' @param align left (default), center or right.
#' @param split TRUE or FALSE (default) indicating whether activate Word option 'Allow row to break across pages'.
#' @param keep_with_next TRUE (default) or FALSE indicating whether a table should use Word option 'keep rows
#' together' is activated when TRUE
#'
#' @noRd
as_word_tbl_header_caption <- function(
data,
align = "left",
split = FALSE,
keep_with_next = TRUE
) {

# Perform input object validation
stop_if_not_gt(data = data)

# Composition of caption OOXML -----------------------------------------------

# Create the table caption
caption_xml <-
create_table_caption_component_xml(
data = data,
align = align,
keep_with_next = keep_with_next
)

caption_xml
}

#' Generate ooxml for the table body
#'
#' @param data A processed table object that is created using the `build_data()`
#' function.
#' @param align left, center (default) or right.
#' @param split TRUE or FALSE (default) indicating whether activate Word option
#' 'Allow row to break across pages'.
#' @param keep_with_next TRUE (default) or FALSE indicating whether a table
#' should use Word option 'keep rows together' is activated when TRUE
#' @param embedded_heading TRUE or FALSE (default) indicating whether a table
#' should add the title and subtitle at the top of the table.
#'
#' @noRd
as_word_tbl_body <- function(
data,
align = "center",
split = FALSE,
keep_with_next = TRUE,
embedded_heading = FALSE
) {

# Perform input object validation
stop_if_not_gt(data = data)

# Composition of table Word OOXML -----------------------------------------------

# Create the table properties component
table_props_component <- create_table_props_component_xml(data = data, align = align)

# # Create the heading component
if (embedded_heading) {
heading_component <- create_heading_component_xml(data = data, split = split, keep_with_next = keep_with_next)
} else {
heading_component <- NULL
}

# Create the columns component
columns_component <- create_columns_component_xml(data = data, split = split, keep_with_next = keep_with_next)

# Create the body component
body_component <- create_body_component_xml(data = data, split = split, keep_with_next = keep_with_next)

# Create the footnotes component
footnotes_component <- create_footnotes_component_xml(data = data, split = split, keep_with_next = keep_with_next)

# Create the source notes component
source_notes_component <- create_source_notes_component_xml(data = data, split = split, keep_with_next = keep_with_next)

# Compose the Word OOXML table
word_tbl <-
xml_tbl(
paste0(
table_props_component,
heading_component,
columns_component,
body_component,
footnotes_component,
source_notes_component,
collapse = ""
)
)

as.character(word_tbl)
}

#' Extract a summary list from a **gt** object
#'
Expand Down Expand Up @@ -610,7 +784,7 @@ as_rtf <- function(data) {
#'
#' @family Export Functions
#' @section Function ID:
#' 13-5
#' 13-6
#'
#' @export
extract_summary <- function(data) {
Expand Down
3 changes: 3 additions & 0 deletions R/format_data.R
Original file line number Diff line number Diff line change
Expand Up @@ -2792,6 +2792,9 @@ fmt_markdown <- function(
rtf = function(x) {
markdown_to_rtf(x)
},
word = function(x) {
markdown_to_xml(x)
},
default = function(x) {
vapply(
x,
Expand Down
16 changes: 16 additions & 0 deletions R/print.R
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ knitr_is_rtf_output <- function() {
"rtf" %in% knitr::opts_knit$get("rmarkdown.pandoc.to")
}

knitr_is_word_output <- function() {

"word_document" %in% rmarkdown::all_output_formats(knitr::current_input())
}

#' Knit print the table
#'
#' This facilitates printing of the HTML table within a knitr code chunk.
Expand All @@ -34,10 +39,21 @@ knitr_is_rtf_output <- function() {
knit_print.gt_tbl <- function(x, ...) {

if (knitr_is_rtf_output()) {

x <- as_rtf(x)

} else if (knitr::is_latex_output()) {

x <- as_latex(x)

} else if (knitr_is_word_output()) {

x <-
paste("```{=openxml}", as_word(x), "```\n\n", sep = "\n") %>%
knitr::asis_output()

} else {

# Default to HTML output
x <- as.tags.gt_tbl(x, ...)
}
Expand Down
Loading