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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ r2rtf.Rcheck/
r2rtf*.tar.gz
r2rtf*.tgz
revdep/
Rplots.pdf
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ Suggests:
xml2
Config/testthat/edition: 3
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
RoxygenNote: 7.3.3
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export(rtf_source)
export(rtf_subline)
export(rtf_title)
export(utf8Tortf)
export(write_docx)
export(write_html)
export(write_rtf)
importFrom(grDevices,colors)
importFrom(utils,tail)
3 changes: 2 additions & 1 deletion R/rtf_convert_format.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
#' @param output_file A vector of filename for the output file.
#' Default is the same filename for input.
#' @param output_dir The output directory for the converted `output_dir`.
#' @param format Converted file format extension. Currently support "pdf" or "docx"
#' @param format Converted file format extension. Currently support "pdf"
#' or "docx" or "html"
#' @param overwrite logical; should existing destination files be overwritten?
#'
#' @return A vector of file paths for the converted files.
Expand Down
116 changes: 116 additions & 0 deletions R/write_rtf.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,119 @@ write_rtf_para <- function(rtf, file) {

invisible(file)
}

#' Write an RTF Table or Figure to a DOCX File
#'
#' @description
#' The write_docx function writes an RTF encoding string to a .docx file
#' by first writing to a temporary RTF file and then converting it to DOCX
#' using LibreOffice.
#'
#' @section Specification:
#' \if{latex}{
#' \itemize{
#' \item Write RTF encoding to a temporary RTF file.
#' \item Convert RTF to DOCX using LibreOffice command-line tool via \code{rtf_convert_format()}.
#' }
#' }
#' \if{html}{The contents of this section are shown in PDF user manual only.}
#'
#' @param rtf A character rtf encoding string rendered by `rtf_encode()`.
#' @param file A character string naming a file to save docx file.
#'
#' @details
#' This function requires LibreOffice to be installed on the system.
#' The function uses the internal \code{rtf_convert_format()} function
#' to perform the conversion from RTF to DOCX format.
#'
#' Currently only Unix/Linux/macOS systems are supported.
#'
#' @export
write_docx <- function(rtf, file) {
# Normalize the output file path
file <- normalizePath(file, mustWork = FALSE)

# Create output directory if it doesn't exist
output_dir <- dirname(file)
if (!dir.exists(output_dir)) {
dir.create(output_dir, recursive = TRUE)
}

# Create a temporary RTF file
tmpdir <- tempfile(pattern = "r2rtf_")
dir.create(tmpdir)
on.exit(unlink(tmpdir, recursive = TRUE), add = TRUE)

file_basename <- tools::file_path_sans_ext(basename(file))
rtf_path <- file.path(tmpdir, paste0(file_basename, ".rtf"))
write_rtf(rtf, rtf_path)

# Convert RTF to DOCX using existing rtf_convert_format function
rtf_convert_format(
input = rtf_path,
output_file = basename(file),
output_dir = output_dir,
format = "docx",
overwrite = TRUE
)

invisible(file)
}

#' Write an RTF Table or Figure to an HTML File
#'
#' @description
#' The write_html function writes an RTF encoding string to an .html file
#' by first writing to a temporary RTF file and then converting it to HTML
#' using LibreOffice.
#'
#' @section Specification:
#' \if{latex}{
#' \itemize{
#' \item Write RTF encoding to a temporary RTF file.
#' \item Convert RTF to HTML using LibreOffice command-line tool via \code{rtf_convert_format()}.
#' }
#' }
#' \if{html}{The contents of this section are shown in PDF user manual only.}
#'
#' @param rtf A character rtf encoding string rendered by `rtf_encode()`.
#' @param file A character string naming a file to save html file.
#'
#' @details
#' This function requires LibreOffice to be installed on the system.
#' The function uses the internal \code{rtf_convert_format()} function
#' to perform the conversion from RTF to HTML format.
#'
#' Currently only Unix/Linux/macOS systems are supported.
#'
#' @export
write_html <- function(rtf, file) {
# Normalize the output file path
file <- normalizePath(file, mustWork = FALSE)

# Create output directory if it doesn't exist
output_dir <- dirname(file)
if (!dir.exists(output_dir)) {
dir.create(output_dir, recursive = TRUE)
}

# Create a temporary RTF file
tmpdir <- tempfile(pattern = "r2rtf_")
dir.create(tmpdir)
on.exit(unlink(tmpdir, recursive = TRUE), add = TRUE)

file_basename <- tools::file_path_sans_ext(basename(file))
rtf_path <- file.path(tmpdir, paste0(file_basename, ".rtf"))
write_rtf(rtf, rtf_path)

# Convert RTF to HTML using existing rtf_convert_format function
rtf_convert_format(
input = rtf_path,
output_file = basename(file),
output_dir = output_dir,
format = "html",
overwrite = TRUE
)

invisible(file)
}
6 changes: 6 additions & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,13 @@ reference:
- "rtf_footnote"
- "rtf_source"
- "rtf_encode"
- title: Write to File
contents:
- "write_rtf"
- "write_docx"
- "write_html"
- title: Assemble Documents
contents:
- "assemble_rtf"
- "assemble_docx"
- title: RTF Figure
Expand Down
2 changes: 1 addition & 1 deletion man/assemble_docx.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions man/write_docx.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions man/write_html.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

