diff --git a/NEWS.md b/NEWS.md index ba64b6d462..61683895da 100644 --- a/NEWS.md +++ b/NEWS.md @@ -19,6 +19,8 @@ * Closed arrows in `element_line()` are now filled (@yutannihilation, #2924). +* ggplot2 now works in Turkish locale (@yutannihilation, #3011). + # ggplot2 3.1.0 ## Breaking changes diff --git a/R/fortify-multcomp.r b/R/fortify-multcomp.r index ff054c0e72..8aa165eeb3 100644 --- a/R/fortify-multcomp.r +++ b/R/fortify-multcomp.r @@ -46,7 +46,7 @@ fortify.glht <- function(model, data, ...) { #' @export fortify.confint.glht <- function(model, data, ...) { coef <- model$confint - colnames(coef) <- tolower(colnames(coef)) + colnames(coef) <- to_lower_ascii(colnames(coef)) plyr::unrowname(base::data.frame( lhs = rownames(coef), diff --git a/R/layer.r b/R/layer.r index 7994670713..e172f7fa3b 100644 --- a/R/layer.r +++ b/R/layer.r @@ -341,7 +341,7 @@ is.layer <- function(x) inherits(x, "Layer") check_subclass <- function(x, subclass, - argname = tolower(subclass), + argname = to_lower_ascii(subclass), env = parent.frame()) { if (inherits(x, subclass)) { x diff --git a/R/save.r b/R/save.r index fdddc7eeac..7f2609d312 100644 --- a/R/save.r +++ b/R/save.r @@ -145,7 +145,7 @@ plot_dev <- function(device, filename = NULL, dpi = 300) { ) if (is.null(device)) { - device <- tolower(tools::file_ext(filename)) + device <- to_lower_ascii(tools::file_ext(filename)) } if (!is.character(device) || length(device) != 1) { diff --git a/R/stat-ydensity.r b/R/stat-ydensity.r index 6f3769c61e..978f60ad0c 100644 --- a/R/stat-ydensity.r +++ b/R/stat-ydensity.r @@ -110,7 +110,7 @@ calc_bw <- function(x, bw) { if (length(x) < 2) stop("need at least 2 points to select a bandwidth automatically", call. = FALSE) bw <- switch( - tolower(bw), + to_lower_ascii(bw), nrd0 = stats::bw.nrd0(x), nrd = stats::bw.nrd(x), ucv = stats::bw.ucv(x), diff --git a/R/utilities.r b/R/utilities.r index 1e2d687c93..9b422e0d74 100644 --- a/R/utilities.r +++ b/R/utilities.r @@ -302,6 +302,20 @@ has_name <- function(x) { !is.na(nms) & nms != "" } +# Use chartr() for safety since toupper() fails to convert i to I in Turkish locale +lower_ascii <- "abcdefghijklmnopqrstuvwxyz" +upper_ascii <- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +to_lower_ascii <- function(x) chartr(upper_ascii, lower_ascii, x) +to_upper_ascii <- function(x) chartr(lower_ascii, upper_ascii, x) + +tolower <- function(x) { + stop('Please use `to_lower_ascii()`, which works fine in all locales.', call. = FALSE) +} + +toupper <- function(x) { + stop('Please use `to_upper_ascii()`, which works fine in all locales.', call. = FALSE) +} + # Convert a snake_case string to camelCase camelize <- function(x, first = FALSE) { x <- gsub("_(.)", "\\U\\1", x, perl = TRUE) @@ -313,11 +327,11 @@ snakeize <- function(x) { x <- gsub("([A-Za-z])([A-Z])([a-z])", "\\1_\\2\\3", x) x <- gsub(".", "_", x, fixed = TRUE) x <- gsub("([a-z])([A-Z])", "\\1_\\2", x) - tolower(x) + to_lower_ascii(x) } firstUpper <- function(s) { - paste(toupper(substring(s, 1,1)), substring(s, 2), sep = "") + paste0(to_upper_ascii(substring(s, 1, 1)), substring(s, 2)) } snake_class <- function(x) {