diff --git a/NAMESPACE b/NAMESPACE index da483518..eac3636e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -32,6 +32,7 @@ export(str_flatten_comma) export(str_glue) export(str_glue_data) export(str_ilike) +export(str_indent) export(str_interp) export(str_length) export(str_like) @@ -48,6 +49,7 @@ export(str_replace) export(str_replace_all) export(str_replace_na) export(str_sort) +export(str_space) export(str_split) export(str_split_1) export(str_split_fixed) diff --git a/R/indent.R b/R/indent.R new file mode 100644 index 00000000..596d8c01 --- /dev/null +++ b/R/indent.R @@ -0,0 +1,39 @@ +#' Indent multiple strings +#' +#' @description +#' `str_indent()` adds a customizable amount of spaces (or other characters) +#' before every word, as if it was tabbed, and puts every word on a new line. +#' @param indent_level controls the number of characters to add, +#' @param indent_character controls what character is placed. +#' @returns a newline separated list of words with a 'tab' character in between +#' @seealso [str_spaceout()] to add spaces between words. +#' @export +#' @examples +#' x <- c("why", "video", "cross", "extra", "deal", "authority") +#' # Default options +#' str_indent(x) +#' # Extra indentation +#' str_indent(x, indent_level = 4) +#' # Using periods for visibility +#' str_indent(x, indent_character = '.') +#' # Both parameters changed +#' str_indent(x, indent_level = 6, indent_character = '-') + +str_indent <- function(x, indent_level = 3, indent_character = ' ', collapse = NULL) { + + if (indent_level < 0) { + stop("Invalid indent level, indent_level must be zero or positive.") + } + # Create a "tab" string out of 3 spaces or other character + indent <- paste0(rep(indent_character, indent_level), collapse = '') + new_strings <- gsub("(?m)^", indent, x, perl = TRUE) + + # If vector not atomic, turns it into a single string separated by newlines + if (!is.null(collapse)) { + new_strings <- paste0(new_strings, collapse = collapse) + } + + return(new_strings) + # perl must be TRUE to use regular expressions in baser +} + diff --git a/R/space.R b/R/space.R new file mode 100644 index 00000000..e4905b6a --- /dev/null +++ b/R/space.R @@ -0,0 +1,48 @@ +#' Split up strings +#' +#' @description +#' `str_space()` adds a space wherever a lowercase letter is followed by an +#' uppercase letter, with modifiable functionality for special cases. +#' +#' @param split_style controls the placement of splits and can be +#' modified to the following styles: +#' `acronyms`: splits at lowercase-uppercase and between two uppercase letters +#' followed by lowercase, +#' `allcaps`: splits between all consecutive uppercase letters +#' `default`: splits only when a lowercase letter is succeeded by an uppercase letter +#' `everything`: splits between every character +#' +#' @param split_char controls the character that splits words. +#' This defaults to space but can be changed to anything. +#' +#' @seealso [str_indent()] to add tabs between words. +#' @export +#' @examples +#' input <- "XMLHTTPRequestAndHTMLParser" +#' # Default splitting +#' str_space(input, split_style = "default") +#' # Split acronyms +#' str_space(input, split_style = "acronyms") +#' # Split all consecutive uppercase letters +#' str_space(input, split_style = "allcaps") +#' # Split every character +#' str_space(input, split_style = "everything") +#' + +str_space <- function(x, split_style = "default", split_char = " ") { + if (split_style == "acronyms") { + # Splits at lowercase-uppercase and between two uppercase letters followed by lowercase + str_replace_all(x, "(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])", split_char) + } else if (split_style == "allcaps") { + # Splits between all consecutive uppercase letters + str_replace_all(x, "(?<=\\p{Lu})(?=\\p{Lu})", split_char) + } else if (split_style == "default") { + # Splits only when a lowercase letter is succeeded by an uppercase letter + str_replace_all(x, "(?<=[a-z])(?=[A-Z])", split_char) + } else if (split_style == "everything") { + # Splits between every character + str_replace_all(x, "(?<=.)(?=.)", split_char) + } else { + stop("Invalid split_style. Choose from 'default', 'acronyms', 'allcaps', or 'everything'.") + } +} diff --git a/man/str_indent.Rd b/man/str_indent.Rd new file mode 100644 index 00000000..67f74808 --- /dev/null +++ b/man/str_indent.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/indent.R +\name{str_indent} +\alias{str_indent} +\title{Indent multiple strings} +\usage{ +str_indent(x, indent_level = 3, indent_character = " ", collapse = NULL) +} +\arguments{ +\item{indent_level}{controls the number of characters to add,} + +\item{indent_character}{controls what character is placed.} +} +\value{ +a newline separated list of words with a 'tab' character in between +} +\description{ +\code{str_indent()} adds a customizable amount of spaces (or other characters) +before every word, as if it was tabbed, and puts every word on a new line. +} +\examples{ +x <- c("why", "video", "cross", "extra", "deal", "authority") +# Default options +str_indent(x) +# Extra indentation +str_indent(x, indent_level = 4) +# Using periods for visibility +str_indent(x, indent_character = '.') +# Both parameters changed +str_indent(x, indent_level = 6, indent_character = '-') +} +\seealso{ +\code{\link[=str_spaceout]{str_spaceout()}} to add spaces between words. +} diff --git a/man/str_space.Rd b/man/str_space.Rd new file mode 100644 index 00000000..826efa7b --- /dev/null +++ b/man/str_space.Rd @@ -0,0 +1,39 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/space.R +\name{str_space} +\alias{str_space} +\title{Split up strings} +\usage{ +str_space(x, split_style = "default", split_char = " ") +} +\arguments{ +\item{split_style}{controls the placement of splits and can be +modified to the following styles: +\code{acronyms}: splits at lowercase-uppercase and between two uppercase letters +followed by lowercase, +\code{allcaps}: splits between all consecutive uppercase letters +\code{default}: splits only when a lowercase letter is succeeded by an uppercase letter +\code{everything}: splits between every character} + +\item{split_char}{controls the character that splits words. +This defaults to space but can be changed to anything.} +} +\description{ +\code{str_space()} adds a space wherever a lowercase letter is followed by an +uppercase letter, with modifiable functionality for special cases. +} +\examples{ +input <- "XMLHTTPRequestAndHTMLParser" +# Default splitting +str_space(input, split_style = "default") +# Split acronyms +str_space(input, split_style = "acronyms") +# Split all consecutive uppercase letters +str_space(input, split_style = "allcaps") +# Split every character +str_space(input, split_style = "everything") + +} +\seealso{ +\code{\link[=str_indent]{str_indent()}} to add tabs between words. +} diff --git a/tests/testthat/test-indent.R b/tests/testthat/test-indent.R new file mode 100644 index 00000000..ea4bdd86 --- /dev/null +++ b/tests/testthat/test-indent.R @@ -0,0 +1,21 @@ +test_that("indenting works on vectors of different lengths", { + expect_equal(str_indent(c("why", "video", "cross", "extra", "deal", "authority")), + c(" why", " video", " cross", " extra", " deal", " authority")) + + expect_equal(str_indent(c("why", "video", "cross", "extra", "deal", "authority")), + c(" why", " video", " cross", " extra", " deal", " authority")) + expect_equal(str_indent("Jan\nFeb\nMar"), " Jan\n Feb\n Mar") +}) + +test_that("indenting works on vectors of different lengths with optional indent character", { + expect_equal(str_indent(c("why", "video", "cross", "extra", "deal", "authority"), + indent_character = ".", collapse = "\n"), "...why\n...video\n...cross\n...extra\n...deal\n...authority") + expect_equal(str_indent("Jan\nFeb\nMar", indent_character = "."), "...Jan\n...Feb\n...Mar") +}) + +test_that("indenting with collapse works", { + + expect_equal(str_indent(c("why", "video", "cross", "extra", "deal", "authority"), + indent_character = ".", collapse = "\n"), + "...why\n...video\n...cross\n...extra\n...deal\n...authority") +}) diff --git a/tests/testthat/test-space.R b/tests/testthat/test-space.R new file mode 100644 index 00000000..adab8f3d --- /dev/null +++ b/tests/testthat/test-space.R @@ -0,0 +1,6 @@ +test_that("str_space works", { + expect_equal(str_space("XMLHTTPRequestAndHTMLParser"), "XMLHTTPRequest And HTMLParser") + expect_equal(str_space("XMLHTTPRequestAndHTMLParser", "allcaps"), "X M L H T T P RequestAndH T M L Parser") + expect_equal(str_space("XMLHTTPRequestAndHTMLParser", "acronyms"), "XMLHTTP Request And HTML Parser") + expect_equal(str_space("XMLHTTPRequestAndHTMLParser", "everything"), "X M L H T T P R e q u e s t A n d H T M L P a r s e r") +})