diff --git a/DESCRIPTION b/DESCRIPTION index d4b1e1e..4af1dbf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -47,6 +47,5 @@ Collate: 'utils.R' 'zzz.R' VignetteBuilder: knitr -RoxygenNote: 5.0.1.9000 +RoxygenNote: 6.0.1 Repository: CRAN - diff --git a/NEWS.md b/NEWS.md index 5cab2ac..310de77 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,12 @@ lettercase ==== +2018-?-? : Version 0.15.0 +---- +- New Features: +-- CamelCase to snake_case (Issue #1) + + 2016-03-03 : Version 0.13.0 ---- First CRAN Release @@ -10,3 +16,4 @@ First CRAN Release -- Update README.md -- Improve vignettes - Ready for CRAN release + diff --git a/R/str_snake_case.R b/R/str_snake_case.R index 61cc14d..b4652a8 100644 --- a/R/str_snake_case.R +++ b/R/str_snake_case.R @@ -14,6 +14,8 @@ #' * multiple adjacent undescores are replaced by single underscore #' * Underscores at beginning or end of names are dropped #' +#' @note The CamelCase conversion is adapted from an approach described on [Stack Overflow](https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case/1176023#1176023). +#' #' @examples #' str_snake_case( "One Flew Over The Cuckoo's Nest" ) #' str_snake_case( "Catch-22" ) # catch_22 @@ -22,6 +24,10 @@ #' str_snake_case( "Catch 22" ) #' str_snake_case( " Catch 22 " ) #' +#' str_snake_case( "patient.dob" ) +#' str_snake_case( "patientDob" ) +#' str_snake_case( "PatientDob" ) +#' #' @rdname str_snake_case #' @aliases str_snake_case #' @export @@ -35,6 +41,10 @@ str_snake_case <- function( # for( ac in acronyms ) string <- gsub( tolower(ac), ac, string ) + # The first two lines accommodate CamelCase: https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case/1176023#1176023 + string <- gsub("(.)([A-Z][a-z]+)" , "\\1_\\2", string, perl=TRUE ) # Separate w/ dashes based on capitalization + string <- gsub("([a-z0-9])([A-Z])", "\\1_\\2", string, perl=TRUE ) + string <- gsub( '[^\\w\\s-\\.]', '', string, perl=TRUE ) string <- tolower(string) string <- gsub( pattern_separators, '_', string, perl=TRUE ) diff --git a/README.md b/README.md index 5d5abbb..4f66a3b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Lettercase [![Downloads](http://cranlogs.r-pkg.org/badges/lettercase?color=brightgreen)](http://www.r-pkg.org/pkg/lettercase) [![](http://cranlogs.r-pkg.org/badges/grand-total/lettercase)](http://cran.rstudio.com/web/packages/lettercase/index.html) [![software impact](http://depsy.org/api/package/r/lettercase/badge.svg)](http://depsy.org/package/r/lettercase) +[![Build Status](https://travis-ci.org/decisionpatterns/lettercase.svg?branch=dev)](https://travis-ci.org/decisionpatterns/lettercase) Utilities for formatting strings and character vectors to for capitalization, diff --git a/man/lettercase.Rd b/man/lettercase.Rd index 01eee0e..266b53a 100644 --- a/man/lettercase.Rd +++ b/man/lettercase.Rd @@ -33,4 +33,3 @@ Most often, the common convenience functions will be used. These are: \url{http://en.wikipedia.org/wiki/Capitalization} \url{http://perldoc.perl.org/perlrecharclass.html} } - diff --git a/man/make_names.Rd b/man/make_names.Rd index e76e897..3b18fd0 100644 --- a/man/make_names.Rd +++ b/man/make_names.Rd @@ -50,9 +50,6 @@ to use snake_case naming convention or are using SQL. make_names( c(".foo", "_bar"), leading="." ) # ".foo" ".bar" -} -\author{ -Christopher Brown } \references{ \url{https://en.wikipedia.org/wiki/Snake_case} \cr @@ -61,4 +58,6 @@ Christopher Brown \seealso{ \code{\link[base]{make.names}}, \code{\link[base]{make.unique}} } - +\author{ +Christopher Brown +} diff --git a/man/make_str_replace.Rd b/man/make_str_replace.Rd index f0bf988..c08bbec 100644 --- a/man/make_str_replace.Rd +++ b/man/make_str_replace.Rd @@ -1,8 +1,8 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/make_str_replace.R \name{make_str_replace} -\alias{make_str_delete} \alias{make_str_replace} +\alias{make_str_delete} \title{Make replace, delete and "is" functions for strings} \usage{ make_str_replace(pattern, replacement) @@ -37,4 +37,3 @@ Functions for building string functions for replacement, deletion and testing \examples{ # -tk } - diff --git a/man/patterns.Rd b/man/patterns.Rd index 1de0b21..ebfa910 100644 --- a/man/patterns.Rd +++ b/man/patterns.Rd @@ -2,14 +2,14 @@ % Please edit documentation in R/patterns.R \docType{data} \name{pattern_whitespace} -\alias{pattern_lowercase} -\alias{pattern_nonword} -\alias{pattern_separators} -\alias{pattern_ucfirst} -\alias{pattern_uppercase} \alias{pattern_whitespace} \alias{pattern_whitespace_like} +\alias{pattern_separators} +\alias{pattern_ucfirst} \alias{pattern_word} +\alias{pattern_nonword} +\alias{pattern_uppercase} +\alias{pattern_lowercase} \title{Common regular expression patterns used by lettercase} \format{An object of class \code{character} of length 1.} \usage{ @@ -39,4 +39,3 @@ These are patterns that are used in the lettercase package. These are not exported; to use them prefix them with \code{lettercase:::*} } \keyword{datasets} - diff --git a/man/str_cap_words.Rd b/man/str_cap_words.Rd index 711d990..3d4efbb 100644 --- a/man/str_cap_words.Rd +++ b/man/str_cap_words.Rd @@ -1,8 +1,8 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_cap_words.R \name{str_cap_words} -\alias{cap_words} \alias{str_cap_words} +\alias{cap_words} \title{str_cap_words} \usage{ str_cap_words(string) @@ -33,4 +33,3 @@ Function used to convert character vectors to CapWord format. str_cap_words( "Catch-22" ) # CATCH } - diff --git a/man/str_collapse_whitespace.Rd b/man/str_collapse_whitespace.Rd index f2afb4c..d9246b3 100644 --- a/man/str_collapse_whitespace.Rd +++ b/man/str_collapse_whitespace.Rd @@ -77,4 +77,3 @@ Collapses adjacent whitespace into a single character \code{?patterns} \cr \code{\link[base]{gsub}} which is used to implement this function. \cr } - diff --git a/man/str_delete.Rd b/man/str_delete.Rd index 9b233de..04b91de 100644 --- a/man/str_delete.Rd +++ b/man/str_delete.Rd @@ -27,4 +27,3 @@ Deletes all occurences of the patterns from the string using \code{\link[stringr]{modifiers}} \cr \code{\link[stringr]{str_replace_all}} } - diff --git a/man/str_is.Rd b/man/str_is.Rd index 389050e..b03453a 100644 --- a/man/str_is.Rd +++ b/man/str_is.Rd @@ -1,12 +1,14 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_is.R \name{str_is} -\alias{make_str_are} +\alias{str_is} +\alias{str_is_all} \alias{make_str_is} +\alias{make_str_are} +\alias{str_are_uppercase} \alias{str_are_upper_case} \alias{str_are_uppercase} -\alias{str_is} -\alias{str_is_all} +\alias{str_are_upper_case} \title{Test whether strings are of the specified type} \usage{ str_is(string, type, autostart = 30L) @@ -79,4 +81,3 @@ Family of functions for testing whether strings are of the specified type. \code{\link{make_str_replace}} \cr \code{\link{make_str_delete}} \cr } - diff --git a/man/str_sentence_case.Rd b/man/str_sentence_case.Rd index 5903947..8385aaa 100644 --- a/man/str_sentence_case.Rd +++ b/man/str_sentence_case.Rd @@ -14,4 +14,3 @@ Sentance case is ...} \description{ Format a string in sentence case } - diff --git a/man/str_snake_case.Rd b/man/str_snake_case.Rd index 1ddfbd1..cfb8b8a 100644 --- a/man/str_snake_case.Rd +++ b/man/str_snake_case.Rd @@ -23,6 +23,9 @@ str_snake_case(string, whitespace = getOption("lettercase.whitespace", \description{ Function used to convert character vectors to snake case format. } +\note{ +The CamelCase conversion is adapted from an approach described on [Stack Overflow](https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case/1176023#1176023). +} \examples{ str_snake_case( "One Flew Over The Cuckoo's Nest" ) str_snake_case( "Catch-22" ) # catch_22 @@ -31,5 +34,8 @@ Function used to convert character vectors to snake case format. str_snake_case( "Catch 22" ) str_snake_case( " Catch 22 " ) + str_snake_case( "patient.dob" ) + str_snake_case( "patientDob" ) + str_snake_case( "PatientDob" ) + } - diff --git a/man/str_spine_case.Rd b/man/str_spine_case.Rd index 6c4d5b0..bb966cb 100644 --- a/man/str_spine_case.Rd +++ b/man/str_spine_case.Rd @@ -1,9 +1,9 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_spine_case.R \name{str_spine_case} -\alias{str_hyphen_case} -\alias{str_spinal_case} \alias{str_spine_case} +\alias{str_spinal_case} +\alias{str_hyphen_case} \title{str_spine_case} \usage{ str_spine_case(string, whitespace = getOption("lettercase.whitespace", @@ -38,4 +38,3 @@ Function used to convert character vectors to spine case format. str_spine_case( "Catch_ 22" ) } - diff --git a/man/str_title_case.Rd b/man/str_title_case.Rd index 573e3ee..b00e358 100644 --- a/man/str_title_case.Rd +++ b/man/str_title_case.Rd @@ -18,4 +18,3 @@ exported and should not be called directly. str_title_case( "one_flew_over_the_cuckoo_'_s_nest" ) } - diff --git a/man/str_transform.Rd b/man/str_transform.Rd index b9faa81..c4d370e 100644 --- a/man/str_transform.Rd +++ b/man/str_transform.Rd @@ -39,4 +39,3 @@ Convert a string by applying one or more str_* functions. \code{\link{make_str_replace}} \code{\link{make_str_delete}} } - diff --git a/man/str_ucfirst.Rd b/man/str_ucfirst.Rd index ca143af..bbacc2c 100644 --- a/man/str_ucfirst.Rd +++ b/man/str_ucfirst.Rd @@ -1,8 +1,8 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_ucfirst.R \name{str_ucfirst} -\alias{is_ucfirst} \alias{str_ucfirst} +\alias{is_ucfirst} \title{str_ucfirst} \usage{ str_ucfirst(string) @@ -32,4 +32,3 @@ Convert first character of a string to uppercase \seealso{ \code{\link{str_title_case}} } - diff --git a/man/str_uppercase.Rd b/man/str_uppercase.Rd index a58eeb3..2132ce2 100644 --- a/man/str_uppercase.Rd +++ b/man/str_uppercase.Rd @@ -1,28 +1,28 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_lowercase.R, R/str_uppercase.R \name{str_lowercase} -\alias{is_all_caps} -\alias{is_allcaps} -\alias{is_lower} -\alias{is_lower_case} -\alias{is_lowercase} -\alias{is_upper} -\alias{is_upper_case} -\alias{is_uppercase} -\alias{lower_case} +\alias{str_lowercase} \alias{lowercase} -\alias{str_all_caps} -\alias{str_allcaps} -\alias{str_capitalize} -\alias{str_decapitalize} -\alias{str_lower} +\alias{lower_case} \alias{str_lower_case} -\alias{str_lowercase} -\alias{str_upper} -\alias{str_upper_case} +\alias{str_lower} +\alias{str_decapitalize} +\alias{is_lowercase} +\alias{is_lower_case} +\alias{is_lower} \alias{str_uppercase} -\alias{upper_case} \alias{uppercase} +\alias{upper_case} +\alias{str_upper_case} +\alias{str_upper} +\alias{str_all_caps} +\alias{str_allcaps} +\alias{str_capitalize} +\alias{is_uppercase} +\alias{is_upper_case} +\alias{is_upper} +\alias{is_all_caps} +\alias{is_allcaps} \title{str_uppercase, str_lowercases} \usage{ str_lowercase(string) @@ -81,6 +81,7 @@ convert string to upper or lower case \code{str_all_caps} is a synonym for \code{str_uppercase}. \code{is_all_caps} is a synonym for \code{is_upper_case}. } + \examples{ str_decapitalize( "ABC" ) # abc @@ -107,4 +108,3 @@ convert string to upper or lower case \seealso{ \code{\link{str_is}} } - diff --git a/man/string_transformations.Rd b/man/string_transformations.Rd index fe207d5..3ce1ff0 100644 --- a/man/string_transformations.Rd +++ b/man/string_transformations.Rd @@ -1,12 +1,12 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/str_functions.R \name{str_delete_whitespace} -\alias{str_delete_leading_nonword} -\alias{str_delete_nonword} -\alias{str_delete_separators} -\alias{str_delete_space} \alias{str_delete_whitespace} +\alias{str_delete_separators} +\alias{str_delete_nonword} \alias{str_expand_capwords} +\alias{str_delete_leading_nonword} +\alias{str_delete_space} \title{Common string transformations} \usage{ str_delete_whitespace(string) @@ -46,4 +46,3 @@ Perform common transformations on strings str_delete_nonword( "ABC & 123" ) # ABC123 } - diff --git a/tests/testthat/test-snake_case.r b/tests/testthat/test-snake_case.r index 560b4bc..aa7265d 100644 --- a/tests/testthat/test-snake_case.r +++ b/tests/testthat/test-snake_case.r @@ -8,8 +8,19 @@ str_snake_case( 'mission_of_burma' ) %>% expect_equal( 'mission_of_burma' ) str_snake_case( 'mission-of-burma' ) %>% expect_equal( 'mission_of_burma' ) str_snake_case( 'mission.of.burma' ) %>% expect_equal( 'mission_of_burma' ) str_snake_case( 'Mission of Burma' ) %>% expect_equal( 'mission_of_burma' ) +str_snake_case( 'MissionOfBurma' ) %>% expect_equal( 'mission_of_burma' ) +str_snake_case( 'missionOfBurma' ) %>% expect_equal( 'mission_of_burma' ) str_snake_case( ' .mission.of.burma. ' ) %>% expect_equal( 'mission_of_burma' ) -# str_snake_case( 'mission-of-burma' ) %>% expect_equal( 'mission_of_burma' ) -# str_snake_case( 'mission_of_burma' ) %>% expect_equal( 'mission_of_burma' ) -# str_snake_case( 'MissionOfBurma' ) %>% expect_equal( 'mission_of_burma' ) +str_snake_case( 'mission' ) %>% expect_equal( 'mission' ) +str_snake_case( 'Mission' ) %>% expect_equal( 'mission' ) + +str_snake_case( "Catch-22" ) %>% expect_equal( 'catch_22' ) +str_snake_case( "Catch.22" ) %>% expect_equal( 'catch_22' ) +str_snake_case( "Catch_22" ) %>% expect_equal( 'catch_22' ) +str_snake_case( "Catch 22" ) %>% expect_equal( 'catch_22' ) +str_snake_case( " Catch 22 " ) %>% expect_equal( 'catch_22' ) + +str_snake_case( "patient.dob" ) %>% expect_equal( 'patient_dob' ) +str_snake_case( "patientDob" ) %>% expect_equal( 'patient_dob' ) +str_snake_case( "PatientDob" ) %>% expect_equal( 'patient_dob' )