127 changes: 127 additions & 0 deletions tests/testthat/test-independent-testing-write_rtf.R
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,130 @@ test_that("Write function test for dataset input", {

expect_equal(y, z)
})

test_that("write_docx creates DOCX file from RTF encoding", {
skip_on_os("windows") # rtf_convert_format only supports Unix/Linux/macOS
skip_if_not(
nzchar(Sys.which("libreoffice")) ||
nzchar(Sys.which("libreoffice24.8")) ||
nzchar(Sys.which("libreoffice7.6")),
"LibreOffice is not installed"
)

# Create RTF encoding
rtf <- head(iris) |>
rtf_body() |>
rtf_encode()

# Write to DOCX
docx_file <- file.path(tempdir(), "test_table.docx")
result <- write_docx(rtf, docx_file)

# Verify file was created
expect_true(file.exists(docx_file))
expect_equal(result, docx_file)

# Clean up
unlink(docx_file)
})

test_that("write_docx creates output directory if needed", {
skip_on_os("windows") # rtf_convert_format only supports Unix/Linux/macOS
skip_if_not(
nzchar(Sys.which("libreoffice")) ||
nzchar(Sys.which("libreoffice24.8")) ||
nzchar(Sys.which("libreoffice7.6")),
"LibreOffice is not installed"
)

# Create RTF encoding
rtf <- head(cars) |>
rtf_body() |>
rtf_encode()

# Create nested path
nested_path <- file.path(tempdir(), "test_output_dir", "nested", "test.docx")

# Write to DOCX
result <- write_docx(rtf, nested_path)

# Verify directory and file were created
expect_true(dir.exists(dirname(nested_path)))
expect_true(file.exists(nested_path))

# Clean up
unlink(file.path(tempdir(), "test_output_dir"), recursive = TRUE)
})

test_that("write_docx fails gracefully when LibreOffice is not available", {
skip_on_os("windows") # rtf_convert_format only supports Unix/Linux/macOS
skip_if(
nzchar(Sys.which("libreoffice")) ||
nzchar(Sys.which("libreoffice24.8")) ||
nzchar(Sys.which("libreoffice7.6")),
"Skip if LibreOffice IS installed"
)

rtf <- head(iris) |>
rtf_body() |>
rtf_encode()

expect_error(
write_docx(rtf, file.path(tempdir(), "test.docx")),
"Can't find libreoffice"
)
})

test_that("write_html creates HTML file from RTF encoding", {
skip_on_os("windows") # rtf_convert_format only supports Unix/Linux/macOS
skip_if_not(
nzchar(Sys.which("libreoffice")) ||
nzchar(Sys.which("libreoffice24.8")) ||
nzchar(Sys.which("libreoffice7.6")),
"LibreOffice is not installed"
)

# Create RTF encoding
rtf <- head(iris) |>
rtf_body() |>
rtf_encode()

# Write to HTML
html_file <- file.path(tempdir(), "test_table.html")
result <- write_html(rtf, html_file)

# Verify file was created
expect_true(file.exists(html_file))
expect_equal(result, html_file)

# Clean up
unlink(html_file)
})

test_that("write_html creates output directory if needed", {
skip_on_os("windows") # rtf_convert_format only supports Unix/Linux/macOS
skip_if_not(
nzchar(Sys.which("libreoffice")) ||
nzchar(Sys.which("libreoffice24.8")) ||
nzchar(Sys.which("libreoffice7.6")),
"LibreOffice is not installed"
)

# Create RTF encoding
rtf <- head(cars) |>
rtf_body() |>
rtf_encode()

# Create nested path
nested_path <- file.path(tempdir(), "test_html_output", "nested", "test.html")

# Write to HTML
result <- write_html(rtf, nested_path)

# Verify directory and file were created
expect_true(dir.exists(dirname(nested_path)))
expect_true(file.exists(nested_path))

# Clean up
unlink(file.path(tempdir(), "test_html_output"), recursive = TRUE)
})
Loading
Loading