Skip to content

Commit

Permalink
Fix #162
Browse files Browse the repository at this point in the history
sheet - use only in R to denote an argument that can either be a name or index
sheet_index - use in R and C++ to denote an integer representing the sheet index, e.g. 2
sheet_name - use in R and C++ to denote a string representing the sheet name, e.g. "Sheet1"
sheet_file - use in R and C++ to denote the often throwaway XML file
  • Loading branch information
chainsawriot committed Sep 10, 2023
1 parent e0f5c09 commit 36643c8
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 106 deletions.
24 changes: 12 additions & 12 deletions R/cpp11.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,26 @@ get_flat_sheet_names_ <- function(file, include_external_data) {
.Call(`_readODS_get_flat_sheet_names_`, file, include_external_data)
}

read_flat_ods_ <- function(file, start_row, stop_row, start_col, stop_col, sheet, formula_as_formula) {
.Call(`_readODS_read_flat_ods_`, file, start_row, stop_row, start_col, stop_col, sheet, formula_as_formula)
read_flat_ods_ <- function(file, start_row, stop_row, start_col, stop_col, sheet_index, formula_as_formula) {
.Call(`_readODS_read_flat_ods_`, file, start_row, stop_row, start_col, stop_col, sheet_index, formula_as_formula)
}

read_ods_ <- function(file, start_row, stop_row, start_col, stop_col, sheet, formula_as_formula) {
.Call(`_readODS_read_ods_`, file, start_row, stop_row, start_col, stop_col, sheet, formula_as_formula)
read_ods_ <- function(file, start_row, stop_row, start_col, stop_col, sheet_index, formula_as_formula) {
.Call(`_readODS_read_ods_`, file, start_row, stop_row, start_col, stop_col, sheet_index, formula_as_formula)
}

splice_sheet_ <- function(original_xml, sheet_xml, flat) {
.Call(`_readODS_splice_sheet_`, original_xml, sheet_xml, flat)
splice_sheet_ <- function(original_xml, sheet_file, flat) {
.Call(`_readODS_splice_sheet_`, original_xml, sheet_file, flat)
}

update_sheet_ <- function(original_xml, sheet_xml, flat, sheet) {
.Call(`_readODS_update_sheet_`, original_xml, sheet_xml, flat, sheet)
update_sheet_ <- function(original_xml, sheet_file, flat, sheet_index) {
.Call(`_readODS_update_sheet_`, original_xml, sheet_file, flat, sheet_index)
}

write_sheet_ <- function(filename, x, sheet, row_names, col_names, na_as_string, padding, header, footer) {
.Call(`_readODS_write_sheet_`, filename, x, sheet, row_names, col_names, na_as_string, padding, header, footer)
write_sheet_file_ <- function(filename, x, sheet_name, row_names, col_names, na_as_string, padding, header, footer) {
.Call(`_readODS_write_sheet_file_`, filename, x, sheet_name, row_names, col_names, na_as_string, padding, header, footer)
}

write_sheet_list_ <- function(filename, x, sheet, row_names, col_names, na_as_string, padding, header, footer) {
.Call(`_readODS_write_sheet_list_`, filename, x, sheet, row_names, col_names, na_as_string, padding, header, footer)
write_sheet_file_list_ <- function(filename, x, sheet_name, row_names, col_names, na_as_string, padding, header, footer) {
.Call(`_readODS_write_sheet_file_list_`, filename, x, sheet_name, row_names, col_names, na_as_string, padding, header, footer)
}
2 changes: 1 addition & 1 deletion R/list_ods_sheets.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#'
#' @param path Path to the (f)ods file
#' @param include_external_data A boolean value to show or hide sheets containing archived linked data (default false)
#' @return For `list_(f)ods_sheets`, a character vector of sheet names; for `get_num_sheets_in_(f)ods`, the total number of sheets
#' @return A character vector of sheet names
#' @details The default "include_external_data" for `ods_sheets` is TRUE to maintain compatibility with version 1 of readODS. It will change to `TRUE` in version 3.
#' @author Peter Brohan <peter.brohan+cran@@gmail.com>, Chung-hong Chan <chainsawtiney@@gmail.com>, Gerrit-Jan Schutten <phonixor@@gmail.com>
#' @examples
Expand Down
14 changes: 8 additions & 6 deletions R/read_ods.R
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@
.type_convert(df = res, col_types = col_types, verbose = verbose, na = na)
}

## standardise `sheet` parameter as a number
## standardise `sheet` parameter as a number, i.e. sheet_index
.standardise_sheet <- function(sheet, sheets, limits, range) {
sheet_from_range <- cellranger::as.cell_limits(range)[["sheet"]]
if (!is.null(range) && !is.na(sheet_from_range)) {
Expand All @@ -168,9 +168,11 @@
call. = FALSE))
}
if (!is.numeric(sheet)) {
sheet <- which(is_in_sheet_names)
sheet_index <- which(is_in_sheet_names)
} else {
sheet_index <- sheet
}
return(sheet)
return(sheet_index)
}

.read_ods <- function(path,
Expand Down Expand Up @@ -209,14 +211,14 @@
}
## Get cell range info
limits <- .standardise_limits(range, skip)
sheet <- .standardise_sheet(sheet = sheet, sheets = .get_sheet_names_func(file = path, include_external_data = TRUE),
limits = limits, range = range)
sheet_index <- .standardise_sheet(sheet = sheet, sheets = .get_sheet_names_func(file = path, include_external_data = TRUE),
limits = limits, range = range)
strings <- .read_ods_func(file = path,
start_row = limits["min_row"],
stop_row = limits["max_row"],
start_col = limits["min_col"],
stop_col = limits["max_col"],
sheet = sheet,
sheet_index = sheet_index,
formula_as_formula = formula_as_formula)

if (((strings[1] == 0 || strings[2] == 0)) &&
Expand Down
30 changes: 16 additions & 14 deletions R/write_ods.R
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
return(path)
}

.convert_df_to_sheet <- function(x, sheet = "Sheet1", row_names = FALSE, col_names = FALSE, na_as_string = FALSE, padding = FALSE, xml_file = file.path(tempfile(fileext = ".xml"))) {
write_sheet_(x = x, filename = xml_file, sheet = sheet, row_names = row_names, col_names = col_names,
.convert_df_to_sheet_file <- function(x, sheet_name = "Sheet1", row_names = FALSE, col_names = FALSE, na_as_string = FALSE, padding = FALSE, xml_file = file.path(tempfile(fileext = ".xml"))) {
write_sheet_file_(x = x, filename = xml_file, sheet_name = sheet_name, row_names = row_names, col_names = col_names,
na_as_string = na_as_string, padding = padding,
header = "",
footer = "")
Expand Down Expand Up @@ -49,37 +49,39 @@
}

.update_ods <- function(x, path = tempfile(fileext = ".ods"), sheet = "Sheet1", append = FALSE, update = FALSE, row_names = FALSE, col_names = TRUE, na_as_string = FALSE, padding = FALSE, flat = FALSE, temp_ods_dir = NULL) {
sheet_name <- sheet
if (!file.exists(path)) {
stop("File does not exist: ", path, call. = FALSE)
}
if (isFALSE(flat)) {
zip::unzip(path, exdir = temp_ods_dir)
contentfile <- file.path(temp_ods_dir, "content.xml")
sheets <- list_ods_sheets(path, include_external_data = TRUE)
sheet_names <- list_ods_sheets(path, include_external_data = TRUE)
} else {
contentfile <- path
sheets <- list_fods_sheets(path, include_external_data = TRUE)
sheet_names <- list_fods_sheets(path, include_external_data = TRUE)
}
is_in_sheet_names <- stringi::stri_cmp(e1 = sheet, e2 = sheets) == 0
is_in_sheet_names <- stringi::stri_cmp(e1 = sheet_name, e2 = sheet_names) == 0
sheet_exist <- any(is_in_sheet_names)
if ((sheet_exist && append && !update) || (sheet_exist && !update)) {
## Sheet exists so we cannot append
stop(paste0("Sheet ", sheet, " exists. Set update to TRUE is you want to update this sheet."), call. = FALSE)
stop(paste0("Sheet ", sheet_name, " exists. Set update to TRUE is you want to update this sheet."), call. = FALSE)
}
if (!sheet_exist && update) {
stop(paste0("Sheet ", sheet, " does not exist. Cannot update."), call. = FALSE)
stop(paste0("Sheet ", sheet_name, " does not exist. Cannot update."), call. = FALSE)
}
## numeric
normalized_sheet <- which(is_in_sheet_names)
throwaway_xml_file <- .convert_df_to_sheet(x = x, sheet = sheet, row_names = row_names, col_names = col_names,
na_as_string = na_as_string, padding = padding)
sheet_index <- which(is_in_sheet_names)
throwaway_xml_file <- .convert_df_to_sheet_file(x = x, sheet_name = sheet_name, row_names = row_names, col_names = col_names,
na_as_string = na_as_string, padding = padding)
if (append) {
return(splice_sheet_(contentfile, throwaway_xml_file, flat))
}
return(update_sheet_(contentfile, throwaway_xml_file, flat, normalized_sheet))
return(update_sheet_(contentfile, throwaway_xml_file, flat, sheet_index))
}

.write_ods <- function(x, path = tempfile(fileext = ".ods"), sheet = "Sheet1", append = FALSE, update = FALSE, row_names = FALSE, col_names = TRUE, na_as_string = FALSE, padding = FALSE, flat = FALSE) {
sheet_name <- sheet
if (isFALSE(inherits(x, "data.frame")) && !is.list(x)) {
stop("x must be data.frame or list.", call. = FALSE)
}
Expand All @@ -100,14 +102,14 @@
}
if (isTRUE(inherits(x, "data.frame"))) {
x <- .preprocess_x(x)
.write_fun <- write_sheet_
.write_fun <- write_sheet_file_
} else {
## it's a list (at least we assume)
x <- lapply(x, .preprocess_x)
if (is.null(names(x))) {
names(x) <- paste0("Sheet", seq_along(x))
}
.write_fun <- write_sheet_list_
.write_fun <- write_sheet_file_list_
}
path <- .preprocess_path(path)
if (isFALSE(flat)) {
Expand All @@ -121,7 +123,7 @@
header <- .FODS_HEADER
footer <- .FODS_FOOTER
}
.write_fun(filename = filename, x = x, sheet = sheet, row_names = row_names, col_names = col_names, na_as_string = na_as_string, padding = padding, header = header, footer = footer)
.write_fun(filename = filename, x = x, sheet_name = sheet_name, row_names = row_names, col_names = col_names, na_as_string = na_as_string, padding = padding, header = header, footer = footer)
return(invisible(.zip_tmp_to_path(temp_ods_dir, path, flat = flat)))
}

Expand Down
2 changes: 1 addition & 1 deletion man/list_ods_sheets.Rd

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

Loading

0 comments on commit 36643c8

Please sign in to comment.